示例#1
0
//## 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);
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
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;
}
示例#5
0
//## @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);
}
示例#6
0
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;
}
示例#7
0
// @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);
}
示例#8
0
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;
}
示例#9
0
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;
}
示例#10
0
//## @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);
	}
}
示例#11
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();
}
示例#12
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();
}
示例#13
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();
}
示例#14
0
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);
}
示例#15
0
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;
}
示例#16
0
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;
}
示例#17
0
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;
}
示例#18
0
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));
	}
}
示例#19
0
/* ------------------------------------------------------------------------ */
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);
}
示例#20
0
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)));
}
示例#21
0
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));
}
示例#22
0
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));
}
示例#23
0
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));
	}
}