Esempio n. 1
0
static intptr_t MiniVMBuilder_FindLocalVar(KonohaContext *kctx, KBuilder *builder, ksymbol_t symbol, ktypeattr_t typeId, intptr_t index)
{
	unsigned i, localSize;
	kParam *params;
	kMethod *mtd = builder->currentMtd;
	if(mtd->typeId != KType_void && mtd->typeId == typeId && index == 0) {
		return 0;
	}

	params = kMethod_GetParam(mtd);
	for(i = 0; i < params->psize; ++i) {
		ktypeattr_t ptype = params->paramtypeItems[i].typeAttr;
		if(ptype == typeId && index == i ) {
			return i;
		}
	}

	localSize = builder->localVar.bytesize / sizeof(LocalVarInfo);
	for(i = 0; i < localSize; i++) {
		LocalVarInfo *local = &((LocalVarInfo *)builder->localVar.bytebuf)[i];
		if(local->index == index && local->type == typeId && local->sym == symbol) {
			return local->index;
		}
	}
	return -1;
}
Esempio n. 2
0
static INode *SetUpArguments(KonohaContext *kctx, FuelIRBuilder *builder, kMethod *mtd)
{
	kParam *params = kMethod_GetParam(mtd);
	unsigned i;
	INode *Arg;
	INode *Val;
	INode *Arg0 = NULL;
	if(mtd->typeId != TYPE_void) {
		Arg = CreateArgument(builder, 0);
		Val = CreateLocal(builder, mtd->typeId);
		CreateUpdate(builder, Val, Arg);
		INode_setType(Arg, mtd->typeId);
		IField_setHash((IField *) Val, 0);
		Arg0 = Val;
	}
	for(i = 0; i < params->psize; ++i) {
		enum TypeId type = ConvertToTypeId(kctx, params->paramtypeItems[i].attrTypeId);
		Arg = CreateArgument(builder, i+1);
		Val = CreateLocal(builder, type);
		CreateUpdate(builder, Val, Arg);
		INode_setType(Arg, type);
		IField_setHash((IField *) Val, i+1);
	}
	return Arg0;
}
Esempio n. 3
0
static KMETHOD KMethodFunc_UnboxPrototypeSetter(KonohaContext *kctx, KonohaStack *sfp)
{
	kMethod *mtd = sfp[K_MTDIDX].calledMethod;
	ksymbol_t key = (ksymbol_t)mtd->delta;
	kParam *pa = kMethod_GetParam(mtd);
	KLIB kObjectProto_SetUnboxValue(kctx, sfp[0].asObject, key, pa->paramtypeItems[0].typeAttr, sfp[1].unboxValue);
	KReturnUnboxValue(sfp[1].unboxValue);
}
Esempio n. 4
0
static void KStackDynamicTypeCheck(KonohaContext *kctx, KonohaStack *sfp, kMethod *mtd, KClass *thisClass)
{
	kushort_t i;
	kParam *pa = kMethod_GetParam(mtd);
	for(i = 0; i < pa->psize; i++) {
		KClass *objectType = kObject_class(sfp[i+1].asObject);
		KClass *paramType = KClass_(pa->paramtypeItems[i].attrTypeId);
		paramType = paramType->realtype(kctx, paramType, thisClass);
		if(objectType == paramType || objectType->isSubType(kctx, objectType, paramType)) {
			if(KClass_Is(UnboxType, paramType)) {
				KStackSetUnboxValue(sfp[i+1].unboxValue, kObject_Unbox(sfp[i+1].asObject));
			}
			continue; // OK
		}
		ThrowTypeError(kctx, sfp, i + 1);
	}
}
Esempio n. 5
0
static void kMethod_WriteToBuffer(KonohaContext *kctx, kMethod *mtd, KBuffer *wb)
{
	kParam *pa = kMethod_GetParam(mtd);
	Method_WriteAttributeToBuffer(kctx, mtd, wb);
	KLIB KBuffer_printf(kctx, wb, "%s %s.%s%s", KType_text(pa->rtype), KType_text(mtd->typeId), KMethodName_Fmt2(mtd->mn));
	{
		size_t i;
		KLIB KBuffer_Write(kctx, wb, "(", 1);
		for(i = 0; i < pa->psize; i++) {
			if(i > 0) {
				KLIB KBuffer_Write(kctx, wb, ", ", 2);
			}
			if(KTypeAttr_Is(ReadOnly, pa->paramtypeItems[i].attrTypeId)) {
				KLIB KBuffer_printf(kctx, wb, "@ReadOnly ");
			}
			if(KTypeAttr_Is(Coercion, pa->paramtypeItems[i].attrTypeId)) {
				KLIB KBuffer_printf(kctx, wb, "@Coercion ");
			}
			KLIB KBuffer_printf(kctx, wb, "%s %s", KType_text(pa->paramtypeItems[i].attrTypeId), KSymbol_text(pa->paramtypeItems[i].name));
		}
		KLIB KBuffer_Write(kctx, wb, ")", 1);
	}
}
Esempio n. 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;
}