static void report( neko_vm *vm, value exc, int isexc ) { int i; buffer b = alloc_buffer(NULL); value st = neko_exc_stack(vm); for(i=0;i<val_array_size(st);i++) { value s = val_array_ptr(st)[i]; buffer_append(b,"Called from "); if( val_is_null(s) ) buffer_append(b,"a C function"); else if( val_is_string(s) ) { buffer_append(b,val_string(s)); buffer_append(b," (no debug available)"); } else if( val_is_array(s) && val_array_size(s) == 2 && val_is_string(val_array_ptr(s)[0]) && val_is_int(val_array_ptr(s)[1]) ) { val_buffer(b,val_array_ptr(s)[0]); buffer_append(b," line "); val_buffer(b,val_array_ptr(s)[1]); } else val_buffer(b,s); buffer_append_char(b,'\n'); } if( isexc ) buffer_append(b,"Uncaught exception - "); val_buffer(b,exc); # ifdef NEKO_STANDALONE neko_standalone_error(val_string(buffer_to_string(b))); # else fprintf(stderr,"%s\n",val_string(buffer_to_string(b))); # endif }
char *Val2Str(value inVal) { if (val_is_string(inVal)) return (char *)val_string(inVal); if (val_is_object(inVal)) { value __s = val_field(inVal, val_id("__s")); if (val_is_string(__s)) return (char *)val_string(__s); } else if (val_is_object(inVal)) return val_bool(inVal) ? (char *)"true":(char *)"false"; return (char *)""; }
value lime_audio_load (value data) { AudioBuffer audioBuffer; Resource resource; if (val_is_string (data)) { resource = Resource (val_string (data)); } else { Bytes bytes (data); resource = Resource (&bytes); } if (WAV::Decode (&resource, &audioBuffer)) { return audioBuffer.Value (); } #ifdef LIME_OGG if (OGG::Decode (&resource, &audioBuffer)) { return audioBuffer.Value (); } #endif return alloc_null (); }
value lime_image_load (value data) { ImageBuffer buffer; Resource resource; if (val_is_string (data)) { resource = Resource (val_string (data)); } else { Bytes bytes (data); resource = Resource (&bytes); } #ifdef LIME_PNG if (PNG::Decode (&resource, &buffer)) { return buffer.Value (); } #endif #ifdef LIME_JPEG if (JPEG::Decode (&resource, &buffer)) { return buffer.Value (); } #endif return alloc_null (); }
const char * api_val_string(value arg1) { if (val_is_string(arg1)) return val_string(arg1); value s = val_field(arg1,__s_id); return val_string(s); }
/** connect : { host => string, port => int, user => string, pass => string, socket => string? } -> 'connection <doc>Connect to a database using the connection informations</doc> **/ static value connect_mysql( value params ) { value host, port, user, pass, socket; val_check(params,object); host = val_field(params,val_id("host")); port = val_field(params,val_id("port")); user = val_field(params,val_id("user")); pass = val_field(params,val_id("pass")); socket = val_field(params,val_id("socket")); val_check(host,string); val_check(port,int); val_check(user,string); val_check(pass,string); if( !val_is_string(socket) && !val_is_null(socket) ) neko_error(); { connection *c = (connection*)alloc(sizeof(connection)); value v; c->m = mysql_init(NULL); c->conv_string = NULL; c->conv_date = NULL; c->conv_bytes = NULL; if( mysql_real_connect(c->m,val_string(host),val_string(user),val_string(pass),NULL,val_int(port),val_is_null(socket)?NULL:val_string(socket),0) == NULL ) { buffer b = alloc_buffer("Failed to connect to mysql server : "); buffer_append(b,mysql_error(c->m)); mysql_close(c->m); bfailure(b); } v = alloc_abstract(k_connection,c); val_gc(v,free_connection); return v; } }
// String access int api_val_strlen(value arg1) { if (val_is_string(arg1)) return val_strlen(arg1); value l = val_field(arg1,length_id); if (val_is_int(l)) return val_int(l); return 0; }
/** $float : any -> float? <doc>Convert the value to the corresponding float or return [null]</doc> **/ static value builtin_float( value f ) { if( val_is_string(f) ) { char *c = val_string(f), *end; tfloat f = (tfloat)strtod(c,&end); return (c == end) ? val_null : alloc_float(f); } if( val_is_number(f) ) return alloc_float( val_number(f) ); return val_null; }
static void report( neko_vm *vm, value exc ) { #if OSX CFStringRef title = CFSTR("Uncaught exception"); CFStringRef message; #endif int i = 0; buffer b = alloc_buffer(NULL); value st = neko_exc_stack(vm); if( val_array_size(st) > 20 ) { i = val_array_size(st) - 20; buffer_append(b,"...\n"); } for(i;i<val_array_size(st);i++) { value s = val_array_ptr(st)[i]; if( val_is_null(s) ) buffer_append(b,"Called from a C function\n"); else if( val_is_string(s) ) { buffer_append(b,"Called from "); buffer_append(b,val_string(s)); buffer_append(b," (no debug available)\n"); } else if( val_is_array(s) && val_array_size(s) == 2 && val_is_string(val_array_ptr(s)[0]) && val_is_int(val_array_ptr(s)[1]) ) { buffer_append(b,"Called from "); buffer_append(b,val_string(val_array_ptr(s)[0])); buffer_append(b," line "); val_buffer(b,val_array_ptr(s)[1]); buffer_append(b,"\n"); } else { buffer_append(b,"Called from "); val_buffer(b,s); buffer_append(b,"\n"); } } val_buffer(b,exc); #if _WIN32 MessageBox(NULL,val_string(buffer_to_string(b)),"Uncaught exception",MB_OK | MB_ICONERROR); #elif OSX message = CFStringCreateWithCString(NULL,val_string(buffer_to_string(b)), kCFStringEncodingUTF8); CFUserNotificationDisplayNotice(0,0,NULL,NULL,NULL,title,message,NULL); #elif LINUX fprintf(stderr,"Uncaught Exception: %s\n",val_string(buffer_to_string(b))); #endif }
/** $print : any* -> void <doc>Can print any value</doc> **/ static value builtin_print( value *args, int nargs ) { buffer b; int i; if( nargs == 1 && val_is_string(*args) ) { val_print(*args); return neko_builtins[1]; } b = alloc_buffer(NULL); for(i=0;i<nargs;i++) val_buffer(b,args[i]); val_print(buffer_to_string(b)); return neko_builtins[1]; }
static value systray_create_icon( value w, value iconpath, value tooltip ) { val_check(tooltip,string); if ( !(val_is_string(iconpath) || val_is_null(iconpath)) ) val_throw(alloc_string(tray_icon_error)); else { tray_icon *tray = systools_win_create_tray_icon(val_hwnd(w),val_string(iconpath),val_string(tooltip)); if (!tray) val_throw(alloc_string(tray_icon_error)); return alloc_abstract(k_tray_icon,tray); } return val_null; }
void NekoCodeChunk::neko_dump(std::string const & indent) const { for (const_iterator it = begin(); it != end(); ++it) { std::cout << indent << it->first << ": "; print_neko_instruction((OPCODE) it->second.first, it->second.second, parameter_table[it->second.first]); std::cout << "; // "; { int ppc = (int)((int_val *)it->first - m->code); int idx = m->dbgidxs[ppc>>5].base + bitcount(m->dbgidxs[ppc>>5].bits >> (31 - (ppc & 31))); value s = val_array_ptr(m->dbgtbl)[idx]; if( val_is_string(s) ) printf("%s",val_string(s)); else if( val_is_array(s) && val_array_size(s) == 2 && val_is_string(val_array_ptr(s)[0]) && val_is_int(val_array_ptr(s)[1]) ) printf("file %s line %d",val_string(val_array_ptr(s)[0]),val_int(val_array_ptr(s)[1])); else printf("???"); } std::cout << std::endl; } }
const unsigned char *ByteArray::Bytes () const { value bytes = val_call1 (gByteArrayBytes->get (), mValue); if (val_is_string (bytes)) return (unsigned char *)val_string (bytes); buffer buf = val_to_buffer (bytes); if (buf == 0) { val_throw (alloc_string ("Bad ByteArray")); } return (unsigned char *)buffer_data (buf); }
value hx_zmq_setbytessockopt(value socket_handle_, value option_, value bytes_optval_) { val_check_kind(socket_handle_, k_zmq_socket_handle); if (!val_is_int(option_)) { printf("option_ is not int"); val_throw(alloc_int(EINVAL)); return alloc_null(); } size_t size = 0; uint8_t *data = 0; // If data from neko if (val_is_string(bytes_optval_)) { size = val_strlen(bytes_optval_); data = (uint8_t *)val_string(bytes_optval_); } // else from C++ else if (val_is_buffer(bytes_optval_)) { buffer buf = val_to_buffer(bytes_optval_); size = buffer_size(buf); data = (uint8_t *)buffer_data(buf); } else { printf("bytes_optval_ not string or buffer"); val_throw(alloc_int(EINVAL)); return alloc_null(); } int rc = 0; int err = 0; int option = val_int(option_); rc = zmq_setsockopt (val_data(socket_handle_), option, data, size); err = zmq_errno(); if (rc != 0) { printf("err:%d",err); val_throw(alloc_int(err)); return alloc_null(); } return alloc_int(rc); }
value hx_zmq_bind(value socket_handle, value addr) { val_check_kind(socket_handle, k_zmq_socket_handle); if (!val_is_string(addr)) { val_throw(alloc_int(EINVAL)); return alloc_null(); } int rc = zmq_bind(val_data(socket_handle),val_string(addr)); int err = zmq_errno(); if (rc != 0) { val_throw(alloc_int(err)); return alloc_null(); } return alloc_int(rc); }
value lime_font_load (value data) { #ifdef LIME_FREETYPE Resource resource; if (val_is_string (data)) { resource = Resource (val_string (data)); } else { Bytes bytes (data); resource = Resource (&bytes); } Font *font = new Font (&resource, 0); if (font) { if (font->face) { value v = alloc_float ((intptr_t)font); val_gc (v, lime_font_destroy); return v; } else { delete font; } } #endif return alloc_null (); }
// Determine value type int api_val_type(value arg1) { int t=val_type(arg1); if (t==VAL_OBJECT) { value __a = val_field(arg1,__a_id); if (val_is_array(__a)) return valtArray; value __s = val_field(arg1,__s_id); if (val_is_string(__s)) return valtString; } if (t<7) return (ValueType)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; }
value lime_font_load (value data) { #ifdef LIME_FREETYPE Resource resource; Bytes bytes; if (val_is_string (data)) { resource = Resource (val_string (data)); } else { bytes.Set (data); resource = Resource (&bytes); } Font *font = new Font (&resource, 0); if (font) { if (font->face) { return CFFIPointer (font, gc_font); } else { delete font; } } #endif return alloc_null (); }
void Bytes::Set (value bytes) { if (val_is_null (bytes)) { _length = 0; _data = 0; _value = 0; } else { _value = bytes; _length = val_int (val_field (bytes, id_length)); if (_length > 0) { value b = val_field (bytes, id_b); if (val_is_string (b)) { _data = (unsigned char*)val_string (b); } else { _data = (unsigned char*)buffer_data (val_to_buffer (b)); } } else { _data = 0; } } }
static int neko_handler_rec( request_rec *r ) { mcontext ctx; neko_vm *vm; const char *ctype; value exc = NULL; /* Seems to crash on Windows. And on Linux, we rarely have libGC 7.x installed anyway # if defined(APACHE_2_X) || defined(NEKO_WINDOWS) // we are using threads, so let's make sure that the current thread is registered neko_thread_register(true); # endif */ config.hits++; ctx.r = r; ctx.main = cache_find(r); ctx.post_data = val_null; ctx.headers_sent = false; ctx.content_type = alloc_string("text/html"); r->content_type = val_string(ctx.content_type); if( ap_setup_client_block(r,REQUEST_CHUNKED_ERROR) != 0 ) { send_headers(&ctx); apache_error(APLOG_WARNING,r,"ap_setup_client_block failed"); return OK; } ctype = ap_table_get(r->headers_in,"Content-Type"); if( (!ctype || strstr(ctype,"multipart/form-data") == NULL) && ap_should_client_block(r) ) { # define MAXLEN 1024 char buf[MAXLEN]; int len; int tlen = 0; buffer b = alloc_buffer(NULL); while( (len = ap_get_client_block(r,buf,MAXLEN)) > 0 ) { if( tlen < config.max_post_size ) buffer_append_sub(b,buf,len); tlen += len; } if( tlen >= config.max_post_size ) { send_headers(&ctx); apache_error(APLOG_WARNING,r,"Maximum POST data exceeded. Try using multipart encoding"); return OK; } ctx.post_data = buffer_to_string(b); } vm = neko_vm_alloc(NULL); if( config.use_stats ) neko_vm_set_stats(vm,neko_stats_measure,config.use_prim_stats?neko_stats_measure:NULL); neko_vm_set_custom(vm,k_mod_neko,&ctx); if( config.use_jit && !neko_vm_jit(vm,1) ) { send_headers(&ctx); apache_error(APLOG_WARNING,r,"JIT required by env. var but not enabled in NekoVM"); return OK; } neko_vm_redirect(vm,request_print,&ctx); neko_vm_select(vm); if( ctx.main != NULL ) { value old = ctx.main; if( config.use_stats ) neko_stats_measure(vm,r->filename,1); val_callEx(val_null,old,NULL,0,&exc); if( config.use_stats ) neko_stats_measure(vm,r->filename,0); if( old != ctx.main ) cache_module(r->filename,FTIME(r),ctx.main); } else { char *base_uri = request_base_uri(r); value mload = neko_default_loader(&base_uri,1); value args[] = { alloc_string(r->filename), mload }; char *p = strrchr(val_string(args[0]),'.'); if( p != NULL ) *p = 0; val_callEx(mload,val_field(mload,val_id("loadmodule")),args,2,&exc); if( ctx.main != NULL && config.use_cache ) cache_module(r->filename,FTIME(r),ctx.main); } if( exc != NULL ) { buffer b = alloc_buffer(NULL); value v; int i; const char *p, *start; value st = neko_exc_stack(vm); val_buffer(b,exc); config.exceptions++; ap_soft_timeout("Client Timeout",r); send_headers(&ctx); v = buffer_to_string(b); p = val_string(v); start = p; ap_rprintf(r,"Uncaught exception - "); while( *p ) { if( *p == '<' || *p == '>' ) { ap_rwrite(start,(int)(p - start),r); ap_rwrite((*p == '<')?"<":">",4, r); start = p + 1; } p++; } ap_rwrite(start,(int)(p - start),r); ap_rprintf(r,"<br/><br/>"); for(i=0;i<val_array_size(st);i++) { value s = val_array_ptr(st)[i]; if( val_is_null(s) ) ap_rprintf(r,"Called from a C function<br/>"); else if( val_is_string(s) ) { ap_rprintf(r,"Called from %s (no debug available)<br/>",val_string(s)); } else if( val_is_array(s) && val_array_size(s) == 2 && val_is_string(val_array_ptr(s)[0]) && val_is_int(val_array_ptr(s)[1]) ) ap_rprintf(r,"Called from %s line %d<br/>",val_string(val_array_ptr(s)[0]),val_int(val_array_ptr(s)[1])); else { b = alloc_buffer(NULL); val_buffer(b,s); ap_rprintf(r,"Called from %s<br/>",val_string(buffer_to_string(b))); } } ap_kill_timeout(r); return OK; } send_headers(&ctx); return OK; }
/** * Receive data from socket * Based on code in https://github.com/zeromq/jzmq/blob/master/src/Socket.cpp */ value hx_zmq_send(value socket_handle_, value msg_data, value flags) { val_check_kind(socket_handle_, k_zmq_socket_handle); if (!val_is_null(flags) && !val_is_int(flags)) { val_throw(alloc_int(EINVAL)); return alloc_null(); } size_t size = 0; uint8_t *data = 0; zmq_msg_t message; // Extract byte data from either Neko string or C++ buffer // see: http://waxe.googlecode.com/svn-history/r32/trunk/src/waxe/HaxeAPI.cpp "Val2ByteData" if (val_is_string(msg_data)) { // Neko size = val_strlen(msg_data); data = (uint8_t *)val_string(msg_data); } else if (val_is_buffer(msg_data)) { // CPP buffer buf = val_to_buffer(msg_data); size = buffer_size(buf); data = (uint8_t *)buffer_data(buf); } else { val_throw(alloc_int(EINVAL)); return alloc_null(); } // Set up send message buffer by referencing the provided bytes data //zero copy version: int rc = zmq_msg_init_data (&message, data, size,NULL,NULL); int rc = zmq_msg_init_size(&message, size); memcpy (zmq_msg_data(&message), data, size); int err = zmq_errno(); if (rc != 0) { val_throw(alloc_int(err)); return alloc_null(); } gc_enter_blocking(); // Send #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0) rc = zmq_sendmsg (val_data(socket_handle_), &message, val_int(flags)); #else rc = zmq_send (val_data(socket_handle_), &message, val_int(flags)); #endif err = zmq_errno(); gc_exit_blocking(); // If NOBLOCK, but cant send message now, close message first before quitting if (rc == -1 && err == EAGAIN) { rc = zmq_msg_close (&message); err = zmq_errno(); if (rc != 0) { val_throw(alloc_int(err)); return alloc_null(); } return alloc_null(); } if (rc == -1) { val_throw(alloc_int(err)); rc = zmq_msg_close (&message); err = zmq_errno(); if (rc != 0) { val_throw(alloc_int(err)); return alloc_null(); } return alloc_null(); } rc = zmq_msg_close (&message); err = zmq_errno(); if (rc != 0) { val_throw(alloc_int(err)); return alloc_null(); } return alloc_null(); }
static void val_buffer_rec( buffer b, value v, vlist *stack ) { char buf[32]; int i, l; vlist *vtmp = stack; while( vtmp != NULL ) { if( vtmp->v == v ) { buffer_append_sub(b,"...",3); return; } vtmp = vtmp->next; } switch( val_type(v) ) { case VAL_INT: buffer_append_sub(b,buf,sprintf(buf,"%d",val_int(v))); break; case VAL_STRING: buffer_append_sub(b,val_string(v),val_strlen(v)); break; case VAL_FLOAT: buffer_append_sub(b,buf,sprintf(buf,FLOAT_FMT,val_float(v))); break; case VAL_NULL: buffer_append_sub(b,"null",4); break; case VAL_BOOL: if( val_bool(v) ) buffer_append_sub(b,"true",4); else buffer_append_sub(b,"false",5); break; case VAL_FUNCTION: buffer_append_sub(b,buf,sprintf(buf,"#function:%d",val_fun_nargs(v))); break; case VAL_OBJECT: { value s = val_field(v,id_string); if( s != val_null ) s = val_callEx(v,s,NULL,0,NULL); if( val_is_string(s) ) buffer_append_sub(b,val_string(s),val_strlen(s)); else { vlist2 vtmp; vtmp.v = v; vtmp.next = stack; vtmp.b = b; vtmp.prev = 0; buffer_append_sub(b,"{",1); val_iter_fields(v,val_buffer_fields,&vtmp); if( vtmp.prev ) buffer_append_sub(b," }",2); else buffer_append_sub(b,"}",1); } break; } case VAL_ARRAY: buffer_append_sub(b,"[",1); l = val_array_size(v); { vlist vtmp; vtmp.v = v; vtmp.next = stack; for(i=0;i<l;i++) { value vi = val_array_ptr(v)[i]; val_buffer_rec(b,vi,&vtmp); if( i != l - 1 ) buffer_append_sub(b,",",1); } } buffer_append_sub(b,"]",1); break; case VAL_INT32: buffer_append_sub(b,buf,sprintf(buf,"%d",val_int32(v))); break; case VAL_ABSTRACT: buffer_append_sub(b,"#abstract",9); break; default: buffer_append_sub(b,"#unknown",8); break; } }
void check_cptr( value cp, int size ) { if( !val_is_string( cp ) ) val_throw( alloc_string("not a string - cannot access as cptr") ); if( size>0 && val_strlen(cp) < size ) val_throw( alloc_string("cptr overflow") ); }