#ifndef HX_CFFI_NEKO_LOADER_H #define HX_CFFI_NEKO_LOADER_H //-------- NEKO Interface ----------------------------------------------------- namespace { #include 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> 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