コード例 #1
0
//This is an inefficient implementation. It would be faster to sort according
//to COMPARE_FUNC and then do an O(n) merge.
overlapSet *os_intersect(overlapSet *os1, overlapSet *os2, COMPARE_FUNC f) {
    overlapSet *os = os_init(os1->tree);
    int i, j;

    for(i=0; i<os1->l; i++) {
        for(j=0; j<os2->l; j++) {
            if(f(os1->overlaps[i],os2->overlaps[j]) == 0) {
                os_push(os, os1->overlaps[i]);
                os_exclude(os2, j);
                break;
            }
        }
    }

    return os;
}
コード例 #2
0
//This could be made much more efficient
overlapSet *osl_union(overlapSetList *osl) {
    int i, j;
    if(!osl->l) NULL;

    if(!osl->os) return NULL;
    if(!osl->os[0]) return NULL;
    overlapSet *os = os_dup(osl->os[0]);
    for(i=1; i<osl->l; i++) {
        for(j=0; j<osl->os[i]->l; j++) {
            if(!os_contains(os, osl->os[i]->overlaps[j])) {
                os_push(os, osl->os[i]->overlaps[j]);
            }
        }
    }
    return os;
}
コード例 #3
0
static void pushOverlaps(overlapSet *os, GTFtree *t, GTFentry *e, uint32_t start, uint32_t end, int comparisonType, int direction, FILTER_ENTRY_FUNC ffunc) {
    int dir;
    int keep = 1;
    if(!e) return;

    if(ffunc) keep = ffunc(t, e);

    switch(comparisonType) {
    case GTF_MATCH_EXACT :
        if((dir = rangeExact(start, end, e)) == 0) {
            if(keep) os_push(os, e);
        }
        break;
    case GTF_MATCH_WITHIN :
        if((dir = rangeAny(start, end, e)) == 0) {
            if(keep) if(rangeWithin(start, end ,e) == 0) os_push(os, e);
        }
        break;
    case GTF_MATCH_CONTAIN :
        if((dir = rangeAny(start, end, e)) == 0) {
            if(keep) if(rangeContains(start, end, e) == 0) os_push(os, e);
        }
        break;
    case GTF_MATCH_START :
        if((dir = rangeStart(start, end, e)) == 0) {
            if(keep) os_push(os, e);
        }
        break;
    case GTF_MATCH_END :
        if((dir = rangeEnd(start, end, e)) == 0) {
            if(keep) os_push(os, e);
        }
        break;
    default :
        if((dir = rangeAny(start, end, e)) == 0) {
            if(keep) os_push(os, e);
        }
        break;
    }

    if(direction) {
        if(dir > 0) return;
        pushOverlaps(os, t, e->right, start, end, comparisonType, direction, ffunc);
    } else {
        if(dir < 0) return;
        pushOverlaps(os, t, e->left, start, end, comparisonType, direction, ffunc);
    }
}
コード例 #4
0
ファイル: jit.c プロジェクト: NoSuchProcess/phantomuserland
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;
        }
    }
}
コード例 #5
0
overlapSet *os_dup(overlapSet *os) {
    int i;
    overlapSet *os2 = os_init(os->tree);
    for(i=0; i<os->l; i++) os_push(os2, os->overlaps[i]);
    return os2;
}