X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FInterfaces%2FUDI%2Fudi_lib%2Fcore%2Fmei.c;fp=KernelLand%2FModules%2FInterfaces%2FUDI%2Fudi_lib%2Fcore%2Fmei.c;h=e0caec7e6c271efb344e0b2ca0527e3c67e0b548;hb=3fe3238f90216eeec97778e3ae91f462d27c60ac;hp=e92afce383e752ebf798715bcd2c8472c0e763f8;hpb=6cec03a9241ec39dec9347d1dcf634c393b33f20;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c index e92afce3..e0caec7e 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c @@ -5,12 +5,88 @@ * udi_lib/mei.c * - Metalanguage-to-Environment Interface */ +#define DEBUG 1 #include #include +#include + +typedef struct { + tUDI_DeferredCall DCall; + const udi_mei_op_template_t *mei_op; +} tUDI_MeiCall; // === CODE === +void _udi_mei_call_unmarshal(tUDI_DeferredCall *DCall) +{ + tUDI_MeiCall *Call = (void*)DCall; + const udi_mei_op_template_t *mei_op = Call->mei_op; + mei_op->backend_stub(Call->DCall.Handler, Call->DCall.cb, Call+1); +} + 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, ...) { - UNIMPLEMENTED(); + ENTER("pgcb pmeta_info imeta_ops_num ivec_idx", + gcb, meta_info, meta_ops_num, vec_idx); + const udi_mei_op_template_t *mei_op; + + { + udi_mei_ops_vec_template_t *ops = meta_info->ops_vec_template_list; + for( ; ops->meta_ops_num && ops->meta_ops_num != meta_ops_num; ops ++ ) + ; + if( !ops->meta_ops_num ) { + LEAVE('-'); + return ; + } + mei_op = &ops->op_template_list[vec_idx-1]; + } + + LOG("%s", mei_op->op_name); + + // Check CB type + udi_index_t cb_type; + tUDI_MetaLang *metalang = UDI_int_GetCbType(gcb, &cb_type); + //if( metalang->MeiInfo != meta_info ) + // return ; + if( mei_op->meta_cb_num != cb_type ) { + LEAVE('-'); + return ; + } + // Check call type + udi_op_t *const*ops = UDI_int_ChannelPrepForCall(gcb, metalang, meta_ops_num); + udi_op_t *op = ops[vec_idx]; + + // Start va_args + // Determine if indirect call is needed + // > check stack depth? + // > Direction? + int indirect_call = (mei_op->op_category == UDI_MEI_OPCAT_REQ) + || (mei_op->op_category == UDI_MEI_OPCAT_IND); + if( indirect_call ) + { + va_list args; + va_start(args, vec_idx); + size_t marshal_size = _udi_marshal_values(NULL, mei_op->marshal_layout, args); + va_end(args); + tUDI_MeiCall *call = malloc(sizeof(tUDI_MeiCall) + marshal_size); + call->DCall.Next = NULL; + call->DCall.Unmarshal = _udi_mei_call_unmarshal; + call->DCall.cb = gcb; + call->DCall.Handler = op; + call->mei_op = mei_op; + void *marshal_space = (void*)(call+1); + va_start(args, vec_idx); + _udi_marshal_values(marshal_space, mei_op->marshal_layout, args); + va_end(args); + + UDI_int_AddDeferred(&call->DCall); + } + else + { + va_list args; + va_start(args, vec_idx); + mei_op->direct_stub( op, gcb, args ); + va_end(args); + } + LEAVE('-'); }