amduat/src/pel_stack/surf/surf.c
2026-01-23 20:18:23 +01:00

838 lines
28 KiB
C

#include "amduat/pel/surf.h"
#include "amduat/asl/asl_materialization_cache_fs.h"
#include "amduat/asl/asl_store_fs.h"
#include "amduat/enc/pel1_result.h"
#include "amduat/enc/pel_program_dag.h"
#include "amduat/enc/pel_trace_dag.h"
#include "amduat/pel/derivation_sid.h"
#include "amduat/pel/opreg_kernel.h"
#include "amduat/util/log.h"
#include "pel_program_dag_internal.h"
#include "amduat/pel/program_dag_desc.h"
#include <stdarg.h>
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void amduat_pel_surf_free_refs(amduat_reference_t *refs, size_t refs_len) {
size_t i;
if (refs == NULL) {
return;
}
for (i = 0; i < refs_len; ++i) {
amduat_reference_free(&refs[i]);
}
free(refs);
}
void amduat_pel_surf_free_ref(amduat_reference_t *ref) {
amduat_reference_free(ref);
}
static bool amduat_pel_surf_resolve_artifact(amduat_reference_t ref,
amduat_artifact_t *out_artifact,
void *ctx) {
amduat_asl_store_t *store = (amduat_asl_store_t *)ctx;
if (store == NULL || out_artifact == NULL) {
return false;
}
return amduat_asl_store_get(store, ref, out_artifact) ==
AMDUAT_ASL_STORE_OK;
}
static void amduat_init_core_result(amduat_pel_execution_result_value_t *result,
amduat_reference_t scheme_ref,
amduat_pel_execution_status_t status,
amduat_pel_execution_error_kind_t kind,
uint32_t status_code) {
if (result == NULL) {
return;
}
result->pel1_version = 1;
result->status = status;
result->scheme_ref = scheme_ref;
result->summary.kind = kind;
result->summary.status_code = status_code;
result->diagnostics = NULL;
result->diagnostics_len = 0;
}
static bool amduat_surf_diag_setf(
amduat_pel_execution_result_value_t *result,
uint32_t code,
const char *fmt,
...) {
va_list ap;
va_list ap_copy;
int needed;
size_t message_len;
uint8_t *buffer;
amduat_pel_diagnostic_entry_t *entries;
if (result == NULL || fmt == NULL) {
return false;
}
amduat_pel_execution_result_free(result);
va_start(ap, fmt);
va_copy(ap_copy, ap);
needed = vsnprintf(NULL, 0, fmt, ap_copy);
va_end(ap_copy);
if (needed < 0) {
va_end(ap);
return false;
}
message_len = (size_t)needed;
buffer = NULL;
if (message_len != 0) {
buffer = (uint8_t *)malloc(message_len + 1);
if (buffer == NULL) {
va_end(ap);
return false;
}
if (vsnprintf((char *)buffer, message_len + 1, fmt, ap) < 0) {
free(buffer);
va_end(ap);
return false;
}
}
va_end(ap);
entries = (amduat_pel_diagnostic_entry_t *)calloc(1, sizeof(*entries));
if (entries == NULL) {
free(buffer);
return false;
}
entries[0].code = code;
entries[0].message = amduat_octets(buffer, message_len);
result->diagnostics = entries;
result->diagnostics_len = 1;
return true;
}
enum {
AMDUAT_PEL_DAG_DIAG_DECODE_FAILED = 0x00010001u,
AMDUAT_PEL_DAG_DIAG_WRONG_TYPE_TAG = 0x00010002u
};
static bool amduat_store_error_map(amduat_asl_store_error_t err,
amduat_pel_store_error_code_t *out_code) {
if (out_code == NULL) {
return false;
}
switch (err) {
case AMDUAT_ASL_STORE_ERR_NOT_FOUND:
*out_code = AMDUAT_PEL_STORE_ERROR_NOT_FOUND;
return true;
case AMDUAT_ASL_STORE_ERR_INTEGRITY:
*out_code = AMDUAT_PEL_STORE_ERROR_INTEGRITY;
return true;
case AMDUAT_ASL_STORE_ERR_UNSUPPORTED:
*out_code = AMDUAT_PEL_STORE_ERROR_UNSUPPORTED;
return true;
default:
return false;
}
}
static bool amduat_store_surface_result(
amduat_asl_store_t *store,
const amduat_pel_execution_result_value_t *core_result,
amduat_reference_t scheme_ref,
amduat_reference_t program_ref,
const amduat_reference_t *input_refs,
size_t input_refs_len,
const amduat_reference_t *output_refs,
size_t output_refs_len,
bool has_params_ref,
amduat_reference_t params_ref,
bool has_store_failure,
const amduat_pel_store_failure_t *store_failure,
bool has_trace_ref,
amduat_reference_t trace_ref,
amduat_reference_t *out_result_ref) {
amduat_pel_surface_execution_result_t result;
amduat_octets_t encoded;
amduat_artifact_t artifact;
amduat_asl_store_error_t store_err;
if (store == NULL || core_result == NULL || out_result_ref == NULL) {
return false;
}
memset(&result, 0, sizeof(result));
result.pel1_version = 1;
result.core_result = *core_result;
result.scheme_ref = scheme_ref;
result.program_ref = program_ref;
result.input_refs = (amduat_reference_t *)input_refs;
result.input_refs_len = input_refs_len;
result.output_refs = (amduat_reference_t *)output_refs;
result.output_refs_len = output_refs_len;
result.has_params_ref = has_params_ref;
if (has_params_ref) {
result.params_ref = params_ref;
}
result.has_store_failure = has_store_failure;
if (has_store_failure && store_failure != NULL) {
result.store_failure = *store_failure;
}
result.has_trace_ref = has_trace_ref;
if (has_trace_ref) {
result.trace_ref = trace_ref;
}
encoded = amduat_octets(NULL, 0);
if (!amduat_enc_pel1_result_encode_v1(&result, &encoded)) {
return false;
}
artifact = amduat_artifact_with_type(
encoded, amduat_type_tag(AMDUAT_TYPE_TAG_PEL1_RESULT_1));
store_err = amduat_asl_store_put(store, artifact, out_result_ref);
free((void *)encoded.data);
return store_err == AMDUAT_ASL_STORE_OK;
}
static void amduat_trace_nodes_free(amduat_pel_node_trace_dag_t *nodes,
size_t nodes_len) {
size_t i;
if (nodes == NULL) {
return;
}
for (i = 0; i < nodes_len; ++i) {
amduat_pel_node_trace_dag_t *node = &nodes[i];
if (node->output_refs != NULL) {
size_t j;
for (j = 0; j < node->output_refs_len; ++j) {
amduat_reference_free(&node->output_refs[j]);
}
free(node->output_refs);
node->output_refs = NULL;
node->output_refs_len = 0;
}
if (node->diagnostics != NULL) {
size_t j;
for (j = 0; j < node->diagnostics_len; ++j) {
amduat_octets_free(&node->diagnostics[j].message);
}
free(node->diagnostics);
node->diagnostics = NULL;
node->diagnostics_len = 0;
}
}
free(nodes);
}
static const char k_materialized_hit_op_name[] = "materialized_hit";
static bool amduat_pel_surf_store_fs_ctx(
const amduat_asl_store_t *store,
amduat_asl_store_fs_t **out_fs) {
amduat_asl_store_ops_t fs_ops;
if (out_fs == NULL) {
return false;
}
*out_fs = NULL;
if (store == NULL) {
return false;
}
fs_ops = amduat_asl_store_fs_ops();
if (store->ops.put != fs_ops.put ||
store->ops.get != fs_ops.get ||
store->ops.put_indexed != fs_ops.put_indexed ||
store->ops.get_indexed != fs_ops.get_indexed ||
store->ops.tombstone != fs_ops.tombstone ||
store->ops.tombstone_lift != fs_ops.tombstone_lift ||
store->ops.log_scan != fs_ops.log_scan ||
store->ops.current_state != fs_ops.current_state ||
store->ops.validate_config != fs_ops.validate_config) {
return false;
}
*out_fs = (amduat_asl_store_fs_t *)store->ctx;
return *out_fs != NULL;
}
static bool amduat_store_trace(
amduat_asl_store_t *store,
amduat_reference_t scheme_ref,
amduat_reference_t program_ref,
const amduat_reference_t *input_refs,
size_t input_refs_len,
bool has_params_ref,
amduat_reference_t params_ref,
bool has_exec_result_ref,
amduat_reference_t exec_result_ref,
const amduat_pel_execution_result_value_t *core_result,
const amduat_pel_program_t *program,
const amduat_pel_program_dag_trace_t *trace_eval,
bool materialized_hit,
amduat_reference_t *out_trace_ref) {
amduat_pel_trace_dag_value_t trace;
amduat_pel_node_trace_dag_t *node_traces;
amduat_octets_t encoded;
amduat_artifact_t artifact;
amduat_asl_store_error_t store_err;
size_t node_count;
size_t i;
if (store == NULL || core_result == NULL || out_trace_ref == NULL) {
return false;
}
node_traces = NULL;
node_count = 0;
if (program != NULL && trace_eval != NULL && trace_eval->any_node_executed) {
node_count = program->nodes_len;
if (node_count != 0) {
node_traces = (amduat_pel_node_trace_dag_t *)calloc(
node_count, sizeof(*node_traces));
if (node_traces == NULL) {
return false;
}
}
for (i = 0; i < node_count; ++i) {
size_t node_index = trace_eval->order[i];
const amduat_pel_node_t *node = &program->nodes[node_index];
amduat_pel_program_dag_node_result_t *state =
&trace_eval->nodes[node_index];
amduat_pel_node_trace_dag_t *trace_node = &node_traces[i];
trace_node->node_id = node->id;
trace_node->op_name = node->op.name;
trace_node->op_version = node->op.version;
trace_node->status = state->status;
trace_node->status_code = state->status_code;
trace_node->diagnostics = NULL;
trace_node->diagnostics_len = 0;
if (state->diagnostics_len != 0) {
size_t j;
trace_node->diagnostics = (amduat_pel_diagnostic_entry_t *)calloc(
state->diagnostics_len, sizeof(*trace_node->diagnostics));
if (trace_node->diagnostics == NULL) {
amduat_trace_nodes_free(node_traces, node_count);
return false;
}
trace_node->diagnostics_len = state->diagnostics_len;
for (j = 0; j < state->diagnostics_len; ++j) {
trace_node->diagnostics[j].code = state->diagnostics[j].code;
if (!amduat_octets_clone(state->diagnostics[j].message,
&trace_node->diagnostics[j].message)) {
amduat_trace_nodes_free(node_traces, node_count);
return false;
}
}
}
if (state->status == AMDUAT_PEL_NODE_TRACE_OK &&
state->outputs_len != 0) {
size_t j;
trace_node->output_refs = (amduat_reference_t *)calloc(
state->outputs_len, sizeof(*trace_node->output_refs));
if (trace_node->output_refs == NULL) {
amduat_trace_nodes_free(node_traces, node_count);
return false;
}
trace_node->output_refs_len = state->outputs_len;
for (j = 0; j < state->outputs_len; ++j) {
store_err = amduat_asl_store_put(store, state->outputs[j],
&trace_node->output_refs[j]);
if (store_err != AMDUAT_ASL_STORE_OK) {
amduat_trace_nodes_free(node_traces, node_count);
return false;
}
}
}
}
}
if (materialized_hit) {
amduat_pel_node_trace_dag_t *next;
/* Emit a synthetic trace entry to mark a materialization cache hit. */
next = (amduat_pel_node_trace_dag_t *)realloc(
node_traces, (node_count + 1u) * sizeof(*node_traces));
if (next == NULL) {
amduat_trace_nodes_free(node_traces, node_count);
return false;
}
node_traces = next;
memset(&node_traces[node_count], 0, sizeof(*node_traces));
/* UINT32_MAX is a reserved sentinel; decoders treat node_id as opaque. */
node_traces[node_count].node_id = UINT32_MAX;
node_traces[node_count].op_name = amduat_octets(
(const uint8_t *)k_materialized_hit_op_name,
sizeof(k_materialized_hit_op_name) - 1u);
node_traces[node_count].op_version = 1u;
node_traces[node_count].status = AMDUAT_PEL_NODE_TRACE_SKIPPED;
node_traces[node_count].status_code = 0u;
node_count += 1u;
}
memset(&trace, 0, sizeof(trace));
trace.pel1_version = 1;
trace.scheme_ref = scheme_ref;
trace.program_ref = program_ref;
trace.status = core_result->status;
trace.summary = core_result->summary;
trace.has_exec_result_ref = has_exec_result_ref;
if (has_exec_result_ref) {
trace.exec_result_ref = exec_result_ref;
}
trace.input_refs = (amduat_reference_t *)input_refs;
trace.input_refs_len = input_refs_len;
trace.has_params_ref = has_params_ref;
if (has_params_ref) {
trace.params_ref = params_ref;
}
trace.node_traces = node_traces;
trace.node_traces_len = node_count;
encoded = amduat_octets(NULL, 0);
if (!amduat_enc_pel_trace_dag_encode_v1(&trace, &encoded)) {
amduat_trace_nodes_free(node_traces, node_count);
return false;
}
artifact = amduat_artifact_with_type(
encoded, amduat_type_tag(AMDUAT_TYPE_TAG_PEL_TRACE_DAG_1));
store_err = amduat_asl_store_put(store, artifact, out_trace_ref);
free((void *)encoded.data);
amduat_trace_nodes_free(node_traces, node_count);
return store_err == AMDUAT_ASL_STORE_OK;
}
bool amduat_pel_surf_run(amduat_asl_store_t *store,
amduat_reference_t scheme_ref,
amduat_reference_t program_ref,
const amduat_reference_t *input_refs,
size_t input_refs_len,
bool has_params_ref,
amduat_reference_t params_ref,
amduat_reference_t **out_output_refs,
size_t *out_output_refs_len,
amduat_reference_t *out_result_ref) {
amduat_pel_execution_result_value_t core_result;
amduat_pel_store_failure_t store_failure;
amduat_pel_store_error_code_t store_error_code;
amduat_asl_store_error_t store_err;
amduat_artifact_t program_artifact;
amduat_artifact_t *input_artifacts;
amduat_artifact_t params_artifact;
amduat_pel_program_t program;
amduat_pel_program_dag_trace_t trace_eval;
amduat_artifact_t *outputs;
size_t outputs_len;
amduat_reference_t *output_refs;
size_t output_refs_len;
amduat_asl_materialization_cache_fs_t mat_cache;
amduat_octets_t sid;
amduat_reference_t trace_ref;
amduat_reference_t exec_result_ref;
size_t i;
bool program_decoded = false;
bool has_params_artifact = false;
bool exec_invoked = false;
bool trace_ok = false;
bool has_exec_result_ref = false;
bool mat_cache_ready = false;
bool materialized_hit = false;
bool cache_miss_due_missing = false;
bool executed = false;
if (store == NULL || out_output_refs == NULL ||
out_output_refs_len == NULL || out_result_ref == NULL) {
return false;
}
if (input_refs_len != 0 && input_refs == NULL) {
return false;
}
*out_output_refs = NULL;
*out_output_refs_len = 0;
out_result_ref->hash_id = 0;
out_result_ref->digest = amduat_octets(NULL, 0);
trace_ref.hash_id = 0;
trace_ref.digest = amduat_octets(NULL, 0);
exec_result_ref.hash_id = 0;
exec_result_ref.digest = amduat_octets(NULL, 0);
sid = amduat_octets(NULL, 0);
if (!amduat_reference_eq(scheme_ref,
amduat_pel_program_dag_scheme_ref())) {
amduat_init_core_result(&core_result, scheme_ref,
AMDUAT_PEL_EXEC_STATUS_SCHEME_UNSUPPORTED,
AMDUAT_PEL_EXEC_ERROR_SCHEME, 1);
return amduat_store_surface_result(store, &core_result, scheme_ref,
program_ref, input_refs, input_refs_len,
NULL, 0, has_params_ref, params_ref,
false, NULL, false, trace_ref,
out_result_ref);
}
store_err = amduat_asl_store_get(store, program_ref, &program_artifact);
if (store_err != AMDUAT_ASL_STORE_OK) {
if (!amduat_store_error_map(store_err, &store_error_code)) {
return false;
}
amduat_init_core_result(&core_result, scheme_ref,
AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM,
AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2);
store_failure.phase = AMDUAT_PEL_STORE_FAILURE_PROGRAM;
store_failure.error_code = store_error_code;
store_failure.failing_ref = program_ref;
return amduat_store_surface_result(
store, &core_result, scheme_ref, program_ref, input_refs,
input_refs_len, NULL, 0, has_params_ref, params_ref, true,
&store_failure, false, trace_ref, out_result_ref);
}
input_artifacts = NULL;
if (input_refs_len != 0) {
input_artifacts = (amduat_artifact_t *)calloc(
input_refs_len, sizeof(*input_artifacts));
if (input_artifacts == NULL) {
amduat_artifact_free(&program_artifact);
return false;
}
}
for (i = 0; i < input_refs_len; ++i) {
store_err = amduat_asl_store_get(store, input_refs[i],
&input_artifacts[i]);
if (store_err != AMDUAT_ASL_STORE_OK) {
size_t j;
if (!amduat_store_error_map(store_err, &store_error_code)) {
amduat_artifact_free(&program_artifact);
free(input_artifacts);
return false;
}
for (j = 0; j < i; ++j) {
amduat_artifact_free(&input_artifacts[j]);
}
free(input_artifacts);
amduat_artifact_free(&program_artifact);
amduat_init_core_result(&core_result, scheme_ref,
AMDUAT_PEL_EXEC_STATUS_INVALID_INPUTS,
AMDUAT_PEL_EXEC_ERROR_INPUTS, 3);
store_failure.phase = AMDUAT_PEL_STORE_FAILURE_INPUT;
store_failure.error_code = store_error_code;
store_failure.failing_ref = input_refs[i];
return amduat_store_surface_result(
store, &core_result, scheme_ref, program_ref, input_refs,
input_refs_len, NULL, 0, has_params_ref, params_ref, true,
&store_failure, false, trace_ref, out_result_ref);
}
}
if (has_params_ref) {
store_err = amduat_asl_store_get(store, params_ref, &params_artifact);
if (store_err != AMDUAT_ASL_STORE_OK) {
if (!amduat_store_error_map(store_err, &store_error_code)) {
amduat_artifact_free(&program_artifact);
for (i = 0; i < input_refs_len; ++i) {
amduat_artifact_free(&input_artifacts[i]);
}
free(input_artifacts);
return false;
}
amduat_artifact_free(&program_artifact);
for (i = 0; i < input_refs_len; ++i) {
amduat_artifact_free(&input_artifacts[i]);
}
free(input_artifacts);
amduat_init_core_result(&core_result, scheme_ref,
AMDUAT_PEL_EXEC_STATUS_INVALID_INPUTS,
AMDUAT_PEL_EXEC_ERROR_INPUTS, 3);
store_failure.phase = AMDUAT_PEL_STORE_FAILURE_INPUT;
store_failure.error_code = store_error_code;
store_failure.failing_ref = params_ref;
return amduat_store_surface_result(
store, &core_result, scheme_ref, program_ref, input_refs,
input_refs_len, NULL, 0, has_params_ref, params_ref, true,
&store_failure, false, trace_ref, out_result_ref);
}
has_params_artifact = true;
}
/*
* Cache safety assumptions:
* - PEL DAG execution is deterministic for ProgramRef + Inputs + Params.
* - ExecProfile is currently absent and encoded as a marker only.
* - The store is single-tenant; SID collisions are treated as integrity errors.
* - This code path assumes amduat_asl_store_fs_t as the backing store.
*/
{
amduat_pel_derivation_sid_input_t sid_input;
memset(&sid_input, 0, sizeof(sid_input));
sid_input.program_ref = program_ref;
sid_input.input_refs = input_refs;
sid_input.input_refs_len = input_refs_len;
sid_input.has_params_ref = has_params_ref;
if (has_params_ref) {
sid_input.params_ref = params_ref;
}
sid_input.has_exec_profile = false;
sid_input.exec_profile = amduat_octets(NULL, 0u);
if (amduat_pel_derivation_sid_compute(&sid_input, &sid)) {
amduat_asl_store_fs_t *fs = NULL;
if (amduat_pel_surf_store_fs_ctx(store, &fs) &&
amduat_asl_materialization_cache_fs_init(&mat_cache,
fs->root_path)) {
mat_cache_ready = true;
}
}
}
if (mat_cache_ready) {
amduat_reference_t *cached_refs = NULL;
size_t cached_len = 0;
amduat_asl_store_error_t cache_err;
cache_err = amduat_asl_materialization_cache_fs_get(&mat_cache, sid,
&cached_refs,
&cached_len);
if (cache_err == AMDUAT_ASL_STORE_OK) {
bool cache_valid = true;
for (i = 0; i < cached_len; ++i) {
amduat_artifact_t cached_artifact;
if (amduat_asl_store_get(store, cached_refs[i],
&cached_artifact) !=
AMDUAT_ASL_STORE_OK) {
cache_valid = false;
break;
}
amduat_artifact_free(&cached_artifact);
}
if (cache_valid) {
output_refs = cached_refs;
output_refs_len = cached_len;
materialized_hit = true;
exec_invoked = true;
amduat_init_core_result(&core_result, scheme_ref,
AMDUAT_PEL_EXEC_STATUS_OK,
AMDUAT_PEL_EXEC_ERROR_NONE, 0);
outputs = NULL;
outputs_len = 0;
amduat_artifact_free(&program_artifact);
goto cache_hit;
}
cache_miss_due_missing = true;
amduat_pel_surf_free_refs(cached_refs, cached_len);
}
}
exec_invoked = true;
outputs = NULL;
outputs_len = 0;
memset(&trace_eval, 0, sizeof(trace_eval));
{
amduat_type_tag_t expected_type_tag;
amduat_asl_encoding_profile_id_t expected_profile;
if (!amduat_pel_program_dag_desc_get_program_binding(&expected_type_tag,
&expected_profile)) {
amduat_artifact_free(&program_artifact);
for (i = 0; i < input_refs_len; ++i) {
amduat_artifact_free(&input_artifacts[i]);
}
free(input_artifacts);
if (has_params_artifact) {
amduat_artifact_free(&params_artifact);
}
return false;
}
if (expected_profile != AMDUAT_PEL_ENC_PROGRAM_DAG_V1) {
amduat_artifact_free(&program_artifact);
for (i = 0; i < input_refs_len; ++i) {
amduat_artifact_free(&input_artifacts[i]);
}
free(input_artifacts);
if (has_params_artifact) {
amduat_artifact_free(&params_artifact);
}
return false;
}
if (!program_artifact.has_type_tag ||
program_artifact.type_tag.tag_id != expected_type_tag.tag_id) {
amduat_init_core_result(&core_result, scheme_ref,
AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM,
AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2);
amduat_surf_diag_setf(&core_result,
AMDUAT_PEL_DAG_DIAG_WRONG_TYPE_TAG,
"invalid program: wrong type tag");
} else {
amduat_pel_program_dag_decode_status_t decode_status =
amduat_enc_pel_program_dag_decode_v1_ex(program_artifact.bytes,
&program);
if (decode_status == AMDUAT_PEL_PROGRAM_DAG_DECODE_OOM) {
amduat_artifact_free(&program_artifact);
for (i = 0; i < input_refs_len; ++i) {
amduat_artifact_free(&input_artifacts[i]);
}
free(input_artifacts);
if (has_params_artifact) {
amduat_artifact_free(&params_artifact);
}
return false;
}
if (decode_status != AMDUAT_PEL_PROGRAM_DAG_DECODE_OK) {
amduat_init_core_result(&core_result, scheme_ref,
AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM,
AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2);
amduat_surf_diag_setf(&core_result,
AMDUAT_PEL_DAG_DIAG_DECODE_FAILED,
"invalid program: decode failed");
} else {
program_decoded = true;
const amduat_artifact_t *params_arg =
has_params_artifact ? &params_artifact : NULL;
amduat_pel_kernel_set_artifact_resolver(
amduat_pel_surf_resolve_artifact, store);
if (!amduat_pel_program_dag_exec_trace(
&program, input_artifacts, input_refs_len, params_arg, &outputs,
&outputs_len, &core_result, &trace_eval)) {
amduat_pel_kernel_clear_artifact_resolver();
amduat_artifact_free(&program_artifact);
amduat_enc_pel_program_dag_free(&program);
for (i = 0; i < input_refs_len; ++i) {
amduat_artifact_free(&input_artifacts[i]);
}
free(input_artifacts);
if (has_params_artifact) {
amduat_artifact_free(&params_artifact);
}
amduat_pel_program_dag_free_outputs(outputs, outputs_len);
return false;
}
amduat_pel_kernel_clear_artifact_resolver();
executed = true;
}
}
}
amduat_artifact_free(&program_artifact);
output_refs = NULL;
output_refs_len = outputs_len;
if (outputs_len != 0) {
output_refs = (amduat_reference_t *)calloc(outputs_len, sizeof(*output_refs));
if (output_refs == NULL) {
trace_ok = false;
goto cleanup;
}
for (i = 0; i < outputs_len; ++i) {
store_err = amduat_asl_store_put(store, outputs[i], &output_refs[i]);
if (store_err != AMDUAT_ASL_STORE_OK) {
trace_ok = false;
goto cleanup;
}
}
}
if (mat_cache_ready) {
(void)amduat_asl_materialization_cache_fs_put(&mat_cache, sid,
output_refs, output_refs_len);
}
cache_hit:
#ifndef NDEBUG
if (cache_miss_due_missing) {
assert(!materialized_hit);
}
#endif
if (materialized_hit) {
amduat_log(AMDUAT_LOG_DEBUG, "pel surf: materialization hit");
} else if (executed) {
if (cache_miss_due_missing) {
amduat_log(AMDUAT_LOG_DEBUG,
"pel surf: executed (cache miss: missing outputs)");
} else {
amduat_log(AMDUAT_LOG_DEBUG, "pel surf: executed");
}
}
trace_ok = false;
if (exec_invoked) {
if (!amduat_store_surface_result(
store, &core_result, scheme_ref, program_ref, input_refs,
input_refs_len, output_refs, output_refs_len, has_params_ref,
params_ref, false, NULL, false, trace_ref, &exec_result_ref)) {
goto cleanup;
}
has_exec_result_ref = true;
trace_ok = amduat_store_trace(
store, scheme_ref, program_ref, input_refs, input_refs_len,
has_params_ref, params_ref, has_exec_result_ref, exec_result_ref,
&core_result,
program_decoded ? &program : NULL,
program_decoded ? &trace_eval : NULL,
materialized_hit,
&trace_ref);
if (!trace_ok) {
goto cleanup;
}
}
if (!amduat_store_surface_result(
store, &core_result, scheme_ref, program_ref, input_refs,
input_refs_len, output_refs, output_refs_len, has_params_ref,
params_ref, false, NULL, trace_ok, trace_ref, out_result_ref)) {
goto cleanup;
}
*out_output_refs = output_refs;
*out_output_refs_len = output_refs_len;
if (program_decoded) {
amduat_enc_pel_program_dag_free(&program);
amduat_pel_program_dag_trace_free(&trace_eval);
}
for (i = 0; i < input_refs_len; ++i) {
amduat_artifact_free(&input_artifacts[i]);
}
free(input_artifacts);
if (has_params_artifact) {
amduat_artifact_free(&params_artifact);
}
amduat_pel_program_dag_free_outputs(outputs, outputs_len);
amduat_pel_execution_result_free(&core_result);
amduat_pel_surf_free_ref(&exec_result_ref);
amduat_octets_free(&sid);
return true;
cleanup:
amduat_pel_surf_free_refs(output_refs, output_refs_len);
if (program_decoded) {
amduat_enc_pel_program_dag_free(&program);
amduat_pel_program_dag_trace_free(&trace_eval);
}
for (i = 0; i < input_refs_len; ++i) {
amduat_artifact_free(&input_artifacts[i]);
}
free(input_artifacts);
if (has_params_artifact) {
amduat_artifact_free(&params_artifact);
}
amduat_pel_program_dag_free_outputs(outputs, outputs_len);
amduat_pel_execution_result_free(&core_result);
amduat_pel_surf_free_ref(&exec_result_ref);
amduat_octets_free(&sid);
return false;
}