Example #1
0
// 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;
}
Example #2
0
pvm_object_t pvm_get_class( pvm_object_t o )
{
    if( pvm_is_null(o))
        return o;

    return o.data->_class;
}
Example #3
0
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;
}
Example #4
0
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 );
}
Example #5
0
// 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 );
}
Example #6
0
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;
}
Example #7
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;
}
Example #8
0
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;
}
Example #9
0
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;
    }

}
Example #10
0
// 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;
}
Example #11
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;
}
Example #12
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;
        }
    }
}