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; }
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; }
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); }
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); } }
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); } }
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; }