Ticket #1105: alloca_optional.patch

File alloca_optional.patch, 17.9 KB (added by plobsing, 12 years ago)
  • src/pmc/nci.pmc

     
    6363                param_sig[j++] = 'P'; 
    6464            case (INTVAL)'v': 
    6565                break; 
    66                 /* I have no idea how to handle these */ 
    6766            case (INTVAL)'2': 
    6867            case (INTVAL)'3': 
    6968            case (INTVAL)'4': 
    70                 param_sig[j++] = 'I'; 
     69                param_sig[j++] = 'P'; 
    7170                break; 
    7271            case (INTVAL)'@': 
    7372                param_sig[j++] = '@'; 
  • config/auto/libjit.pm

     
    9494    if ($has_libjit) { 
    9595        $conf->data->set( 
    9696            cc_build_call_frames => '-DCAN_BUILD_CALL_FRAMES', 
    97             has_exec_protect => 1, 
     97            has_exec_protect     => 1, 
     98            libjit_has_alloca    => ($conf->data->get('cpuarch') eq 'i386' ? '1' : '0'), 
    9899        ); 
    99100        $conf->data->add( ' ', libs => $extra_libs ); 
    100101    } 
  • config/gen/libjit.pm

     
    6161 
    6262            Parrot_init_arg_nci => [ qw(void_ptr void_ptr void_ptr) => 'void_ptr' ], 
    6363            pmc_new_noinit      => [ qw(void_ptr INTVAL)            => 'void_ptr' ], 
     64 
     65            mem_sys_allocate => [ ('long')     => 'void_ptr' ], 
     66            mem_sys_free     => [ ('void_ptr') => 'void' ], 
    6467        }, 
    6568    ); 
    6669    return \%data; 
  • config/gen/libjit/frame_builder_libjit_c.in

     
    112112Parrot_jit_create_thunk(PARROT_INTERP, char *sig, void *priv) { 
    113113    struct jit_buffer_private_data *p; 
    114114    jit_function_t f; 
    115     jit_value_t jit_interp, jit_func; 
    116     jit_type_t *jit_args_t; 
    117     jit_value_t *jit_args_v, *jit_regs; 
     115    jit_value_t jit_interp, jit_nci_pmc, jit_pcc_sig; 
     116    jit_value_t jit_func, jit_st; 
    118117 
    119118    /* populate private data */ 
    120119    p      = (struct jit_buffer_private_data*)priv; 
     
    127126    /* start JIT function */ 
    128127    { 
    129128        jit_type_t arg_types[] = { 
    130             jit_type_void_ptr,  /* interp */ 
    131             jit_type_void_ptr   /* nci_info */ 
     129            jit_type_void_ptr, /* interp */ 
     130            jit_type_void_ptr, /* nci_pmc */ 
     131            jit_type_void_ptr  /* pcc_sig */ 
    132132        }; 
    133         jit_type_t f_sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void, arg_types, 2, 1); 
     133        jit_type_t f_sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void, arg_types, 3, 1); 
    134134        f                = jit_function_create(p->ctx, f_sig); 
    135135    } 
    136136 
    137137    /* get the incomming args */ 
    138     jit_interp = jit_value_get_param(f, 0); 
    139     jit_func   = jit__vtable_get_pointer(f, jit_interp, jit_value_get_param(f, 1)); 
     138    jit_interp  = jit_value_get_param(f, 0); 
     139    jit_nci_pmc = jit_value_get_param(f, 1); 
     140    jit_pcc_sig = jit_value_get_param(f, 2); 
    140141 
     142    /* get the wrapped function */ 
     143    jit_func   = jit__vtable_get_pointer(f, jit_interp, jit_nci_pmc); 
     144 
     145    /* allocate call_state */ 
     146    { 
     147        jit_value_t sizeof_call_state 
     148               = jit_value_create_nint_constant(f, jit_type_sys_int, sizeof (call_state)); 
     149        jit_st = JIT_ALLOCA(f, sizeof_call_state); 
     150    } 
     151 
     152    /* init pcc */ 
     153    jit__Parrot_init_arg_nci(f, jit_interp, jit_st, jit_pcc_sig); 
     154 
    141155    /* get the outgoing args */ 
    142156    { 
    143         jit_value_t st; 
    144         int nargs; 
     157        int nargs = strlen(sig) - 1; 
    145158 
    146         { 
    147             jit_value_t sizeof_call_state 
    148                 = jit_value_create_nint_constant(f, jit_type_sys_int, sizeof (call_state)); 
    149             st  = jit_insn_alloca(f, sizeof_call_state); 
    150         } 
     159        jit_type_t jit_args_t[nargs]; 
     160        jit_value_t jit_args_v[nargs]; 
     161        jit_value_t jit_regs[nargs]; 
    151162 
    152         nargs = Parrot_jit_parse_sig_args_pre(interp, sig, f, jit_interp, st, 
    153                                               &jit_args_t, &jit_args_v, &jit_regs); 
     163        Parrot_jit_parse_sig_args_pre(interp, sig, nargs, f, jit_interp, jit_st, 
     164                                      jit_args_t, jit_args_v, jit_regs); 
    154165 
    155166        /* get the return type */ 
    156167        { 
     
    167178            } 
    168179 
    169180            /* get the incomming return */ 
    170             Parrot_jit_parse_sig_ret_post(interp, sig, f, jit_interp, st, ret_v); 
     181            Parrot_jit_parse_sig_ret_post(interp, sig, f, jit_interp, jit_st, ret_v); 
    171182        } 
    172183 
    173184        /* clean up args */ 
    174185        Parrot_jit_parse_sig_args_post(interp, sig, nargs, f, jit_interp, jit_args_v, jit_regs); 
    175186    } 
    176187 
     188    /* deallocate call_state */ 
     189    JIT_ALLOCA_FREE(f, jit_st); 
     190 
    177191    /* end JIT function */ 
    178192    jit_insn_return(f, NULL); 
    179193 
     
    181195    jit_function_compile(f); 
    182196    jit_context_build_end(p->ctx); 
    183197 
    184     mem_sys_free(jit_args_t); 
    185     mem_sys_free(jit_args_v); 
    186     mem_sys_free(jit_regs); 
    187  
    188198    return jit_function_to_closure(f); 
    189199} 
    190200 
    191 int 
    192 Parrot_jit_parse_sig_args_pre(PARROT_INTERP, char *sig, jit_function_t f, 
    193                               jit_value_t jinterp, jit_value_t st, 
    194                               jit_type_t **arg_types, 
    195                               jit_value_t **arg_vals, jit_value_t **arg_regs) { 
    196     int nargs, nregs, i, j; 
     201void 
     202Parrot_jit_parse_sig_args_pre(PARROT_INTERP, char *sig, int nargs, 
     203                              jit_function_t f, jit_value_t jinterp, jit_value_t st, 
     204                              jit_type_t *arg_types, 
     205                              jit_value_t *arg_vals, jit_value_t *arg_regs) { 
     206    int i, j; 
    197207 
    198208    sig += 1; /* ignore return character */ 
    199209 
    200     nargs = strlen(sig); 
    201     nregs = Parrot_jit_init_pcc(sig, nargs, f, jinterp, st); 
    202  
    203     *arg_types = (jit_type_t *)mem_sys_allocate(nargs * sizeof (jit_type_t)); 
    204     *arg_vals  = (jit_value_t *)mem_sys_allocate(nargs * sizeof (jit_value_t)); 
    205     *arg_regs  = (jit_value_t *)mem_sys_allocate(nregs * sizeof (jit_value_t)); 
    206  
    207210    for (i = 0, j = 0; i < nargs; i++) { 
    208211        char c; 
    209212        jit_type_t t1; 
     
    212215          case 'I': 
    213216            t1 = JIT_TYPE_INTVAL; 
    214217          read_int_reg: 
    215             (*arg_types)[i]  = t1; 
    216             v1               = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
    217             v2               = jit__get_nci_I(f, jinterp, st, v1); 
    218             (*arg_regs)[j++] = (*arg_vals)[i] = v2; 
     218            arg_types[i]  = t1; 
     219            v1            = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
     220            v2            = jit__get_nci_I(f, jinterp, st, v1); 
     221            arg_regs[j++] = arg_vals[i] = v2; 
    219222            break; 
    220223          case 'c': 
    221224            t1 = jit_type_sys_char; 
     
    233236          case 'N': 
    234237            t1 = JIT_TYPE_FLOATVAL; 
    235238          read_float_reg: 
    236             (*arg_types)[i]  = t1; 
    237             v1               = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
    238             v2               = jit__get_nci_N(f, jinterp, st, v1); 
    239             (*arg_regs)[j++] = (*arg_vals)[i] = v2; 
     239            arg_types[i]  = t1;         
     240            v1            = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
     241            v2            = jit__get_nci_N(f, jinterp, st, v1); 
     242            arg_regs[j++] = arg_vals[i] = v2; 
    240243            break; 
    241244          case 'f': 
    242245            t1 = jit_type_sys_float; 
     
    246249            goto read_float_reg; 
    247250 
    248251          case 'S': 
    249             (*arg_types)[i]  = jit_type_void_ptr; 
    250             v1               = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
    251             v2               = jit__get_nci_S(f, jinterp, st, v1); 
    252             (*arg_regs)[j++] = (*arg_vals)[i] = v2; 
     252            arg_types[i]  = jit_type_void_ptr; 
     253            v1            = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
     254            v2            = jit__get_nci_S(f, jinterp, st, v1); 
     255            arg_regs[j++] = arg_vals[i] = v2; 
    253256            break; 
    254257 
    255258          case 't': 
    256             (*arg_types)[i]  = jit_type_void_ptr; 
    257             v1               = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
    258             v2               = jit__get_nci_S(f, jinterp, st, v1); 
    259             (*arg_regs)[j++] = v2; 
    260             (*arg_vals)[i]   = jit__Parrot_str_to_cstring(f, jinterp, v2); 
     259            arg_types[i]  = jit_type_void_ptr; 
     260            v1            = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
     261            v2            = jit__get_nci_S(f, jinterp, st, v1); 
     262            arg_regs[j++] = v2; 
     263            arg_vals[i]   = jit__Parrot_str_to_cstring(f, jinterp, v2); 
    261264            break; 
    262265 
    263266          case 'b': 
    264             (*arg_types)[i]  = jit_type_void_ptr; 
    265             v1               = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
    266             v2               = jit__get_nci_S(f, jinterp, st, v1); 
    267             (*arg_regs)[j++] = v2; 
    268             (*arg_vals)[i]   = jit__Buffer_bufstart(f, v2); 
     267            arg_types[i]  = jit_type_void_ptr; 
     268            v1            = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
     269            v2            = jit__get_nci_S(f, jinterp, st, v1); 
     270            arg_regs[j++] = v2; 
     271            arg_vals[i]   = jit__Buffer_bufstart(f, v2); 
    269272            break; 
    270273          case 'B': 
    271             (*arg_types)[i]  = jit_type_void_ptr; 
    272             v1               = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
    273             v2               = jit__get_nci_S(f, jinterp, st, v1); 
    274             (*arg_regs)[j++] = v2; 
    275             v3               = jit__Parrot_str_to_cstring(f, jinterp, v2); 
     274            arg_types[i]  = jit_type_void_ptr; 
     275            v1            = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
     276            v2            = jit__get_nci_S(f, jinterp, st, v1); 
     277            arg_regs[j++] = v2; 
     278            v3            = jit__Parrot_str_to_cstring(f, jinterp, v2); 
    276279            jit_value_set_addressable(v3); 
    277             (*arg_vals)[i]   = jit_insn_address_of(f, v3); 
     280            arg_vals[i]   = jit_insn_address_of(f, v3); 
    278281            break; 
    279282 
    280283          case 'p': 
    281             (*arg_types)[i]  = jit_type_void_ptr; 
    282             v1               = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
    283             v2               = jit__get_nci_p(f, jinterp, st, v1); 
    284             (*arg_regs)[j++] = (*arg_vals)[i] = v2; 
     284            arg_types[i]  = jit_type_void_ptr; 
     285            v1            = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
     286            v2            = jit__get_nci_p(f, jinterp, st, v1); 
     287            arg_regs[j++] = arg_vals[i] = v2; 
    285288            break; 
    286289          case 'P': 
    287290          case 'O': 
    288291          case '@': 
    289             (*arg_types)[i]  = jit_type_void_ptr; 
    290             v1               = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
    291             v2               = jit__get_nci_P(f, jinterp, st, v1); 
    292             (*arg_regs)[j++] = (*arg_vals)[i] = v2; 
     292            arg_types[i]  = jit_type_void_ptr; 
     293            v1            = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
     294            v2            = jit__get_nci_P(f, jinterp, st, v1); 
     295            arg_regs[j++] = arg_vals[i] = v2; 
    293296            break; 
    294297          case '2': 
    295298            t1 = jit_type_sys_short; 
     
    300303          case '4': 
    301304            t1 = jit_type_sys_long; 
    302305          call_get_integer: 
    303             (*arg_types)[i]  = jit_type_void_ptr; 
    304             v1               = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
    305             v2               = jit__get_nci_P(f, jinterp, st, v1); 
    306             (*arg_regs)[j++] = v2; 
    307             v3               = jit__vtable_get_integer(f, jinterp, v2); 
    308             v4               = jit_value_create(f, t1); 
     306            arg_types[i]  = jit_type_void_ptr; 
     307            v1            = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
     308            v2            = jit__get_nci_P(f, jinterp, st, v1); 
     309            arg_regs[j++] = v2; 
     310            v3            = jit__vtable_get_integer(f, jinterp, v2); 
     311            v4            = jit_value_create(f, t1); 
    309312            jit_value_set_addressable(v4); 
    310313            jit_insn_store(f, v4, v3); 
    311             (*arg_vals)[i]   = jit_insn_address_of(f, v4); 
     314            arg_vals[i]   = jit_insn_address_of(f, v4); 
    312315            break; 
    313316 
    314317          case 'V': 
    315             (*arg_types)[i]  = jit_type_void_ptr; 
    316             v1               = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
    317             v2               = jit__get_nci_P(f, jinterp, st, v1); 
    318             (*arg_regs)[j++] = v2; 
    319             v3               = jit__vtable_get_pointer(f, jinterp, v2); 
    320             v4               = jit_value_create(f, jit_type_void_ptr); 
     318            arg_types[i]  = jit_type_void_ptr; 
     319            v1            = jit_value_create_nint_constant(f, jit_type_sys_int, j); 
     320            v2            = jit__get_nci_P(f, jinterp, st, v1); 
     321            arg_regs[j++] = v2; 
     322            v3            = jit__vtable_get_pointer(f, jinterp, v2); 
     323            v4            = jit_value_create(f, jit_type_void_ptr); 
    321324            jit_value_set_addressable(v4); 
    322325            jit_insn_store(f, v4, v3); 
    323             (*arg_vals)[i]   = jit_insn_address_of(f, v4); 
     326            arg_vals[i]   = jit_insn_address_of(f, v4); 
    324327            break; 
    325328 
    326329          case '0': 
    327             (*arg_types)[i] = jit_type_void_ptr; 
    328             (*arg_vals)[i]  = jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL); 
     330            arg_types[i] = jit_type_void_ptr; 
     331            arg_vals[i]  = jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL); 
    329332            break; 
    330333 
    331334          case 'J': 
    332             (*arg_types)[i] = jit_type_void_ptr; 
    333             (*arg_vals)[i]  = jinterp; 
     335            arg_types[i] = jit_type_void_ptr; 
     336            arg_vals[i]  = jinterp; 
    334337            break; 
    335338 
    336339          case 'U': 
    337340            /* TODO */ 
    338341            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 
    339342                "arg type 'U' not yet implemented"); 
    340             return -1; 
     343            return; 
    341344 
    342345          default: 
    343346            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 
    344347                "unkown arg type '%c'", c); 
    345             return -1; 
     348            return; 
    346349        } 
    347350    } 
    348  
    349     return nargs; 
    350351} 
    351352 
    352 int 
    353 Parrot_jit_init_pcc(char *sig, int nargs, jit_function_t f, jit_value_t interp, jit_value_t st) { 
    354     int i, j; 
    355     char pcc_sig[nargs]; 
    356  
    357     for (i = 0, j = 0; i < nargs; i++) { 
    358         switch (sig[i]) { 
    359           case 'I': 
    360           case 'c': 
    361           case 's': 
    362           case 'i': 
    363           case 'l': 
    364             pcc_sig[j++] = 'I'; 
    365             break; 
    366  
    367           case 'N': 
    368           case 'f': 
    369           case 'd': 
    370             pcc_sig[j++] = 'N'; 
    371             break; 
    372  
    373           case 'S': 
    374           case 't': 
    375           case 'b': 
    376           case 'B': 
    377             pcc_sig[j++] = 'S'; 
    378             break; 
    379  
    380           case 'p': 
    381           case 'P': 
    382           case 'O': 
    383           case 'V': 
    384           case '2': 
    385           case '3': 
    386           case '4': 
    387             pcc_sig[j++] = 'P'; 
    388             break; 
    389  
    390           case '@': 
    391             pcc_sig[j++] = '@'; 
    392             break; 
    393  
    394           default: 
    395             break; 
    396         } 
    397     } 
    398     pcc_sig[j]  = '\0'; 
    399  
    400     jit__Parrot_init_arg_nci(f, interp, st, 
    401                              jit_value_create_string_constant(f, pcc_sig, j+1)); 
    402  
    403     return j; 
    404 } 
    405  
    406353jit_type_t 
    407354Parrot_jit_parse_sig_ret_pre(PARROT_INTERP, char *sig) { 
    408355    char c; 
     
    591538    return jit_value_create_nint_constant(f, JIT_TYPE_INTVAL, i); 
    592539} 
    593540 
    594 jit_value_t 
    595 jit_value_create_string_constant(jit_function_t f, char *str, int len) { 
    596     jit_value_t jit_len, jit_str; 
    597     int i; 
    598  
    599     if (len < 1) { 
    600         len = strlen(str); 
    601     } 
    602  
    603     jit_len = jit_value_create_nint_constant(f, jit_type_sys_int, len); 
    604     jit_str = jit_insn_alloca(f, jit_len); 
    605  
    606     for (i = 0; i < len; i++) { 
    607         jit_value_t c = jit_value_create_nint_constant(f, jit_type_sys_char, str[i]); 
    608         jit_insn_store_relative(f, jit_str, i, c); 
    609     } 
    610  
    611     return jit_str; 
    612 } 
    613  
    614541/* 
    615542 * JIT wrappers 
    616543 */ 
  • config/gen/libjit/frame_builder_libjit_h.in

     
    3333 * JIT types 
    3434 */ 
    3535 
    36 #define JIT_TYPE_UINTVAL  @libjit_uv@ // jit_type_sys_ulong 
    37 #define JIT_TYPE_INTVAL   @libjit_iv@ // jit_type_sys_long 
    38 #define JIT_TYPE_FLOATVAL @libjit_nv@ // jit_type_sys_double 
     36#define JIT_TYPE_UINTVAL  @libjit_uv@ 
     37#define JIT_TYPE_INTVAL   @libjit_iv@ 
     38#define JIT_TYPE_FLOATVAL @libjit_nv@ 
    3939 
    4040/* 
    4141 * JIT functions 
     
    4444void * 
    4545Parrot_jit_create_thunk(Interp *, char *, void *); 
    4646 
    47 int 
    48 Parrot_jit_parse_sig_args_pre(Interp *, char *, jit_function_t, jit_value_t, jit_value_t, 
    49                               jit_type_t **, jit_value_t **, jit_value_t **); 
     47void 
     48Parrot_jit_parse_sig_args_pre(Interp *, char *, int, jit_function_t, jit_value_t, jit_value_t, 
     49                              jit_type_t *, jit_value_t *, jit_value_t *); 
    5050 
    51 int 
    52 Parrot_jit_init_pcc(char *, int, jit_function_t, jit_value_t, jit_value_t); 
    53  
    5451jit_type_t 
    5552Parrot_jit_parse_sig_ret_pre(Interp *, char *); 
    5653 
     
    6360jit_value_t 
    6461jit_value_create_intval_constant(jit_function_t, INTVAL); 
    6562 
    66 jit_value_t 
    67 jit_value_create_string_constant(jit_function_t, char *, int); 
     63/* 
     64 * workaround for platforms that lack libjit alloca support 
     65 */ 
     66#if @libjit_has_alloca@ 
     67#  define JIT_ALLOCA(f, n)      jit_insn_alloca(f, n) 
     68#  define JIT_ALLOCA_FREE(f, p) 
     69#else 
     70#  define JIT_ALLOCA(f, n)      jit__mem_sys_allocate(f, n) 
     71#  define JIT_ALLOCA_FREE(f, p) jit__mem_sys_free(f, p) 
     72#endif 
    6873 
    6974/* 
    7075 * JIT wrappers