static KMETHOD TypeCheck_Bracket(KonohaContext *kctx, KonohaStack *sfp) { VAR_TypeCheck(stmt, expr, gma, reqty); // [0] currentToken, [1] NULL, [2] .... size_t i; KonohaClass *requestClass = CT_(reqty); KonohaClass *paramType = (requestClass->baseTypeId == TY_Array) ? CT_(requestClass->p0) : CT_INFER; for(i = 2; i < kArray_size(expr->cons); i++) { kExpr *typedExpr = SUGAR kStmt_TypeCheckExprAt(kctx, stmt, expr, i, gma, paramType, 0); if(typedExpr == K_NULLEXPR) { KReturn(typedExpr); } if(paramType->typeId == TY_var) { paramType = CT_(typedExpr->attrTypeId); } } if(requestClass->baseTypeId != TY_Array) { requestClass = (paramType->typeId == TY_var) ? CT_Array : CT_p0(kctx, CT_Array, paramType->typeId); } kMethod *mtd = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, Stmt_ns(stmt), CT_Array, MN_("[]"), -1, MethodMatch_NoOption); DBG_ASSERT(mtd != NULL); KFieldSet(expr, expr->cons->MethodItems[0], mtd); KFieldSet(expr, expr->cons->ExprItems[1], SUGAR kExpr_SetVariable(kctx, NULL, gma, TEXPR_NEW, requestClass->typeId, kArray_size(expr->cons) - 2)); KReturn(Expr_typed(expr, TEXPR_CALL, requestClass->typeId)); }
static KMETHOD Statement_for(KonohaContext *kctx, KonohaStack *sfp) { VAR_Statement(stmt, gma); DBG_P("for statement .. "); int isOkay = false; if(SUGAR kStmt_TypeCheckByName(kctx, stmt, KW_ExprPattern, gma, CT_INFER, 0)) { kNameSpace *ns = Stmt_ns(stmt); kToken *TypeToken = SUGAR kStmt_GetToken(kctx, stmt, KW_TypePattern, NULL); kToken *VariableToken = SUGAR kStmt_GetToken(kctx, stmt, KW_SymbolPattern, NULL); DBG_P("typeToken=%p, varToken=%p", TypeToken, VariableToken); kExpr *IteratorExpr = SUGAR kStmt_GetExpr(kctx, stmt, KW_ExprPattern, NULL); if(!TY_isIterator(IteratorExpr->attrTypeId)) { kMethod *mtd = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, ns, CT_(IteratorExpr->attrTypeId), MN_to(TY_Iterator), 0, MethodMatch_NoOption); if(mtd == NULL) { kStmtExpr_Message(kctx, stmt, IteratorExpr, ErrTag, "expected Iterator expression after in"); KReturnUnboxValue(false); } IteratorExpr = SUGAR new_TypedCallExpr(kctx, stmt, gma, CT_INFER, mtd, 1, IteratorExpr); kStmt_setObject(kctx, stmt, KW_ExprPattern, IteratorExpr); } kBlock *block = new_MacroBlock(kctx, stmt, new_TypeToken(kctx, ns, CT_(IteratorExpr->attrTypeId)), new_ParsedExprToken(kctx, ns, IteratorExpr), TypeToken, VariableToken); kStmt *IfStmt = block->StmtList->StmtItems[1]; // @see macro; kStmt_appendBlock(kctx, IfStmt, SUGAR kStmt_GetBlock(kctx, stmt, ns, KW_BlockPattern, NULL)); kStmt_Set(CatchBreak, IfStmt, true); kStmt_Set(CatchContinue, IfStmt, true); isOkay = SUGAR kBlock_TypeCheckAll(kctx, block, gma); if(isOkay) { kStmt_typed(IfStmt, LOOP); kStmt_setObject(kctx, stmt, KW_BlockPattern, block); kStmt_typed(stmt, BLOCK); } } KReturnUnboxValue(isOkay); }
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)); } }
static KonohaClass *loadcidClass(KonohaContext *kctx, kNameSpace *ns, KTraceInfo *trace) { static KDEFINE_CLASS defcid = {0}; defcid.structname = "cid"; defcid.cflag = CFLAG_int; defcid.init = CT_(TY_int)->init; defcid.unbox = CT_(TY_int)->unbox; defcid.p = kcid_p; KonohaClass *ccid = KLIB kNameSpace_DefineClass(kctx, ns, NULL, &defcid, trace); KDEFINE_METHOD MethodData[] = { _Public|_Coercion|_Const, _F(Object_tocid), ccid->typeId, TY_Object, MN_to(ccid->typeId), 0, DEND, }; KLIB kNameSpace_LoadMethodData(kctx, ns, MethodData, trace); return ccid; }
static KonohaClass *defineSymbolClass(KonohaContext *kctx, kNameSpace *ns, KTraceInfo *trace) { static KDEFINE_CLASS defSymbol = {0}; defSymbol.structname = "Symbol"; defSymbol.cflag = CFLAG_int; defSymbol.init = CT_(TY_int)->init; defSymbol.unbox = CT_(TY_int)->unbox; defSymbol.p = kSymbol_p; KonohaClass *cSymbol = KLIB kNameSpace_DefineClass(kctx, ns, NULL, &defSymbol, trace); KDEFINE_METHOD MethodData[] = { _Public|_Coercion|_Const, _F(String_toSymbol), cSymbol->typeId, TY_String, MN_to(cSymbol->typeId), 0, DEND, }; KLIB kNameSpace_LoadMethodData(kctx, ns, MethodData, trace); return cSymbol; }
//## cid Object.tocid(); static KMETHOD Object_tocid(KonohaContext *kctx, KonohaStack *sfp) { kObject *o = sfp[0].asObject; ktype_t cid = O_typeId(o); DBG_P(">>> Class=%s, cid=%d", SYM_t(CT_(cid)->classNameSymbol), cid); KReturnUnboxValue(cid); }
static void DumpVisitor_visitLocalExpr(KonohaContext *kctx, IRBuilder *self, kExpr *expr) { char buf[128]; snprintf(buf, 128, "LOCAL(%d, %s)", (int)expr->index, CT_t(CT_(expr->ty))); emit_string(buf, "", "", DUMPER(self)->indent); }
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(); }
static kbool_t var_PackupNameSpace(KonohaContext *kctx, kNameSpace *ns, int option, KTraceInfo *trace) { KDEFINE_INT_CONST ClassData[] = { // add Array as available {"var", VirtualType_KonohaClass, (uintptr_t)CT_(TY_var)}, {NULL}, }; KLIB kNameSpace_LoadConstData(kctx, ns, KonohaConst_(ClassData), trace); return true; }
static KMETHOD TypeCheck_as(KonohaContext *kctx, KonohaStack *sfp) { VAR_TypeCheck(stmt, expr, gma, reqty); kExpr *targetExpr = SUGAR kStmt_TypeCheckExprAt(kctx, stmt, expr, 2, gma, TY_var, 0); kExpr *selfExpr = SUGAR kStmt_TypeCheckExprAt(kctx, stmt, expr, 1, gma, targetExpr->ty, TypeCheckPolicy_NOCHECK); if(selfExpr != K_NULLEXPR && targetExpr != K_NULLEXPR) { KonohaClass *selfClass = CT_(selfExpr->ty), *targetClass = CT_(targetExpr->ty); if(selfExpr->ty == targetExpr->ty || selfClass->isSubType(kctx, selfClass, targetClass)) { KReturn(selfExpr); } if(selfClass->isSubType(kctx, targetClass, selfClass)) { kNameSpace *ns = Stmt_ns(stmt); kMethod *mtd = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, ns, TY_Object, MN_("as"), 0); DBG_ASSERT(mtd != NULL); KReturn(SUGAR kStmtkExpr_TypeCheckCallParam(kctx, stmt, expr, mtd, gma, targetClass->typeId)); } KReturn(kStmtExpr_Message(kctx, stmt, selfExpr, ErrTag, "unable to downcast: %s as %s", TY_t(selfExpr->ty), TY_t(targetExpr->ty))); } }
static void dumpEval(CTX, kwb_t *wb) { kstack_t *base = _ctx->stack; ktype_t ty = base->evalty; if(ty != TY_void) { ksfp_t *lsfp = base->stack + base->evalidx; CT_(ty)->p(_ctx, lsfp, 0, wb, P_DUMP); fflush(stdout); fprintf(stdout, "TYPE=%s EVAL=%s\n", TY_t(ty), kwb_top(wb,1)); } }
static kbool_t object_PackupNameSpace(KonohaContext *kctx, kNameSpace *ns, int option, KTraceInfo *trace) { // KRequirePackage("konoha.subtype", trace); KDEFINE_INT_CONST ClassData[] = { // add Object as available {"Object", VirtualType_KonohaClass, (uintptr_t)CT_(TY_Object)}, {NULL}, }; KLIB kNameSpace_LoadConstData(kctx, ns, KonohaConst_(ClassData), false/*isOverride*/, trace); object_defineMethod(kctx, ns, trace); subtype_defineSyntax(kctx, ns, trace); return true; }
static KMETHOD TypeCheck_InstanceOf(KonohaContext *kctx, KonohaStack *sfp) { VAR_TypeCheck(stmt, expr, gma, reqty); kExpr *selfExpr = SUGAR kStmt_TypeCheckExprAt(kctx, stmt, expr, 1, gma, TY_var, 0); kExpr *targetExpr = SUGAR kStmt_TypeCheckExprAt(kctx, stmt, expr, 2, gma, TY_var, 0); if(selfExpr != K_NULLEXPR && targetExpr != K_NULLEXPR) { KonohaClass *selfClass = CT_(selfExpr->ty), *targetClass = CT_(targetExpr->ty); if(CT_is(Final, selfClass)) { kbool_t staticSubType = (selfClass == targetClass || selfClass->isSubType(kctx, selfClass, targetClass)); KReturn(SUGAR kExpr_SetUnboxConstValue(kctx, expr, TY_boolean, staticSubType)); } kNameSpace *ns = Stmt_ns(stmt); kMethod *mtd = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, ns, TY_Object, MN_("<:"), 1); DBG_ASSERT(mtd != NULL); KFieldSet(expr->cons, expr->cons->MethodItems[0], mtd); kExpr *classValue = SUGAR kExpr_SetConstValue(kctx, expr->cons->ExprItems[2], targetExpr->ty, KLIB Knull(kctx, targetClass)); KFieldSet(expr->cons, expr->cons->ExprItems[2], classValue); KReturn(SUGAR kStmtkExpr_TypeCheckCallParam(kctx, stmt, expr, mtd, gma, TY_boolean)); } }
static KMETHOD TypeCheck_to(KonohaContext *kctx, KonohaStack *sfp) { VAR_TypeCheck(stmt, expr, gma, reqty); kExpr *targetExpr = SUGAR kStmt_TypeCheckExprAt(kctx, stmt, expr, 2, gma, TY_var, 0); kExpr *selfExpr = SUGAR kStmt_TypeCheckExprAt(kctx, stmt, expr, 1, gma, targetExpr->ty, TypeCheckPolicy_NOCHECK); if(selfExpr != K_NULLEXPR && targetExpr != K_NULLEXPR) { KonohaClass *selfClass = CT_(selfExpr->ty), *targetClass = CT_(targetExpr->ty); if(selfExpr->ty == targetExpr->ty || selfClass->isSubType(kctx, selfClass, targetClass)) { kStmtExpr_Message(kctx, stmt, selfExpr, InfoTag, "no need: %s to %s", TY_t(selfExpr->ty), TY_t(targetExpr->ty)); KReturn(selfExpr); } kNameSpace *ns = Stmt_ns(stmt); kMethod *mtd = KLIB kNameSpace_GetCoercionMethodNULL(kctx, ns, selfExpr->ty, targetExpr->ty); if(mtd == NULL) { mtd = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, ns, selfExpr->ty, MN_("to"), 0); DBG_ASSERT(mtd != NULL); // because Object.to is found. if(mtd->typeId != selfExpr->ty) { KReturn(kStmtExpr_Message(kctx, stmt, selfExpr, ErrTag, "undefined coercion: %s to %s", TY_t(selfExpr->ty), TY_t(targetExpr->ty))); } } KReturn(SUGAR kStmtkExpr_TypeCheckCallParam(kctx, stmt, expr, mtd, gma, targetClass->typeId)); } }
static kbool_t process_PackupNameSpace(KonohaContext *kctx, kNameSpace *ns, int option, KTraceInfo *trace) { kparamtype_t p = {TY_int}; KonohaClass *cintArray = KLIB KonohaClass_Generics(kctx, CT_(TY_Array), TY_void, 1, &p); #define TY_intArray (cintArray->typeId) KDEFINE_METHOD MethodData[] = { _Public|_Static, _F(System_getpid), TY_int, TY_System, MN_("getpid"), 0, _Public|_Static, _F(System_getppid), TY_int, TY_System, MN_("getppid"), 0, _Public|_Static, _F(System_getuid), TY_int, TY_System, MN_("getuid"), 0, _Public|_Static, _F(System_geteuid), TY_int, TY_System, MN_("geteuid"), 0, _Public|_Static, _F(System_getgid), TY_int, TY_System, MN_("getgid"), 0, _Public|_Static, _F(System_getegid), TY_int, TY_System, MN_("getegid"), 0, _Public|_Static, _F(System_getpgid), TY_int, TY_System, MN_("getpgid"), 1, TY_int, FN_("pid"), _Public|_Static, _F(System_setpgid), TY_int, TY_System, MN_("setpgid"), 2, TY_int, FN_("pid"), TY_int, FN_("pgid"), _Public|_Static, _F(System_getpriority), TY_int, TY_System, MN_("getpriority"), 2, TY_int, FN_("which"), TY_int, FN_("who"), _Public|_Static, _F(System_setpriority), TY_int, TY_System, MN_("setpriority"), 3, TY_int, FN_("which"), TY_int, FN_("who"), TY_int, FN_("priority"), _Public|_Static, _F(System_getgroups), TY_int, TY_System, MN_("getgroups"), 2, TY_int, FN_("size"), TY_intArray, FN_("list[]"), _Public|_Static, _F(System_setgroups), TY_int, TY_System, MN_("setgroups"), 2, TY_int, FN_("size"), TY_intArray, FN_("*list"), _Public|_Static, _F(System_fork), TY_int, TY_System, MN_("fork"), 0, _Public|_Static, _F(System_wait), TY_int, TY_System, MN_("wait"), 0, _Public|_Static, _F(System_waitpid), TY_int, TY_System, MN_("wait"), 2, TY_int, FN_("pid"), TY_int, FN_("options"), _Public|_Static, _F(System_setuid), TY_int, TY_System, MN_("setuid"), 1, TY_int, FN_("uid"), _Public|_Static, _F(System_seteuid), TY_int, TY_System, MN_("seteuid"), 1, TY_int, FN_("euid"), _Public|_Static, _F(System_setreuid), TY_int, TY_System, MN_("setreuid"), 2, TY_int, FN_("ruid"), TY_int, FN_("euid"), _Public|_Static, _F(System_setgid), TY_int, TY_System, MN_("setgid"), 1, TY_int, FN_("gid"), _Public|_Static, _F(System_setegid), TY_int, TY_System, MN_("setguid"), 1, TY_int, FN_("egid"), _Public|_Static, _F(System_setregid), TY_int, TY_System, MN_("setrguid"), 2, TY_int, FN_("rgid"), TY_int, FN_("egid"), _Public|_Static, _F(System_setsid), TY_int, TY_System, MN_("setsid"), 0, _Public|_Static, _F(System_getsid), TY_int, TY_System, MN_("getsid"), 1, TY_int, FN_("pid"), _Public|_Static, _F(System_sleep), TY_int, TY_System, MN_("sleep"), 1, TY_int, FN_("sec"), _Public|_Static, _F(System_usleep), TY_boolean, TY_System, MN_("usleep"), 1, TY_int, FN_("usec"), _Public|_Static, _F(System_system), TY_int, TY_System, MN_("system"), 1, TY_String, FN_("command"), DEND, }; KLIB kNameSpace_LoadMethodData(kctx, ns, MethodData, trace); KDEFINE_INT_CONST intData[] = { {KDefineConstInt(SIGHUP)}, {KDefineConstInt(SIGINT)}, {KDefineConstInt(SIGABRT)}, {KDefineConstInt(SIGKILL)}, /*for System.setpriority*/ {KDefineConstInt(PRIO_PROCESS)}, {KDefineConstInt(PRIO_PGRP)}, {KDefineConstInt(PRIO_USER)}, {} }; KLIB kNameSpace_LoadConstData(kctx, ns, KonohaConst_(intData), false/*isOverride*/, trace); return true; }
static KMETHOD Statement_class(KonohaContext *kctx, KonohaStack *sfp) { VAR_Statement(stmt, gma); kToken *tokenClassName = SUGAR kStmt_GetToken(kctx, stmt, SYM_("$ClassName"), NULL); kNameSpace *ns = Stmt_ns(stmt); int isNewlyDefinedClass = false; KonohaClassVar *definedClass = (KonohaClassVar *)KLIB kNameSpace_GetClassByFullName(kctx, ns, S_text(tokenClassName->text), S_size(tokenClassName->text), NULL); if(definedClass == NULL) { // Already defined kshortflag_t cflag = kStmt_ParseClassFlag(kctx, stmt, kClass_Virtual); KMakeTraceUL(trace, sfp, stmt->uline); definedClass = kNameSpace_DefineClassName(kctx, ns, cflag, tokenClassName->text, trace); isNewlyDefinedClass = true; } kBlock *bk = kStmt_ParseClassBlockNULL(kctx, stmt, tokenClassName); size_t declsize = kBlock_countFieldSize(kctx, bk); if(isNewlyDefinedClass) { // Already defined KonohaClass *superClass = CT_Object; kToken *tokenSuperClass= SUGAR kStmt_GetToken(kctx, stmt, SYM_("extends"), NULL); if(tokenSuperClass != NULL) { DBG_ASSERT(Token_isVirtualTypeLiteral(tokenSuperClass)); superClass = CT_(Token_typeLiteral(tokenSuperClass)); if(CT_is(Final, superClass)) { SUGAR kStmt_Message2(kctx, stmt, NULL, ErrTag, "%s is final", CT_t(superClass)); KReturnUnboxValue(false); } if(CT_is(Virtual, superClass)) { SUGAR kStmt_Message2(kctx, stmt, NULL, ErrTag, "%s is still virtual", CT_t(superClass)); KReturnUnboxValue(false); } } size_t initsize = (bk != NULL) ? declsize : initFieldSizeOfVirtualClass(superClass); KonohaClass_InitField(kctx, definedClass, superClass, initsize); } else { if(declsize > 0 && !CT_is(Virtual, definedClass)) { SUGAR kStmt_Message2(kctx, stmt, NULL, ErrTag, "%s has already defined", CT_t(definedClass)); KReturnUnboxValue(false); } } if(bk != NULL) { if(!kBlock_declClassField(kctx, bk, gma, definedClass)) { KReturnUnboxValue(false); } CT_set(Virtual, definedClass, false); } kToken_setTypeId(kctx, tokenClassName, ns, definedClass->typeId); kBlock_AddMethodDeclStmt(kctx, bk, tokenClassName, stmt); kStmt_done(kctx, stmt); KReturnUnboxValue(true); }
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)); } } } }
static void DumpVisitor_visitNConstExpr(KonohaContext *kctx, IRBuilder *self, kExpr *expr) { KGrowingBuffer wb; KLIB Kwb_init(&(kctx->stack->cwb), &wb); KonohaStack sfp[1]; unsigned long unboxVal = expr->unboxConstValue; KonohaClass *ct = CT_(expr->ty); sfp[0].unboxValue = unboxVal; ct->p(kctx, sfp, 0, &wb, 0); char *str = (char *) KLIB Kwb_top(kctx, &wb, 0); char buf[128]; snprintf(buf, 128, "NCONST:'%s'", str); emit_string(buf, "", "", DUMPER(self)->indent); KLIB Kwb_free(&wb); }
static kbool_t object_initPackage(KonohaContext *kctx, kNameSpace *ns, int argc, const char**args, KTraceInfo *trace) { KRequirePackage("konoha.subtype", trace); KDEFINE_INT_CONST ClassData[] = { // add Object as available {"Object", VirtualType_KonohaClass, (uintptr_t)CT_(TY_Object)}, {NULL}, }; KLIB kNameSpace_loadConstData(kctx, ns, KonohaConst_(ClassData), 0); KDEFINE_METHOD MethodData[] = { _Public|_Const, _F(Object_getTypeId), TY_int, TY_Object, MN_("getTypeId"), 0, DEND, }; KLIB kNameSpace_loadMethodData(kctx, ns, MethodData); return true; }
static KMETHOD Array_newArray(KonohaContext *kctx, KonohaStack *sfp) { kArrayVar *a = (kArrayVar *)sfp[0].asObject; size_t asize = (size_t)sfp[1].intValue; a->bytemax = asize * sizeof(uintptr_t); kArray_SetSize(a, asize); a->ObjectItems = (kObject**)KCalloc_UNTRACE(a->bytemax, 1); if(!kArray_isUnboxData(a)) { size_t i; kObject *null = KLIB Knull(kctx, CT_(O_p0(a))); for(i = 0; i < asize; i++) { KFieldSet(a, a->ObjectItems[i], null); } } KReturn(a); }
static kbool_t array_defineMethod(KonohaContext *kctx, kNameSpace *ns, KTraceInfo *trace) { KRequireKonohaCommonModule(trace); KImportPackageSymbol(ns, "cstyle", "[]", trace); KDEFINE_INT_CONST ClassData[] = { // add Array as available {"Array", VirtualType_KonohaClass, (uintptr_t)CT_(TY_Array)}, {NULL}, }; KLIB kNameSpace_LoadConstData(kctx, ns, KonohaConst_(ClassData), false/*isOverride*/, trace); KonohaClass *CT_ArrayT0 = CT_p0(kctx, CT_Array, TY_0); kattrtype_t TY_ArrayT0 = CT_ArrayT0->typeId; kparamtype_t p[] = {{TY_0}}; kattrtype_t TY_FuncMap = (KLIB KonohaClass_Generics(kctx, CT_Func, TY_0 , 1, p))->typeId; kparamtype_t P_inject[] = {{TY_0},{TY_0}}; kattrtype_t TY_FuncInject = (KLIB KonohaClass_Generics(kctx, CT_Func, TY_0 , 2, P_inject))->typeId; KDEFINE_METHOD MethodData[] = { _Public|_Im, _F(Array_get), TY_0, TY_Array, MN_("get"), 1, TY_int, FN_("index"), _Public, _F(Array_set), TY_void, TY_Array, MN_("set"), 2, TY_int, FN_("index"), TY_0, FN_("value"), _Public|_Im, _F(Array_removeAt), TY_0, TY_Array, MN_("removeAt"), 1, TY_int, FN_("index"), _Public|_Const, _F(Array_getSize), TY_int, TY_Array, MN_("getSize"), 0, _Public|_Const, _F(Array_getSize), TY_int, TY_Array, MN_("getlength"), 0, _Public, _F(Array_clear), TY_void, TY_Array, MN_("clear"), 0, _Public, _F(Array_Add1), TY_void, TY_Array, MN_("add"), 1, TY_0, FN_("value"), _Public, _F(Array_Push), TY_int, TY_Array, MN_("push"), 1, TY_0, FN_("value"), _Public, _F(Array_Pop), TY_0, TY_Array, MN_("pop"), 0, _Public, _F(Array_shift), TY_0, TY_Array, MN_("shift"), 0, _Public, _F(Array_unshift), TY_int, TY_Array, MN_("unshift"), 1, TY_0, FN_("value"), _Public, _F(Array_reverse), TY_Array, TY_Array, MN_("reverse"), 0, // _Public|_Im, _F(Array_map), TY_ArrayT0, TY_Array, MN_("map"), 1, TY_FuncMap, FN_("func"), // _Public|_Im, _F(Array_inject), TY_0, TY_Array, MN_("inject"), 1, TY_FuncInject, FN_("func"), _Public, _F(Array_concat), TY_ArrayT0, TY_Array, MN_("concat"), 1, TY_ArrayT0, FN_("a1"), _Public, _F(Array_indexOf), TY_int, TY_Array, MN_("indexOf"), 1, TY_0, FN_("value"), _Public, _F(Array_lastIndexOf), TY_int, TY_Array, MN_("lastIndexOf"), 1, TY_0, FN_("value"), // _Public, _F(Array_toString), TY_String, TY_Array, MN_("toString"), 0, _Public|_Im, _F(Array_new), TY_void, TY_Array, MN_("new"), 1, TY_int, FN_("size"), _Public, _F(Array_newArray), TY_Array, TY_Array, MN_("newArray"), 1, TY_int, FN_("size"), _Public|kMethod_Hidden, _F(Array_newList), TY_Array, TY_Array, MN_("[]"), 0, DEND, }; KLIB kNameSpace_LoadMethodData(kctx, ns, MethodData, trace); return true; }
static KMETHOD Statement_ConstDecl(KonohaContext *kctx, KonohaStack *sfp) { VAR_Statement(stmt, gma); kNameSpace *ns = Stmt_ns(stmt); kToken *SymbolToken = SUGAR kStmt_GetToken(kctx, stmt, KW_SymbolPattern, NULL); ksymbol_t unboxKey = SymbolToken->resolvedSymbol; kbool_t result = SUGAR kStmt_TypeCheckByName(kctx, stmt, KW_ExprPattern, gma, TY_var, TypeCheckPolicy_CONST); if(result) { kExpr *ConstExpr = SUGAR kStmt_GetExpr(kctx, stmt, KW_ExprPattern, NULL); ktype_t type = ConstExpr->ty; uintptr_t unboxValue; result = false; if(ConstExpr->build == TEXPR_NULL) { // const C = String type = VirtualType_KonohaClass; unboxValue = (uintptr_t)(CT_(ConstExpr->ty)); result = true; } else if(ConstExpr->build == TEXPR_CONST) { // const C = "1" unboxValue = (uintptr_t)ConstExpr->objectConstValue; result = true; } else if(ConstExpr->build == TEXPR_NCONST) { // const c = 1 unboxValue = ConstExpr->unboxConstValue; result = true; } if(result) { KMakeTraceUL(trace, sfp, stmt->uline); result = KLIB kNameSpace_SetConstData(kctx, ns, unboxKey, type, unboxValue, trace); } else { kStmt_Message(kctx, stmt, ErrTag, "constant value is expected: %s%s", PSYM_t(unboxKey)); } } kStmt_done(kctx, stmt); KReturnUnboxValue(result); }
static void CALL_asm(KonohaContext *kctx, kStmt *stmt, int a, kExpr *expr, int shift, int espidx) { kMethod *mtd = expr->cons->methodItems[0]; DBG_ASSERT(IS_Method(mtd)); int i, s = Method_isStatic(mtd) ? 2 : 1, thisidx = espidx + K_CALLDELTA; #ifdef _CLASSICVM if (CLASSICVM_CALL_asm(kctx, mtd, expr, shift, espidx)) { return; } #endif for(i = s; i < kArray_size(expr->cons); i++) { kExpr *exprN = kExpr_at(expr, i); DBG_ASSERT(IS_Expr(exprN)); EXPR_asm(kctx, stmt, thisidx + i - 1, exprN, shift, thisidx + i - 1); } int argc = kArray_size(expr->cons) - 2; // if (mtd->mn == MN_new && mtd->invokeMethodFunc == MethodFunc_abstract) { // /* do nothing */ // } else // if(Method_isFinal(mtd) || !Method_isVirtual(mtd)) { // if(mtd->invokeMethodFunc != MethodFunc_runVirtualMachine) { // ASM(SCALL, ctxcode->uline, SFP_(thisidx), ESP_(espidx, argc), mtd, KLIB Knull(kctx, CT_(expr->ty))); // } // else { // ASM(VCALL, ctxcode->uline, SFP_(thisidx), ESP_(espidx, argc), mtd, KLIB Knull(kctx, CT_(expr->ty))); // } // } // else { if(Method_isFinal(mtd) || !Method_isVirtual(mtd)) { ASM(NSET, NC_(thisidx-1), (intptr_t)mtd, CT_Method); } else { ASM(LOOKUP, SFP_(thisidx), Stmt_nameSpace(stmt), mtd); } ASM(CALL, ctxcode->uline, SFP_(thisidx), ESP_(espidx, argc), KLIB Knull(kctx, CT_(expr->ty))); }
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); } }
static void DumpVisitor_visitNullExpr(KonohaContext *kctx, IRBuilder *self, kExpr *expr) { char buf[128]; snprintf(buf, 128, "%s.NULL", CT_t(CT_(expr->ty))); emit_string(buf, "", "", DUMPER(self)->indent); }
static void kcid_p(KonohaContext *kctx, KonohaValue *v, int pos, KGrowingBuffer *wb) { ktype_t cid = (ktype_t)v[pos].intValue; DBG_P(">>> Class=%s, cid=%d", SYM_t(CT_(cid)->classNameSymbol), cid); KLIB Kwb_printf(kctx, wb, "%s%s", PSYM_t(CT_(cid)->classNameSymbol)); }