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); }
//## Node Node.TypeCheckNodeAt(int pos, Object type, int policy); static KMETHOD Node_TypeCheckNodeAt(KonohaContext *kctx, KonohaStack *sfp) { kNode *node = sfp[0].asNode; size_t pos = sfp[1].intValue; KClass *type = kObject_class(sfp[2].asObject); int policy = sfp[3].intValue; KReturn(SUGAR TypeCheckNodeAt(kctx, node, pos, kNode_ns(node), type, policy)); }
//## Node Node.TypeCheckNode(Symbol key, Object type, int policy); static KMETHOD Node_TypeCheckNode(KonohaContext *kctx, KonohaStack *sfp) { kNode *node = sfp[0].asNode; ksymbol_t key = (ksymbol_t)sfp[1].intValue; KClass *type = kObject_class(sfp[2].asObject); int policy = sfp[3].intValue; KReturn(SUGAR TypeCheckNodeByName(kctx, node, key, kNode_ns(node), type, policy)); }
//## Node Node.setConstValue(Object value); static KMETHOD Node_setConstValue(KonohaContext *kctx, KonohaStack *sfp) { kNodeVar *expr = (kNodeVar *)sfp[0].asNode; KClass *ct = kObject_class(sfp[1].asObject); if(KClass_Is(UnboxType, (ct))) { KReturn(SUGAR kNode_SetUnboxConst(kctx, expr, ct->typeId, sfp[1].unboxValue)); } KReturn(SUGAR kNode_SetConst(kctx, expr, ct, sfp[1].asObject)); }
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 void ObjectField_Reftrace(KonohaContext *kctx, kObject *o, KObjectVisitor *visitor) { KClass *c =kObject_class(o); KClassField *fieldItems = c->fieldItems; size_t i, fieldsize = c->fieldsize; for (i = 0; i < fieldsize; i++) { if(KTypeAttr_Is(Boxed, fieldItems[i].attrTypeId)) { KRefTraceNullable(o->fieldObjectItems[i]); // FIXME: } } }
// @SmartReturn void Object.set(Symbol symbol, Object value) static KMETHOD Prototype_SetObject(KonohaContext *kctx, KonohaStack *sfp) { ksymbol_t symbol = (ksymbol_t)sfp[1].intValue; KClass *c = kObject_class(sfp[2].asObject); if(KClass_Is(UnboxType, c)) { KLIB kObjectProto_SetUnboxValue(kctx, sfp[0].asObject, symbol, c->typeId, kObject_Unbox(sfp[2].asObject)); } else { KLIB kObjectProto_SetObject(kctx, sfp[0].asObject, symbol, c->typeId, sfp[2].asObject); } }
//## void NameSpace.useStaticFunc(Object o); static KMETHOD NameSpace_useStaticFunc(KonohaContext *kctx, KonohaStack *sfp) { KMakeTrace(trace, sfp); KClass *ct = kObject_class(sfp[1].asObject); kNameSpace *ns = sfp[0].asNameSpace; kNameSpace_SetStaticFunction(kctx, ns, ct->classMethodList, ct->typeId, trace); while(ns != NULL) { kNameSpace_SetStaticFunction(kctx, ns, ns->methodList_OnList, ct->typeId, trace); ns = ns->parentNULL; } KReturnVoid(); }
static void kNameSpace_LookupMethodWithInlineCache(KonohaContext *kctx, KonohaStack *sfp, kNameSpace *ns, kMethod **cache) { ktypeattr_t typeId = kObject_typeId(sfp[0].asObject); kMethod *mtd = cache[0]; if(mtd->typeId != typeId) { KClass *ct = kObject_class(sfp[0].asObject); mtd = KLIB kNameSpace_GetMethodBySignatureNULL(kctx, ns, ct, mtd->mn, mtd->paramdom, 0, NULL); cache[0] = mtd; } KStackSetUnboxValue(sfp[0].unboxValue, kObject_Unbox(sfp[0].asObject)); KStackSetUnboxValue(sfp[K_MTDIDX].calledMethod, mtd); }
static kbool_t KClass_SetClassFieldObjectValue(KonohaContext *kctx, KClassVar *definedClass, ksymbol_t sym, kObject *ObjectValue) { int i; for(i = definedClass->fieldsize - 1; i >= 0; i--) { if(definedClass->fieldItems[i].name == sym && kObject_class(definedClass->defaultNullValueVar->fieldObjectItems[i]) == kObject_class(ObjectValue)) { kObjectVar *o = definedClass->defaultNullValueVar; KFieldSet(o, o->fieldObjectItems[i], ObjectValue); return true; } } return false; }
//## Node Node.newMethodNode(Object type, Symbol keyword, Node expr1); static KMETHOD Node_newMethodNode1(KonohaContext *kctx, KonohaStack *sfp) { kNameSpace *ns = kNode_ns(sfp[0].asNode); KClass *type = kObject_class(sfp[1].asObject); ksymbol_t keyword = (ksymbol_t)sfp[2].intValue; kNode *expr1 = sfp[3].asNode; kMethod *mtd = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, ns, type, keyword, 0, KMethodMatch_NoOption); if(mtd == NULL) { KReturn(KNULL(Node)); } KReturn(SUGAR new_MethodNode(kctx, ns, type, mtd, 1, expr1)); }
static size_t sweep0(GcContext *mng, void *p, int n, size_t sizeOfObject) { KonohaContext *kctx = mng->kctx; unsigned i; size_t collected = 0; size_t pageSize = K_PAGESIZE/sizeOfObject; for(i = 0; i < pageSize; ++i) { kGCObject0 *o = (kGCObject0 *)ShiftPointer(p,sizeOfObject*i); if(!Object_isMark((kObject *)o)) { if( kObject_class(o)) { DBG_P("~Object%d %s", n, kObject_class(o)->DBG_NAME); KLIB kObjectProto_Free(kctx, (kObjectVar *)o); assert(kObject_class(o)->cstruct_size == sizeOfObject); ++collected; OBJECT_REUSE(o, n); MSGC(n).freelist.size += 1; } } Object_unsetMark(((kObjectVar *)o)); } return collected; }
// @SmartReturn Object Object.as(Object target) static KMETHOD Object_as(KonohaContext *kctx, KonohaStack *sfp) { KClass *selfClass = kObject_class(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); } KStackSetUnboxValue(sfp[K_RTNIDX].unboxValue, kObject_Unbox(returnValue)); KReturn(returnValue); }
static KMETHOD NameSpace_man(KonohaContext *kctx, KonohaStack *sfp) { INIT_GCSTACK(); kArray *list = kctx->stack->gcStack; size_t start = kArray_size(list); kNameSpace *ns = sfp[0].asNameSpace; KClass *ct = kObject_class(sfp[1].asObject); DBG_P("*** man %s", KType_text(ct->typeId)); while(ns != NULL) { copyMethodList(kctx, ct->typeId, ns->methodList_OnList, list); ns = ns->parentNULL; } copyMethodList(kctx, ct->typeId, ct->classMethodList, list); dumpMethodList(kctx, sfp, start, list); RESET_GCSTACK(); }
static void DeclVariable(KonohaContext *kctx, kNode *stmt, kNameSpace *ns, ktypeattr_t ty, kNode *termNode) { DBG_ASSERT(kNode_isSymbolTerm(termNode)); kToken *termToken = termNode->TermToken; if(kNameSpace_IsTopLevel(ns)) { if(ns->globalObjectNULL == NULL) { kNodeToken_Message(kctx, stmt, termToken, ErrTag, "unavailable global variable"); return; } kNodeToken_Message(kctx, stmt, termToken, InfoTag, "global variable %s%s has type %s", KSymbol_Fmt2(termToken->symbol), KType_text(ty)); KLIB KClass_AddField(kctx, kObject_class(ns->globalObjectNULL), ty, termToken->symbol); } else { kNodeToken_Message(kctx, stmt, termToken, InfoTag, "%s%s has type %s", KSymbol_Fmt2(termToken->symbol), KType_text(ty)); KLIB AddLocalVariable(kctx, ns, ty, termToken->symbol); } }
//## Prototype Prototype.(Object o); static KMETHOD Prototype_(KonohaContext *kctx, KonohaStack *sfp) { ksymbol_t symbol = KDynamicCallSymbol(sfp); KKeyValue *kvs = KLIB kObjectProto_GetKeyValue(kctx, sfp[0].asObject, symbol); if(kvs != NULL) { KClass *c = KClass_(kvs->attrTypeId); kParam *cparam = KClass_cparam(c); if(KClass_isFunc(c) && cparam->psize <= KDynamicCallArgument(sfp)) { KClass *thisClass = kObject_class(sfp[0].asObject), *returnType = KGetReturnType(sfp); kFunc *fo = (kFunc *)kvs->FuncValue; KStackSetFunc(sfp, fo); KStackDynamicTypeCheck(kctx, sfp, fo->method, thisClass); KStackCall(sfp); KStackReturnTypeCheck(kctx, sfp, fo->method, thisClass, returnType); } } }
static void KStackDynamicTypeCheck(KonohaContext *kctx, KonohaStack *sfp, kMethod *mtd, KClass *thisClass) { kushort_t i; kParam *pa = kMethod_GetParam(mtd); for(i = 0; i < pa->psize; i++) { KClass *objectType = kObject_class(sfp[i+1].asObject); KClass *paramType = KClass_(pa->paramtypeItems[i].attrTypeId); paramType = paramType->realtype(kctx, paramType, thisClass); if(objectType == paramType || objectType->isSubType(kctx, objectType, paramType)) { if(KClass_Is(UnboxType, paramType)) { KStackSetUnboxValue(sfp[i+1].unboxValue, kObject_Unbox(sfp[i+1].asObject)); } continue; // OK } ThrowTypeError(kctx, sfp, i + 1); } }
static void DumpOpArgument(KonohaContext *kctx, KBuffer *wb, KVirtualCodeType type, KVirtualCode *c, size_t i, KVirtualCode *vcode_start) { switch(type) { case VMT_VOID: break; case VMT_ADDR: KLIB KBuffer_printf(kctx, wb, " L%d", (int)((KVirtualCode *)c->p[i] - vcode_start)); break; case VMT_UL: { kfileline_t uline = (kfileline_t)c->data[i]; KLIB KBuffer_printf(kctx, wb, " (%s:%d)", PLATAPI shortFilePath(KFileLine_textFileName(uline)), (khalfword_t)uline); break; } case VMT_R: { KLIB KBuffer_printf(kctx, wb, " sfp[%d,r=%d]", (int)c->data[i]/2, (int)c->data[i]); break; } case VMT_FX: { khalfword_t index = (khalfword_t)c->data[i]; khalfword_t xindex = (khalfword_t)(c->data[i] >> (sizeof(khalfword_t)*8)); KLIB KBuffer_printf(kctx, wb, " sfp[%d,r=%d][%d]", (int)index/2, (int)index, (int)xindex); break; } case VMT_U: KLIB KBuffer_printf(kctx, wb, " i%ld", (long)c->data[i]); break; case VMT_C: case VMT_TY: KLIB KBuffer_printf(kctx, wb, "(%s)", KClass_text(c->ct[i])); break; case VMT_F: KLIB KBuffer_printf(kctx, wb, " function(%p)", c->p[i]); break; case VMT_Object: { kObject *o = c->o[i]; if(IS_Method(o)) { kMethod *mtd = (kMethod *)o; KLIB KBuffer_printf(kctx, wb, " %s.%s%s", KType_text(mtd->typeId), KMethodName_Fmt2(mtd->mn)); } else { KLIB KBuffer_printf(kctx, wb, " (%s)", KClass_text(kObject_class(o))); KLIB kObject_WriteToBuffer(kctx, o, 0, wb, NULL, 0); } break; } case VMT_HCACHE: break; }/*switch*/ }
static kbool_t FuelVM_VisitFunctionNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk) { /* * [FunctionExpr] := new Function(method, env1, env2, ...) * expr->NodeList = [method, defObj, env1, env2, ...] **/ enum TypeId Type; kMethod *mtd = CallNode_getMethod(expr); kObject *obj = expr->NodeList->ObjectItems[1]; INode *MtdObj = CreateObject(BLD(builder), KType_Method, (void *) mtd); Type = ConvertToTypeId(kctx, kObject_class(obj)->typeId); INode *NewEnv = CreateNew(BLD(builder), 0, Type); size_t i, ParamSize = kArray_size(expr->NodeList)-2; for(i = 0; i < ParamSize; i++) { kNode *envN = kNode_At(expr, i+2); enum TypeId FieldType = ConvertToTypeId(kctx, envN->attrTypeId); INode *Node = CreateField(BLD(builder), FieldScope, FieldType, NewEnv, i); SUGAR VisitNode(kctx, builder, envN, thunk); CreateUpdate(BLD(builder), Node, FuelVM_getExpression(builder)); } Type = ConvertToTypeId(kctx, expr->attrTypeId); INode *NewFunc = CreateNew(BLD(builder), 0, Type); kNameSpace *ns = kNode_ns(expr); mtd = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, ns, KClass_Func, KMethodName_("_Create"), 2, KMethodMatch_NoOption); INode *CallMtd = CreateObject(BLD(builder), KType_Method, (void *) mtd); INode *Params[4]; Params[0] = CallMtd; Params[1] = NewFunc; Params[2] = NewEnv; Params[3] = MtdObj; builder->Value = CreateICall(BLD(builder), Type, DefaultCall, kNode_uline(expr), Params, 4); return true; }
static KMETHOD PyObject_toString(KonohaContext *kctx, KonohaStack *sfp) { kPyObject *po = (kPyObject *)sfp[0].asObject; KBuffer wb; // assert DBG_ASSERT(po->self != NULL); KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); kObject_class(sfp[0].asObject)->p(kctx, sfp, 0, &wb); kString *s = KLIB new_kString(kctx, OnStack, KLIB KBuffer_text(kctx, &wb, 1), KBuffer_bytesize(&wb), 0); KLIB KBuffer_Free(&wb); KReturn(s); //if(PyString_Check(po->self)) { // //dec // t = PyString_AsString(po->self); // KReturn(KLIB new_kString(kctx, t, strlen(t), 0)); //} //else if(PyUnicode_Check(po->self)) { // //dec // PyObject *s = PyUnicode_AsUTF8String(po->self); // // [TODO] there is no t's NULL check. Is it OK? // t = PyString_AsString(s); // KReturn(KLIB new_kString(kctx, t, strlen(t), 0)); //} //else if(PyByteArray_Check(po->self)) { // //dec // t = PyByteArray_AsString(po->self); // KReturn(KLIB new_kString(kctx, t, strlen(t), 0)); //} //else { // KBuffer wb; // KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); // kObject_class(sfp[0].asObject)->p(kctx, sfp, 0, &wb, 0); // kString *s = KLIB new_kString(kctx, KLIB KBuffer_text(kctx, &wb, 1), KBuffer_bytesize(&wb), 0); // KLIB KBuffer_Free(&wb); // KReturn(s); //} }
static void Object_InitToMakeDefaultValueAsNull(KonohaContext *kctx, kObject *o, void *conf) { kObjectVar *of = (kObjectVar *)o; KClass *c = kObject_class(o); bzero(of->fieldObjectItems, c->cstruct_size - sizeof(kObjectHeader)); }
static inline kObject *new_ReturnCppObject(KonohaContext *kctx,KonohaStack *sfp, void *ptr) { kObject *defobj = sfp[(-(K_CALLDELTA))].asObject; kObject *ret = KLIB new_kObject(kctx, OnStack, kObject_class(defobj), (uintptr_t)ptr); ((kRawPtr *)ret)->rawptr = ptr; return ret; }
static void ObjectField_Init(KonohaContext *kctx, kObject *o, void *conf) { KClass *c = kObject_class(o); size_t fieldsize = c->fieldsize; memcpy(((kObjectVar *)o)->fieldObjectItems, c->defaultNullValue->fieldObjectItems, fieldsize * sizeof(void *)); }
// Object.getTypeId() static KMETHOD Object_getTypeId(KonohaContext *kctx, KonohaStack *sfp) { KReturnUnboxValue(kObject_class(sfp[0].asObject)->typeId); }
// boolean Object.instanceOf(Object o) static KMETHOD Object_instanceOf(KonohaContext *kctx, KonohaStack *sfp) { KClass *selfClass = kObject_class(sfp[0].asObject), *targetClass = kObject_class(sfp[1].asObject); KReturnUnboxValue(selfClass == targetClass || selfClass->isSubType(kctx, selfClass, targetClass)); }