예제 #1
0
파일: Messaging.c 프로젝트: LinkinW/monkc
mc_message _self_response_to_h(const mo obj, const char* methodname, unsigned hashval)
{
	//we will return a struct
	mc_hashitem* res;
	mc_message tmpmsg = {nil, nil};

	if(obj == nil){
		error_log("_self_response_to(obj) obj is nil. return {nil, nil}\n");
		return tmpmsg;
	}
	if(obj->isa == nil){
		error_log("_self_response_to(obj) obj->isa is nil. return {nil, nil}\n");
		return tmpmsg;
	}

	if((res=get_item_byhash(&(obj->isa->table), hashval, methodname)) != nil){
		tmpmsg.object = obj;
		tmpmsg.addr = res->value;
		runtime_log("return a message[%s/%s]\n", nameof(tmpmsg.object), methodname);
		return tmpmsg;
	}else{
		runtime_log("self_response_to class[%s] can not response to method[%s]\n", nameof(obj), methodname);
		return tmpmsg;
	}
}
예제 #2
0
mc_message _self_response_to_h(const mo obj, const char* methodname, MCHash hashval)
{
	//we will return a struct
	mc_hashitem* res = mull;
	mc_message tmpmsg = {mull, mull};

	if(obj == mull){
		//no need to warning user
		return tmpmsg;
	}
	if(obj->isa == mull){
		error_log("_self_response_to(obj, '%s') obj->isa is mull. return {mull, mull}\n", methodname);
		return tmpmsg;
	}

	if((res=get_item_byhash(obj->isa->table, hashval, methodname)) != mull){
		tmpmsg.object = obj;
		tmpmsg.address = res->value.mcfuncptr;
		runtime_log("return a message[%s/%s]\n", nameof(obj), methodname);
		return tmpmsg;
	}else{
        if (obj->nextResponder != mull) {
            return _self_response_to_h(obj->nextResponder, methodname, hashval);
        }else{
            runtime_log("self_response_to class[%s] can not response to method[%s]\n", nameof(obj), methodname);
            if (MC_STRICT_MODE == 1) {
                exit(-1);
            }else{
                return tmpmsg;
            }
        }
	}
}
예제 #3
0
파일: monkc.c 프로젝트: sunpaq/monkc
mc_hashitem* get_item_bykey(mc_hashtable* const table_p, const char* key)
{
	if (table_p == null) {
		error_log("get_item_bykey(table_p) table_p is nil return nil\n");
		return null;
	}
	//try get index
	return get_item_byhash(table_p, hash(key), key);
}
예제 #4
0
파일: monkc.c 프로젝트: sunpaq/monkc
MCInline mc_class* findclass(const char* name)
{
	//create a class hashtable
	if (mc_global_classtable == null)
		mc_global_classtable = new_table(MCHashTableLevel1);

	//cache
	//    mc_hashitem* cache = mc_global_classtable->cache;
	//    if (cache && cache->key == name) {
	//        return (mc_class*)(cache->value.mcvoidptr);
	//    }

	mc_hashitem* item = get_item_byhash(mc_global_classtable, hash(name), name);
	if (item == null)
		return null;
	else
		runtime_log("findClass item key:%s, value:%p\n", item->key, item->value.mcvoidptr);
	return (mc_class*)(item->value.mcvoidptr);
}
예제 #5
0
파일: Messaging.c 프로젝트: LinkinW/monkc
mc_message _response_to_h(const mo obj, const char* methodname, unsigned hashval, int strict)
{
	mc_object* obj_iterator = obj;
	mc_object* obj_first_hit = nil;
	mc_hashitem* met_first_hit = nil;
	mc_hashitem* met_item = nil;
	int hit_count = 0;
	int iter_count = 0;
	//int max_iter = get_tablesize(5);
	int max_iter = 10000;

	mc_message tmpmsg = {nil, nil};
	if(obj == nil || obj->isa == nil){
		error_log("_response_to(obj) obj is nil or obj->isa is nil. return {nil, nil}\n");
		return tmpmsg;
	}

	for(obj_iterator = obj;
		obj_iterator!= nil;
		obj_iterator = obj_iterator->super){
		if(iter_count++ > max_iter){
			error_log("iter_count>max but class still can not response to method\n");
			break;
		}
		if((met_item=get_item_byhash(&(obj_iterator->isa->table), hashval, methodname)) != nil) {
			runtime_log("hit a method [%s/%d] to match [%s]\n", 
				met_item->key, met_item->index, methodname);
			hit_count++;
			tmpmsg.object = obj_iterator;
			tmpmsg.addr = met_item->value;
			if(obj_first_hit==nil)obj_first_hit = obj_iterator;
			if(met_first_hit==nil)met_first_hit = met_item;
			//for the method key have conflicted with some super class in inherit tree
			if(hit_count>1){
				if(hit_count==2){
					//to support the "overide" feature of oop
					if(mc_compare_key(met_first_hit->key, methodname) == 0){
						tmpmsg.object = obj_first_hit;
                        tmpmsg.addr = met_first_hit->value;
						runtime_log("[first hit]return a message[%s/%s(%p/%p)]\n", 
                                                            tmpmsg.object->isa->item->key, 
                                                            methodname,
                                                            tmpmsg.object,
                                                            tmpmsg.addr);
						return tmpmsg;}
				}
				if(mc_compare_key(met_item->key, methodname) == 0){
					tmpmsg.object = obj_iterator;
					runtime_log("[string equal]return a message[%s/%s]\n", tmpmsg.object->isa->item->key, methodname);
					return tmpmsg;}
			}
		}
	}
	if(hit_count==1)
		runtime_log("return a message[%s/%s]\n", nameof(tmpmsg.object), methodname);
	else if(hit_count==0)
    {
        if (strict!=2) error_log("class[%s] can not response to method[%s]\n", nameof(obj), methodname);
        if (strict==1) exit(1);
    }
	else
    {
        if (strict!=2) error_log("hit_count>1 but class still can not response to method\n");
        if (strict==1) exit(1);
    }
	return tmpmsg;
}