static kbool_t KBuilder_VisitMethodCallNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk) { kshort_t a = AssignStack(thunk), espidx = expr->stackbase, thisidx = espidx + K_CALLDELTA; DBG_ASSERT(a <= espidx); kMethod *mtd = CallNode_getMethod(expr); DBG_ASSERT(IS_Method(mtd)); int i, s = kMethod_Is(Static, mtd) ? 2 : 1; int argc = CallNode_getArgCount(expr); for (i = s; i < argc + 2; i++) { intptr_t a = thisidx + i - 1; kNode *paramNode = kNode_At(expr, i); if(!kNode_IsValue(paramNode) && paramNode->stackbase != a) { DBG_P("a=%d, stackbase=%d", a, paramNode->stackbase); DBG_ASSERT(paramNode->stackbase == a); } SUGAR VisitNode(kctx, builder, paramNode, &a); } if(kMethod_Is(Final, mtd) || !kMethod_Is(Virtual, mtd)) { ASM(NSET, NC_(thisidx-1), (intptr_t)mtd, KClass_Method); if(kMethod_Is(Virtual, mtd)) { // set namespace to enable method lookups ASM(NSET, OC_(thisidx-2), (intptr_t)kNode_ns(expr), KClass_NameSpace); } } else { ASM(NSET, OC_(thisidx-2), (intptr_t)kNode_ns(expr), KClass_NameSpace); ASM(LOOKUP, SFP_(thisidx), kNode_ns(expr), mtd); } int esp_ = SFP_(espidx + argc + K_CALLDELTA + 1); ASM(CALL, builder->common.uline, SFP_(thisidx), esp_, KLIB Knull(kctx, KClass_(expr->attrTypeId))); ReAssignNonValueNode(kctx, builder, a, expr); return true; }
static kbool_t CollectLocalVar_VisitMethodCallNode(KVISITOR_PARAM) { kMethod *mtd = CallNode_getMethod(node); int i, s = kMethod_Is(Static, mtd) ? 2 : 1; int argc = CallNode_getArgCount(node); for (i = s; i < argc + 2; i++) { kUntypedNode *exprN = kUntypedNode_At(node, i); KLIB VisitNode(kctx, builder, exprN, thunk); } return true; }
static kbool_t MiniVM_VisitMethodCallNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk) { kMethod *mtd = CallNode_getMethod(node); /* * [CallExpr] := this.method(arg1, arg2, ...) * node->NodeList = [method, this, arg1, arg2, ...] **/ intptr_t stackbase, thisidx; int i, s, argc = CallNode_getArgCount(node); DBG_ASSERT(IS_Method(mtd)); s = kMethod_Is(Static, mtd) ? 2 : 1; if(kMethod_Is(Static, mtd)) { KClass *selfTy = KClass_(mtd->typeId); kObject *obj = KLIB Knull(kctx, selfTy); ASM(NSET, OC_(builder->stackbase), (uintptr_t) obj, selfTy); } stackbase = builder->stackbase; thisidx = stackbase + K_CALLDELTA; for (i = s; i < argc + 2; i++) { kUntypedNode *exprN = kUntypedNode_At(node, i); builder->stackbase = thisidx + i - 1; DBG_ASSERT(IS_Node(exprN)); KLIB VisitNode(kctx, builder, exprN, thunk); if(builder->Value != builder->stackbase) { KClass *ty = KClass_(exprN->typeAttr); ASM_NMOV(kctx, builder, ty, builder->stackbase, builder->Value); } } if(kMethod_Is(Final, mtd) || !kMethod_Is(Virtual, mtd)) { ASM(NSET, NC_(thisidx-1), (intptr_t)mtd, KClass_Method); if(kMethod_Is(Virtual, mtd)) { // set namespace to enable method lookups ASM(NSET, OC_(thisidx-2), (intptr_t)kUntypedNode_ns(node), KClass_NameSpace); } } else { ASM(NSET, OC_(thisidx-2), (intptr_t)kUntypedNode_ns(node), KClass_NameSpace); ASM(LOOKUP, SFP_(thisidx), kUntypedNode_ns(node), mtd); } ASM(CALL, kUntypedNode_uline(node), SFP_(thisidx), SFP_(thisidx + argc + 1), KLIB Knull(kctx, KClass_(node->typeAttr))); builder->stackbase = stackbase; builder->Value = builder->stackbase; return true; }