예제 #1
0
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();
}
예제 #2
0
static kMethod *CompileClosure(KonohaContext *kctx, kNameSpace *ns, kNode *expr, KClass *envCt, kToken *typeTk, kNode **texprRef)
{
	INIT_GCSTACK();
	kParam *pa = kNode_GetParamNULL(kctx, expr, typeTk, ns);
	kMethodVar *mtd = (kMethodVar *) KLIB new_kMethod(kctx, _GcStack, 0, envCt->typeId, 0/*mn*/, NULL);
	KLIB kMethod_SetParam(kctx, mtd, pa->rtype, pa->psize, (kparamtype_t *)pa->paramtypeItems);

	int errorCount = KGetParserContext(kctx)->errorMessageCount;
	KGammaStackDecl lvarItems[32] = {};
	struct KGammaLocalData newgma = {};
	newgma.flag = 0;
	newgma.currentWorkingMethod = mtd;
	newgma.thisClass            = envCt;
	newgma.localScope.varItems  = lvarItems;
	newgma.localScope.capacity  = 32;
	newgma.localScope.varsize   = 0;
	newgma.localScope.allocsize = 0;
	kNameSpace_InitParam(kctx, ns, &newgma, pa, envCt);

	KPushGammaStack(ns, &newgma);
	*texprRef = SUGAR TypeCheckNodeByName(kctx, expr, KSymbol_BlockPattern, ns, KClass_var, TypeCheckPolicy_AllowVoid);

	kNode *block = SUGAR kNode_GetNode(kctx, expr, KSymbol_BlockPattern, NULL);
	KLIB kMethod_GenCode(kctx, mtd, block, HatedLazyCompile);

	KPopGammaStack(ns, &newgma);
	kMethod_Set(StaticError, mtd, KGetParserContext(kctx)->errorMessageCount > errorCount);
	RESET_GCSTACK();
	return mtd;
}
예제 #3
0
//## @Const method String[] String.split(RegExp regex);
static KMETHOD String_split(KonohaContext *kctx, KonohaStack *sfp)
{
	INIT_GCSTACK();
	kArray *resultArray = (kArray *)KLIB new_kObject(kctx, _GcStack, KGetReturnType(sfp), 0);
	kArray_split(kctx, resultArray, sfp[0].asString, sfp[1].asRegExp, S_size(sfp[0].asString));
	KReturnWith(resultArray, RESET_GCSTACK());
}
예제 #4
0
파일: Compiler.c 프로젝트: myoan/minikonoha
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
//## @Const method String[] String.split(RegExp regex, Int limit);
static KMETHOD String_splitWithLimit(KonohaContext *kctx, KonohaStack *sfp)
{
	INIT_GCSTACK();
	size_t limit = sfp[2].intValue < 0 ? S_size(sfp[0].asString) : (size_t) sfp[2].intValue;
	kArray *resultArray = (kArray *)KLIB new_kObject(kctx, _GcStack, KGetReturnType(sfp), 0);
	kArray_split(kctx, resultArray, sfp[0].asString, sfp[1].asRegExp, limit);
	KReturnWith(resultArray, RESET_GCSTACK());
}
예제 #6
0
static kstatus_t MODSUGAR_loadScript(KonohaContext *kctx, const char *path, size_t len, KTraceInfo *trace)
{
	if(KGetParserContext(kctx) == NULL) {
		KPARSERM->h.setupModelContext(kctx, (KRuntimeModel *)KPARSERM, 0/*lazy*/);
	}
	INIT_GCSTACK();
	kpackageId_t packageId = KLIB KpackageId(kctx, "main", sizeof("main")-1, 0, _NEWID);
	kNameSpace *ns = new_PackageNameSpace(kctx, packageId);
	kstatus_t result = (kstatus_t)kNameSpace_LoadScript(kctx, ns, path, trace);
	RESET_GCSTACK();
	return result;
}
예제 #7
0
static kstatus_t MODSUGAR_loadScript(KonohaContext *kctx, const char *path, size_t len, KTraceInfo *trace)
{
	if(GetSugarContext(kctx) == NULL) {
		kmodsugar->h.setupModuleContext(kctx, (KonohaModule *)kmodsugar, 0/*lazy*/);
	}
	INIT_GCSTACK();
	kpackageId_t packageId = KLIB KpackageId(kctx, "main", sizeof("main")-1, 0, _NEWID);
	kNameSpace *ns = new_PackageNameSpace(kctx, packageId);
	kstatus_t result = (kstatus_t)kNameSpace_LoadScript(kctx, ns, path, trace);
	RESET_GCSTACK();
	return result;
}
예제 #8
0
//## @Native Thread Thread.create(Func f)
static KMETHOD Thread_create(KonohaContext *kctx, KonohaStack *sfp)
{
	INIT_GCSTACK();
	kFunc *f = sfp[1].asFunc;
	KLIB kMethod_DoLazyCompilation(kctx, (f)->mtd, NULL, HatedLazyCompile);
	kThread *thread = (kThread *)KLIB new_kObject(kctx, _GcStack, KGetReturnType(sfp), 0);
	thread->rootCtx = kctx; //TODO getRootContext
	thread->kctx = KLIB KonohaContext_Init(kctx, kctx->platApi);
	KFieldSet(thread, thread->func, f);
	pthread_create(&(thread->thread), NULL, spawn_start, thread);
	RESET_GCSTACK(); // FIXME?? Not sure this is okay??
	KReturn(thread);
}
예제 #9
0
void MODCODE_init(KonohaContext *kctx, KonohaContextVar *ctx)
{
	KModuleByteCode *base = (KModuleByteCode*)KCALLOC(sizeof(KModuleByteCode), 1);
	opcode_check();
	base->h.name     = "minivm";
	base->h.setup    = kmodcode_setup;
	base->h.reftrace = kmodcode_reftrace;
	base->h.free     = kmodcode_free;
	KLIB Konoha_setModule(kctx, MOD_code, &base->h, 0);

	KDEFINE_CLASS defBasicBlock = {
		STRUCTNAME(BasicBlock),
		.init = BasicBlock_init,
		.free = BasicBlock_free,
	};

	KDEFINE_CLASS defByteCode = {
		STRUCTNAME(ByteCode),
		.init = ByteCode_init,
		.reftrace = ByteCode_reftrace,
		.free = ByteCode_free,
	};

	base->cBasicBlock = KLIB Konoha_defineClass(kctx, PackageId_sugar, PackageId_sugar, NULL, &defBasicBlock, 0);
	base->cByteCode = KLIB Konoha_defineClass(kctx, PackageId_sugar, PackageId_sugar, NULL, &defByteCode, 0);
	kmodcode_setup(kctx, &base->h, 0/*lazy*/);
	{
		INIT_GCSTACK();
		kBasicBlock* ia = (kBasicBlock*)new_(BasicBlock, 0);
		kBasicBlock* ib = (kBasicBlock*)new_(BasicBlock, 0);
		PUSH_GCSTACK(ia);
		PUSH_GCSTACK(ib);
		kBasicBlock_add(ia, THCODE, _THCODE);
		kBasicBlock_add(ia, NCALL); // FUNCCALL
		kBasicBlock_add(ia, ENTER);
		kBasicBlock_add(ia, EXIT);
		kBasicBlock_add(ib, RET);   // NEED TERMINATION
		ia->nextBlock = ib;
		kByteCode *kcode = new_ByteCode(kctx, ia, ib);
		KINITv(kmodcode->codeNull, kcode);
		VirtualMachineInstruction *pc = KonohaVirtualMachine_run(kctx, kctx->esp, kcode->code);
		CODE_ENTER = pc;
		CODE_ENTER = pc+1;
		KLIB kArray_clear(kctx, ctxcode->codeList, 0);
		RESET_GCSTACK();
	}
	KonohaLibVar *l = (KonohaLibVar*)kctx->klib;
	l->kMethod_setFunc = kMethod_setFunc;
	l->kMethod_genCode = kMethod_genCode;
}
예제 #10
0
//## ResultSet Connection.query(String query);
static KMETHOD Connection_query(KonohaContext *kctx, KonohaStack *sfp)
{
	INIT_GCSTACK();
	KMakeTrace(trace, sfp);
	kConnection *conn = (kConnection *)sfp[0].asObject;
	const char *query = kString_text(sfp[1].asString);
	kResultSet *rs = (kResultSet *)KLIB new_kObject(kctx, OnStack, KGetReturnType(sfp), (uintptr_t)conn);
	KCursor *qcur = conn->driver->qexec(kctx, conn->db, query, rs, trace);
	if(qcur != NULL) {
		rs->qcur   = qcur;
		rs->driver = conn->driver;
	}
	KReturnWith(rs, RESET_GCSTACK());
}
예제 #11
0
static struct KVirtualCode *MiniVM_GenerateVirtualCode(KonohaContext *kctx, kMethod *mtd, kUntypedNode *block, int option)
{
	KVirtualCode *vcode;
	KBuffer wb;
	KBuilder builderbuf = {{0}}, *builder = &builderbuf;
	kNameSpace *ns = kUntypedNode_ns(block);

