Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
static void ASM_SAFEPOINT(KonohaContext *kctx, int espidx)
{
	kBasicBlock *bb = ctxcode->currentWorkingBlock;
	size_t i;
	for(i = 0; i < BasicBlock_codesize(bb); i++) {
		VirtualMachineInstruction *op = BBOP(bb) + i;
		if(op->opcode == OPCODE_SAFEPOINT) return;
	}
	ASM(SAFEPOINT, SFP_(espidx));
}
Exemple #4
0
static void CALL_asm(KonohaContext *kctx, kStmt *stmt, int a, kExpr *expr, int shift, int espidx)
{
	kMethod *mtd = expr->cons->methodItems[0];
	DBG_ASSERT(IS_Method(mtd));
	int i, s = Method_isStatic(mtd) ? 2 : 1, thisidx = espidx + K_CALLDELTA;
#ifdef _CLASSICVM
	if (CLASSICVM_CALL_asm(kctx, mtd, expr, shift, espidx)) {
		return;
	}
#endif
	for(i = s; i < kArray_size(expr->cons); i++) {
		kExpr *exprN = kExpr_at(expr, i);
		DBG_ASSERT(IS_Expr(exprN));
		EXPR_asm(kctx, stmt, thisidx + i - 1, exprN, shift, thisidx + i - 1);
	}
	int argc = kArray_size(expr->cons) - 2;
//	if (mtd->mn == MN_new && mtd->invokeMethodFunc == MethodFunc_abstract) {
//		/* do nothing */
//	} else
//	if(Method_isFinal(mtd) || !Method_isVirtual(mtd)) {
//		if(mtd->invokeMethodFunc != MethodFunc_runVirtualMachine) {
//		ASM(SCALL, ctxcode->uline, SFP_(thisidx), ESP_(espidx, argc), mtd, KLIB Knull(kctx, CT_(expr->ty)));
//		}
//		else {
//			ASM(VCALL, ctxcode->uline, SFP_(thisidx), ESP_(espidx, argc), mtd, KLIB Knull(kctx, CT_(expr->ty)));
//		}
//	}
//	else {
	if(Method_isFinal(mtd) || !Method_isVirtual(mtd)) {
		ASM(NSET, NC_(thisidx-1), (intptr_t)mtd, CT_Method);
	}
	else {
		ASM(LOOKUP, SFP_(thisidx), Stmt_nameSpace(stmt), mtd);
	}
	ASM(CALL, ctxcode->uline, SFP_(thisidx), ESP_(espidx, argc), KLIB Knull(kctx, CT_(expr->ty)));
}
Exemple #5
0
static void KBuilder_AsmSAFEPOINT(KonohaContext *kctx, KBuilder *builder, kfileline_t uline, int espidx)
{
	ASM(SAFEPOINT, uline, SFP_(espidx));
}