Exemple #1
0
// @SmartReturn Object Prototype.get(Symbol symbol)
static KMETHOD Prototype_get(KonohaContext *kctx, KonohaStack *sfp)
{
	KClass *targetClass = KGetReturnType(sfp);
	DBG_P("requesting type=%s", KClass_text(targetClass));
	ksymbol_t symbol = sfp[1].intValue;
	KKeyValue *kvs = KLIB kObjectProto_GetKeyValue(kctx, sfp[0].asObject, symbol);
	if(kvs != NULL) {
		KClass *c = KClass_(kvs->attrTypeId);
		if(targetClass == c) {
			if(KClass_Is(UnboxType, targetClass)) {
				KReturnUnboxValue(kvs->unboxValue);
			}
			else {
				KReturnField(kvs->ObjectValue);
			}
		}
		DBG_P("requesting type=%s instanceof %s ? %d", KClass_text(c), KClass_text(targetClass), c->isSubType(kctx, c, targetClass));
		if(c->isSubType(kctx, c, targetClass)) {
			if(KClass_Is(UnboxType, c)) {
				if(KClass_Is(UnboxType, targetClass)) {
					KReturnUnboxValue(kvs->unboxValue);
				}
				else {
					DBG_P("boxing type=%s instanceof %s ? %d", KClass_text(c), KClass_text(targetClass), c->isSubType(kctx, c, targetClass));
					KReturn(KLIB new_kObject(kctx, OnStack, c, kvs->unboxValue));
				}
			}
			KReturnField(kvs->ObjectValue);
		}
	}
	KReturnUnboxValue(0);  // return default value
}
Exemple #2
0
static void KStackReturnTypeCheck(KonohaContext *kctx, KonohaStack *sfp, kMethod *mtd, KClass *reqType, KClass *thisClass)
{
	if(!kMethod_Is(SmartReturn, mtd)) {
		KClass *returnType = kMethod_GetReturnType(mtd);
		returnType = returnType->realtype(kctx, returnType, thisClass);
		if(reqType == returnType || returnType->isSubType(kctx, returnType, reqType)) {
			if(KClass_Is(UnboxType, returnType) && !KClass_Is(UnboxType, reqType)) {
				KReturn(KLIB new_kObject(kctx, OnStack, returnType, sfp[K_RTNIDX].unboxValue));
			}
		}
		else {
			ThrowTypeError(kctx, sfp, -1);
		}
	}
}
static KMETHOD Statement_class(KonohaContext *kctx, KonohaStack *sfp)
{
	VAR_TypeCheck(stmt, ns, reqc);
	kToken *tokenClassName = SUGAR kNode_GetToken(kctx, stmt, KSymbol_("$ClassName"), NULL);
	int isNewlyDefinedClass = false;
	KClassVar *definedClass = (KClassVar *)KLIB kNameSpace_GetClassByFullName(kctx, ns, kString_text(tokenClassName->text), kString_size(tokenClassName->text), NULL);
	if(definedClass == NULL) {   // Already defined
		kshortflag_t cflag = kNode_ParseClassFlag(kctx, stmt, KClassFlag_Virtual);
		KMakeTraceUL(trace, sfp, kNode_uline(stmt));
		definedClass = kNameSpace_DefineClassName(kctx, ns, cflag, tokenClassName->text, trace);
		isNewlyDefinedClass = true;
	}
	kNode *block = kNode_ParseClassNodeNULL(kctx, stmt, tokenClassName);
	size_t declsize = kNode_countFieldSize(kctx, block);
	if(isNewlyDefinedClass) {   // Already defined
		KClass *superClass = KClass_Object;
		kToken *tokenSuperClass= SUGAR kNode_GetToken(kctx, stmt, KSymbol_("extends"), NULL);
		if(tokenSuperClass != NULL) {
			DBG_ASSERT(Token_isVirtualTypeLiteral(tokenSuperClass));
			superClass = KClass_(Token_typeLiteral(tokenSuperClass));
			if(KClass_Is(Final, superClass)) {
				KReturn(SUGAR MessageNode(kctx, stmt, NULL, ns, ErrTag, "%s is final", KClass_text(superClass)));
			}
			if(KClass_Is(Virtual, superClass)) {
				KReturn(SUGAR MessageNode(kctx, stmt, NULL, ns, ErrTag, "%s is still virtual", KClass_text(superClass)));
			}
		}
		size_t initsize = (block != NULL) ? declsize : initFieldSizeOfVirtualClass(superClass);
		KClass_InitField(kctx, definedClass, superClass, initsize);
	}
	else {
		if(declsize > 0 && !KClass_Is(Virtual, definedClass)) {
			KReturn(SUGAR MessageNode(kctx, stmt, NULL, ns, ErrTag, "%s has already defined", KClass_text(definedClass)));
		}
	}
	if(block != NULL) {
		if(!kNode_declClassField(kctx, block, ns, definedClass)) {
			KReturnUnboxValue(false);
		}
		KClass_Set(Virtual, definedClass, false);
	}
	kToken_SetTypeId(kctx, tokenClassName, ns, definedClass->typeId);
	kNode_AddMethodDeclNode(kctx, block, tokenClassName, stmt);
	KReturn(kNode_Type(kctx, stmt, KNode_Done, KType_void));
}
Exemple #4
0
static void KBuffer_WriteValue(KonohaContext *kctx, KBuffer *wb, KClass *c, KonohaStack *sfp)
{
	if(KClass_Is(UnboxType, c)) {
		c->p(kctx, sfp, 0, wb);
	}
	else {
		KLIB kObject_WriteToBuffer(kctx, sfp[0].asObject, false/*delim*/, wb, NULL, 0);
	}
}
Exemple #5
0
//## 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));
}
Exemple #6
0
// @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);
	}
}
Exemple #7
0
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);
	}
}
Exemple #8
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));
	}
}