	INIT_GCSTACK();
	KLIB KBuffer_Init(&(kctx->stack->cwb), &wb);
	builder->common.api = ns->builderApi;
	builder->constPools = ns->NameSpaceConstList;
	builder->bbBeginId  = new_BasicBlockLABEL(kctx);
	builder->bbReturnId = new_BasicBlockLABEL(kctx);
	builder->bbMainId   = builder->bbBeginId;
	builder->currentMtd = mtd;
	builder->Value      = 0;
	builder->stackbase  = 0;
	builder->InstructionSize = 0;

	builder->common.api = &CollectLocalVar_BuilderAPI;
	KLIB VisitNode(kctx, builder, block, NULL);
	builder->stackbase += builder->localVarSize + 1/* == this object */;
	builder->common.api = ns->builderApi;

	KLIB KArray_Init(kctx, &builder->localVar, sizeof(LocalVarInfo) * builder->stackbase);

	ASM(THCODE, 0, _THCODE);
	ASM(CHKSTACK, 0);

	KLIB VisitNode(kctx, builder, block, NULL);

	if(!Block_HasTerminatorInst(kctx, builder->bbMainId)) {
		MiniVMBuilder_JumpTo(kctx, builder, builder->bbReturnId);
	}

	MiniVMBuilder_setBlock(kctx, builder, builder->bbReturnId);
	if(mtd->mn == MN_new) {
		// FIXME: Type 'This' must be resolved
		ASM(NMOV, OC_(K_RTNIDX), OC_(0), KClass_(mtd->typeId));
	}
	ASM(RET);
	vcode = CompileVirtualCode(kctx, builder, builder->bbBeginId, builder->bbReturnId);

