Esempio n. 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;
}
Esempio n. 2
0
static void kMethod_genCode(KonohaContext *kctx, kMethod *mtd, kBlock *bk)
{
	DBG_P("START CODE GENERATION..");
	INIT_GCSTACK();
	if(ctxcode == NULL) {
		kmodcode->h.setup(kctx, NULL, 0);
	}
	KLIB kMethod_setFunc(kctx, mtd, MethodFunc_runVirtualMachine);
	DBG_ASSERT(kArray_size(ctxcode->codeList) == 0);
	kBasicBlock* lbINIT  = new_BasicBlockLABEL(kctx);
	kBasicBlock* lbBEGIN = new_BasicBlockLABEL(kctx);
	ctxcode->lbEND = new_BasicBlockLABEL(kctx);
	PUSH_GCSTACK(lbINIT);
	PUSH_GCSTACK(lbBEGIN);
	PUSH_GCSTACK(ctxcode->lbEND);
	ctxcode->currentWorkingBlock = lbINIT;
//	BUILD_pushLABEL(kctx, NULL, lbBEGIN, lbEND);
	ASM(THCODE, _THCODE);
	ASM(CHKSTACK, 0);
	ASM_LABEL(kctx, lbBEGIN);
	BLOCK_asm(kctx, bk, 0);
	ASM_LABEL(kctx, ctxcode->lbEND);
	if (mtd->mn == MN_new) {
		ASM(NMOV, OC_(K_RTNIDX), OC_(0), CT_(mtd->typeId));   // FIXME: Type 'This' must be resolved
	}
	ASM(RET);
	assert(ctxcode->lbEND);/* scan-build: remove warning */
//	BUILD_popLABEL(kctx);
	BUILD_compile(kctx, mtd, lbINIT, ctxcode->lbEND);
	ctxcode->lbEND = NULL;
	RESET_GCSTACK();
}
Esempio n. 3
0
static void NMOV_asm(KonohaContext *kctx, int a, ktype_t ty, int b)
{
	if(TY_isUnbox(ty)) {
		ASM(NMOV, NC_(a), NC_(b), CT_(ty));
	}
	else {
		ASM(NMOV, OC_(a), OC_(b), CT_(ty));
	}
}
Esempio n. 4
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;
}
Esempio n. 5
0
static struct KVirtualCode *MiniVM_GenerateVirtualCode(KonohaContext *kctx, kMethod *mtd, kUntypedNode *block, int option)
{
	KVirtualCode *vcode;
	KBuffer wb;
	KBuilder builderbuf = {{0}}, *builder = &builderbuf;
	kNameSpace *ns = kUntypedNode_ns(block);

	INIT_GCSTACK();
	KLIB KBuffer_Init(&(kctx->stack->cwb), &wb);
	builder->common.api = ns->builderApi;
	builder->constPools = ns->NameSpaceConstList;
	builder->bbBeginId  = new_BasicBlockLABEL(kctx);
	builder->bbReturnId = new_BasicBlockLABEL(kctx);
	builder->bbMainId   = builder->bbBeginId;
	builder->currentMtd = mtd;
	builder->Value      = 0;
	builder->stackbase  = 0;
	builder->InstructionSize = 0;

	builder->common.api = &CollectLocalVar_BuilderAPI;
	KLIB VisitNode(kctx, builder, block, NULL);
	builder->stackbase += builder->localVarSize + 1/* == this object */;
	builder->common.api = ns->builderApi;

	KLIB KArray_Init(kctx, &builder->localVar, sizeof(LocalVarInfo) * builder->stackbase);

	ASM(THCODE, 0, _THCODE);
	ASM(CHKSTACK, 0);

	KLIB VisitNode(kctx, builder, block, NULL);

	if(!Block_HasTerminatorInst(kctx, builder->bbMainId)) {
		MiniVMBuilder_JumpTo(kctx, builder, builder->bbReturnId);
	}

	MiniVMBuilder_setBlock(kctx, builder, builder->bbReturnId);
	if(mtd->mn == MN_new) {
		// FIXME: Type 'This' must be resolved
		ASM(NMOV, OC_(K_RTNIDX), OC_(0), KClass_(mtd->typeId));
	}
	ASM(RET);
	vcode = CompileVirtualCode(kctx, builder, builder->bbBeginId, builder->bbReturnId);

