forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			724 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			724 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | #ifndef HX_CFFI_NEKO_LOADER_H
 | ||
|  | #define HX_CFFI_NEKO_LOADER_H
 | ||
|  | 
 | ||
|  | //-------- NEKO Interface -----------------------------------------------------
 | ||
|  | namespace | ||
|  | { | ||
|  | 
 | ||
|  | #include <hx/NekoFunc.h>
 | ||
|  | 
 | ||
|  | 
 | ||
|  | void *sNekoDllHandle = 0; | ||
|  | 
 | ||
|  | void *LoadNekoFunc(const char *inName) | ||
|  | { | ||
|  |    #ifdef HX_WINRT
 | ||
|  |    return 0; | ||
|  |    #else
 | ||
|  |    static bool tried = false; | ||
|  |    if (tried && !sNekoDllHandle) | ||
|  |        return 0; | ||
|  |    tried = true; | ||
|  | 
 | ||
|  |    if (!sNekoDllHandle) | ||
|  |    { | ||
|  |       #ifdef HX_WINDOWS
 | ||
|  |       sNekoDllHandle = GetModuleHandleA("neko.dll"); | ||
|  |       #else
 | ||
|  |       sNekoDllHandle = dlopen("libneko." NEKO_EXT, RTLD_NOW); | ||
|  |       // The debian package creates libneko.so.0 without libneko.so...
 | ||
|  |       // The fedora/openSUSE rpm packages create libneko.so.1...
 | ||
|  |       if (!sNekoDllHandle) | ||
|  |          sNekoDllHandle = dlopen("libneko." NEKO_EXT ".0", RTLD_NOW); | ||
|  |       if (!sNekoDllHandle) | ||
|  |          sNekoDllHandle = dlopen("libneko." NEKO_EXT ".1", RTLD_NOW); | ||
|  |       if (!sNekoDllHandle) | ||
|  |          sNekoDllHandle = dlopen("libneko." NEKO_EXT ".2", RTLD_NOW); | ||
|  |       #endif
 | ||
|  |    | ||
|  |       if (!sNekoDllHandle) | ||
|  |       { | ||
|  |          fprintf(stderr,"Could not link to neko.\n"); | ||
|  |          return 0; | ||
|  |       } | ||
|  |    } | ||
|  | 
 | ||
|  | 
 | ||
|  |    #ifdef HX_WINDOWS
 | ||
|  |    void *result = (void *)GetProcAddress((HMODULE)sNekoDllHandle,inName); | ||
|  |    #else
 | ||
|  |    void *result = dlsym(sNekoDllHandle,inName); | ||
|  |    #endif
 | ||
|  | 
 | ||
|  |    //printf(" %s = %p\n", inName, result );
 | ||
|  |    return result; | ||
|  |    #endif // !HX_WINRT
 | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | static int __a_id = 0; | ||
|  | static int __s_id = 0; | ||
|  | static int b_id = 0; | ||
|  | static int length_id = 0; | ||
|  | static int push_id = 0; | ||
|  | 
 | ||
|  | neko_value *gNeko2HaxeString = 0; | ||
|  | neko_value *gNekoNewArray = 0; | ||
|  | neko_value gNekoNull = 0; | ||
|  | neko_value gNekoTrue = 0; | ||
|  | neko_value gNekoFalse = 0; | ||
|  | 
 | ||
|  | 
 | ||
|  | namespace | ||
|  | { | ||
|  | void CheckInitDynamicNekoLoader() | ||
|  | { | ||
|  |    if (!gNekoNull) | ||
|  |    { | ||
|  |       printf("Haxe code is missing a call to cpp.Prime.nekoInit().\n"); | ||
|  |    } | ||
|  | } | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /*
 | ||
|  | 
 | ||
|  | 
 | ||
|  | */ | ||
|  | 
 | ||
|  | void *DynamicNekoLoader(const char *inName); | ||
|  | 
 | ||
|  | typedef neko_value (*alloc_object_func)(neko_value); | ||
|  | typedef neko_value (*alloc_string_func)(const char *); | ||
|  | typedef neko_value (*alloc_abstract_func)(neko_vkind,void *); | ||
|  | typedef neko_value (*val_call1_func)(neko_value,neko_value); | ||
|  | typedef neko_value (*val_field_func)(neko_value,int); | ||
|  | typedef neko_value (*alloc_float_func)(double); | ||
|  | typedef void (*alloc_field_func)(neko_value,int,neko_value); | ||
|  | typedef neko_value *(*alloc_root_func)(int); | ||
|  | typedef char *(*alloc_private_func)(int); | ||
|  | typedef neko_value (*copy_string_func)(const char *,int); | ||
|  | typedef int (*val_id_func)(const char *); | ||
|  | typedef neko_buffer (*alloc_buffer_func)(const char *); | ||
|  | typedef neko_value (*val_buffer_func)(neko_buffer); | ||
|  | typedef void (*buffer_append_sub_func)(neko_buffer,const char *,int); | ||
|  | typedef void (*fail_func)(neko_value,const char *,int); | ||
|  | typedef neko_value (*alloc_array_func)(unsigned int); | ||
|  | typedef void (*val_gc_func)(neko_value,void *); | ||
|  | typedef void (*val_ocall1_func)(neko_value,int,neko_value); | ||
|  | typedef neko_value (*alloc_empty_string_func)(int); | ||
|  | 
 | ||
|  | static alloc_object_func dyn_alloc_object = 0; | ||
|  | static alloc_string_func dyn_alloc_string = 0; | ||
|  | static alloc_abstract_func dyn_alloc_abstract = 0; | ||
|  | static val_call1_func dyn_val_call1 = 0; | ||
|  | static val_field_func dyn_val_field = 0; | ||
|  | static alloc_field_func dyn_alloc_field = 0; | ||
|  | static alloc_float_func dyn_alloc_float = 0; | ||
|  | static alloc_root_func dyn_alloc_root = 0; | ||
|  | static alloc_private_func dyn_alloc_private = 0; | ||
|  | static alloc_private_func dyn_alloc = 0; | ||
|  | static copy_string_func dyn_copy_string = 0; | ||
|  | static val_id_func dyn_val_id = 0; | ||
|  | static alloc_buffer_func dyn_alloc_buffer = 0; | ||
|  | static val_buffer_func dyn_val_buffer = 0; | ||
|  | static fail_func dyn_fail = 0; | ||
|  | static buffer_append_sub_func dyn_buffer_append_sub = 0; | ||
|  | static alloc_array_func dyn_alloc_array = 0; | ||
|  | static val_gc_func dyn_val_gc = 0; | ||
|  | static val_ocall1_func dyn_val_ocall1 = 0; | ||
|  | static alloc_empty_string_func dyn_alloc_empty_string = 0; | ||
|  | 
 | ||
|  | 
 | ||
|  | neko_value api_alloc_string(const char *inString) | ||
|  | { | ||
|  |    CheckInitDynamicNekoLoader(); | ||
|  |    neko_value neko_string = dyn_alloc_string(inString); | ||
|  |    if (gNeko2HaxeString) | ||
|  |       return dyn_val_call1(*gNeko2HaxeString,neko_string); | ||
|  |    return neko_string; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | char *api_alloc_string_data(const char *inString,int inLength) | ||
|  | { | ||
|  |    CheckInitDynamicNekoLoader(); | ||
|  |    char *result = (char *)dyn_alloc_private(inLength+1); | ||
|  |    memcpy(result,inString,inLength); | ||
|  |    result[inLength]='\0'; | ||
|  |    return result; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | neko_value api_alloc_raw_string(int inLength) | ||
|  | { | ||
|  |    CheckInitDynamicNekoLoader(); | ||
|  |    return dyn_alloc_empty_string(inLength); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | #define NEKO_NOT_IMPLEMENTED(func) dyn_fail(api_alloc_string("NOT Implemented:" func),__FILE__,__LINE__)
 | ||
|  | 
 | ||
|  | void * api_empty() { return 0; } | ||
|  | 
 | ||
|  | bool api_val_bool(neko_value  arg1) { return arg1==gNekoTrue; } | ||
|  | int api_val_int(neko_value  arg1) { return neko_val_int(arg1); } | ||
|  | double api_val_float(neko_value  arg1) { return *(double *)( ((char *)arg1) + 4 ); } | ||
|  | double api_val_number(neko_value  arg1) { return neko_val_is_int(arg1) ? neko_val_int(arg1) : api_val_float(arg1); } | ||
|  | 
 | ||
|  | 
 | ||
|  | neko_value api_alloc_bool(bool arg1) { CheckInitDynamicNekoLoader(); return arg1 ? gNekoTrue : gNekoFalse; } | ||
|  | neko_value api_alloc_int(int arg1) { return neko_alloc_int(arg1); } | ||
|  | neko_value api_alloc_empty_object() | ||
|  | { | ||
|  |    return dyn_alloc_object(gNekoNull); | ||
|  | } | ||
|  | 
 | ||
|  | neko_value api_buffer_to_string(neko_buffer arg1) | ||
|  | { | ||
|  |    neko_value neko_string = dyn_val_buffer(arg1); | ||
|  |    if (gNeko2HaxeString) | ||
|  |       return dyn_val_call1(*gNeko2HaxeString,neko_string); | ||
|  |    return neko_string; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | const char * api_val_string(neko_value  arg1) | ||
|  | { | ||
|  | 	if (neko_val_is_string(arg1)) | ||
|  | 	   return neko_val_string(arg1); | ||
|  | 
 | ||
|  | 	if (neko_val_is_object(arg1)) | ||
|  |    { | ||
|  | 	   neko_value s = dyn_val_field(arg1,__s_id); | ||
|  |       if (neko_val_is_string(s)) | ||
|  | 	      return neko_val_string(s); | ||
|  |    } | ||
|  | 
 | ||
|  |    return 0; | ||
|  | } | ||
|  | 
 | ||
|  | void api_alloc_field_numeric(neko_value  arg1,int arg2, double arg3) | ||
|  | { | ||
|  |    dyn_alloc_field(arg1, arg2, dyn_alloc_float(arg3) ); | ||
|  | } | ||
|  | 
 | ||
|  | double  api_val_field_numeric(neko_value  arg1,int arg2) | ||
|  | { | ||
|  | 	neko_value field = dyn_val_field(arg1, arg2); | ||
|  | 	if (neko_val_is_number(field)) | ||
|  | 		return api_val_number(field); | ||
|  | 	if (field==gNekoTrue) | ||
|  |       return 1; | ||
|  | 	return 0; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | int api_val_strlen(neko_value  arg1) | ||
|  | { | ||
|  | 	if (neko_val_is_string(arg1)) | ||
|  | 	   return neko_val_strlen(arg1); | ||
|  | 
 | ||
|  | 	if (neko_val_is_object(arg1)) | ||
|  |    { | ||
|  |       neko_value l =  dyn_val_field(arg1,length_id); | ||
|  |       if (neko_val_is_int(l)) | ||
|  |          return api_val_int(l); | ||
|  |    } | ||
|  | 	return 0; | ||
|  | } | ||
|  | void api_buffer_set_size(neko_buffer inBuffer,int inLen) {  | ||
|  |    NEKO_NOT_IMPLEMENTED("api_buffer_set_size"); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | void api_buffer_append_char(neko_buffer inBuffer,int inChar) | ||
|  | { | ||
|  |    NEKO_NOT_IMPLEMENTED("api_buffer_append_char"); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | // Byte arrays - use strings
 | ||
|  | neko_buffer api_val_to_buffer(neko_value  arg1) | ||
|  | { | ||
|  |    return (neko_buffer)api_val_string(arg1); | ||
|  | } | ||
|  | bool api_val_is_buffer(neko_value  arg1) { return neko_val_is_string(arg1); }  | ||
|  | int api_buffer_size(neko_buffer inBuffer) { return neko_val_strlen((neko_value)inBuffer); } | ||
|  | char * api_buffer_data(neko_buffer inBuffer) { return (char *)api_val_string((neko_value)inBuffer); } | ||
|  | 
 | ||
|  | char * api_val_dup_string(neko_value inVal) | ||
|  | { | ||
|  | 	int len = api_val_strlen(inVal); | ||
|  | 	const char *ptr = api_val_string(inVal); | ||
|  | 	char *result = dyn_alloc_private(len+1); | ||
|  | 	memcpy(result,ptr,len); | ||
|  | 	result[len] = '\0'; | ||
|  | 	return result; | ||
|  | } | ||
|  | 
 | ||
|  | neko_value api_alloc_string_len(const char *inStr,int inLen) | ||
|  | { | ||
|  | 	if (gNeko2HaxeString) | ||
|  |    { | ||
|  |       if (!inStr) | ||
|  | 		   return dyn_val_call1(*gNeko2HaxeString,api_alloc_raw_string(inLen)); | ||
|  | 		return dyn_val_call1(*gNeko2HaxeString,dyn_copy_string(inStr,inLen)); | ||
|  |    } | ||
|  |    if (!inStr) | ||
|  | 		inStr = dyn_alloc_private(inLen); | ||
|  |    return dyn_copy_string(inStr,inLen); | ||
|  | } | ||
|  | 
 | ||
|  | neko_buffer api_alloc_buffer_len(int inLen) | ||
|  | { | ||
|  | 	neko_value str=api_alloc_string_len(0,inLen+1); | ||
|  | 	char *s=(char *)api_val_string(str); | ||
|  | 	memset(s,0,inLen+1); | ||
|  | 	return (neko_buffer)str; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | neko_value api_alloc_wstring_len(const wchar_t *inStr,int inLen) | ||
|  | { | ||
|  |   int len = 0; | ||
|  |   const wchar_t *chars = inStr; | ||
|  |   for(int i=0;i<inLen;i++) | ||
|  |    { | ||
|  |       int c = chars[i]; | ||
|  |       if( c <= 0x7F ) len++; | ||
|  |       else if( c <= 0x7FF ) len+=2; | ||
|  |       else if( c <= 0xFFFF ) len+=3; | ||
|  |       else len+= 4; | ||
|  |    } | ||
|  | 
 | ||
|  |    char *result = dyn_alloc_private(len);//+1?
 | ||
|  |    unsigned char *data =  (unsigned char *) &result[0]; | ||
|  |    for(int i=0;i<inLen;i++) | ||
|  |    { | ||
|  |       int c = chars[i]; | ||
|  |       if( c <= 0x7F ) | ||
|  |          *data++ = c; | ||
|  |       else if( c <= 0x7FF ) | ||
|  |       { | ||
|  |          *data++ = 0xC0 | (c >> 6); | ||
|  |          *data++ = 0x80 | (c & 63); | ||
|  |       } | ||
|  |       else if( c <= 0xFFFF ) | ||
|  |       { | ||
|  |          *data++ = 0xE0 | (c >> 12); | ||
|  |          *data++ = 0x80 | ((c >> 6) & 63); | ||
|  |          *data++ = 0x80 | (c & 63); | ||
|  |       } | ||
|  |       else | ||
|  |       { | ||
|  |          *data++ = 0xF0 | (c >> 18); | ||
|  |          *data++ = 0x80 | ((c >> 12) & 63); | ||
|  |          *data++ = 0x80 | ((c >> 6) & 63); | ||
|  |          *data++ = 0x80 | (c & 63); | ||
|  |       } | ||
|  |    } | ||
|  |    //result[len] = 0;
 | ||
|  | 
 | ||
|  |    return api_alloc_string_len(result,len); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | const wchar_t *api_val_wstring(neko_value  arg1) | ||
|  | { | ||
|  | 	int len = api_val_strlen(arg1); | ||
|  | 
 | ||
|  |    unsigned char *b = (unsigned char *)api_val_string(arg1); | ||
|  |    wchar_t *result = (wchar_t *)dyn_alloc_private((len+1)*sizeof(wchar_t)); | ||
|  |    int l = 0; | ||
|  | 
 | ||
|  |    for(int i=0;i<len;) | ||
|  |    { | ||
|  |        int c = b[i++]; | ||
|  |        if (c==0) break; | ||
|  |        else if( c < 0x80 ) | ||
|  |        { | ||
|  |            result[l++] = c; | ||
|  |        } | ||
|  |        else if( c < 0xE0 ) | ||
|  |            result[l++] = ( ((c & 0x3F) << 6) | (b[i++] & 0x7F) ); | ||
|  |        else if( c < 0xF0 ) | ||
|  |        { | ||
|  |            int c2 = b[i++]; | ||
|  |            result[l++] = ( ((c & 0x1F) << 12) | ((c2 & 0x7F) << 6) | ( b[i++] & 0x7F) ); | ||
|  |        } | ||
|  |        else | ||
|  |        { | ||
|  |            int c2 = b[i++]; | ||
|  |            int c3 = b[i++]; | ||
|  |            result[l++] = ( ((c & 0x0F) << 18) | ((c2 & 0x7F) << 12) | ((c3 << 6) & 0x7F) | (b[i++] & 0x7F) ); | ||
|  |        } | ||
|  |    } | ||
|  |    result[l] = '\0'; | ||
|  | 
 | ||
|  |    return result; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | wchar_t * api_val_dup_wstring(neko_value inVal) | ||
|  | { | ||
|  | 	return (wchar_t *)api_val_wstring(inVal); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | int api_val_type(neko_value  arg1) | ||
|  | { | ||
|  | 	int t=neko_val_type(arg1); | ||
|  | 
 | ||
|  | 	if (t==VAL_OBJECT) | ||
|  | 	{ | ||
|  | 		neko_value __a = dyn_val_field(arg1,__a_id); | ||
|  | 		if (neko_val_is_array(__a)) | ||
|  | 			return valtArray; | ||
|  | 		neko_value __s = dyn_val_field(arg1,__s_id); | ||
|  | 		if (neko_val_is_string(__s)) | ||
|  | 			return valtString; | ||
|  | 	} | ||
|  | 	if (t<7) | ||
|  | 		return (hxValueType)t; | ||
|  | 	if (t==VAL_ABSTRACT) | ||
|  | 		return valtAbstractBase; | ||
|  | 
 | ||
|  | 	if (t==VAL_PRIMITIVE || t==VAL_JITFUN) | ||
|  | 		return valtFunction; | ||
|  | 	if (t==VAL_32_BITS || t==VAL_INT) | ||
|  | 		return valtInt; | ||
|  | 	return valtNull; | ||
|  | } | ||
|  | 
 | ||
|  | neko_value *api_alloc_root() | ||
|  | { | ||
|  |    return dyn_alloc_root(1); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | void * api_val_to_kind(neko_value  arg1,neko_vkind arg2) | ||
|  | { | ||
|  | 	neko_vkind k = (neko_vkind)neko_val_kind(arg1); | ||
|  | 	if (k!=arg2) | ||
|  | 		return 0; | ||
|  | 	return neko_val_data(arg1); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | int api_alloc_kind() | ||
|  | { | ||
|  | 	static int id = 1; | ||
|  | 	int result = id; | ||
|  | 	id += 4; | ||
|  | 	return result; | ||
|  | } | ||
|  | neko_value api_alloc_null() | ||
|  | { | ||
|  |    CheckInitDynamicNekoLoader(); | ||
|  |    return gNekoNull; | ||
|  | } | ||
|  | 
 | ||
|  | neko_value api_create_abstract(neko_vkind inKind,int inSize,void *inFinalizer) | ||
|  | { | ||
|  |    void *data = dyn_alloc(inSize); | ||
|  |    neko_value val = dyn_alloc_abstract(inKind, data); | ||
|  |    dyn_val_gc(val, inFinalizer); | ||
|  |    return val; | ||
|  | } | ||
|  | 
 | ||
|  | void api_free_abstract(neko_value inAbstract) | ||
|  | { | ||
|  |    if (neko_val_is_abstract(inAbstract)) | ||
|  |    { | ||
|  |       dyn_val_gc(inAbstract,0); | ||
|  |       neko_val_kind(inAbstract) = 0; | ||
|  |    } | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | neko_value api_buffer_val(neko_buffer arg1) | ||
|  | { | ||
|  |         if (neko_val_is_string(arg1)) | ||
|  |             return (neko_value)arg1; | ||
|  | 
 | ||
|  |         if (neko_val_is_object(arg1)) | ||
|  |         { | ||
|  |             neko_value s = dyn_val_field((neko_value)arg1,__s_id); | ||
|  |             if (neko_val_is_string(s)) | ||
|  |                 return (neko_value)(s); | ||
|  |         } | ||
|  | 
 | ||
|  | 
 | ||
|  |    return api_alloc_null(); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | void api_hx_error() | ||
|  | { | ||
|  |    dyn_fail(dyn_alloc_string("An unknown error has occurred."),"",1); | ||
|  | } | ||
|  | 
 | ||
|  | void * api_val_data(neko_value  arg1) { return neko_val_data(arg1); } | ||
|  | 
 | ||
|  | // Array access - generic
 | ||
|  | int api_val_array_size(neko_value  arg1) | ||
|  | { | ||
|  | 	if (neko_val_is_array(arg1)) | ||
|  | 	   return neko_val_array_size(arg1); | ||
|  | 	neko_value l = dyn_val_field(arg1,length_id); | ||
|  | 	return neko_val_int(l); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | neko_value  api_val_array_i(neko_value  arg1,int arg2) | ||
|  | { | ||
|  | 	if (neko_val_is_array(arg1)) | ||
|  | 	   return neko_val_array_ptr(arg1)[arg2]; | ||
|  | 	return neko_val_array_ptr(dyn_val_field(arg1,__a_id))[arg2]; | ||
|  | } | ||
|  | 
 | ||
|  | void api_val_array_set_i(neko_value  arg1,int arg2,neko_value inVal) | ||
|  | { | ||
|  | 	if (!neko_val_is_array(arg1)) | ||
|  | 		arg1 = dyn_val_field(arg1,__a_id); | ||
|  | 	neko_val_array_ptr(arg1)[arg2] = inVal; | ||
|  | } | ||
|  | 
 | ||
|  | void api_val_array_set_size(neko_value  arg1,int inLen) | ||
|  | { | ||
|  | 	NEKO_NOT_IMPLEMENTED("api_val_array_set_size"); | ||
|  | } | ||
|  | 
 | ||
|  | void api_val_array_push(neko_value  inArray,neko_value inValue) | ||
|  | { | ||
|  |    dyn_val_ocall1(inArray,push_id,inValue); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | neko_value  api_alloc_array(int arg1) | ||
|  | { | ||
|  |    if (!gNekoNewArray) | ||
|  | 	   return dyn_alloc_array(arg1); | ||
|  | 	return dyn_val_call1(*gNekoNewArray,neko_alloc_int(arg1)); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | neko_value * api_val_array_value(neko_value  arg1) | ||
|  | { | ||
|  | 	if (neko_val_is_array(arg1)) | ||
|  | 	   return neko_val_array_ptr(arg1); | ||
|  | 	return neko_val_array_ptr(dyn_val_field(arg1,__a_id)); | ||
|  | } | ||
|  | 
 | ||
|  | neko_value  api_val_call0_traceexcept(neko_value  arg1) | ||
|  | { | ||
|  | 	NEKO_NOT_IMPLEMENTED("api_val_call0_traceexcept"); | ||
|  | 	return gNekoNull; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | int  api_val_fun_nargs(neko_value arg1) | ||
|  | { | ||
|  |    if (!arg1 || !neko_val_is_function(arg1) ) | ||
|  |       return faNotFunction; | ||
|  |    return neko_val_fun_nargs(arg1); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | void api_val_gc(neko_value obj, void *finalizer) | ||
|  | { | ||
|  |    // Let neko deal with ints or abstracts ...
 | ||
|  |    if (neko_val_is_int(obj) || neko_val_is_abstract(obj)) | ||
|  |    { | ||
|  |       dyn_val_gc(obj,finalizer); | ||
|  |    } | ||
|  |    else | ||
|  |    { | ||
|  |       // Hack type to abstract for the duration
 | ||
|  |       neko_val_type old_tag = neko_val_tag(obj); | ||
|  |       neko_val_tag(obj) = VAL_ABSTRACT; | ||
|  |       dyn_val_gc(obj,finalizer); | ||
|  |       neko_val_tag(obj) = old_tag; | ||
|  |    } | ||
|  | } | ||
|  | 
 | ||
|  | void api_gc_change_managed_memory(int,const char *) | ||
|  | { | ||
|  |    // Nothing to do here
 | ||
|  | } | ||
|  | 
 | ||
|  | bool api_gc_try_blocking() { return false; } | ||
|  | bool api_gc_try_unblocking() { return false; } | ||
|  | 
 | ||
|  | #define IMPLEMENT_HERE(x) if (!strcmp(inName,#x)) return (void *)api_##x;
 | ||
|  | #define IGNORE_API(x) if (!strcmp(inName,#x)) return (void *)api_empty;
 | ||
|  | 
 | ||
|  | 
 | ||
|  | void *DynamicNekoLoader(const char *inName) | ||
|  | { | ||
|  |    IMPLEMENT_HERE(alloc_kind) | ||
|  |    IMPLEMENT_HERE(alloc_null) | ||
|  |    IMPLEMENT_HERE(val_to_kind) | ||
|  |    if (!strcmp(inName,"hx_fail")) | ||
|  |       return LoadNekoFunc("_neko_failure"); | ||
|  |    IMPLEMENT_HERE(val_type) | ||
|  |    IMPLEMENT_HERE(val_bool) | ||
|  |    IMPLEMENT_HERE(val_int) | ||
|  |    IMPLEMENT_HERE(val_float) | ||
|  |    IMPLEMENT_HERE(val_number) | ||
|  |    IMPLEMENT_HERE(val_field_numeric) | ||
|  |    IMPLEMENT_HERE(alloc_bool) | ||
|  |    IMPLEMENT_HERE(alloc_int) | ||
|  |    IMPLEMENT_HERE(alloc_empty_object) | ||
|  |    IMPLEMENT_HERE(alloc_root) | ||
|  |    IMPLEMENT_HERE(val_gc) | ||
|  |    IMPLEMENT_HERE(gc_try_blocking) | ||
|  |    IMPLEMENT_HERE(gc_try_unblocking) | ||
|  | 
 | ||
|  |    IMPLEMENT_HERE(create_abstract) | ||
|  |    IMPLEMENT_HERE(free_abstract) | ||
|  | 
 | ||
|  |    IGNORE_API(gc_enter_blocking) | ||
|  |    IGNORE_API(gc_exit_blocking) | ||
|  |    IGNORE_API(gc_safe_point) | ||
|  |    IGNORE_API(gc_add_root) | ||
|  |    IGNORE_API(gc_remove_root) | ||
|  |    IGNORE_API(gc_set_top_of_stack) | ||
|  |    IGNORE_API(gc_change_managed_memory) | ||
|  |    IGNORE_API(create_root) | ||
|  |    IGNORE_API(query_root) | ||
|  |    IGNORE_API(destroy_root) | ||
|  |    IGNORE_API(hx_register_prim) | ||
|  |    IGNORE_API(val_array_int) | ||
|  |    IGNORE_API(val_array_double) | ||
|  |    IGNORE_API(val_array_float) | ||
|  |    IGNORE_API(val_array_bool) | ||
|  | 
 | ||
|  |    if (!strcmp(inName,"hx_alloc")) | ||
|  |       return LoadNekoFunc("neko_alloc"); | ||
|  | 
 | ||
|  |    IMPLEMENT_HERE(buffer_to_string) | ||
|  |    IMPLEMENT_HERE(buffer_val) | ||
|  | 
 | ||
|  |    if (!strcmp(inName,"val_iter_field_vals")) | ||
|  |       return LoadNekoFunc("neko_val_iter_fields"); | ||
|  | 
 | ||
|  |    IMPLEMENT_HERE(val_strlen) | ||
|  |    IMPLEMENT_HERE(val_wstring) | ||
|  |    IMPLEMENT_HERE(val_string) | ||
|  |    IMPLEMENT_HERE(alloc_string) | ||
|  |    IMPLEMENT_HERE(alloc_raw_string) | ||
|  |    IMPLEMENT_HERE(alloc_string_data) | ||
|  |    IMPLEMENT_HERE(val_dup_wstring) | ||
|  |    IMPLEMENT_HERE(val_dup_string) | ||
|  |    IMPLEMENT_HERE(alloc_string_len) | ||
|  |    IMPLEMENT_HERE(alloc_wstring_len) | ||
|  | 
 | ||
|  |    IMPLEMENT_HERE(val_is_buffer) | ||
|  |    IMPLEMENT_HERE(val_to_buffer) | ||
|  |    IMPLEMENT_HERE(alloc_buffer_len) | ||
|  |    IMPLEMENT_HERE(buffer_size) | ||
|  |    IMPLEMENT_HERE(buffer_set_size) | ||
|  |    IMPLEMENT_HERE(buffer_append_char) | ||
|  |    IMPLEMENT_HERE(buffer_data) | ||
|  | 
 | ||
|  |    IMPLEMENT_HERE(hx_error) | ||
|  |    IMPLEMENT_HERE(val_array_i) | ||
|  |    IMPLEMENT_HERE(val_array_size) | ||
|  |    IMPLEMENT_HERE(val_data) | ||
|  |    IMPLEMENT_HERE(val_array_set_i) | ||
|  |    IMPLEMENT_HERE(val_array_set_size) | ||
|  |    IMPLEMENT_HERE(val_array_push) | ||
|  |    IMPLEMENT_HERE(alloc_array) | ||
|  |    IMPLEMENT_HERE(alloc_field_numeric) | ||
|  |    IMPLEMENT_HERE(val_array_value) | ||
|  | 
 | ||
|  |    IMPLEMENT_HERE(val_fun_nargs) | ||
|  | 
 | ||
|  |    IMPLEMENT_HERE(val_call0_traceexcept) | ||
|  | 
 | ||
|  | 
 | ||
|  |    char buffer[100]; | ||
|  |    strcpy(buffer,"neko_"); | ||
|  |    strcat(buffer,inName); | ||
|  |    void *result = LoadNekoFunc(buffer); | ||
|  |    if (result) | ||
|  |       return result; | ||
|  | 
 | ||
|  | 	return 0; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | ResolveProc InitDynamicNekoLoader() | ||
|  | { | ||
|  |    static bool init = false; | ||
|  |    if (!init) | ||
|  |    { | ||
|  |       dyn_alloc_private = (alloc_private_func)LoadNekoFunc("neko_alloc_private"); | ||
|  |       dyn_alloc = (alloc_private_func)LoadNekoFunc("neko_alloc"); | ||
|  |       dyn_alloc_object = (alloc_object_func)LoadNekoFunc("neko_alloc_object"); | ||
|  |       dyn_alloc_string = (alloc_string_func)LoadNekoFunc("neko_alloc_string"); | ||
|  |       dyn_alloc_abstract = (alloc_abstract_func)LoadNekoFunc("neko_alloc_abstract"); | ||
|  |       dyn_val_call1 = (val_call1_func)LoadNekoFunc("neko_val_call1"); | ||
|  |       dyn_val_field = (val_field_func)LoadNekoFunc("neko_val_field"); | ||
|  |       dyn_alloc_field = (alloc_field_func)LoadNekoFunc("neko_alloc_field"); | ||
|  |       dyn_alloc_float = (alloc_float_func)LoadNekoFunc("neko_alloc_float"); | ||
|  |       dyn_alloc_root = (alloc_root_func)LoadNekoFunc("neko_alloc_root"); | ||
|  |       dyn_copy_string = (copy_string_func)LoadNekoFunc("neko_copy_string"); | ||
|  |       dyn_val_id = (val_id_func)LoadNekoFunc("neko_val_id"); | ||
|  |       dyn_alloc_buffer = (alloc_buffer_func)LoadNekoFunc("neko_alloc_buffer"); | ||
|  |       dyn_val_buffer = (val_buffer_func)LoadNekoFunc("neko_buffer_to_string"); | ||
|  |       dyn_fail = (fail_func)LoadNekoFunc("_neko_failure"); | ||
|  |       dyn_buffer_append_sub = (buffer_append_sub_func)LoadNekoFunc("neko_buffer_append_sub"); | ||
|  |       dyn_alloc_array = (alloc_array_func)LoadNekoFunc("neko_alloc_array"); | ||
|  |       dyn_val_gc = (val_gc_func)LoadNekoFunc("neko_val_gc"); | ||
|  |       dyn_val_ocall1 = (val_ocall1_func)LoadNekoFunc("neko_val_ocall1"); | ||
|  |       dyn_alloc_empty_string = (alloc_empty_string_func)LoadNekoFunc("neko_alloc_empty_string"); | ||
|  |       init = true; | ||
|  |    } | ||
|  | 
 | ||
|  |    if (!dyn_val_id) | ||
|  |      return 0; | ||
|  | 
 | ||
|  | 
 | ||
|  |    __a_id = dyn_val_id("__a"); | ||
|  |    __s_id = dyn_val_id("__s"); | ||
|  |    b_id = dyn_val_id("b"); | ||
|  |    length_id = dyn_val_id("length"); | ||
|  |    push_id = dyn_val_id("push"); | ||
|  | 
 | ||
|  |    return DynamicNekoLoader; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | neko_value neko_init(neko_value inNewString,neko_value inNewArray,neko_value inNull, neko_value inTrue, neko_value inFalse) | ||
|  | { | ||
|  |    InitDynamicNekoLoader(); | ||
|  | 
 | ||
|  |    gNekoNull = inNull; | ||
|  |    gNekoTrue = inTrue; | ||
|  |    gNekoFalse = inFalse; | ||
|  | 
 | ||
|  |    gNeko2HaxeString = dyn_alloc_root(1); | ||
|  |    *gNeko2HaxeString = inNewString; | ||
|  |    gNekoNewArray = dyn_alloc_root(1); | ||
|  |    *gNekoNewArray = inNewArray; | ||
|  | 
 | ||
|  |    return gNekoNull; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | } // end anon namespace
 | ||
|  | 
 | ||
|  | #endif
 | ||
|  | 
 |