/* doc: <routine name="execute_scoop_call" return_type="void" export="private"> doc: <summary> Execute the feature in 'a_call' and do not catch exceptions. </summary> doc: <param name="a_call" type="struct eif_scoop_call_data*"> The feature to be executed. Must not be NULL. </param> doc: <thread_safety> Safe, if arguments differ. </thread_safety> doc: <synchronization> None. </synchronization> doc: </routine> */ rt_private void execute_scoop_call (struct eif_scoop_call_data* a_call) { #ifndef WORKBENCH a_call->pattern (a_call); /* Execute a feature in finalized mode. */ #else /* Execute a feature in workbench mode. */ EIF_GET_CONTEXT uint32 pid = 0; /* Pattern id of the frozen feature */ EIF_NATURAL_32 i; EIF_NATURAL_32 n; BODY_INDEX body_id; EIF_TYPED_VALUE * v; REQUIRE("call_not_null", a_call); REQUIRE("target_not_null", a_call->target); /* Push arguments to the evaluation stack */ for (n = a_call->count, i = 0; i < n; i++) { v = eif_opstack_push_empty(&op_stack); * v = a_call->argument [i]; } if (a_call->routine_id >= 0) { /*NOTE: Tuple access has a negative routine ID.*/ /* Regular feature call. */ /* Push current to the evaluation stack */ v = eif_opstack_push_empty(&op_stack); v->it_r = a_call->target; v->type = SK_REF; /* Make a feature call. */ CBodyId(body_id, a_call->routine_id,Dtype(a_call->target)); if (egc_frozen [body_id]) { /* We are below zero Celsius, i.e. ice */ pid = (uint32) FPatId(body_id); (pattern[pid].toc)(egc_frozen[body_id]); /* Call pattern */ } else { /* The proper way to start the interpretation of a melted feature is to call `xinterp' * in order to initialize the calling context (which is not done by `interpret'). * `tagval' will therefore be set, but we have to resynchronize the registers anyway. */ xinterp(MTC melt[body_id], 0); } /* Save result of a call if any. */ v = a_call->result; if (v) { * v = * eif_opstack_pop_address(&op_stack); } } else { /* Tuple access. */ if (n == 0) { /* Access to a tuple field. */ v = a_call->result; eif_tuple_access (a_call->target, - a_call->routine_id, v); } else { /* Assignment to a tuple field. */ v = eif_opstack_pop_address(&op_stack); eif_tuple_assign (a_call->target, - a_call->routine_id, v); } } #endif }
rt_private void rt_apply_wcall (call_data *data) { EIF_GET_CONTEXT uint32 pid = 0; /* Pattern id of the frozen feature */ EIF_NATURAL_32 i; EIF_NATURAL_32 n; BODY_INDEX body_id; EIF_TYPED_VALUE * v; REQUIRE("has data", data); REQUIRE("has target", data->target); /* Push arguments to the evaluation stack */ for (n = data->count, i = 0; i < n; i++) { v = eif_opstack_push_empty(&op_stack); * v = data->argument [i]; } if (data->routine_id >= 0) { /* Regular feature call. */ /* Push current to the evaluation stack */ v = eif_opstack_push_empty(&op_stack); v->it_r = data->target; v->type = SK_REF; /* Make a feature call. */ CBodyId(body_id, data->routine_id,Dtype(data->target)); if (egc_frozen [body_id]) { /* We are below zero Celsius, i.e. ice */ pid = (uint32) FPatId(body_id); (pattern[pid].toc)(egc_frozen[body_id]); /* Call pattern */ } else { /* The proper way to start the interpretation of a melted feature is to call `xinterp' * in order to initialize the calling context (which is not done by `interpret'). * `tagval' will therefore be set, but we have to resynchronize the registers anyway. */ xinterp(MTC melt[body_id], 0); } /* Save result of a call if any. */ v = data->result; if (v) { * v = * eif_opstack_pop_address(&op_stack); } } else { /* Tuple access. */ if (n == 0) { /* Access to a tuple field. */ v = data->result; eif_tuple_access (data->target, - data->routine_id, v); } else { /* Assignment to a tuple field. */ v = eif_opstack_pop_address(&op_stack); eif_tuple_assign (data->target, - data->routine_id, v); } } }
rt_public void eif_try_call (call_data * a) { uint32 pid = 0; /* Pattern id of the frozen feature */ EIF_NATURAL_32 i; EIF_NATURAL_32 n; BODY_INDEX body_id = a -> body_index; EIF_TYPED_VALUE * v; /* Push arguments to the evaluation stack */ for (n = a -> count, i = 0; i < n; i++) { v = iget (); * v = a -> argument [i]; if ((v -> it_r) && (v -> type & SK_HEAD) == SK_REF) { v -> it_r = eif_access (v -> it_r); } } /* Push current to the evaluation stack */ v = iget (); v -> it_r = eif_access (a -> target); v -> type = SK_REF; /* Make a call */ if (egc_frozen [body_id]) { /* We are below zero Celsius, i.e. ice */ pid = (uint32) FPatId(body_id); (pattern[pid].toc)(egc_frozen[body_id]); /* Call pattern */ } else { /* The proper way to start the interpretation of a melted feature is to call `xinterp' * in order to initialize the calling context (which is not done by `interpret'). * `tagval' will therefore be set, but we have to resynchronize the registers anyway. */ xinterp(MTC melt[body_id], 0); } /* Save result of a call */ v = a -> result; if (v) { * v = * opop (); switch (v -> type & SK_HEAD) { case SK_REF: case SK_EXP: /* Avoid reference result to be GC'ed by storing it in the protected location, pointed by `a -> result_address. */ * (a -> result_address) = v -> it_r; } } }