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 kbool_t MiniVM_VisitConstNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk) { kObject *v = MiniVM_AddConstPool(kctx, builder, node->ObjectConstValue); DBG_ASSERT(!KType_Is(UnboxType, node->typeAttr)); ASM(NSET, OC_(builder->stackbase), (uintptr_t) v, KClass_(node->typeAttr)); builder->Value = builder->stackbase; return true; }
static kbool_t KBuilder_VisitConstNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk) { DBG_ASSERT(!KType_Is(UnboxType, expr->attrTypeId)); kObject *v = KBuilder_AddConstPool(kctx, builder, expr->ObjectConstValue); kshort_t a = AssignStack(thunk); ASM(NSET, OC_(a), (uintptr_t)v, KClass_(expr->attrTypeId)); return true; }
static kbool_t MiniVM_VisitUnboxConstNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk) { uintptr_t Val = node->unboxConstValue; DBG_ASSERT(KType_Is(UnboxType, node->typeAttr)); ASM(NSET, NC_(builder->stackbase), Val, KClass_(node->typeAttr)); builder->Value = builder->stackbase; return true; }
static kbool_t FuelVM_VisitConstNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk) { kObject *v = expr->ObjectConstValue; DBG_ASSERT(!KType_Is(UnboxType, expr->attrTypeId)); //DBG_ASSERT(kNode_HasObjectConstValue(expr)); builder->Value = CreateObject(BLD(builder), expr->attrTypeId, (void *)v); return true; }
static void Iterator_Init(KonohaContext *kctx, kObject *o, void *conf) { kIterator *itr = (kIterator *)o; int isUnboxEntry = KType_Is(UnboxType, kObject_class(itr)->p0); KFieldInit(itr, itr->source, K_NULL); itr->current_pos = 0; itr->hasNext = Nothing_hasNext; itr->setNextResult = isUnboxEntry ? Nothing_SetNextResultUnbox : Nothing_SetNextResult; }
static kMethod *new_FieldGetter(KonohaContext *kctx, kArray *gcstack, ktypeattr_t cid, ksymbol_t sym, ktypeattr_t ty, int idx) { kmethodn_t mn = KMethodName_ToGetter(sym); KMethodFunc f = (KType_Is(UnboxType, ty)) ? KMethodFunc_UnboxFieldGetter : KMethodFunc_ObjectFieldGetter; kMethod *mtd = KLIB new_kMethod(kctx, gcstack, kMethod_Public|kMethod_Immutable, cid, mn, f); KLIB kMethod_SetParam(kctx, mtd, ty, 0, NULL); ((kMethodVar *)mtd)->delta = idx; // FIXME return mtd; }
static kMethod *new_FieldSetter(KonohaContext *kctx, kArray *gcstack, ktypeattr_t cid, kmethodn_t sym, ktypeattr_t ty, int idx) { kmethodn_t mn = KMethodName_ToSetter(sym); KMethodFunc f = (KType_Is(UnboxType, ty)) ? KMethodFunc_UnboxFieldSetter : KMethodFunc_ObjectFieldSetter; kparamtype_t p = {ty, KFieldName_("x")}; kMethod *mtd = KLIB new_kMethod(kctx, gcstack, kMethod_Public, cid, mn, f); KLIB kMethod_SetParam(kctx, mtd, ty, 1, &p); ((kMethodVar *)mtd)->delta = idx; // FIXME return mtd; }
static KMETHOD Array_toIterator(KonohaContext *kctx, KonohaStack *sfp) { kArray *a = sfp[0].asArray; KClass *cIterator = KClass_p0(kctx, KClass_Iterator, kObject_class(a)->p0); kIterator *itr = (kIterator *)KLIB new_kObject(kctx, OnStack, cIterator, 0); KFieldSet(itr, itr->arrayList, a); itr->hasNext = Array_hasNext; itr->setNextResult = KType_Is(UnboxType, kObject_class(a)->p0) ? Array_SetNextResultUnbox : Array_SetNextResult; KReturn(itr); }
static kbool_t FuelVM_VisitUnboxConstNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk) { DBG_ASSERT(KType_Is(UnboxType, expr->attrTypeId)); //DBG_ASSERT(!kNode_HasObjectConstValue(expr)); SValue Val = {}; Val.bits = expr->unboxConstValue; builder->Value = CreateConstant(BLD(builder), ConvertToTypeId(kctx, expr->attrTypeId), Val); return true; }
static kbool_t MiniVM_VisitNullNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk) { if(KType_Is(UnboxType, node->typeAttr)) { ASM(NSET, NC_(builder->stackbase), 0, KClass_(node->typeAttr)); } else { ASM(NUL, OC_(builder->stackbase), KClass_(node->typeAttr)); } builder->Value = builder->stackbase; return true; }
static kbool_t KBuilder_VisitNullNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk) { kshort_t a = AssignStack(thunk); if(KType_Is(UnboxType, expr->attrTypeId)) { ASM(NSET, NC_(a), 0, KClass_(expr->attrTypeId)); } else { ASM(NUL, OC_(a), KClass_(expr->attrTypeId)); } return true; }
static kbool_t KClass_SetClassFieldUnboxValue(KonohaContext *kctx, KClassVar *definedClass, ksymbol_t sym, uintptr_t unboxValue) { int i; for(i = definedClass->fieldsize - 1; i >= 0; i--) { if(definedClass->fieldItems[i].name == sym && KType_Is(UnboxType, definedClass->fieldItems[i].attrTypeId)) { definedClass->defaultNullValueVar->fieldUnboxItems[i] = unboxValue; return true; } } return false; }
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; }
static void kResultSet_Reftrace(KonohaContext *kctx, kObject *p, KObjectVisitor *visitor) { kResultSet *rs = (kResultSet *)p; KColumn *col = rs->column; KColumn *end = col + rs->column_size; while(col < end) { KRefTrace(col->name); if(KType_Is(UnboxType, col->type)) { KRefTrace(col->val.asObject); } } KRefTraceNullable(rs->connectionNULL); }
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 void kResultSet_format(KonohaContext *kctx, KonohaValue *v, int pos, KBuffer *wb) { kResultSet *rs = (kResultSet *) v[0].asObject; KLIB KBuffer_printf(kctx, wb, "{"); size_t i; for(i = 0; i < (rs)->column_size; i++) { if(i > 0) { KLIB KBuffer_printf(kctx, wb, ","); } KLIB KBuffer_printf(kctx, wb, "(%d): ", i); ktypeattr_t type = rs->column[i].type; krbp_t *val = &rs->column[i].val; if(KType_Is(UnboxType, type)) { KonohaValue sp[1]; KStackSetUnboxValue(sp[0].unboxValue, val[0].unboxValue); KClass_(type)->format(kctx, sp, 0, wb); } else { KLIB kObject_WriteToBuffer(kctx, val[0].asObject, false/*delim*/, wb, NULL, 0); } } KLIB KBuffer_printf(kctx, wb, "}"); }