Ejemplo n.º 1
0
static kbool_t FuelVM_VisitIfNode(KonohaContext *kctx, KBuilder *builder, kNode *stmt, void *thunk)
{
	kNode *expr    = kNode_getFirstNode(kctx, stmt);
	Block *ThenBB  = CreateBlock(BLD(builder));
	Block *ElseBB  = CreateBlock(BLD(builder));
	Block *MergeBB = CreateBlock(BLD(builder));
	/* if */
	SUGAR VisitNode(kctx, builder, expr, thunk);
	CreateBranch(BLD(builder), FuelVM_getExpression(builder), ThenBB, ElseBB);
	{ /* then */
		IRBuilder_setBlock(BLD(builder), ThenBB);
		SUGAR VisitNode(kctx, builder, kNode_getFirstBlock(kctx, stmt), thunk);
		if(!Block_HasTerminatorInst(BLD(builder)->Current)) {
			IRBuilder_JumpTo(BLD(builder), MergeBB);
		}
	}
	{ /* else */
		IRBuilder_setBlock(BLD(builder), ElseBB);
		SUGAR VisitNode(kctx, builder, kNode_getElseBlock(kctx, stmt), thunk);
		if(!Block_HasTerminatorInst(BLD(builder)->Current)) {
			IRBuilder_JumpTo(BLD(builder), MergeBB);
		}
	}
	/* endif */
	IRBuilder_setBlock(BLD(builder), MergeBB);
	return true;
}
Ejemplo n.º 2
0
static struct KVirtualCode *FuelVM_GenerateVirtualCode(KonohaContext *kctx, kMethod *mtd, kNode *block, int option)
{
	if(unlikely(AbstractMethodPtr == 0)) {
		AbstractMethodPtr = mtd->invokeKMethodFunc;
	}

	kNameSpace *ns = kNode_ns(block);
	KBuilder builderbuf = {}, *builder = &builderbuf;
	FuelIRBuilder Builder = {};
	INIT_GCSTACK();
	IRBuilder_Init(&Builder, kctx, ns);
	builder->builder = &Builder;
	builder->common.api = ns->builderApi;
	Block *EntryBlock = CreateBlock(BLD(builder));
	IRBuilder_setBlock(BLD(builder), EntryBlock);
	INode *Self = SetUpArguments(kctx, &Builder, mtd);

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

	if(!Block_HasTerminatorInst(BLD(builder)->Current)) {
		if(mtd->mn == MN_new) {
			INode *Ret = CreateReturn(BLD(builder), Self);
			INode_setType(Ret, ConvertToTypeId(kctx, mtd->typeId));
		} else {
			ktypeattr_t retTy = kMethod_GetReturnType(mtd)->typeId;
			if(retTy == KType_void) {
				CreateReturn(BLD(builder), 0);
			} else {
				enum TypeId Type = ConvertToTypeId(kctx, retTy);
				INode *Ret;
				if(KType_Is(UnboxType, retTy)) {
					SValue V; V.bits = 0;
					Ret = CreateConstant(BLD(builder), Type, V);
				} else {
					kObject *obj = KLIB Knull(kctx, KClass_(retTy));
					Ret = CreateObject(BLD(builder), Type, (void *)obj);
				}
				Ret = CreateReturn(BLD(builder), Ret);
				INode_setType(Ret, Type);
				CreateReturn(BLD(builder), 0);
			}
		}
	}
	RESET_GCSTACK();
	IMethod Mtd = {kctx, mtd, EntryBlock, ns};
	BLD(builder)->Method = &Mtd;
	bool JITCompiled = false;
	union ByteCode *code = IRBuilder_Compile(BLD(builder), &Mtd, option, &JITCompiled);
	if(mtd->invokeKMethodFunc == FuelVM_RunVirtualMachine) {
		mtd->virtualCodeApi_plus1[-1]->FreeVirtualCode(kctx, mtd->vcode_start);
	}
	KLIB kMethod_SetFunc(kctx, mtd, 0);
	if(JITCompiled) {
		KLIB kMethod_SetFunc(kctx, mtd, (KMethodFunc) code);
	}
	KFieldSet(mtd, ((kMethodVar *)mtd)->CompiledNode, block);
	IRBuilder_Exit(&Builder);
	return (struct KVirtualCode *) code;
}
Ejemplo n.º 3
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;

}
Ejemplo n.º 4
0
static kbool_t MiniVM_VisitIfNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk)
{
	bblock_t ThenBB  = new_BasicBlockLABEL(kctx);
	bblock_t ElseBB  = new_BasicBlockLABEL(kctx);
	bblock_t MergeBB = new_BasicBlockLABEL(kctx);
	/* if */
	KLIB VisitNode(kctx, builder, kUntypedNode_getFirstNode(kctx, node), thunk);
	CreateBranch(kctx, builder, MiniVM_getExpression(builder), ThenBB, ElseBB, false);
	{ /* then */
		MiniVMBuilder_setBlock(kctx, builder, ThenBB);
		KLIB VisitNode(kctx, builder, kUntypedNode_getFirstBlock(kctx, node), thunk);
		if(!Block_HasTerminatorInst(kctx, builder->bbMainId))
			MiniVMBuilder_JumpTo(kctx, builder, MergeBB);
	}
	{ /* else */
		MiniVMBuilder_setBlock(kctx, builder, ElseBB);
		KLIB VisitNode(kctx, builder, kUntypedNode_getElseBlock(kctx, node), thunk);
		if(!Block_HasTerminatorInst(kctx, builder->bbMainId))
			MiniVMBuilder_JumpTo(kctx, builder, MergeBB);
	}
	/* endif */
	MiniVMBuilder_setBlock(kctx, builder, MergeBB);
	return true;
}