Exemple #1
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;
}
Exemple #2
0
static void KStackReturnTypeCheck(KonohaContext *kctx, KonohaStack *sfp, kMethod *mtd, KClass *reqType, KClass *thisClass)
{
	if(!kMethod_Is(SmartReturn, mtd)) {
		KClass *returnType = kMethod_GetReturnType(mtd);
		returnType = returnType->realtype(kctx, returnType, thisClass);
		if(reqType == returnType || returnType->isSubType(kctx, returnType, reqType)) {
			if(KClass_Is(UnboxType, returnType) && !KClass_Is(UnboxType, reqType)) {
				KReturn(KLIB new_kObject(kctx, OnStack, returnType, sfp[K_RTNIDX].unboxValue));
			}
		}
		else {
			ThrowTypeError(kctx, sfp, -1);
		}
	}
}
Exemple #3
0
/*
 * cbufferevent Class (*buffer_event_cb)() 1st stage callback from event_base_dispatch(), NEVER BE CALLED FROM OTHERS.
 */
static void Cbev_eventCB_1st(struct bufferevent *bev, short what, void *arg)
{
	kbuffereventCBArg *cbArg = arg;
	KonohaContext *kctx = cbArg->kctx;

	BEGIN_UnusedStack(lsfp);
	KClass *returnType = kMethod_GetReturnType(cbArg->kcb[BEV_EventCB]->method);
	KUnsafeFieldSet(lsfp[0].asObject, K_NULL);
	KUnsafeFieldSet(lsfp[1].asObject, (kObject *)cbArg->cbev);
	lsfp[2].intValue = what;
	KUnsafeFieldSet(lsfp[3].asObject, (kObject *)cbArg->arg);
	KStackSetFuncAll(lsfp, KLIB Knull(kctx, returnType), 0/*UL*/, cbArg->kcb[BEV_EventCB], 3);
	KStackCall(lsfp);
	END_UnusedStack();
}
Exemple #4
0
static void Cbev_dataCB_dispatcher(enum e_buffereventCB cat, struct bufferevent *bev, void *arg)
{
	kbuffereventCBArg *cbArg = arg;
	KonohaContext *kctx = cbArg->kctx;

	BEGIN_UnusedStack(lsfp);
	KClass *returnType = kMethod_GetReturnType(cbArg->kcb[cat]->method);
	KUnsafeFieldSet(lsfp[0].asObject, K_NULL);
	KUnsafeFieldSet(lsfp[1].asObject, (kObject *)cbArg->cbev);
	KUnsafeFieldSet(lsfp[2].asObject, (kObject *)cbArg->arg);

	KStackSetFuncAll(lsfp, KLIB Knull(kctx, returnType), 0/*UL*/, cbArg->kcb[cat], 2);
	KStackCall(lsfp);
	END_UnusedStack();
}
Exemple #5
0
/*
 * cevent_base Class 1st stage callback from event_base_dispatch(), NEVER BE CALLED FROM OTHERS.
 */
