3 * - By John Hodge (thePowersGang)
6 * - Metalanguage-to-Environment Interface
11 #include <udi_internal.h>
14 tUDI_DeferredCall DCall;
15 const udi_mei_op_template_t *mei_op;
19 void _udi_mei_call_unmarshal(tUDI_DeferredCall *DCall)
21 tUDI_MeiCall *Call = (void*)DCall;
22 const udi_mei_op_template_t *mei_op = Call->mei_op;
23 mei_op->backend_stub(Call->DCall.Handler, Call->DCall.cb, Call+1);
26 void udi_mei_call(udi_cb_t *gcb, udi_mei_init_t *meta_info, udi_index_t meta_ops_num, udi_index_t vec_idx, ...)
28 ENTER("pgcb pmeta_info imeta_ops_num ivec_idx",
29 gcb, meta_info, meta_ops_num, vec_idx);
30 const udi_mei_op_template_t *mei_op;
33 udi_mei_ops_vec_template_t *ops = meta_info->ops_vec_template_list;
34 for( ; ops->meta_ops_num && ops->meta_ops_num != meta_ops_num; ops ++ )
36 if( !ops->meta_ops_num ) {
40 mei_op = &ops->op_template_list[vec_idx-1];
43 LOG("%s", mei_op->op_name);
47 tUDI_MetaLang *metalang = UDI_int_GetCbType(gcb, &cb_type);
48 //if( metalang->MeiInfo != meta_info )
50 if( mei_op->meta_cb_num != cb_type ) {
55 udi_op_t *const*ops = UDI_int_ChannelPrepForCall(gcb, metalang, meta_ops_num);
56 udi_op_t *op = ops[vec_idx];
59 // Determine if indirect call is needed
60 // > check stack depth?
62 int indirect_call = (mei_op->op_category == UDI_MEI_OPCAT_REQ)
63 || (mei_op->op_category == UDI_MEI_OPCAT_IND);
67 va_start(args, vec_idx);
68 size_t marshal_size = _udi_marshal_values(NULL, mei_op->marshal_layout, args);
70 tUDI_MeiCall *call = malloc(sizeof(tUDI_MeiCall) + marshal_size);
71 call->DCall.Next = NULL;
72 call->DCall.Unmarshal = _udi_mei_call_unmarshal;
74 call->DCall.Handler = op;
75 call->mei_op = mei_op;
76 void *marshal_space = (void*)(call+1);
77 va_start(args, vec_idx);
78 _udi_marshal_values(marshal_space, mei_op->marshal_layout, args);
81 UDI_int_AddDeferred(&call->DCall);
86 va_start(args, vec_idx);
87 mei_op->direct_stub( op, gcb, args );