//## Json Json.getJson(String key); static KMETHOD Json_getJson(KonohaContext *kctx, KonohaStack *sfp) { json_t* obj = ((struct _kJson *)sfp[0].asObject)->obj; CHECK_JSON(obj, KReturn((kJson *)KLIB Knull(kctx, O_ct(sfp[0].asObject)))); const char *key = S_text(sfp[1].asString); json_t* ret = json_object_get(obj, key); CHECK_JSON(ret, KReturn((kJson *)KLIB Knull(kctx, O_ct(sfp[0].asObject)))); ret = json_incref(ret); struct _kJson *json = (struct _kJson *)KLIB new_kObjectDontUseThis(kctx, KGetReturnType(sfp), 0); json->obj = ret; KReturn(json); }
static kbool_t MiniVM_VisitMethodCallNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk) { kMethod *mtd = CallNode_getMethod(node); /* * [CallExpr] := this.method(arg1, arg2, ...) * node->NodeList = [method, this, arg1, arg2, ...] **/ intptr_t stackbase, thisidx; int i, s, argc = CallNode_getArgCount(node); DBG_ASSERT(IS_Method(mtd)); s = kMethod_Is(Static, mtd) ? 2 : 1; if(kMethod_Is(Static, mtd)) { KClass *selfTy = KClass_(mtd->typeId); kObject *obj = KLIB Knull(kctx, selfTy); ASM(NSET, OC_(builder->stackbase), (uintptr_t) obj, selfTy); } stackbase = builder->stackbase; thisidx = stackbase + K_CALLDELTA; for (i = s; i < argc + 2; i++) { kUntypedNode *exprN = kUntypedNode_At(node, i); builder->stackbase = thisidx + i - 1; DBG_ASSERT(IS_Node(exprN)); KLIB VisitNode(kctx, builder, exprN, thunk); if(builder->Value != builder->stackbase) { KClass *ty = KClass_(exprN->typeAttr); ASM_NMOV(kctx, builder, ty, builder->stackbase, builder->Value); } } if(kMethod_Is(Final, mtd) || !kMethod_Is(Virtual, mtd)) { ASM(NSET, NC_(thisidx-1), (intptr_t)mtd, KClass_Method); if(kMethod_Is(Virtual, mtd)) { // set namespace to enable method lookups ASM(NSET, OC_(thisidx-2), (intptr_t)kUntypedNode_ns(node), KClass_NameSpace); } } else { ASM(NSET, OC_(thisidx-2), (intptr_t)kUntypedNode_ns(node), KClass_NameSpace); ASM(LOOKUP, SFP_(thisidx), kUntypedNode_ns(node), mtd); } ASM(CALL, kUntypedNode_uline(node), SFP_(thisidx), SFP_(thisidx + argc + 1), KLIB Knull(kctx, KClass_(node->typeAttr))); builder->stackbase = stackbase; builder->Value = builder->stackbase; return true; }
static kbool_t KBuilder_VisitMethodCallNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk) { kshort_t a = AssignStack(thunk), espidx = expr->stackbase, thisidx = espidx + K_CALLDELTA; DBG_ASSERT(a <= espidx); kMethod *mtd = CallNode_getMethod(expr); DBG_ASSERT(IS_Method(mtd)); int i, s = kMethod_Is(Static, mtd) ? 2 : 1; int argc = CallNode_getArgCount(expr); for (i = s; i < argc + 2; i++) { intptr_t a = thisidx + i - 1; kNode *paramNode = kNode_At(expr, i); if(!kNode_IsValue(paramNode) && paramNode->stackbase != a) { DBG_P("a=%d, stackbase=%d", a, paramNode->stackbase); DBG_ASSERT(paramNode->stackbase == a); } SUGAR VisitNode(kctx, builder, paramNode, &a); } if(kMethod_Is(Final, mtd) || !kMethod_Is(Virtual, mtd)) { ASM(NSET, NC_(thisidx-1), (intptr_t)mtd, KClass_Method); if(kMethod_Is(Virtual, mtd)) { // set namespace to enable method lookups ASM(NSET, OC_(thisidx-2), (intptr_t)kNode_ns(expr), KClass_NameSpace); } } else { ASM(NSET, OC_(thisidx-2), (intptr_t)kNode_ns(expr), KClass_NameSpace); ASM(LOOKUP, SFP_(thisidx), kNode_ns(expr), mtd); } int esp_ = SFP_(espidx + argc + K_CALLDELTA + 1); ASM(CALL, builder->common.uline, SFP_(thisidx), esp_, KLIB Knull(kctx, KClass_(expr->attrTypeId))); ReAssignNonValueNode(kctx, builder, a, expr); return true; }
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; }
//## @Static Json Json.parse(String str); static KMETHOD Json_parse(KonohaContext *kctx, KonohaStack *sfp) { const char *buf = S_text(sfp[1].asString); json_t* obj; json_error_t err; obj = json_loads(buf, 0, &err); struct _kJson *ret = (struct _kJson *)KLIB new_kObjectDontUseThis(kctx, KGetReturnType(sfp), 0); CHECK_JSON(obj, KReturn((kJson *)KLIB Knull(kctx, O_ct(ret)))); obj = json_incref(obj); ret->obj = obj; KReturn(ret); }
static kbool_t FuelVM_VisitNullNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk) { SValue Val = {}; ktypeattr_t type = expr->attrTypeId; if(KType_Is(UnboxType, type)) { Val.bits = 0; } else { Val.ptr = (void *) KLIB Knull(kctx, KClass_(type)); } builder->Value = CreateConstant(BLD(builder), ConvertToTypeId(kctx, expr->attrTypeId), Val); return true; }
// @SmartReturn Object Object.as(Object target) static KMETHOD Object_as(KonohaContext *kctx, KonohaStack *sfp) { KonohaClass *selfClass = O_ct(sfp[0].asObject), *targetClass = KGetReturnType(sfp); kObject *returnValue; if(selfClass == targetClass || selfClass->isSubType(kctx, selfClass, targetClass)) { returnValue = sfp[0].asObject; } else { returnValue = KLIB Knull(kctx, targetClass); } sfp[K_RTNIDX].unboxValue = O_unbox(returnValue); KReturn(returnValue); }
static kbool_t kNameSpace_InitGlobalObject(KonohaContext *kctx, kNameSpace *ns, KTraceInfo *trace) { if(ns->globalObjectNULL_OnList == NULL) { KDEFINE_CLASS defGlobalObject = {0}; defGlobalObject.structname = "GlobalObject"; defGlobalObject.typeId = TY_newid; defGlobalObject.cflag = kClass_Singleton|kClass_Final; defGlobalObject.cstruct_size = sizeof(kGlobalObject); KonohaClass *cGlobalObject = KLIB kNameSpace_DefineClass(kctx, ns, NULL, &defGlobalObject, trace); ((kNameSpaceVar *)ns)->globalObjectNULL_OnList = KLIB Knull(kctx, cGlobalObject); return KLIB kNameSpace_SetConstData(kctx, ns, SYM_("global"), cGlobalObject->typeId, (uintptr_t)ns->globalObjectNULL_OnList, true/*isOverride*/, trace); } return true; }
static const char *getThisFileName(KonohaContext *kctx) { static char shell[] = "shell"; kNameSpace *ns = (kNameSpace *)KLIB Knull(kctx, KClass_NameSpace); ksymbol_t sym = KSymbol_("SCRIPT_ARGV"); KKeyValue *kv = KLIB kNameSpace_GetConstNULL(kctx, ns, sym, false/*isLocalOnly*/); if(kv != NULL) { kArray *sa = (kArray *)kv->ObjectValue; if(sa->stringItems != NULL) { const char *file = kString_text(sa->stringItems[0]); return file; } } return shell; }
//## @SmartReturn Object ResultSet.get(String n); static KMETHOD ResultSet_get(KonohaContext *kctx, KonohaStack *sfp) { KClass *retClass = KGetReturnType(sfp); if(retClass->typeId == KType_Int) { ResultSet_getInt(kctx, sfp); } else if(retClass->typeId == KType_String) { ResultSet_getString(kctx, sfp); } else if(KDefinedKonohaCommonModule() && retClass->typeId == KType_float) { ResultSet_getFloat(kctx, sfp); } else { kObject *returnValue = KLIB Knull(kctx, retClass); KStackSetUnboxValue(sfp[K_RTNIDX].unboxValue, kObject_Unbox(returnValue)); KReturn(returnValue); } }
/* * 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(); }
/* * 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(); }
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(); }
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 FuelVM_VisitMethodCallNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk) { kMethod *mtd = CallNode_getMethod(expr); DBG_ASSERT(IS_Method(mtd)); enum TypeId Type = ConvertToTypeId(kctx, expr->attrTypeId); if(mtd->mn == KMethodName_("box")) { Type = ToBoxType(Type); } /* * [CallExpr] := this.method(arg1, arg2, ...) * expr->NodeList = [method, this, arg1, arg2, ...] **/ INode *Inst; if((Inst = CreateSpecialInstruction(kctx, builder, mtd, expr, thunk)) != 0) { INode_setType(Inst, Type); builder->Value = Inst; return true; } int i, s = kMethod_Is(Static, mtd) ? 2 : 1; int argc = CallExpr_getArgCount(expr); INode *Params[argc+2]; if(kMethod_Is(Static, mtd)) { kObject *obj = KLIB Knull(kctx, KClass_(mtd->typeId)); INode *Self = CreateObject(BLD(builder), mtd->typeId, (void *) obj); Params[1] = Self; } for (i = s; i < argc + 2; i++) { kNode *exprN = kNode_At(expr, i); DBG_ASSERT(IS_Node(exprN)); SUGAR VisitNode(kctx, builder, exprN, thunk); INode *Node = FuelVM_getExpression(builder); assert(Node->Type != TYPE_void); Params[i] = Node; } INode *MtdObj = CreateObject(BLD(builder), KType_Method, (void *) mtd); enum CallOp Op = (kMethod_Is(Virtual, mtd)) ? VirtualCall : DefaultCall; Params[0] = MtdObj; kNode *stmt = expr->Parent; assert(IS_Node(stmt)); Inst = CreateICall(BLD(builder), Type, Op, kNode_uline(stmt), Params, argc + 2); builder->Value = Inst; return true; }
static int konoha_handler(request_rec *r) { //konoha_config_t *conf = ap_get_module_config( // r->server->module_config, &konoha_module); if(strcmp(r->handler, "konoha-script")) { return DECLINED; } // if(r->method_number != M_GET) { // TODO // return HTTP_METHOD_NOT_ALLOWED; // } KonohaClass *cRequest; verbose_debug = 1; KonohaContext* konoha = konoha_create(&cRequest); //assert(cRequest != NULL); r->content_encoding = "utf-8"; ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, "filename=%s", r->filename); if(Konoha_LoadScript(konoha, r->filename)) { return DECLINED; } KonohaContext *kctx = konoha; kNameSpace *ns = KNULL(NameSpace); kMethod *mtd = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, ns, TY_System, MN_("handler"), -1); // fixme if(mtd == NULL) { ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, "System.handler() not found"); return -1; } /* XXX: We assume Request Object may not be freed by GC */ kObject *req_obj = KLIB new_kObject(kctx, OnStack, cRequest, (uintptr_t)r); BEGIN_LOCAL(lsfp, K_CALLDELTA + 1); KUnsafeFieldSet(lsfp[K_CALLDELTA+0].asObject, K_NULL); KUnsafeFieldSet(lsfp[K_CALLDELTA+1].asObject, req_obj); { KonohaStack *sfp = lsfp + K_CALLDELTA; KSetMethodCallStack(sfp, 0/*UL*/, mtd, 1, KLIB Knull(kctx, CT_Int)); KonohaRuntime_callMethod(kctx, sfp); } END_LOCAL(); int ret = lsfp[0].intValue; Konoha_Destroy(konoha); return ret; }
static kbool_t KClass_AddField(KonohaContext *kctx, KClass *ct, ktypeattr_t typeattr, ksymbol_t sym) { kuhalfword_t pos = ct->fieldsize; if(unlikely(ct->classMethodList == K_EMPTYARRAY)) { ((KClassVar *)ct)->classMethodList = new_(MethodArray, 8, OnGlobalConstList); /*FIXME WriteBarrier */ } INIT_GCSTACK(); if(pos < ct->fieldAllocSize) { KClassVar *definedClass = (KClassVar *)ct; definedClass->fieldsize += 1; definedClass->fieldItems[pos].name = sym; if(KType_Is(UnboxType, typeattr)) { definedClass->defaultNullValueVar->fieldUnboxItems[pos] = 0; definedClass->fieldItems[pos].typeAttr = typeattr; } else { kObjectVar *o = definedClass->defaultNullValueVar; KFieldSet(o, o->fieldObjectItems[pos], KLIB Knull(kctx, KClass_(typeattr))); definedClass->fieldItems[pos].typeAttr = typeattr | KTypeAttr_Boxed; } if(1/*KHalfFlag_Is(flag, kField_Getter)*/) { kMethod *mtd = new_FieldGetter(kctx, _GcStack, definedClass->typeId, sym, KTypeAttr_Unmask(typeattr), pos); KLIB kArray_Add(kctx, ct->classMethodList, mtd); } if(!KTypeAttr_Is(ReadOnly, typeattr)/*KHalfFlag_Is(flag, kField_Setter)*/) { kMethod *mtd = new_FieldSetter(kctx, _GcStack, definedClass->typeId, sym, KTypeAttr_Unmask(typeattr), pos); KLIB kArray_Add(kctx, ct->classMethodList, mtd); } } else { if(1/*KHalfFlag_Is(flag, kField_Getter)*/) { kMethod *mtd = new_PrototypeGetter(kctx, _GcStack, ct->typeId, sym, KTypeAttr_Unmask(typeattr)); KLIB kArray_Add(kctx, ct->classMethodList, mtd); } if(!KTypeAttr_Is(ReadOnly, typeattr)/*KHalfFlag_Is(flag, kField_Setter)*/) { kMethod *mtd = new_PrototypeSetter(kctx, _GcStack, ct->typeId, sym, KTypeAttr_Unmask(typeattr)); KLIB kArray_Add(kctx, ct->classMethodList, mtd); } } RESET_GCSTACK(); 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_Closure(KonohaContext *kctx, KonohaStack *sfp) { VAR_TypeCheck(expr, ns, reqc); kNode *texpr = K_NULLNODE; INIT_GCSTACK(); kToken *typeTk = SUGAR kNode_GetToken(kctx, expr, KSymbol_TypePattern, NULL); KClass *EnvObjectClass = NULL; KClass *envCt = CreateEnvClass(kctx, ns, typeTk, &EnvObjectClass); kMethod *mtd = CompileClosure(kctx, ns, expr, envCt, typeTk, &texpr); /* type check is OK */ if(texpr != K_NULLNODE) { /* * FunctionExpression * 0: Method * 1: EnvObject's Default Object * 2: Current LocalScope Variable * 3: ditto * 4: ... */ kNode_Type(texpr, KNode_Function, envCt->typeId); KFieldSet(expr, texpr->NodeList, new_(Array, 0, OnField)); KLIB kArray_Add(kctx, texpr->NodeList, mtd); KLIB kArray_Add(kctx, texpr->NodeList, KLIB Knull(kctx, EnvObjectClass)); size_t i = 0; struct KGammaLocalData *genv = ns->genv; if(genv->thisClass == KClass_NameSpace) { i = 1; } for(; i < genv->localScope.varsize; i++) { kNode *node = new_VariableNode(kctx, ns, KNode_Local, genv->localScope.varItems[i].attrTypeId, i); KLIB kArray_Add(kctx, texpr->NodeList, node); } } RESET_GCSTACK(); KReturn(texpr); }
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))); }
void MODSUGAR_Init(KonohaContext *kctx, KonohaContextVar *ctx) { KParserModel *mod = (KParserModel *)KCalloc_UNTRACE(sizeof(KParserModel), 1); mod->h.name = "sugar"; mod->h.allocSize = sizeof(KParserModel); mod->h.setupModelContext = SugarModule_Setup; KLIB KRuntime_SetModule(kctx, ParserModelIndex, (KRuntimeModel *)mod, 0); KonohaLibVar *l = (KonohaLibVar *)ctx->klib; l->kNameSpace_GetClassByFullName = kNameSpace_GetClassByFullName; l->kNameSpace_DefineClass = kNameSpace_DefineClass; l->kNameSpace_LoadMethodData = kNameSpace_LoadMethodData; l->kNameSpace_SetConstData = kNameSpace_SetConstData; l->kNameSpace_LoadConstData = kNameSpace_LoadConstData; l->kNameSpace_GetGetterMethodNULL = kNameSpace_GetGetterMethodNULL; l->kNameSpace_GetSetterMethodNULL = kNameSpace_GetSetterMethodNULL; l->kNameSpace_GetCoercionMethodNULL = kNameSpace_GetCoercionMethodNULL; l->kNameSpace_GetMethodByParamSizeNULL = kNameSpace_GetMethodByParamSizeNULL; l->kNameSpace_GetMethodBySignatureNULL = kNameSpace_GetMethodBySignatureNULL; l->kMethod_DoLazyCompilation = kMethod_DoLazyCompilation; l->kNameSpace_FreeSugarExtension = kNameSpace_FreeSugarExtension; l->Konoha_LoadScript = Konoha_LoadScript; l->Konoha_Eval = Konoha_Eval; l->kMethod_GenCode = kMethod_GenCode; l->kMethod_SetFunc = kMethod_SetFunc; KDEFINE_CLASS defSymbol = {0}; defSymbol.structname = "Symbol"; defSymbol.typeId = KTypeAttr_NewId; defSymbol.cflag = KClassFlag_int; defSymbol.init = KClass_(KType_Int)->init; defSymbol.unbox = KClass_(KType_Int)->unbox; defSymbol.format = kSymbol_format; KDEFINE_CLASS defSyntax = {0}; SETSTRUCTNAME(defSyntax, Syntax); defSyntax.init = kSyntax_Init; //defSyntax.format = kSyntax_format; KDEFINE_CLASS defToken = {0}; SETSTRUCTNAME(defToken, Token); defToken.init = kToken_Init; defToken.reftrace = kToken_Reftrace; defToken.format = kToken_format; KDEFINE_CLASS defNode = {0}; SETSTRUCTNAME(defNode, Node); defNode.init = kUntypedNode_Init; defNode.reftrace = kUntypedNode_Reftrace; defNode.format = kUntypedNode_format; InitNodeClass(kctx, mod); mod->cSymbol = KLIB KClass_define(kctx, PackageId_sugar, NULL, &defSymbol, 0); mod->cSyntax = KLIB KClass_define(kctx, PackageId_sugar, NULL, &defSyntax, 0); mod->cToken = KLIB KClass_define(kctx, PackageId_sugar, NULL, &defToken, 0); mod->cNode = KLIB KClass_define(kctx, PackageId_sugar, NULL, &defNode, 0); mod->cTokenArray = KClass_p0(kctx, KClass_Array, mod->cToken->typeId); KLIB Knull(kctx, mod->cToken); KLIB Knull(kctx, mod->cNode); SugarModule_Setup(kctx, &mod->h, 0); KDEFINE_INT_CONST ClassData[] = { // konoha defined class {"void", VirtualType_KClass, (uintptr_t)KClass_void}, {"boolean", VirtualType_KClass, (uintptr_t)KClass_Boolean}, {"int", VirtualType_KClass, (uintptr_t)KClass_Int}, {"String", VirtualType_KClass, (uintptr_t)KClass_String}, {"Func", VirtualType_KClass, (uintptr_t)KClass_Func}, {"System", VirtualType_KClass, (uintptr_t)KClass_System}, {NULL}, }; kNameSpace_LoadConstData(kctx, KNULL(NameSpace), KConst_(ClassData), 0); l->Tokenize = Tokenize; l->ApplyMacroData = ApplyMacroData; l->SetMacroData = SetMacroData; l->Preprocess = Preprocess; l->EvalTokenList = EvalTokenList; l->ParseTypePattern = ParseTypePattern; l->kToken_ToBraceGroup = kToken_ToBraceGroup; l->kUntypedNode_AddParsedObject = kUntypedNode_AddParsedObject; l->FindEndOfStatement = FindEndOfStatement; l->kUntypedNode_ParseFlag = kUntypedNode_ParseFlag; l->kUntypedNode_GetToken = kUntypedNode_GetToken; l->kUntypedNode_GetNode = kUntypedNode_GetNode; l->kUntypedNode_SetConst = kUntypedNode_SetConst; l->kUntypedNode_SetUnboxConst = kUntypedNode_SetUnboxConst; l->kUntypedNode_SetVariable = kUntypedNode_SetVariable; l->TypeCheckNodeAt = TypeCheckNodeAt; l->TypeCheckNodeByName = TypeCheckNodeByName; l->TypeCheckMethodParam = TypeCheckMethodParam; l->new_MethodNode = new_MethodNode; l->AddLocalVariable = AddLocalVariable; l->kUntypedNode_DeclType = kUntypedNode_DeclType; l->TypeVariableNULL = TypeVariableNULL; l->kNameSpace_DefineSyntax = kNameSpace_DefineSyntax; l->kNameSpace_GetSyntax = kNameSpace_GetSyntax; l->kSyntax_AddPattern = kSyntax_AddPattern; l->kNameSpace_AddSyntax = kNameSpace_AddSyntax; l->kNameSpace_UseDefaultVirtualMachine = kNameSpace_UseDefaultVirtualMachine; l->kUntypedNode_InsertAfter = kUntypedNode_InsertAfter; l->kUntypedNode_AddNode = kUntypedNode_AddNode; l->kUntypedNode_Op = kUntypedNode_Op; l->ParseSyntaxNode = ParseSyntaxNode; l->ParseNode = ParseNode; l->ParseNewNode = ParseNewNode; l->AppendParsedNode = AppendParsedNode; l->kToken_ToError = kToken_ToError; l->MessageNode = MessageNode; l->VisitNode = VisitNode; #ifndef USE_SMALLBUILD l->dumpToken = dumpToken; l->dumpTokenArray = dumpTokenArray; #endif DefineDefaultSyntax(kctx, KNULL(NameSpace)); }
void MODSUGAR_Init(KonohaContext *kctx, KonohaContextVar *ctx) { KModuleSugar *mod = (KModuleSugar *)KCalloc_UNTRACE(sizeof(KModuleSugar), 1); mod->h.name = "sugar"; mod->h.allocSize = sizeof(KModuleSugar); mod->h.setupModuleContext = SugarModule_Setup; KLIB KonohaRuntime_setModule(kctx, MOD_sugar, (KonohaModule *)mod, 0); KonohaLibVar* l = (KonohaLibVar *)ctx->klib; l->kNameSpace_GetClass = kNameSpace_GetClass; l->kNameSpace_DefineClass = kNameSpace_DefineClass; l->kNameSpace_LoadMethodData = kNameSpace_LoadMethodData; l->kNameSpace_SetConstData = kNameSpace_SetConstData; l->kNameSpace_LoadConstData = kNameSpace_LoadConstData; l->kNameSpace_GetGetterMethodNULL = kNameSpace_GetGetterMethodNULL; l->kNameSpace_GetSetterMethodNULL = kNameSpace_GetSetterMethodNULL; l->kNameSpace_GetCoercionMethodNULL = kNameSpace_GetCoercionMethodNULL; l->kNameSpace_GetMethodByParamSizeNULL = kNameSpace_GetMethodByParamSizeNULL; l->kNameSpace_GetMethodBySignatureNULL = kNameSpace_GetMethodBySignatureNULL; l->kMethod_DoLazyCompilation = kMethod_DoLazyCompilation; // l->kNameSpace_compileAllDefinedMethods = kNameSpace_compileAllDefinedMethods; l->kNameSpace_FreeSugarExtension = kNameSpace_FreeSugarExtension; l->Konoha_LoadScript = Konoha_LoadScript; l->Konoha_Eval = Konoha_Eval; l->kMethod_GenCode = kMethod_GenCode; l->kMethod_setFunc = kMethod_setFunc; KDEFINE_CLASS defToken = {0}; SETSTRUCTNAME(defToken, Token); defToken.init = kToken_Init; defToken.reftrace = kToken_Reftrace; defToken.p = kToken_p; KDEFINE_CLASS defExpr = {0}; SETSTRUCTNAME(defExpr, Expr); defExpr.init = kExpr_Init; defExpr.reftrace = kExpr_Reftrace; defExpr.p = kExpr_p; KDEFINE_CLASS defStmt = {0}; SETSTRUCTNAME(defStmt, Stmt); defStmt.init = kStmt_Init; defStmt.reftrace = kStmt_Reftrace; defStmt.p = kStmt_p; KDEFINE_CLASS defBlock = {0}; SETSTRUCTNAME(defBlock, Block); defBlock.init = kBlock_Init; defBlock.reftrace = kBlock_Reftrace; KDEFINE_CLASS defGamma = {0}; SETSTRUCTNAME(defGamma, Gamma); defGamma.init = Gamma_Init; mod->cToken = KLIB KonohaClass_define(kctx, PackageId_sugar, NULL, &defToken, 0); mod->cExpr = KLIB KonohaClass_define(kctx, PackageId_sugar, NULL, &defExpr, 0); mod->cStmt = KLIB KonohaClass_define(kctx, PackageId_sugar, NULL, &defStmt, 0); mod->cBlock = KLIB KonohaClass_define(kctx, PackageId_sugar, NULL, &defBlock, 0); mod->cGamma = KLIB KonohaClass_define(kctx, PackageId_sugar, NULL, &defGamma, 0); mod->cTokenArray = CT_p0(kctx, CT_Array, mod->cToken->typeId); KLIB Knull(kctx, mod->cToken); KLIB Knull(kctx, mod->cExpr); kStmtVar *NullStmt = (kStmtVar *)KLIB Knull(kctx, mod->cStmt); KFieldSet(NullStmt, NullStmt->parentBlockNULL, (kBlock *)KLIB Knull(kctx, mod->cBlock)); SugarModule_Setup(kctx, &mod->h, 0); KDEFINE_INT_CONST ClassData[] = { // minikonoha defined class {"void", VirtualType_KonohaClass, (uintptr_t)CT_void}, {"boolean", VirtualType_KonohaClass, (uintptr_t)CT_Boolean}, {"int", VirtualType_KonohaClass, (uintptr_t)CT_Int}, {"String", VirtualType_KonohaClass, (uintptr_t)CT_String}, {"Func", VirtualType_KonohaClass, (uintptr_t)CT_Func}, {"System", VirtualType_KonohaClass, (uintptr_t)CT_System}, {NULL}, }; kNameSpace_LoadConstData(kctx, KNULL(NameSpace), KonohaConst_(ClassData), 0); mod->kNameSpace_SetTokenFunc = kNameSpace_SetTokenFunc; mod->TokenSeq_Tokenize = TokenSeq_Tokenize; mod->TokenSeq_ApplyMacro = TokenSeq_ApplyMacro; mod->kNameSpace_SetMacroData = kNameSpace_SetMacroData; mod->TokenSeq_Resolve = TokenSeq_Resolve; mod->TokenSeq_Eval = TokenSeq_Eval; mod->TokenUtils_ParseTypePattern = TokenUtils_ParseTypePattern; mod->kToken_ToBraceGroup = kToken_ToBraceGroup; mod->kStmt_AddParsedObject = kStmt_AddParsedObject; mod->kNameSpace_FindEndOfStatement = kNameSpace_FindEndOfStatement; mod->kStmt_ParseFlag = kStmt_ParseFlag; mod->kStmt_GetToken = kStmt_GetToken; mod->kStmt_GetBlock = kStmt_GetBlock; mod->kStmt_GetExpr = kStmt_GetExpr; mod->kStmt_GetText = kStmt_GetText; mod->kExpr_SetConstValue = kExpr_SetConstValue; mod->kExpr_SetUnboxConstValue = kExpr_SetUnboxConstValue; mod->kExpr_SetVariable = kExpr_SetVariable; mod->kStmt_TypeCheckExprAt = kStmt_TypeCheckExprAt; mod->kStmt_TypeCheckByName = kStmt_TypeCheckByName; mod->kBlock_TypeCheckAll = kBlock_TypeCheckAll; mod->kStmtkExpr_TypeCheckCallParam = kStmtkExpr_TypeCheckCallParam; mod->new_TypedCallExpr = new_TypedCallExpr; mod->kGamma_AddLocalVariable = kGamma_AddLocalVariable; mod->kStmt_DeclType = kStmt_DeclType; mod->kStmt_TypeCheckVariableNULL = kStmt_TypeCheckVariableNULL; mod->kNameSpace_DefineSyntax = kNameSpace_DefineSyntax; mod->kNameSpace_GetSyntax = kNameSpace_GetSyntax; mod->kArray_AddSyntaxRule = kArray_AddSyntaxPattern; // mod->kNameSpace_SetSugarFunc = kNameSpace_SetSugarFunc; mod->kNameSpace_AddSugarFunc = kNameSpace_AddSugarFunc; mod->new_kBlock = new_kBlock; mod->new_kStmt = new_kStmt; mod->kBlock_InsertAfter = kBlock_InsertAfter; mod->new_UntypedTermExpr = new_UntypedTermExpr; mod->new_UntypedCallStyleExpr = new_UntypedCallStyleExpr; mod->kStmt_ParseOperatorExpr = kStmt_ParseOperatorExpr; mod->kStmt_ParseExpr = kStmt_ParseExpr; mod->kStmt_AddExprParam = kStmt_AddExprParam; mod->kStmt_RightJoinExpr = kStmt_RightJoinExpr; mod->kToken_ToError = kToken_ToError; mod->kStmt_Message2 = kStmt_Message2; mod->VisitStmt = VisitStmt; mod->VisitExpr = VisitExpr; mod->VisitBlock = VisitBlock; #ifndef USE_SMALLBUILD mod->dumpToken = dumpToken; mod->dumpTokenArray = dumpTokenArray; mod->dumpExpr = dumpExpr; #endif DefineDefaultSyntax(kctx, KNULL(NameSpace)); }
static KMETHOD TypeCheck_InstanceOf(KonohaContext *kctx, KonohaStack *sfp) { VAR_TypeCheck2(stmt, expr, ns, reqc); /* selfNode and targetNode allow void type * e.g. "'a' instanceof void" */ kNode *selfNode = SUGAR TypeCheckNodeAt(kctx, expr, 1, ns, KClass_INFER, TypeCheckPolicy_AllowVoid); kNode *targetNode = SUGAR TypeCheckNodeAt(kctx, expr, 2, ns, KClass_INFER, TypeCheckPolicy_AllowVoid); if(selfNode != K_NULLNODE && targetNode != K_NULLNODE) { KClass *selfClass = KClass_(selfNode->attrTypeId), *targetClass = KClass_(targetNode->attrTypeId); if(KClass_Is(Final, selfClass)) { kbool_t staticSubType = (selfClass == targetClass || selfClass->isSubType(kctx, selfClass, targetClass)); KReturn(SUGAR kNode_SetUnboxConst(kctx, expr, KType_Boolean, staticSubType)); } kNameSpace *ns = kNode_ns(stmt); kMethod *mtd = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, ns, KClass_Object, KMethodName_("instanceof"), 1, KMethodMatch_NoOption); DBG_ASSERT(mtd != NULL); kNode *classValue = SUGAR kNode_SetConst(kctx, expr->NodeList->NodeVarItems[2], NULL, KLIB Knull(kctx, targetClass)); KFieldSet(expr->NodeList, expr->NodeList->NodeItems[2], classValue); KReturn(SUGAR TypeCheckMethodParam(kctx, mtd, expr, ns, KClass_Boolean)); } }