	KLIB KArray_Free(kctx, &builder->localVar);
	RESET_GCSTACK();
	KLIB KBuffer_Free(&wb);
	return vcode;

}
Esempio n. 6
0
static kbool_t KBuilder_VisitConstNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk)
{
	DBG_ASSERT(!KType_Is(UnboxType, expr->attrTypeId));
	kObject *v = KBuilder_AddConstPool(kctx, builder, expr->ObjectConstValue);
	kshort_t a = AssignStack(thunk);
	ASM(NSET, OC_(a), (uintptr_t)v, KClass_(expr->attrTypeId));
	return true;
}
Esempio n. 7
0
static kbool_t MiniVM_VisitConstNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk)
{
	kObject *v = MiniVM_AddConstPool(kctx, builder, node->ObjectConstValue);
	DBG_ASSERT(!KType_Is(UnboxType, node->typeAttr));
	ASM(NSET, OC_(builder->stackbase), (uintptr_t) v, KClass_(node->typeAttr));
	builder->Value = builder->stackbase;
	return true;
}
Esempio n. 8
0
static kbool_t KBuilder_VisitFieldNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk)
{
	kshort_t a = AssignStack(thunk);
	kshort_t index = (kshort_t)expr->index;
	kshort_t xindex = (kshort_t)(expr->index >> (sizeof(kshort_t)*8));
	KClass *ty = KClass_(expr->attrTypeId);
	ASM(NMOVx, TC_(a, ty), OC_(index), xindex, ty);
	return true;
}
Esempio n. 9
0
static kbool_t MiniVM_VisitNullNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk)
{
	if(KType_Is(UnboxType, node->typeAttr)) {
		ASM(NSET, NC_(builder->stackbase), 0, KClass_(node->typeAttr));
	} else {
		ASM(NUL, OC_(builder->stackbase), KClass_(node->typeAttr));
	}
	builder->Value = builder->stackbase;
	return true;
}
Esempio n. 10
0
static kbool_t MiniVM_VisitBoxNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk)
{
	/*
	 * [box] := box(this)
	 **/
	KLIB VisitNode(kctx, builder, node->NodeToPush, thunk);
	ASM(BOX, OC_(builder->stackbase), NC_(MiniVM_getExpression(builder)), KClass_(node->typeAttr));
	builder->Value = builder->stackbase;
	return true;
}
Esempio n. 11
0
static kbool_t KBuilder_VisitNullNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk)
{
	kshort_t a = AssignStack(thunk);
	if(KType_Is(UnboxType, expr->attrTypeId)) {
		ASM(NSET, NC_(a), 0, KClass_(expr->attrTypeId));
	}
	else {
		ASM(NUL, OC_(a), KClass_(expr->attrTypeId));
	}
	return true;
}
Esempio n. 12
0
static kbool_t MiniVM_VisitAssignNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk)
{
	/*
	 * [LetExpr] := lhs = rhs
	 * expr->NodeList = [NULL, lhs, rhs]
	 **/

	intptr_t dst = -1;
	kUntypedNode *left = kUntypedNode_At(node, 1);
	kUntypedNode *right = kUntypedNode_At(node, 2);
	ktypeattr_t type = left->typeAttr;
	ksymbol_t symbol;

	assert(IS_Token(left->TermToken));
	symbol = left->TermToken->symbol;
	if(kUntypedNode_node(left) == KNode_Local) {
		if((dst = MiniVMBuilder_FindLocalVar(kctx, builder, symbol, type, left->index)) == -1) {
			dst = AddLocal(kctx, builder, left->index, symbol, type);
		}
		KLIB VisitNode(kctx, builder, right, thunk);
		CreateUpdate(kctx, builder, type, dst, MiniVM_getExpression(builder));
		builder->Value = dst;
	}
	else {
		khalfword_t index  = (khalfword_t)left->index;
		khalfword_t xindex = (khalfword_t)(left->index >> (sizeof(khalfword_t)*8));
		KClass *lhsClass = KClass_(left->typeAttr);
		KClass *rhsClass = KClass_(right->typeAttr);
		assert(kUntypedNode_node(left) == KNode_Field);
		if((dst = MiniVMBuilder_FindLocalVar(kctx, builder, symbol, KType_Object, index)) == -1) {
			dst = AddLocal(kctx, builder, index, symbol, KType_Object);
		}
		KLIB VisitNode(kctx, builder, right, thunk);
		ASM(XNMOV, OC_(index), xindex, TC_(MiniVM_getExpression(builder), rhsClass), lhsClass);
		if(node->typeAttr != KType_void) {
			builder->Value = builder->stackbase;
			ASM(NMOVx, TC_(builder->stackbase, rhsClass), OC_(index), xindex, lhsClass);
		}
	}
	return true;
}
Esempio n. 13
0
static kbool_t KBuilder_VisitAssignNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk)
{
	kNode *leftHandNode  = kNode_At(expr, 1);
	kNode *rightHandNode = kNode_At(expr, 2);
	//DBG_P("LET (%s) a=%d, shift=%d, espidx=%d", KType_text(expr->attrTypeId), a, shift, espidx);
	if(kNode_node(leftHandNode) == KNode_Local) {
		kshort_t a = AssignStack(thunk);
		SUGAR VisitNode(kctx, builder, rightHandNode, &(leftHandNode->index));
		if(expr->attrTypeId != KType_void && a != leftHandNode->index) {
			AsmMOV(kctx, builder, a, KClass_(leftHandNode->attrTypeId), leftHandNode->index);
		}
	}
	else if(kNode_node(leftHandNode) == KNode_Field) {
		intptr_t espidx = expr->stackbase;
		SUGAR VisitNode(kctx, builder, rightHandNode, &espidx);
		kshort_t index  = (kshort_t)leftHandNode->index;
		kshort_t xindex = (kshort_t)(leftHandNode->index >> (sizeof(kshort_t)*8));
		KClass *lhsClass = KClass_(leftHandNode->attrTypeId), *rhClass = KClass_(rightHandNode->attrTypeId);
		ASM(XNMOV, OC_(index), xindex, TC_(espidx, rhClass), lhsClass);
		if(expr->attrTypeId != KType_void) {
			kshort_t a = AssignStack(thunk);
			ASM(NMOVx, TC_(a, rhClass), OC_(index), xindex, lhsClass);
		}
	}
Esempio n. 14
0
static kbool_t MiniVM_VisitFieldNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk)
{
	ksymbol_t symbol;
	intptr_t src;
	KClass *ty;

	khalfword_t index  = (khalfword_t)(node->index);
	khalfword_t xindex = (khalfword_t)(node->index >> (sizeof(khalfword_t)*8));
	assert(IS_Token(node->TermToken));
	symbol = node->TermToken->symbol;
	if((src = MiniVMBuilder_FindLocalVar(kctx, builder, symbol, KType_Object, index)) == -1) {
		src = AddLocal(kctx, builder, index, symbol, KType_Object);
	}
	ty = KClass_(node->typeAttr);
	ASM(NMOVx, TC_(builder->stackbase, ty), OC_(src), xindex, ty);
	builder->Value = builder->stackbase;
	return true;
}
Esempio n. 15
0
static void LETEXPR_asm(KonohaContext *kctx, kStmt *stmt, int a, kExpr *expr, int shift, int espidx)
{
	kExpr *leftHandExpr = kExpr_at(expr, 1);
	kExpr *rightHandExpr = kExpr_at(expr, 2);
	DBG_P("LET (%s) a=%d, shift=%d, espidx=%d", TY_t(expr->ty), a, shift, espidx);
	if(leftHandExpr->build == TEXPR_LOCAL) {
		EXPR_asm(kctx, stmt, leftHandExpr->index, rightHandExpr, shift, espidx);
		if(expr->ty != TY_void && a != leftHandExpr->index) {
			NMOV_asm(kctx, a, leftHandExpr->ty, leftHandExpr->index);
		}
	}
	else if(leftHandExpr->build == TEXPR_STACKTOP) {
		DBG_P("LET TEXPR_STACKTOP a=%d, leftHandExpr->index=%d, espidx=%d", a, leftHandExpr->index, espidx);
		EXPR_asm(kctx, stmt, leftHandExpr->index + shift, rightHandExpr, shift, espidx);
		if(expr->ty != TY_void && a != leftHandExpr->index + shift) {
			NMOV_asm(kctx, a, leftHandExpr->ty, leftHandExpr->index + shift);
		}
	}
	else{
		assert(leftHandExpr->build == TEXPR_FIELD);
		EXPR_asm(kctx, stmt, espidx, rightHandExpr, shift, espidx);
		kshort_t index = (kshort_t)leftHandExpr->index;
		kshort_t xindex = (kshort_t)(leftHandExpr->index >> (sizeof(kshort_t)*8));
		if(TY_isUnbox(rightHandExpr->ty)) {
			ASM(XNMOV, OC_(index), xindex, NC_(espidx), CT_(leftHandExpr->ty));
			if(expr->ty != TY_void) {
				ASM(NMOVx, NC_(a), OC_(index), xindex, CT_(leftHandExpr->ty));
			}
		}
		else {
			ASM(XNMOV, OC_(index), xindex, OC_(espidx), CT_(leftHandExpr->ty));
			if(expr->ty != TY_void) {
				ASM(NMOVx, OC_(a), OC_(index), xindex, CT_(leftHandExpr->ty));
			}
		}
	}
}
Esempio n. 16
0
static kbool_t MiniVM_VisitNewNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk)
{
	ASM(NEW, OC_(builder->stackbase), 0, KClass_(node->typeAttr));
	builder->Value = builder->stackbase;
	return true;
}
Esempio n. 17
0
static kbool_t KBuilder_VisitNewNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk)
{
	kshort_t a = AssignStack(thunk);
	ASM(NEW, OC_(a), expr->index, KClass_(expr->attrTypeId));
	return true;
}
Esempio n. 18
0
static void EXPR_asm(KonohaContext *kctx, kStmt *stmt, int a, kExpr *expr, int shift, int espidx)
{
	DBG_ASSERT(expr != NULL);
	//DBG_P("a=%d, shift=%d, espidx=%d", a, shift, espidx);
	switch(expr->build) {
	case TEXPR_CONST : {
		kObject *v = expr->objectConstValue;
		DBG_ASSERT(!TY_isUnbox(expr->ty));
		DBG_ASSERT(Expr_hasObjectConstValue(expr));
		v = BUILD_addConstPool(kctx, v);
		ASM(NSET, OC_(a), (uintptr_t)v, CT_(expr->ty));
		break;
	}
	case TEXPR_NEW   : {
		ASM(NEW, OC_(a), expr->index, CT_(expr->ty));
		break;
	}
	case TEXPR_NULL  : {
		if(TY_isUnbox(expr->ty)) {
			ASM(NSET, NC_(a), 0, CT_(expr->ty));
		}
		else {
			ASM(NULL, OC_(a), CT_(expr->ty));
		}
		break;
	}
	case TEXPR_NCONST : {
		ASM(NSET, NC_(a), expr->unboxConstValue, CT_(expr->ty));
		break;
	}
	case TEXPR_LOCAL : {
		NMOV_asm(kctx, a, expr->ty, expr->index);
		break;
	}
	case TEXPR_BLOCK : {
		DBG_ASSERT(IS_Block(expr->block));
		BLOCK_asm(kctx, expr->block, espidx);
		NMOV_asm(kctx, a, expr->ty, /*expr->index*/ espidx);
		break;
	}
	case TEXPR_FIELD : {
		kshort_t index = (kshort_t)expr->index;
		kshort_t xindex = (kshort_t)(expr->index >> (sizeof(kshort_t)*8));
		if(TY_isUnbox(expr->ty)) {
			ASM(NMOVx, NC_(a), OC_(index), xindex, CT_(expr->ty));
		}
		else {
			ASM(NMOVx, OC_(a), OC_(index), xindex, CT_(expr->ty));
		}
		break;
	}
	case TEXPR_CALL  :
		CALL_asm(kctx, stmt, a, expr, shift, espidx);
		if(a != espidx) {
			NMOV_asm(kctx, a, expr->ty, espidx);
		}
		break;
	case TEXPR_AND  :
		AND_asm(kctx, stmt, a, expr, shift, espidx);
		break;
	case TEXPR_OR  :
		OR_asm(kctx, stmt, a, expr, shift, espidx);
		break;
	case TEXPR_LET  :
		LETEXPR_asm(kctx, stmt, a, expr, shift, espidx);
		break;
	case TEXPR_STACKTOP  :
		//DBG_P("STACKTOP mov %d, %d, < %d", a, expr->index + shift, espidx);
		DBG_ASSERT(expr->index + shift < espidx);
		NMOV_asm(kctx, a, expr->ty, expr->index + shift);
		break;
	default:
		DBG_ABORT("unknown expr=%d", expr->build);
	}
}