static void cevent_callback_1st(evutil_socket_t evd, short event, void *arg) {
	keventCBArg *cbArg = arg;
	KonohaContext *kctx = cbArg->kctx;

	BEGIN_UnusedStack(lsfp);
	KClass *returnType = kMethod_GetReturnType(cbArg->kcb->method);
	KUnsafeFieldSet(lsfp[0].asObject, K_NULL);
	lsfp[1].intValue = evd;
	lsfp[2].intValue = event;
	KUnsafeFieldSet(lsfp[3].asObject, (kObject *)cbArg->arg);

	KStackSetFuncAll(lsfp, KLIB Knull(kctx, returnType), 0/*UL*/, cbArg->kcb, 3);
	KStackCall(lsfp);
	END_UnusedStack();
}
Exemple #6
0
static INode *CreateSpecialInstruction(KonohaContext *kctx, KBuilder *builder, kMethod *mtd, kNode *expr, void *thunk)
{
	ktypeattr_t thisTy = mtd->typeId;
	kmethodn_t  mn     = mtd->mn;
	ktypeattr_t retTy  = kMethod_GetReturnType(mtd)->typeId;
	kParam     *params = kMethod_GetParam(mtd);
	kNode *stmt = expr->Parent;
	assert(IS_Node(stmt));
	if(thisTy == KType_Boolean) {
		if(params->psize == 0) { /* UnaryOperator */
			if(retTy == KType_Boolean) {
				/* booleaen booleaen.opNEG() */
				enum UnaryOp Op = KMethodName_toUnaryOperator(kctx, mn);
				INode *Param = FetchINode(kctx, builder, expr, 1, KType_Boolean, thunk);
				return CreateUnaryInst(BLD(builder), Op, Param, kNode_uline(stmt));
			}
		}
		else if(params->psize == 1) { /* BinaryOperator */
			ktypeattr_t ptype = params->paramtypeItems[0].attrTypeId;
			if(retTy == KType_Boolean && ptype == KType_Boolean) {
				/* boolean boolean.(opEQ|opNE) (boolean x) */
				enum BinaryOp Op = KMethodName_toBinaryOperator(kctx, mn);
				assert(Op == Eq || Op == Nq);
				INode *LHS = FetchINode(kctx, builder, expr, 1, KType_Boolean, thunk);
				INode *RHS = FetchINode(kctx, builder, expr, 2, KType_Boolean, thunk);
				return CreateBinaryInst(BLD(builder), Op, LHS, RHS, kNode_uline(stmt));
			}
		}
	}
	else if(thisTy == KType_Int) {
		if(params->psize == 0) { /* UnaryOperator */
			if(retTy == KType_Int) {
				/* int int.opSUB() */
				enum UnaryOp Op = KMethodName_toUnaryOperator(kctx, mn);
				INode *Param = FetchINode(kctx, builder, expr, 1, KType_Int, thunk);
				return CreateUnaryInst(BLD(builder), Op, Param, kNode_uline(stmt));
			}
		}
		else if(params->psize == 1) { /* BinaryOperator */
			ktypeattr_t ptype = params->paramtypeItems[0].attrTypeId;
			if(retTy == KType_Boolean && ptype == KType_Int) {
				/* boolean int.(opEQ|opNE|opGT|opGE|opLT|opLE) (int x) */
				enum BinaryOp Op = KMethodName_toBinaryOperator(kctx, mn);
				INode *LHS = FetchINode(kctx, builder, expr, 1, KType_Int, thunk);
				INode *RHS = FetchINode(kctx, builder, expr, 2, KType_Int, thunk);
				return CreateBinaryInst(BLD(builder), Op, LHS, RHS, kNode_uline(stmt));
			}
			else if(retTy == KType_Int && ptype == KType_Int) {
				/* int int.(opADD|opSUB|opMUL|opDIV|opMOD|opLSHIFT|opRSHIFT|opAND|opOR|opXOR) (int x) */
				enum BinaryOp Op = KMethodName_toBinaryOperator(kctx, mn);
				INode *LHS = FetchINode(kctx, builder, expr, 1, KType_Int, thunk);
				INode *RHS = FetchINode(kctx, builder, expr, 2, KType_Int, thunk);
				return CreateBinaryInst(BLD(builder), Op, LHS, RHS, kNode_uline(stmt));
			}
		}
	}
	else if(FloatIsDefined() && thisTy == KType_float) {
		if(params->psize == 0) { /* UnaryOperator */
			if(retTy == KType_float) {
				/* int int.opSUB() */
				enum UnaryOp Op = KMethodName_toUnaryOperator(kctx, mn);
				INode *Param = FetchINode(kctx, builder, expr, 1, KType_float, thunk);
				return CreateUnaryInst(BLD(builder), Op, Param, kNode_uline(stmt));
			}
		}
		else if(params->psize == 1) { /* BinaryOperator */
			ktypeattr_t ptype = params->paramtypeItems[0].attrTypeId;
			if(retTy == KType_Boolean && ptype == KType_float) {
				/* boolean float.(opEQ|opNE|opGT|opGE|opLT|opLE) (float x) */
				enum BinaryOp Op = KMethodName_toBinaryOperator(kctx, mn);
				INode *LHS = FetchINode(kctx, builder, expr, 1, KType_float, thunk);
				INode *RHS = FetchINode(kctx, builder, expr, 2, KType_float, thunk);
				return CreateBinaryInst(BLD(builder), Op, LHS, RHS, kNode_uline(stmt));
			}
			else if(retTy == KType_float && ptype == KType_float) {
				/* float float.(opADD|opSUB|opMUL|opDIV) (float x) */
				enum BinaryOp Op = KMethodName_toBinaryOperator(kctx, mn);
				INode *LHS = FetchINode(kctx, builder, expr, 1, KType_float, thunk);
				INode *RHS = FetchINode(kctx, builder, expr, 2, KType_float, thunk);
				return CreateBinaryInst(BLD(builder), Op, LHS, RHS, kNode_uline(stmt));
			}
		}
	}
	return 0;
}