// returns ord or -1 int pvm_get_method_ordinal( pvm_object_t tclass, pvm_object_t mname ) { struct data_area_4_class *cda= pvm_object_da( tclass, class ); pvm_object_t mnames = cda->method_names; if( pvm_is_null(mnames) ) return -1; if( pvm_is_null(mname) ) return -1; if( !pvm_object_class_exactly_is( mname, pvm_get_string_class() ) ) return -1; int nitems = get_array_size( mnames.data ); int i; for( i = 0; i < nitems; i++ ) { pvm_object_t curr_mname = pvm_get_ofield( mnames, i ); int diff = pvm_strcmp( curr_mname, mname); if( diff == 0 ) return i; } return -1; }
pvm_object_t pvm_get_class( pvm_object_t o ) { if( pvm_is_null(o)) return o; return o.data->_class; }
struct pvm_object pvm_create_interface_object( int n_methods, struct pvm_object parent_class ) { struct pvm_object ret = create_interface_worker( n_methods ); struct pvm_object * data_area = (struct pvm_object *)ret.data->da; if(pvm_is_null( parent_class )) pvm_exec_panic( "create interface: parent is null" ); struct pvm_object_storage *base_i = ((struct data_area_4_class*)parent_class.data->da)->object_default_interface.data; int base_icount = da_po_limit(base_i); if(base_icount > n_methods) { // root classes have N_SYS_METHODS slots in interface, don't cry about that if( n_methods > N_SYS_METHODS ) printf( " create interface: child has less methods (%d) than parent (%d)\n", n_methods, base_icount ); base_icount = n_methods; } int i = 0; // copy methods from parent for( ; i < base_icount; i++ ) { pvm_object_t baseMethod = (da_po_ptr(base_i->da))[i]; ref_inc_o(baseMethod); data_area[i] = baseMethod; } // fill others with nulls for( ; i < n_methods; i++ ) data_area[i] = pvm_get_null_object(); // null return ret; }
int pvm_get_field_name_count( pvm_object_t tclass ) { struct data_area_4_class *cda= pvm_object_da( tclass, class ); pvm_object_t fnames = cda->field_names; if( pvm_is_null(fnames)) return 0; return get_array_size( fnames.data ); }
// TODO need semaphores here void pvm_set_array_ofield(struct pvm_object_storage *o, unsigned int slot, struct pvm_object value ) { verify_p(o); verify_o(value); if( !(PHANTOM_OBJECT_STORAGE_FLAG_IS_INTERNAL & (o->_flags) ) || !( PHANTOM_OBJECT_STORAGE_FLAG_IS_RESIZEABLE & (o->_flags) ) ) pvm_exec_panic( "attempt to do an array op to non-array" ); if( PHANTOM_OBJECT_STORAGE_FLAG_IS_IMMUTABLE & (o->_flags) ) pvm_exec_panic( "attempt to set_array_ofield for immutable" ); struct data_area_4_array *da = (struct data_area_4_array *)&(o->da); // need resize? if( pvm_is_null(da->page) || slot >= da->page_size ) { const int step = 1024; int new_page_size = slot < (step/2) ? (slot * 2) : (slot+step); if(new_page_size < 16) new_page_size = 16; if( (!pvm_is_null(da->page)) && da->page_size > 0 ) //da->page = pvm_object_storage::create_page( new_page_size, da->page.data()->da_po_ptr(), da->page_size ); da->page = pvm_create_page_object( new_page_size, (void *)&(da->page.data->da), da->page_size ); else da->page = pvm_create_page_object( new_page_size, 0, 0 ); da->page_size = new_page_size; } if( slot >= da->used_slots ) { // set to null all new slots except for indexed //for( int i = da->used_slots; i < index; i++ ) //da->page.save(i, pvm_object()); da->used_slots = slot+1; } pvm_set_ofield( da->page, slot, value ); }
int pvm_object_class_exactly_is( struct pvm_object object, struct pvm_object tclass ) { struct pvm_object_storage *tested = object.data->_class.data; //struct pvm_object_storage *nullc = pvm_get_null_class().data; if( (!pvm_is_null( tclass )) && (tested == tclass.data) ) return 1; return 0; }
pvm_object_t pvm_get_field_name( pvm_object_t tclass, int ordinal ) { struct data_area_4_class *cda= pvm_object_da( tclass, class ); pvm_object_t fnames = cda->field_names; if( pvm_is_null(fnames)) return pvm_get_null_object(); pvm_object_t name = pvm_get_ofield( fnames, ordinal ); return name; }
pvm_object_t pvm_get_method_name( pvm_object_t tclass, int method_ordinal ) { struct data_area_4_class *cda= pvm_object_da( tclass, class ); pvm_object_t mnames = cda->method_names; if( pvm_is_null(mnames)) return pvm_get_null_object(); pvm_object_t name = pvm_get_ofield( mnames, method_ordinal ); return name; }
void pvm_backtrace(struct data_area_4_thread *tda) { struct pvm_code_handler *code = &tda->code; if(code->IP > code->IP_max) { printf("pvm_backtrace IP > IP_Max!\n"); return; } printf("pvm_backtrace thread IP %d\n", code->IP); printf("pvm_backtrace thread this:\n"); pvm_object_dump(tda->_this_object); printf("\n\n"); pvm_object_t sframe = tda->call_frame; while( !pvm_is_null(sframe) ) { //if( !pvm_object_class_is(sframe, pvm_get_stack_frame_class()) ) ??! struct data_area_4_call_frame *fda = pvm_object_da(sframe,call_frame); printf("pvm_backtrace frame:\n"); pvm_object_dump(sframe); printf("\n"); printf("pvm_backtrace frame this:\n"); pvm_object_t thiso = fda->this_object; pvm_object_dump(thiso); printf("\n"); printf("pvm_backtrace frame IP: %d\n", fda->IP); pvm_object_t tclass = thiso.data->_class; int ord = fda->ordinal; int lineno = pvm_ip_to_linenum(tclass, ord, fda->IP); if( lineno >= 0 ) { pvm_object_t mname = pvm_get_method_name( tclass, ord ); pvm_object_print(mname); printf(":%d\n", lineno); } printf("\n\n"); sframe = fda->prev; } }
// Really need this? int pvm_object_class_is_or_parent( struct pvm_object object, struct pvm_object tclass ) { struct pvm_object_storage *tested = object.data->_class.data; struct pvm_object_storage *nullc = pvm_get_null_class().data; while( !pvm_is_null( tclass ) ) { if( tested == tclass.data ) return 1; if( tclass.data == nullc ) break; tclass = pvm_object_da( tclass, class )->class_parent; } return 0; }
int pvm_object_class_is_or_child( struct pvm_object object, struct pvm_object tclass ) { struct pvm_object oclass = object.data->_class; //struct pvm_object_storage *tested = object.data->_class.data; struct pvm_object_storage *nullc = pvm_get_null_class().data; if( pvm_is_null( tclass ) ) return 0; while(1) { if( oclass.data == tclass.data ) return 1; if( oclass.data == nullc ) break; oclass = pvm_object_da( oclass, class )->class_parent; } return 0; }
errno_t jit_compile_method(struct pvm_code_handler *code) { struct jit_out jo; struct jit_out *j = &jo; //struct data_area_4_thread *da = (struct data_area_4_thread *)&(current_thread.data->da); // TODO: check for current_thread to be thread for real // JITted code supposed to be called with da in BX //jit_gen_push( j, JIT_R_BX ); //jit_gen_call( j, JIT_F_LOAD_F_ACC ); //pvm_exec_load_fast_acc(da); // For any case { #warning resleep? // Thread was snapped sleeping - resleep it //if(da->sleep_flag) phantom_thread_sleep_worker( da ); /* jit_load_thread_field( j, offsetof(da->sleep_flag) ); // to AX, gen flags jit_label jl = jit_get_label( j ); jit_jz( jl ); jit_gen_push( j, JIT_R_BX ); jit_gen_call( j, JIT_F_THREAD_SLEEP_WORKER ); jit_mark_label( j, jl ); */ } while(1) { /* if(phantom_virtual_machine_snap_request) { pvm_exec_save_fast_acc(da); // Before snap phantom_thread_wait_4_snap(); //pvm_exec_load_fast_acc(da); // We don't need this, if we die, we will enter again from above :) } */ { jit_check_snap_request( j ); /* jit_label jl = jit_get_label( j ); jit_jz( jl ); //jit_gen_push( j, JIT_R_BX ); jit_gen_call( j, JIT_F_WAIT_SNAP ); jit_mark_label( j, jl ); */ } jit_mark_possible_label(j); unsigned char instruction = pvm_code_get_byte(code); //printf("instr 0x%02X ", instruction); switch(instruction) { case opcode_nop: //if( debug_print_instr ) printf("nop; "); break; case opcode_debug: { int type = pvm_code_get_byte(code); //cf->cs.get_instr( cf->IP ); //printf("\n\nDebug 0x%02X", type ); if( type & 0x80 ) { //printf(" (" ); pvm_object_t o = pvm_code_get_string(code); //pvm_object_print(o); ref_dec_o(o); //printf(")" ); } if( type & 0x01 ) debug_print_instr = 1; if( type & 0x02 ) debug_print_instr = 0; /* if( is_empty() ) printf(", istack empty"); else printf(",\n\tistack top = %d", is_top() ); if( os_empty() ) printf(", ostack empty"); else { printf(",\n\tostack top = {" ); pvm_object_print( os_top() ); printf("}" ); } printf(";\n\n"); */ } break; // int stack ops --------------------------------------- case opcode_is_dup: if( debug_print_instr ) printf("is dup; "); jit_is_push( j, jit_is_top( j ) ); break; case opcode_is_drop: if( debug_print_instr ) printf("is drop; "); jit_is_pop( j ); break; case opcode_iconst_0: if( debug_print_instr ) printf("iconst 0; "); jit_is_push( j, jit_iconst( j, 0 ) ); break; case opcode_iconst_1: if( debug_print_instr ) printf("iconst 1; "); jit_is_push( j, jit_iconst( j, 1 ) ); break; case opcode_iconst_8bit: { int v = pvm_code_get_byte(code); jit_is_push( j, jit_iconst( j, v ) ); if( debug_print_instr ) printf("iconst8 = %d; ", v); break; } case opcode_iconst_32bit: { int v = pvm_code_get_int32(code); jit_is_push( j, jit_iconst( j, v ) ); if( debug_print_instr ) printf("iconst32 = %d; ", v); break; } case opcode_isum: if( debug_print_instr ) printf("isum; "); jit_binary_op( j, jit_gen_add ); break; case opcode_imul: if( debug_print_instr ) printf("imul; "); { //int mul = is_pop(); //is_push( is_pop() * mul ); jit_binary_op( j, jit_gen_mul ); } break; case opcode_isubul: if( debug_print_instr ) printf("isubul; "); { jit_value_t u = jit_is_pop( j ); jit_value_t l = jit_is_pop( j ); jit_value_t r = jit_gen_sub( j, u, l ); jit_is_push( j, r ); } break; case opcode_isublu: if( debug_print_instr ) printf("isublu; "); { jit_value_t u = jit_is_pop( j ); jit_value_t l = jit_is_pop( j ); jit_value_t r = jit_gen_sub( j, l, u ); jit_is_push( j, r ); } break; case opcode_idivul: if( debug_print_instr ) printf("idivul; "); { jit_value_t u = jit_is_pop( j ); jit_value_t l = jit_is_pop( j ); jit_value_t r = jit_gen_div( j, u, l ); jit_is_push( j, r ); } break; case opcode_idivlu: if( debug_print_instr ) printf("idivlu; "); { jit_value_t u = jit_is_pop( j ); jit_value_t l = jit_is_pop( j ); jit_value_t r = jit_gen_div( j, l, u ); jit_is_push( j, r ); } break; case opcode_ior: if( debug_print_instr ) printf("ior; "); //{ int operand = is_pop(); is_push( is_pop() | operand ); } jit_binary_op( j, jit_gen_binor ); break; case opcode_iand: if( debug_print_instr ) printf("iand; "); //{ int operand = is_pop(); is_push( is_pop() & operand ); } jit_binary_op( j, jit_gen_binand ); break; case opcode_ixor: if( debug_print_instr ) printf("ixor; "); //{ int operand = is_pop(); is_push( is_pop() ^ operand ); } jit_binary_op( j, jit_gen_binxor ); break; case opcode_inot: if( debug_print_instr ) printf("inot; "); jit_unary_op( j, jit_gen_binnot ); break; case opcode_log_or: if( debug_print_instr ) printf("lor; "); jit_binary_op( j, jit_gen_logor ); break; case opcode_log_and: if( debug_print_instr ) printf("land; "); jit_binary_op( j, jit_gen_logand ); break; case opcode_log_xor: if( debug_print_instr ) printf("lxor; "); jit_binary_op( j, jit_gen_logxor ); break; case opcode_log_not: if( debug_print_instr ) printf("lnot; "); jit_unary_op( j, jit_gen_lognot ); break; case opcode_ige: // >= if( debug_print_instr ) printf("ige; "); jit_binary_op( j, jit_gen_ige ); break; case opcode_ile: // <= if( debug_print_instr ) printf("ile; "); jit_binary_op( j, jit_gen_ile ); break; case opcode_igt: // > if( debug_print_instr ) printf("igt; "); jit_binary_op( j, jit_gen_igt ); break; case opcode_ilt: // < if( debug_print_instr ) printf("ilt; "); jit_binary_op( j, jit_gen_ilt ); break; case opcode_i2o: if( debug_print_instr ) printf("i2o; "); jit_push_arg( j, jit_is_pop( j ) ); jit_os_push( j, jit_gen_call( j, JIT_F_CREATE_INT_OBJ ) ); break; case opcode_o2i: if( debug_print_instr ) printf("o2i; "); { jit_is_push( j, jit_o2int( j, jit_os_pop( j ) ) );// push AX //jit_refdec( j ); // TODO jit_o2int must refdec? } break; case opcode_os_eq: if( debug_print_instr ) printf("os eq; "); { jit_value_t v1 = jit_os_pop( j ); jit_value_t v2 = jit_os_pop( j ); jit_is_push( j, jit_gen_cmp( j, v1, v2 ) ); jit_refdec( j, v1 ); jit_refdec( j, v2 ); break; } case opcode_os_neq: if( debug_print_instr ) printf("os neq; "); { jit_value_t v1 = jit_os_pop( j ); jit_value_t v2 = jit_os_pop( j ); jit_is_push( j, jit_gen_lognot( j, jit_gen_cmp( j, v1, v2 )) ); jit_refdec( j, v1 ); jit_refdec( j, v2 ); break; } case opcode_os_isnull: if( debug_print_instr ) printf("isnull; "); { jit_value_t o1 = jit_os_pop( j ); jit_is_push( j, jit_is_null( j, o1 ) ); jit_refdec( j, o1 ); break; } case opcode_os_push_null: case opcode_summon_null: if( debug_print_instr ) printf("push null; "); { jit_os_push( j, jit_get_null( j ) ); break; } // summoning, special ---------------------------------------------------- case opcode_summon_thread: if( debug_print_instr ) printf("summon thread; "); jit_os_push( j, jit_get_thread( j ) ); break; case opcode_summon_this: if( debug_print_instr ) printf("summon this; "); jit_os_push( j, jit_refinc( j, jit_get_this( j ) ) ); break; case opcode_summon_class_class: if( debug_print_instr ) printf("summon class class; "); jit_os_push( j, jit_get_class_class( j ) ); break; case opcode_summon_interface_class: if( debug_print_instr ) printf("summon interface class; "); // locked refcnt jit_os_push( j, jit_get_iface_class( j ) ); break; case opcode_summon_code_class: if( debug_print_instr ) printf("summon code class; "); // locked refcnt jit_os_push( j, jit_get_code_class( j ) ); break; case opcode_summon_int_class: if( debug_print_instr ) printf("summon int class; "); // locked refcnt jit_os_push( j, jit_get_int_class( j ) ); break; case opcode_summon_string_class: if( debug_print_instr ) printf("summon string class; "); // locked refcnt jit_os_push( j, jit_get_string_class( j ) ); break; case opcode_summon_array_class: if( debug_print_instr ) printf("summon array class; "); // locked refcnt jit_os_push( j, jit_get_array_class( j ) ); break; // TODO we can turn class to const, but the we have to keep refcount for it in // const space and release when we release compiled code // TODO const list is just an array? easy to release all case opcode_summon_by_name: { if( debug_print_instr ) printf("summon by name; "); struct pvm_object name = pvm_code_get_string(code); struct pvm_object cl = pvm_exec_lookup_class_by_name( name ); // TODO XXX must inc ref ref_dec_o(name); // Need throw here? if( pvm_is_null( cl ) ) { printf("JIT: summon by name: null class\n"); return ENOENT; // TODO XXX generate summon in run time? } int cid = jit_alloc_const( j, cl ); jit_os_push( j, jit_get_const( j, cid ) ); } break; /** * A BIG NOTE for object creation * * We must be SURE that it is NOT ever possible to pass * non-internal object as init data to internal and vice versa! * It would be a securily hole! * **/ case opcode_new: if( debug_print_instr ) printf("new; "); { //pvm_object_t cl = os_pop(); //os_push( pvm_create_object( cl ) ); //ref_dec_o( cl ); // object keep class ref jit_os_pop( j );// pop AX, DX jit_os_push( j, jit_gen_call( j, JIT_F_CREATE_OBJ ) );// push AX, DX } break; case opcode_copy: if( debug_print_instr ) printf("copy; "); { jit_push_arg( j, jit_os_pop( j ) ); jit_os_push( j, jit_gen_call( j, JIT_F_COPY_OBJ ) ); // jit_refdec( j, JIT_R_CX ); XXX TODO need? } break; // if you want to enable these, work out refcount // and security issues first! // compose/decompose #if 0 case opcode_os_compose32: if( debug_print_instr ) printf(" compose32; "); { int num = pvm_code_get_int32(code); struct pvm_object in_class = os_pop(); os_push( pvm_exec_compose_object( in_class, da->_ostack, num ) ); } break; case opcode_os_decompose: if( debug_print_instr ) printf(" decompose; "); { struct pvm_object to_decomp = os_pop(); int num = da_po_limit(to_decomp.data); is_push( num ); while( num ) { num--; struct pvm_object o = pvm_get_ofield( to_decomp, num); os_push( ref_inc_o( o ) ); } os_push(to_decomp.data->_class); } break; #endif // string ---------------------------------------------------------------- case opcode_sconst_bin: if( debug_print_instr ) printf("sconst bin; "); //os_push(pvm_code_get_string(code)); { int constid = jit_alloc_const( j, pvm_code_get_string( code ) ); jit_os_push( j, jit_get_const( j, constid ) ); } break; // flow ------------------------------------------------------------------ case opcode_jmp: { int newip = pvm_code_get_rel_IP_as_abs(code); if( debug_print_instr ) printf("jmp %d; ", newip ); //da->code.IP = pvm_code_get_rel_IP_as_abs(code); jit_jump( j, newip ); } break; case opcode_djnz: { if( debug_print_instr ) printf("djnz " ); int newip = pvm_code_get_rel_IP_as_abs(code); //is_push( is_pop() - 1 ); jit_decrement( j, jit_is_top(j) ); jit_jnz( j, newip, jit_is_top(j) ); //if( debug_print_instr ) printf("(%d) -> %d; ", is_top() , new_IP ); } break; case opcode_jz: { if( debug_print_instr ) printf("jz " ); int newip = pvm_code_get_rel_IP_as_abs(code); jit_jz( j, newip, jit_is_pop(j) ); } break; case opcode_switch: { #warning impl /* if( debug_print_instr ) printf("switch "); unsigned int tabsize = pvm_code_get_int32(code); int shift = pvm_code_get_int32(code); unsigned int divisor = pvm_code_get_int32(code); int stack_top = is_pop(); if( debug_print_instr ) printf("(%d+%d)/%d, ", stack_top, shift, divisor ); unsigned int start_table_IP = da->code.IP; unsigned int displ = (stack_top+shift)/divisor; unsigned int new_IP = start_table_IP+(tabsize*4); // default if( debug_print_instr ) printf("displ %d, etab addr %d ", displ, new_IP ); if( displ < tabsize ) { da->code.IP = start_table_IP+(displ*4); // BUG! 4! if( debug_print_instr ) printf("load from %d, ", da->code.IP ); new_IP = pvm_code_get_rel_IP_as_abs(code); } da->code.IP = new_IP; if( debug_print_instr ) printf("switch(%d) ->%d; ", displ, new_IP ); */ printf("no switch yet"); return ENXIO; } break; case opcode_ret: { if( debug_print_instr ) printf( "\nret\n" ); jit_ret(j); } break; // exceptions are like ret --------------------------------------------------- case opcode_throw: if( debug_print_instr ) printf( "\nthrow\n" ); jit_throw(j, jit_os_pop(j) ); break; case opcode_push_catcher: { unsigned addr = pvm_code_get_rel_IP_as_abs(code); if( debug_print_instr ) printf("push catcher %u; ", addr ); jit_es_push( j, jit_os_pop(j), addr ); } break; case opcode_pop_catcher: if( debug_print_instr ) printf("pop catcher; "); jit_refdec( j, jit_es_pop(j) ); break; // ok, now method calls ------------------------------------------------------ // these 4 are parameter-less calls! case opcode_short_call_0: jit_os_push( j, jit_call_method( j, 0, 0, 1) ); break; case opcode_short_call_1: jit_os_push( j, jit_call_method( j, 1, 0, 1) ); break; case opcode_short_call_2: jit_os_push( j, jit_call_method( j, 2, 0, 1) ); break; case opcode_short_call_3: jit_os_push( j, jit_call_method( j, 3, 0, 1) ); break; case opcode_call_8bit: { unsigned int method_index = pvm_code_get_byte(code); unsigned int n_param = pvm_code_get_int32(code); jit_os_push( j, jit_call_method( j, method_index, n_param, 1) ); // optimization for soon return } break; case opcode_call_32bit: { unsigned int method_index = pvm_code_get_int32(code); unsigned int n_param = pvm_code_get_int32(code); jit_os_push( j, jit_call_method( j, method_index, n_param, 1) ); // optimization for soon return } break; // object stack -------------------------------------------------------------- case opcode_os_dup: if( debug_print_instr ) printf("os dup; "); jit_os_push( j, jit_refinc( j, jit_os_top( j ) ) ); break; case opcode_os_drop: if( debug_print_instr ) printf("os drop; "); jit_refdec( j, jit_os_pop( j ) ); break; case opcode_os_pull32: if( debug_print_instr ) printf("os pull; "); { int pos = pvm_code_get_int32(code); jit_os_push( j, jit_refinc( j, jit_os_pull( j, pos ) ) ); // TODO XXX load must refinc! } break; case opcode_os_load8: { int slot = pvm_code_get_byte(code); jit_os_push( j, jit_os_load( j, slot ) ); // TODO XXX load must refinc! } break; case opcode_os_load32: { int slot = pvm_code_get_int32(code); jit_os_push( j, jit_os_load( j, slot ) ); // TODO XXX load must refinc! break; } case opcode_os_save8: { int slot = pvm_code_get_byte(code); jit_os_save( j, slot, jit_os_pop( j ) ); } break; case opcode_os_save32: { int slot = pvm_code_get_int32(code); jit_os_save( j, slot, jit_os_pop( j ) ); } break; case opcode_is_load8: //pvm_exec_iload(da, pvm_code_get_byte(code)); { int slot = pvm_code_get_byte(code); jit_value_t ov = jit_os_load( j, slot ); jit_value_t iv = jit_o2int( j, ov ); // TODO XXX jit_o2int must gen refdec jit_is_push( j, iv ); } break; case opcode_is_save8: { int slot = pvm_code_get_byte(code); jit_push_arg( j, jit_is_pop( j ) ); // TODO arg is int? // pvm_create_int_object jit_os_save( j, slot, jit_gen_call( j, JIT_F_CREATE_INT_OBJ ) ); } break; case opcode_os_get32: { int pos = pvm_code_get_int32(code); jit_value_t v = jit_os_absget( j, pos ); // AX, DX = obj //jit_refinc( j, v ); // TODO XXX must not be needed - absget must inc! jit_os_push( j, v ); } break; case opcode_os_set32: { int pos = pvm_code_get_int32(code); jit_os_absset( j, pos, jit_os_pop( j ) ); } break; case opcode_is_get32: { int pos = pvm_code_get_int32(code); jit_is_push( j, jit_is_absget( j, pos ) ); } break; case opcode_is_set32: { int pos = pvm_code_get_int32(code); jit_is_absset( j, pos, jit_is_pop( j ) ); } break; default: if( (instruction & 0xF0 ) == opcode_sys_0 ) { jit_sys( j, instruction & 0x0F); /* sys_sleep: // Only sys can put thread asleep // If we are snapped here we, possibly, will continue from // the entry to this func. So save fasc acc and recheck // sleep condition on the func entry. if(da->sleep_flag) { pvm_exec_save_fast_acc(da); // Before snap phantom_thread_sleep_worker( da ); } break; */ } if( instruction == opcode_sys_8bit ) { jit_sys( j, pvm_code_get_byte(code)); //goto sys_sleep; break; } if( (instruction & 0xE0 ) == opcode_call_00 ) { unsigned int n_param = pvm_code_get_byte(code); jit_os_push( j, jit_call_method( j, instruction & 0x1F, n_param, 0) ); //no optimization for soon return break; } printf("JIT: Unknown op code 0x%X\n", instruction ); return ENOENT; } } }