	KLIB KArray_Free(kctx, &builder->localVar);
	RESET_GCSTACK();
	KLIB KBuffer_Free(&wb);
	return vcode;

}
예제 #12
0
static kstatus_t kNameSpace_Eval(KonohaContext *kctx, kNameSpace *ns, const char *script, kfileline_t uline, KTraceInfo *trace)
{
	kstatus_t result;
	kmodsugar->h.setupModuleContext(kctx, (KonohaModule *)kmodsugar, 0/*lazy*/);
	INIT_GCSTACK();
	{
		TokenSeq tokens = {ns, GetSugarContext(kctx)->preparedTokenList};
		TokenSeq_Push(kctx, tokens);
		TokenSeq_Tokenize(kctx, &tokens, script, uline);
		result = TokenSeq_Eval(kctx, &tokens, trace);
		TokenSeq_Pop(kctx, tokens);
	}
	RESET_GCSTACK();
	return result;
}
예제 #13
0
static KMETHOD NameSpace_man(KonohaContext *kctx, KonohaStack *sfp)
{
    INIT_GCSTACK();
    kArray *list = kctx->stack->gcstack_OnContextConstList;
    size_t start = kArray_size(list);
    kNameSpace *ns = sfp[0].asNameSpace;
    KonohaClass *ct = O_ct(sfp[1].asObject);
    DBG_P("*** man %s", TY_t(ct->typeId));
    while(ns != NULL) {
        copyMethodList(kctx, ct->typeId, ns->methodList_OnList, list);
        ns = ns->parentNULL;
    }
    copyMethodList(kctx, ct->typeId, ct->methodList_OnGlobalConstList, list);
    dumpMethodList(kctx, sfp, start, list);
    RESET_GCSTACK();
}
예제 #14
0
static kstatus_t kNameSpace_Eval(KonohaContext *kctx, kNameSpace *ns, const char *script, kfileline_t uline, KTraceInfo *trace)
{
	kstatus_t result;
	KPARSERM->h.setupModelContext(kctx, (KRuntimeModel *)KPARSERM, 0/*lazy*/);
	INIT_GCSTACK();
	{
		KTokenSeq tokens = {ns, KGetParserContext(kctx)->preparedTokenList};
		KTokenSeq_Push(kctx, tokens);
		Tokenize(kctx, ns, script, uline, 0, tokens.tokenList);
		KTokenSeq_End(kctx, tokens);
		result = KLIB EvalTokenList(kctx, &tokens, trace);
		KTokenSeq_Pop(kctx, tokens);
	}
	RESET_GCSTACK();
	return result;
}
예제 #15
0
/* copied from src/parser/import/typecheck.h */
static kNode *CallTypeFunc(KonohaContext *kctx, kFunc *fo, kNode *expr, kNameSpace *ns, kObject *reqType)
{
	INIT_GCSTACK();
	BEGIN_UnusedStack(lsfp);
	KUnsafeFieldSet(lsfp[1].asNode, expr);
	KUnsafeFieldSet(lsfp[2].asNameSpace, ns);
	KUnsafeFieldSet(lsfp[3].asObject, reqType);
	CallSugarMethod(kctx, lsfp, fo, 4, UPCAST(K_NULLNODE));
	END_UnusedStack();
	RESET_GCSTACK();
	if(kNode_IsError(expr)) return expr;
	if(lsfp[K_RTNIDX].asNode == K_NULLNODE) {
		DBG_ASSERT(expr->attrTypeId == KType_var); // untyped
	}
	DBG_ASSERT(IS_Node(lsfp[K_RTNIDX].asObject));
	return (kNode *)lsfp[K_RTNIDX].asObject;
}
예제 #16
0
static KMETHOD Statement_namespace(KonohaContext *kctx, KonohaStack *sfp)
{
	VAR_TypeCheck(stmt, ns, reqc);
	kstatus_t result = K_CONTINUE;
	kToken *tk = SUGAR kNode_GetToken(kctx, stmt, KSymbol_BlockPattern, NULL);
	if(tk != NULL && tk->resolvedSyntaxInfo->keyword == TokenType_LazyBlock) {
		INIT_GCSTACK();
		kNameSpace *ns = new_(NameSpace, kNode_ns(stmt), _GcStack);
		KTokenSeq range = {ns, KGetParserContext(kctx)->preparedTokenList};
		KTokenSeq_Push(kctx, range);
		SUGAR Tokenize(kctx, ns, kString_text(tk->text), tk->uline, tk->indent, range.tokenList);
		KTokenSeq_End(kctx, range);
		result = SUGAR EvalTokenList(kctx, &range, NULL/*trace*/);
		KTokenSeq_Pop(kctx, range);
		RESET_GCSTACK();
		kNode_Type(kctx, stmt, KNode_Done, KType_void);
	}
	KReturnUnboxValue(result == K_CONTINUE);
}
예제 #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 KClass *CreateEnvClass(KonohaContext *kctx, kNameSpace *ns, kToken *typeTk, KClass **EnvObjectClass)
{
	INIT_GCSTACK();
	size_t i = 0, esize = ns->genv->localScope.varsize;
	size_t start = 0, end = esize;
	KGammaStackDecl *oldenv = ns->genv->localScope.varItems;
	kparamtype_t *p = ALLOCA(kparamtype_t, esize);
	char buf[256] = {'_', '_', '_', 'E', 'N', 'V', 0}, *text = buf + 6;
	if(ns->genv->thisClass == KClass_NameSpace) {
		start = 1;
		end = esize - 1;
	}
	assert(end < 256);
	for(i = start; i <= end; i++) {
		p[i-1].name       = oldenv[i].name;
		p[i-1].attrTypeId = oldenv[i].attrTypeId;
		*(text++) = (KType_text(p[i-1].attrTypeId))[0];
	}

	*EnvObjectClass = KLIB kNameSpace_GetClassByFullName(kctx, ns, buf, text - buf, NULL);
	if(*EnvObjectClass == NULL) {
		*EnvObjectClass = kNameSpace_DefineClassName(kctx, ns, buf, text - buf);
	}

	KClass *ct = KLIB KClass_Generics(kctx, KClass_Func, typeTk->resolvedTypeId, end, p);
	if(end >= 1) {
		((KClassVar *)ct)->classMethodList = new_(MethodArray, end*2, OnGlobalConstList);
		for(i = start; i <= end; i++) {
			int n = i - 1;
			ksymbol_t sym    = p[n].name;
			ktypeattr_t type = KTypeAttr_Unmask(p[n].attrTypeId);
			kMethod *getter = new_FunctionGetter(kctx, _GcStack, ct->typeId, sym, type, n);
			kMethod *setter = new_FunctionSetter(kctx, _GcStack, ct->typeId, sym, type, n);
			KLIB kArray_Add(kctx, ct->classMethodList, getter);
			KLIB kArray_Add(kctx, ct->classMethodList, setter);
		}
	}
	RESET_GCSTACK();
	return ct;
}
예제 #19
0
static KVirtualCode *KonohaVirtualMachine_tryJump(KonohaContext *kctx, KonohaStack *sfp, KVirtualCode *pc)
{
	int jmpresult;
	INIT_GCSTACK();
	KRuntimeContextVar *base = kctx->stack;
	jmpbuf_i lbuf = {0};
	if(base->evaljmpbuf == NULL) {
		base->evaljmpbuf = (jmpbuf_i *)KCalloc_UNTRACE(sizeof(jmpbuf_i), 1);
	}
	memcpy(&lbuf, base->evaljmpbuf, sizeof(jmpbuf_i));
	if((jmpresult = PLATAPI setjmp_i(*base->evaljmpbuf)) == 0) {
		pc = MiniVM_RunVirtualMachine(kctx, sfp, pc);
	}
	else {
		DBG_P("Catch eval exception jmpresult=%d", jmpresult);
		//KSETv(sfp[exceptionIdx].e, ..);
		pc = NULL;
	}
	memcpy(base->evaljmpbuf, &lbuf, sizeof(jmpbuf_i));
	RESET_GCSTACK();
	return pc;
}
예제 #20
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);
}
예제 #21
0
static KMETHOD Expression_ExtendedTextLiteral(KonohaContext *kctx, KonohaStack *sfp)
{
	VAR_Expression(expr, tokenList, beginIdx, opIdx, endIdx);
	kNameSpace *ns = kNode_ns(expr);
	kToken *tk = tokenList->TokenItems[opIdx];
	INIT_GCSTACK();
	kString *text = remove_escapes(kctx, tk);
	if(beginIdx != opIdx) {
		/* FIXME */
		assert(0 && "FIXME");
		KReturnUnboxValue(-1);
	}

	if(text == NULL) {
		/* text contain unsupported escape sequences */
		RESET_GCSTACK();
		KReturnUnboxValue(-1);
	}

	const char *str = kString_text(text);
	const char *end = NULL;
	const char *start = strstr(str, "${");
	if(start == NULL) {
		/* text does not contain Interpolation expressions */
		RESET_GCSTACK();
		KReturnUnboxValue(beginIdx+1);
	}
	kSyntax *addSyntax = kSyntax_(ns, KSymbol_("+"));
	kTokenVar *opToken = tokenList->TokenVarItems[beginIdx];
	opToken->symbol = KSymbol_("+");
	opToken->text   = KLIB new_kString(kctx, OnGcStack, "+", 1, 0);
	KFieldSet(opToken, opToken->resolvedSyntaxInfo, addSyntax);
	SUGAR kNode_Op(kctx, expr, opToken, 0);

	/* [before] "aaa${bbb}ccc"
	 * [after]  "" + "aaa" + bbb + "ccc"
	 */
	SUGAR kNode_AddNode(kctx, expr, new_ConstNode(kctx, ns, NULL, UPCAST(TS_EMPTY)));
	while(true) {
		start = strstr(str, "${");
		if(start == NULL)
			break;
		if(start == strstr(str, "${}")) {
			str += 3;
			continue;
		}
		end = strchr(start, '}');
		if(end == NULL)
			break;
		kNode *newexpr = ParseSource(kctx, ns, start+2, end-(start+2));
		if(start - str > 0) {
			kNode *first = new_ConstNode(kctx, ns, NULL,
					UPCAST(KLIB new_kString(kctx, OnGcStack, str, (start - str), 0)));
			SUGAR kNode_AddNode(kctx, expr, first);
		}
		SUGAR kNode_AddNode(kctx, expr, newexpr);
		str = end + 1;
	}

	if((start == NULL) || (start != NULL && end == NULL)) {
		kNode *rest = new_ConstNode(kctx, ns, KClass_String,
				UPCAST(KLIB new_kString(kctx, OnGcStack, str, strlen(str), 0)));
		SUGAR kNode_AddNode(kctx, expr, rest);
	}

	/* (+ 1 2 3 4) => (+ (+ (+ 1 2) 3 ) 4) */
	int i, size = kNode_GetNodeListSize(kctx, expr);
	assert(size > 2);
	kNode *leftNode = kNode_At(expr, 1), *rightNode;
	for(i = 2; i < size-1; i++) {
		kNode *node = KNewNode(ns);
		rightNode = kNode_At(expr, i);
		SUGAR kNode_Op(kctx, node, opToken, 2, leftNode, rightNode);
		leftNode = node;
	}
	rightNode = kNode_At(expr, i);
	KLIB kArray_Clear(kctx, expr->NodeList, 1);
	KLIB kArray_Add(kctx, expr->NodeList, leftNode);
	KLIB kArray_Add(kctx, expr->NodeList, rightNode);
	RESET_GCSTACK();
	KReturnUnboxValue(beginIdx+1);
}