enum MqErrorE NS(ProcInit) ( struct MqS *mqctx, VALUE val, MqServiceCallbackF *procCall, MQ_PTR *procData, MqDataCopyF *procCopy ) { SETUP_self VALUE dataVal; if (rb_obj_is_kind_of(val, rb_cProc) == Qtrue) { *procCall = ProcCall; *procCopy = ProcCopyProc; dataVal = val; } else if (rb_obj_is_kind_of(val, rb_cMethod) == Qtrue) { if (rb_equal(self,rb_funcall(val,id_receiver,0,NULL)) == Qtrue) { // val belongs to calling object, NO argument is required *procCall = ProcCallMethod; *procCopy = ProcCopyMethod; dataVal = val; } else { // val belongs NOT to calling object, argument is required *procCall = ProcCallMethodWithArg; *procCopy = ProcCopyMethodWithArg; dataVal = rb_ary_new3(2,self,val); } } else { return MqErrorC(mqctx,__func__,1,"expect 'proc' or 'method' argument"); } *procData = VAL2PTR(dataVal); INCR_REF(dataVal); return MQ_OK; }
static void ProcCopyProc ( struct MqS * const mqctx, MQ_PTR *dataP ) { VALUE val = PTR2VAL(*dataP); val = rb_funcall(val,id_clone,0,NULL); INCR_REF(val); *dataP = VAL2PTR(val); }
static void ProcCopyMethodWithArg ( struct MqS * const mqctx, MQ_PTR *dataP ) { VALUE ary = PTR2VAL(*dataP); VALUE mth = rb_ary_entry(ary,1); ProcCopyMethod(mqctx, (MQ_PTR*)&mth); ary = rb_ary_new3(2,SELF,mth); INCR_REF(ary); *dataP = VAL2PTR(ary); }
static void ProcCopyMethod ( struct MqS * const mqctx, MQ_PTR *dataP ) { SETUP_self; VALUE val = PTR2VAL(*dataP); val = rb_funcall(val,id_clone,0,NULL); val = rb_funcall(val,id_unbind,0,NULL); val = rb_funcall(val,id_bind,1,self); INCR_REF(val); *dataP = VAL2PTR(val); }
static YogVal new_(YogEnv* env, YogVal self, YogVal pkg, YogVal args, YogVal kw, YogVal block) { SAVE_ARGS5(env, self, pkg, args, kw, block); YogVal obj = YUNDEF; PUSH_LOCAL(env, obj); Allocator allocator = PTR_AS(YogClass, self)->allocator; YogVal klass = self; while (allocator == NULL) { klass = PTR_AS(YogClass, klass)->super; if (VAL2PTR(klass) == NULL) { YOG_ASSERT(env, FALSE, "Can't allocate object."); } allocator = PTR_AS(YogClass, klass)->allocator; } obj = (*allocator)(env, self); uint_t argc = YogArray_size(env, args); YogVal body = PTR_AS(YogArray, args)->body; YogVal* items = PTR_AS(YogValArray, body)->items; /* TODO: dirty hack */ YogVal* arg = (YogVal*)YogSysdeps_alloca(sizeof(YogVal) * argc); uint_t i; for (i = 0; i < argc; i++) { arg[i] = items[i]; } PUSH_LOCALSX(env, argc, arg); if (IS_PTR(block)) { YogEval_call_method2(env, obj, "init", argc, arg, block); } else { YogEval_call_method(env, obj, "init", argc, arg); } RETURN(env, obj); }