Ticket #1105: merge_complete_tweaked.patch

File merge_complete_tweaked.patch, 161.0 KB (added by plobsing, 12 years ago)

slightly modified merge patch (now with 100% less FAIL!)

  • DEPRECATED.pod

     
    7474 
    7575L<https://trac.parrot.org/parrot/ticket/918> 
    7676 
     77=item Use of 'v' in NCI parameter lists [eligible in 2.1] 
     78 
     79An empty parameter list suffices to indicate no parameters to an NCI call. 
     80This has been marked as deprecated in PDD16 for 2 years. 
     81 
     82F<pdds/draft/pdd16_native_call.pod> 
     83 
    7784=back 
    7885 
    7986=head1 Opcodes 
  • src/ops/core.ops

     
    13221322    else { 
    13231323        $1 = pmc_new(interp, enum_class_NCI); 
    13241324        VTABLE_set_pointer_keyed_str(interp, $1, $4, F2DPTR(p)); 
    1325         PObj_get_FLAGS($1) |= PObj_private1_FLAG; 
    13261325    } 
    13271326    Parrot_str_free_cstring(name); 
    13281327} 
  • src/pmc/nci.pmc

     
    1818 
    1919*/ 
    2020 
     21#include "parrot/nci.h" 
     22 
    2123typedef INTVAL (*nci_sub_t)(PARROT_INTERP, PMC *); 
    22 typedef INTVAL (*nci_jit_sub_t)(PARROT_INTERP, PMC *, char *); 
     24typedef nci_sub_t nci_jit_sub_t; 
    2325 
    24 void pcc_params(PARROT_INTERP, STRING *sig, Parrot_NCI_attributes * const nci_info, 
    25                 size_t sig_length); 
    26 void pcc_params(PARROT_INTERP, STRING *sig, Parrot_NCI_attributes * const nci_info, 
    27                 size_t sig_length) { 
    28     char    param_buf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 
    29     char   *param_sig    = sig_length <= 7 
    30                          ? param_buf 
    31                          : mem_allocate_n_typed(sig_length, char); 
    32     size_t  j            = 0; 
    33     size_t  i; 
     26#define NCI_raw_FLAG    PObj_private0_FLAG 
    3427 
    35     for (i = 1; i < sig_length; i++) { 
     28STRING *pcc_sig_params(PARROT_INTERP, STRING *sig); 
     29STRING *pcc_sig_params(PARROT_INTERP, STRING *sig) { 
     30    size_t sig_len = Parrot_str_byte_length(interp, sig); 
     31    char param_buf[sig_len*2]; 
     32 
     33    size_t i, j; 
     34 
     35    for (i = 1, j = 0; i < sig_len; i++) { 
    3636        INTVAL c = Parrot_str_indexed(interp, sig, i); 
    37  
    38         switch (c) { 
    39             case (INTVAL)'0':    /* null ptr or such - doesn't consume a reg */ 
    40                 break; 
    41             case (INTVAL)'f': 
    42             case (INTVAL)'N': 
    43             case (INTVAL)'d': 
    44                 param_sig[j++] = 'N'; 
    45                 break; 
    46             case (INTVAL)'I':   /* INTVAL */ 
    47             case (INTVAL)'l':   /* long */ 
    48             case (INTVAL)'i':   /* int */ 
    49             case (INTVAL)'s':   /* short */ 
    50             case (INTVAL)'c':   /* char */ 
    51                 param_sig[j++] = 'I'; 
    52                 break; 
    53             case (INTVAL)'S': 
    54             case (INTVAL)'t':   /* string, pass a cstring */ 
    55                 param_sig[j++] = 'S'; 
    56                 break; 
    57             case (INTVAL)'J':   /* interpreter */ 
    58                 break; 
    59             case (INTVAL)'p':   /* push pmc->data */ 
    60             case (INTVAL)'O':   /* push PMC * object in P2 */ 
    61             case (INTVAL)'P':   /* push PMC * */ 
    62             case (INTVAL)'V':   /* push PMC * */ 
    63                 param_sig[j++] = 'P'; 
    64             case (INTVAL)'v': 
    65                 break; 
    66                 /* I have no idea how to handle these */ 
    67             case (INTVAL)'2': 
    68             case (INTVAL)'3': 
    69             case (INTVAL)'4': 
    70                 param_sig[j++] = 'I'; 
    71                 break; 
    72             case (INTVAL)'@': 
    73                 param_sig[j++] = '@'; 
    74                 break; 
    75             case (INTVAL)'b': /* buffer (void*) pass Buffer_bufstart(SReg) */ 
    76             case (INTVAL)'B': /* buffer (void**) pass &Buffer_bufstart(SReg) */ 
    77                 param_sig[j++] = 'S'; 
    78                 break; 
    79             default: 
    80                 if (sig_length > 7) 
    81                     mem_sys_free(param_sig); 
    82                 Parrot_ex_throw_from_c_args(interp, NULL, 
     37        if (c > 127) { 
     38            Parrot_ex_throw_from_c_args(interp, NULL, 
    8339                    EXCEPTION_JIT_ERROR, 
    84                     "Unknown param Signature %c\n", (char)c); 
    85                 break; 
     40                    "Unknown param type at %d in signature '%S' (way too big)\n", i, sig); 
    8641        } 
     42        else { 
     43            switch ((char)c) { 
     44                case 'v': 
     45                case '0': 
     46                case 'J': 
     47                    break; 
     48                case 'N': 
     49                case 'd': 
     50                case 'f': 
     51                    param_buf[j++] = 'N'; 
     52                    break; 
     53                case 'I': 
     54                case 'l': 
     55                case 'i': 
     56                case 's': 
     57                case 'c': 
     58                    param_buf[j++] = 'I'; 
     59                    break; 
     60                case 'S': 
     61                case 't': 
     62                case 'b': 
     63                case 'B': 
     64                    param_buf[j++] = 'S'; 
     65                    break; 
     66                case 'P': 
     67                case 'p': 
     68                case 'V': 
     69                case '2': 
     70                case '3': 
     71                case '4': 
     72                    param_buf[j++] = 'P'; 
     73                    break; 
     74                case 'O': 
     75                    param_buf[j++] = 'P'; 
     76                    param_buf[j++] = 'i'; 
     77                    break; 
     78                case '@': 
     79                    param_buf[j++] = 'P'; 
     80                    param_buf[j++] = 's'; 
     81                    break; 
     82                default: 
     83                    Parrot_ex_throw_from_c_args(interp, NULL, 
     84                            EXCEPTION_JIT_ERROR, 
     85                            "Unknown param type at %d in signature '%S'\n", i, sig); 
     86            } 
     87        } 
    8788    } 
    8889 
    89     PARROT_ASSERT(j <= sig_length); 
     90    return string_make(interp, param_buf, j, NULL, PObj_constant_FLAG); 
     91} 
    9092 
    91     /* use only the signature-significant part of the string buffer */ 
    92     if (j) { 
    93         nci_info->pcc_params_signature = string_make(interp, param_sig, j, 
    94             NULL, PObj_constant_FLAG); 
     93STRING *pcc_sig_ret(PARROT_INTERP, STRING *sig); 
     94STRING *pcc_sig_ret(PARROT_INTERP, STRING *sig) { 
     95    INTVAL c = Parrot_str_indexed(interp, sig, 0); 
     96    if (c > 127) { 
     97        Parrot_ex_throw_from_c_args(interp, NULL, 
     98                EXCEPTION_JIT_ERROR, 
     99                "Unknown return type at %d in signature '%S' (way too big)\n", 0, sig); 
    95100    } 
    96     else 
    97         nci_info->pcc_params_signature = CONST_STRING(interp, ""); 
    98  
    99     if (sig_length > 7) 
    100         mem_sys_free(param_sig); 
     101    else { 
     102        switch ((char)c) { 
     103            case 'v': 
     104                return CONST_STRING(interp, "v"); 
     105            case 'N': 
     106            case 'f': 
     107            case 'd': 
     108                return CONST_STRING(interp, "N"); 
     109            case 'I': 
     110            case 'l': 
     111            case 'i': 
     112            case 's': 
     113            case 'c': 
     114                return CONST_STRING(interp, "I"); 
     115            case 'S': 
     116            case 't': 
     117                return CONST_STRING(interp, "S"); 
     118            case 'p': 
     119            case 'P': 
     120                return CONST_STRING(interp, "P"); 
     121            case '2': 
     122            case '3': 
     123            case '4': 
     124                return CONST_STRING(interp, "P"); 
     125            default: 
     126                Parrot_ex_throw_from_c_args(interp, NULL, 
     127                        EXCEPTION_JIT_ERROR, 
     128                        "Unknown return type at %d in signature '%S'\n", 0, sig); 
     129        } 
     130    } 
    101131} 
    102132 
    103133/* actually build the NCI thunk */ 
     
    106136static 
    107137nci_sub_t build_func(PARROT_INTERP, PMC *pmc, Parrot_NCI_attributes *nci_info) 
    108138{ 
    109     STRING    *key        = nci_info->signature; 
    110     size_t     key_length = Parrot_str_byte_length(interp, key); 
     139    STRING    *key        = nci_info->nci_signature; 
    111140    int       jitted      = 0; 
    112141 
    113     pcc_params(interp, key, nci_info, key_length); 
    114  
    115     /* Arity is length of that string minus one (the return type). */ 
    116     nci_info->arity       = key_length - 1; 
    117  
    118142    /* Build call function. */ 
    119143    nci_info->func        = (PMC *)(build_call_func(interp, pmc, key, &jitted)); 
    120     nci_info->jitted      = jitted; 
    121144 
    122145    return (nci_sub_t)nci_info->func; 
    123146} 
    124147 
    125148 
    126149pmclass NCI auto_attrs { 
    127     ATTR STRING    *signature;              /* The signature. */ 
    128     ATTR void      *func;                   /* Function pointer to call. */ 
    129     ATTR void      *orig_func;              /* Function pointer 
    130                                              * used to create func */ 
    131     ATTR STRING    *pcc_params_signature;   /* The signature. */ 
    132     ATTR STRING    *long_signature;         /* The full signature. */ 
    133     ATTR PMC       *multi_sig;              /* type tuple array (?) */ 
    134     ATTR INTVAL     arity;                  /* Cached arity of the NCI. */ 
    135     ATTR INTVAL     jitted;                 /* Is this a jitted NCI stub. */ 
     150    /* Signature Attributes */ 
     151    ATTR STRING    *nci_signature;          /* The NCI signature */ 
     152    ATTR STRING    *pcc_signature_ret;      /* The PCC return signature */ 
     153    ATTR STRING    *pcc_signature_param;    /* The PCC param signature */ 
    136154 
     155    /* Function Pointers */ 
     156    ATTR void      *func;                   /* Function pointer to call */ 
     157    ATTR void      *orig_func;              /* Function pointer being wrapped */ 
     158 
     159    /* Sub PMC Attributes */ 
     160    ATTR INTVAL     arity;                  /* Number of params taken */ 
     161    /* MMD Attributes */ 
     162    ATTR PMC       *multi_sig; 
     163    ATTR STRING    *long_signature; 
     164 
    137165/* 
    138166 
    139167=item C<METHOD get_multisig()> 
     
    147175    METHOD get_multisig() { 
    148176        PMC *sig; 
    149177        GET_ATTR_multi_sig(INTERP, SELF, sig); 
    150         if (PMC_IS_NULL(sig)) 
     178        if (sig == NULL) { 
    151179            sig = PMCNULL; 
     180        } 
    152181        RETURN(PMC *sig); 
    153182    } 
    154183 
     
    178207 
    179208    VTABLE void init() { 
    180209        /* Mark that we're not a raw NCI. */ 
    181         PObj_flag_CLEAR(private2, SELF); 
     210        PObj_get_FLAGS(SELF) &= ~NCI_raw_FLAG; 
     211        /* Mark that we have a custom gc marker */ 
    182212        PObj_custom_mark_SET(SELF); 
    183213    } 
    184214 
    185215/* 
    186216 
    187 =item C<void set_pointer_keyed_str(STRING *key, void *func)> 
     217=item C<void *get_pointer()> 
    188218 
    189 Sets the specified function pointer and signature (C<*key>). 
     219=item C<void set_pointer(void *ptr)> 
    190220 
     221Get/Set the pointer being wrapped. Setting through this interface sets 
     222the raw flag. 
     223 
    191224=cut 
    192225 
    193226*/ 
    194227 
    195228    VTABLE void set_pointer(void *ptr) { 
    196229        SET_ATTR_orig_func(INTERP, SELF, ptr); 
    197         PObj_flag_SET(private2, SELF); 
     230        PObj_get_FLAGS(SELF) |= NCI_raw_FLAG; 
    198231    } 
    199232 
    200233    VTABLE void *get_pointer() { 
    201234        return PARROT_NCI(SELF)->orig_func; 
    202235    } 
    203236 
     237/* 
     238 
     239=item C<void set_pointer_keyed_str(STRING *key, void *func)> 
     240 
     241Roughly equivalent to C<set_string(key)> and C<set_pointer(func)>. 
     242Setting through this interface clears the raw flag. 
     243 
     244=cut 
     245 
     246*/ 
     247 
    204248    VTABLE void set_pointer_keyed_str(STRING *key, void *func) { 
    205         Parrot_NCI_attributes * const nci_info   = PARROT_NCI(SELF); 
     249        SELF.set_string_native(key); 
     250        SELF.set_pointer(func); 
     251        PObj_get_FLAGS(SELF) &= ~NCI_raw_FLAG; 
     252    } 
    206253 
    207         /* Store the original function and signature. */ 
    208         SET_ATTR_orig_func(INTERP, SELF, func); 
     254/* 
    209255 
    210         /* ensure that the STRING signature is constant */ 
    211         if (!PObj_constant_TEST(key)) { 
    212             char * const key_c      = Parrot_str_to_cstring(INTERP, key); 
    213             size_t       key_length = Parrot_str_byte_length(interp, key); 
    214             key                     = string_make(interp, key_c, key_length, 
    215                                         NULL, PObj_constant_FLAG); 
    216             Parrot_str_free_cstring(key_c); 
     256=item C<STRING *get_string()> 
     257 
     258=item C<void set_string(STRING *str)> 
     259 
     260Get/Set the NCI signature. 
     261 
     262=cut 
     263 
     264*/ 
     265 
     266    VTABLE STRING *get_string() { 
     267        return PARROT_NCI(SELF)->nci_signature; 
     268    } 
     269 
     270    VTABLE void set_string_native(STRING *str) { 
     271        if (!PObj_constant_TEST(str)) { 
     272            str = Parrot_str_copy(INTERP, str); 
    217273        } 
     274        SET_ATTR_nci_signature(INTERP, SELF, str); 
    218275 
    219         nci_info->signature = key; 
     276        /* set up derivative attributes */ 
     277        SET_ATTR_pcc_signature_param(INTERP, SELF, pcc_sig_params(INTERP, str)); 
     278        SET_ATTR_pcc_signature_ret(INTERP, SELF, pcc_sig_ret(INTERP, str)); 
     279        /* Arity is length of the NCI signature minus one (the return type). */ 
     280        SET_ATTR_arity(INTERP, SELF, Parrot_str_byte_length(INTERP, str) - 1); 
    220281    } 
    221282 
    222283/* 
     
    232293        if (PARROT_NCI(SELF)) { 
    233294            Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF); 
    234295 
    235             Parrot_gc_mark_STRING_alive(interp, nci_info->signature); 
    236             Parrot_gc_mark_STRING_alive(interp, nci_info->pcc_params_signature); 
     296            Parrot_gc_mark_STRING_alive(interp, nci_info->nci_signature); 
     297            Parrot_gc_mark_STRING_alive(interp, nci_info->pcc_signature_param); 
     298            Parrot_gc_mark_STRING_alive(interp, nci_info->pcc_signature_ret); 
    237299            Parrot_gc_mark_STRING_alive(interp, nci_info->long_signature); 
    238300            Parrot_gc_mark_PMC_alive(interp, nci_info->multi_sig); 
    239301        } 
     
    262324         * ManagedStruct or Buffer? 
    263325         */ 
    264326        nci_info_ret->func                  = nci_info_self->func; 
    265         nci_info_ret->orig_func             = nci_info_self->orig_func; 
    266         nci_info_ret->signature             = nci_info_self->signature; 
    267         nci_info_ret->pcc_params_signature  = nci_info_self->pcc_params_signature; 
     327        nci_info_ret->orig_func              = nci_info_self->orig_func; 
     328        nci_info_ret->nci_signature         = nci_info_self->nci_signature; 
     329        nci_info_ret->pcc_signature_param   = nci_info_self->pcc_signature_param; 
     330        nci_info_ret->pcc_signature_ret     = nci_info_self->pcc_signature_ret; 
     331        nci_info_ret->long_signature        = nci_info_self->long_signature; 
     332        nci_info_ret->multi_sig             = nci_info_self->multi_sig; 
    268333        nci_info_ret->arity                 = nci_info_self->arity; 
    269         nci_info_ret->jitted                = nci_info_self->jitted; 
    270334        PObj_get_FLAGS(ret)                |= (PObj_get_FLAGS(SELF) & 0x7); 
    271335 
    272336        return ret; 
     
    306370        PMC                          *cont; 
    307371 
    308372        GET_ATTR_orig_func(INTERP, SELF, orig_func); 
    309         func = PObj_flag_TEST(private2, SELF) 
     373        func = PObj_get_FLAGS(SELF) & NCI_raw_FLAG 
    310374            ? (nci_sub_t) D2FPTR(orig_func) 
    311375            : (nci_sub_t) D2FPTR(nci_info->func); 
    312376 
     
    320384                    "attempt to call NULL function"); 
    321385        } 
    322386 
    323         if (nci_info->jitted) { 
    324             nci_jit_sub_t jit_func = (nci_jit_sub_t) D2FPTR(nci_info->func); 
     387        func(INTERP, SELF); 
    325388 
    326             /* Parrot_eprintf(interp, "JITTED %S\n", nci_info->signature); */ 
    327             sig_str = Parrot_str_to_cstring(interp, nci_info->pcc_params_signature); 
    328             jit_func(INTERP, SELF, sig_str); 
    329             Parrot_str_free_cstring(sig_str); 
    330         } 
    331         else { 
    332             if (PObj_flag_TEST(private2, SELF)) { 
    333                 /* Parrot_eprintf(interp, "RAW NCI CALL\n"); */ 
    334             } 
    335             else { 
    336                 /* Parrot_eprintf(interp, "HACKED %S\n", nci_info->signature); */ 
    337             } 
    338             func(INTERP, SELF); 
    339         } 
    340389        cont = INTERP->current_cont; 
    341390 
    342391        /* 
     
    397446 
    398447*/ 
    399448    METHOD arity() { 
    400         Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF); 
    401         INTVAL arity = 0; 
     449        INTVAL arity; 
     450        GET_ATTR_arity(INTERP, SELF, arity); 
     451        RETURN(INTVAL arity); 
     452    } 
    402453 
    403         if (nci_info) { 
    404             if (!nci_info->func) 
    405                 build_func(INTERP, SELF, nci_info); 
    406             if (nci_info->func) { 
    407                 arity = nci_info->arity; 
    408                 RETURN(INTVAL arity); 
    409             } 
     454/* 
     455 
     456=item C<INTVAL get_integer_keyed_int(INTVAL key)> 
     457 
     458=item C<STRING *get_string_keyed_int(INTVAL key)> 
     459 
     460=item C<PMC *get_pmc_keyed_int(INTVAL key)> 
     461 
     462Accessors for all attributes of this class not otherwise accessible through VTABLES. 
     463Integers are used for keys to make access easier for JIT. These are also available to 
     464PIR from F<runtime/parrot/include/nci.pasm> 
     465 
     466=over 
     467 
     468=item INTVAL keys 
     469 
     470C<PARROT_NCI_ARITY> 
     471 
     472=item STRING keys 
     473 
     474C<PARROT_NCI_PCC_SIGNATURE_PARAMS>, C<PARROT_NCI_PCC_SIGNATURE_RET>, 
     475C<PARROT_LONG_SIGNATURE> 
     476 
     477=item PMC keys 
     478 
     479C<PARROT_NCI_MULTI_SIG> 
     480 
     481=back 
     482 
     483=cut 
     484 
     485*/ 
     486 
     487    VTABLE INTVAL get_integer_keyed_int(INTVAL key) { 
     488        switch (key) { 
     489            case PARROT_NCI_ARITY: 
     490                return PARROT_NCI(SELF)->arity; 
     491            default: 
     492                Parrot_ex_throw_from_c_args(INTERP, NULL, 
     493                    EXCEPTION_INVALID_OPERATION, 
     494                    "Bad index for NCI.get_integer_keyed_int()"); 
    410495        } 
     496    } 
    411497 
    412         Parrot_ex_throw_from_c_args(INTERP, NULL, 
    413             EXCEPTION_INVALID_OPERATION, 
    414             "You cannot get the arity of an undefined NCI."); 
     498    VTABLE STRING *get_string_keyed_int(INTVAL key) { 
     499        switch (key) { 
     500            case PARROT_NCI_PCC_SIGNATURE_PARAMS: 
     501                return PARROT_NCI(SELF)->pcc_signature_param; 
     502            case PARROT_NCI_PCC_SIGNATURE_RET: 
     503                return PARROT_NCI(SELF)->pcc_signature_ret; 
     504            case PARROT_NCI_LONG_SIGNATURE: 
     505                return PARROT_NCI(SELF)->long_signature; 
     506            default: 
     507                Parrot_ex_throw_from_c_args(INTERP, NULL, 
     508                    EXCEPTION_INVALID_OPERATION, 
     509                    "Bad index for NCI.get_string_keyed_int()"); 
     510        } 
    415511    } 
     512 
     513    VTABLE PMC *get_pmc_keyed_int(INTVAL key) { 
     514        PMC *retval; 
     515        switch (key) { 
     516            case PARROT_NCI_MULTI_SIG: 
     517                GET_ATTR_multi_sig(INTERP, SELF, retval); 
     518            default: 
     519                Parrot_ex_throw_from_c_args(INTERP, NULL, 
     520                    EXCEPTION_INVALID_OPERATION, 
     521                    "Bad index for NCI.get_pmc_keyed_int()"); 
     522        } 
     523        if (retval == NULL) { 
     524            retval = PMCNULL; 
     525        } 
     526        return retval; 
     527    } 
    416528} 
    417529 
    418530/* 
  • src/frame_builder.c

     
    1 /* 
    2 Copyright (C) 2008-2009, Parrot Foundation. 
    3 $Id$ 
    4 */ 
    5  
    6 /* HEADERIZER HFILE: none */ 
    7 /* HEADERIZER STOP */ 
    8  
    9 #include "parrot/parrot.h" 
    10 #include "pmc/pmc_fixedintegerarray.h" 
    11 #include "pmc/pmc_unmanagedstruct.h" 
    12 #include "pmc/pmc_managedstruct.h" 
    13 #include "frame_builder.h" 
    14  
    15 /* 
    16  
    17 =over 4 
    18  
    19 =item C<void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv)> 
    20  
    21 This is a callback to implement the proper freeing semantics.  It is called by 
    22 the ManagedStruct PMC as it is garbage collected. 
    23  
    24 =cut 
    25  
    26 */ 
    27  
    28 void 
    29 Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv) 
    30 { 
    31     const struct jit_buffer_private_data * const jit = (struct jit_buffer_private_data*)priv; 
    32     mem_free_executable(ptr, jit->size); 
    33     free(priv); 
    34 } 
    35  
    36 /* 
    37  
    38 =item C<PMC *Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv)> 
    39  
    40 This is a callback to implement the proper cloning semantics for jit buffers. 
    41 It is called by the ManagedStruct PMC's clone() function. 
    42  
    43 =back 
    44  
    45 =cut 
    46  
    47 */ 
    48  
    49 PMC * 
    50 Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv) 
    51 { 
    52     PMC * const rv = pmc_new(interp, pmc->vtable->base_type); 
    53  
    54     VTABLE_init(interp, rv); 
    55     /* copy the attributes */ 
    56     { 
    57         void (*tmpfreefunc)(PARROT_INTERP, void*, void*); 
    58         GETATTR_ManagedStruct_custom_free_func(interp, pmc, tmpfreefunc); 
    59         SETATTR_ManagedStruct_custom_free_func(interp, rv , tmpfreefunc); 
    60     } 
    61     { 
    62         PMC* (*tmpclonefunc)(PARROT_INTERP, PMC*, void*); 
    63         GETATTR_ManagedStruct_custom_clone_func(interp, pmc, tmpclonefunc); 
    64         SETATTR_ManagedStruct_custom_clone_func(interp, rv , tmpclonefunc); 
    65     } 
    66  
    67     { 
    68         void *freepriv, *clonepriv; 
    69         GETATTR_ManagedStruct_custom_free_priv(interp , pmc, freepriv); 
    70         GETATTR_ManagedStruct_custom_clone_priv(interp, pmc, clonepriv); 
    71         if (freepriv) { 
    72             void *tmp = mem_sys_allocate(sizeof (struct jit_buffer_private_data)); 
    73             memcpy(tmp, freepriv, sizeof (struct jit_buffer_private_data)); 
    74             SETATTR_ManagedStruct_custom_free_priv(interp, rv , tmp); 
    75             if (clonepriv == freepriv) { 
    76                 /* clonepriv is a copy of freepriv, make it a copy in the clone too. */ 
    77                 SETATTR_ManagedStruct_custom_clone_priv(interp, rv , tmp); 
    78                 clonepriv = NULL; /* disable the clonepriv copying below */ 
    79             } 
    80         } 
    81         if (clonepriv) { 
    82             void *tmp = mem_sys_allocate(sizeof (struct jit_buffer_private_data)); 
    83             memcpy(tmp, clonepriv, sizeof (struct jit_buffer_private_data)); 
    84             SETATTR_ManagedStruct_custom_clone_priv(interp, rv , tmp); 
    85         } 
    86     } 
    87  
    88     /* copy the execmem buffer */ 
    89     if (PARROT_MANAGEDSTRUCT(pmc)->ptr) { 
    90         struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv; 
    91         void *ptr = PARROT_MANAGEDSTRUCT(pmc)->ptr; 
    92         void *newptr = mem_alloc_executable(jit->size); 
    93         if (!newptr) 
    94             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 
    95                     "Cannot allocate executable memory"); 
    96         memcpy(newptr, ptr, jit->size); 
    97         PARROT_MANAGEDSTRUCT(rv)->ptr = newptr; 
    98     } 
    99  
    100     return rv; 
    101 } 
    102  
    103  
    104 int 
    105 emit_is8bit(long disp) 
    106 { 
    107     return disp >= -128 && disp <= 127; 
    108 } 
    109  
    110 char * 
    111 emit_disp8_32(char *pc, int disp) 
    112 { 
    113     if (emit_is8bit(disp)) { 
    114         *(pc++) = (char)disp; 
    115         return pc; 
    116     } 
    117     else { 
    118         *(long *)pc = disp; 
    119         return pc + 4; 
    120     } 
    121 } 
    122  
    123 void 
    124 emit_sib(PARROT_INTERP, char *pc, int scale, int i, int base) 
    125 { 
    126     int scale_byte; 
    127  
    128     switch (scale) { 
    129         case 1: 
    130             scale_byte = emit_Scale_1; 
    131             break; 
    132         case 2: 
    133             scale_byte = emit_Scale_2; 
    134             break; 
    135         case 4: 
    136             scale_byte = emit_Scale_4; 
    137             break; 
    138         case 8: 
    139             scale_byte = emit_Scale_8; 
    140             break; 
    141         default: 
    142             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 
    143                 "Invalid scale factor %d\n", scale); 
    144             return; 
    145     } 
    146  
    147     *pc = (char)(scale_byte | (i == emit_None ? emit_Index_None : emit_reg_Index(i)) | 
    148             emit_reg_Base(base)); 
    149 } 
    150  
    151 char * 
    152 emit_r_X(PARROT_INTERP, char *pc, int reg_opcode, int base, int i, int scale, long disp) 
    153 { 
    154     if (i && !scale) 
    155         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 
    156             "emit_r_X passed invalid scale+index combo\n"); 
    157  
    158     if (base == emit_EBP) { 
    159     /* modrm disp */ 
    160         if (i == emit_None) { 
    161             *(pc++) = (char)((emit_is8bit(disp) ? emit_Mod_b01 : emit_Mod_b10) 
    162                     | reg_opcode | emit_reg_rm(emit_EBP)); 
    163             return emit_disp8_32(pc, disp); 
    164         } 
    165         /* modrm sib disp */ 
    166         else { 
    167             *(pc++) = (char)((emit_is8bit(disp) ? emit_Mod_b01 : emit_Mod_b10) 
    168                     | reg_opcode | emit_b100); 
    169             emit_sib(interp, pc++, scale, i, base); 
    170             return emit_disp8_32(pc, disp); 
    171         } 
    172     } 
    173  
    174     /* modrm sib disp */ 
    175     if (base == emit_ESP) { 
    176         *(pc++) = (char)((emit_is8bit(disp) ? emit_Mod_b01 : emit_Mod_b10) 
    177                 | reg_opcode | emit_rm_b100); 
    178         emit_sib(interp, pc++, scale, i, emit_ESP); 
    179         return emit_disp8_32(pc, disp); 
    180     } 
    181  
    182     /* modrm disp32 */ 
    183     if (!base && !(i && scale)) { 
    184         *(pc++) = (char)(emit_Mod_b00 | reg_opcode | emit_rm_b101); 
    185         *(long *)pc = disp; 
    186         return pc + 4; 
    187     } 
    188  
    189     /* Ok, everything should be more regular here */ 
    190     *(pc++) = (char)((disp == 0 ? emit_Mod_b00 : 
    191               (emit_is8bit(disp) ? 
    192                emit_Mod_b01 : emit_Mod_b10)) | 
    193                reg_opcode | 
    194                (!base || (scale && i) ? emit_rm_b100 : emit_reg_rm(base))); 
    195  
    196     if (!base || (scale && i)) { 
    197         emit_sib(interp, pc++, scale, i, base); 
    198     } 
    199     if (disp) 
    200         pc = emit_disp8_32(pc, disp); 
    201  
    202     return pc; 
    203 } 
    204  
    205 char * 
    206 emit_shift_i_r(PARROT_INTERP, char *pc, int opcode, int imm, int reg) 
    207 { 
    208     if (opcode == emit_b000 && imm < 0) { 
    209         opcode = emit_b001;     /* -rol => 32 + ror */ 
    210         imm = -imm; 
    211     } 
    212  
    213     if (imm == 0) { 
    214         /* noop */ 
    215     } 
    216     else if (imm == 1) { 
    217         *(pc++) = (char) 0xd1; 
    218         *(pc++) = (char) emit_alu_X_r(opcode,  reg); 
    219     } 
    220     else if (imm > 1 && imm < 33) { 
    221         *(pc++) = (char) 0xc1; 
    222         *(pc++) = (char) emit_alu_X_r(opcode,  reg); 
    223         *(pc++) = (char)imm; 
    224     } 
    225     else { 
    226         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 
    227             "emit_shift_i_r passed invalid shift\n"); 
    228     } 
    229  
    230     return pc; 
    231 } 
    232  
    233 char * 
    234 emit_popl_r(char *pc, int reg) 
    235 { 
    236     *(pc++) = (char)(0x58 | (reg - 1)); 
    237     return pc; 
    238 } 
    239  
    240 unsigned char *lastpc; 
    241  
    242 size_t 
    243 calc_signature_needs(const char *sig, int *strings) 
    244 { 
    245     size_t stack_size = 0; 
    246     while (*sig) { 
    247         switch (*sig) { 
    248             case 't': 
    249                 (*strings)++; 
    250                 stack_size +=4; 
    251                 break; 
    252             case 'd': 
    253                 stack_size +=8; 
    254                 break; 
    255             default: 
    256                 stack_size +=4; 
    257                 break; 
    258         } 
    259         sig++; 
    260     } 
    261     return stack_size; 
    262  
    263 } 
    264  
    265 /* 
    266  * The function generated here is called as func(interp, nci_info) 
    267  * interp   ...  8(%ebp) 
    268  * nci_info ... 12(%ebp) 
    269  * 
    270  * The generate function for a specific signature looks quite similar to 
    271  * an optimized compile of src/nci.c:pcf_x_yy(). In case of any troubles 
    272  * just compare the disassembly. 
    273  * 
    274  * If a non-NULL sizeptr is passed, the integer it points to will be written 
    275  * with the size of the allocated execmem buffer. 
    276  */ 
    277  
    278 void * 
    279 Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature, int *sizeptr) 
    280 { 
    281     char     *pc; 
    282     char     *execmem; 
    283     int       i                    = 0; 
    284     int       arg_count            = 0; 
    285     int       string_buffer_count  = 0; 
    286     const int ST_SIZE_OF           = 124; 
    287     const int JIT_ALLOC_SIZE       = 1024; 
    288  
    289     char      *signature_str      = Parrot_str_to_cstring(interp, signature); 
    290     /* skip over the result */ 
    291     char      *sig                = signature_str + 1; 
    292     size_t     stack_space_needed = calc_signature_needs(sig, 
    293                                         &string_buffer_count); 
    294  
    295     int base_offset        = 0; 
    296     int strings_offset     = base_offset - (sizeof (char *) * string_buffer_count); 
    297     int st_offset          = strings_offset - ST_SIZE_OF; 
    298     int args_offset        = st_offset - stack_space_needed; 
    299     int temp_calls_offset  = args_offset - 16; 
    300     int total_stack_needed = -temp_calls_offset; 
    301  
    302     /* 
    303      * ESP 
    304      * 0-15, 16 bytes for utility calls 
    305      * stack_space_needed for actual NCI call 
    306      * st 
    307      * STRINGS -> char * holding space 
    308      * EBP 
    309      */ 
    310  
    311     /* this ought to be enough - the caller of this function 
    312      * should free the function pointer returned here 
    313      */ 
    314     pc = execmem = (char *)mem_alloc_executable(JIT_ALLOC_SIZE); 
    315     if (! pc) 
    316         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 
    317                 "Cannot allocate executable memory"); 
    318  
    319  
    320     /* this generated jit function will be called as (INTERP (EBP 8), func_ptr 
    321     * (ESP 12), args signature (ESP 16)) */ 
    322  
    323     /* make stack frame, preserve %ebx */ 
    324     jit_emit_stack_frame_enter(pc); 
    325  
    326     emitm_subl_i_r(pc, total_stack_needed, emit_ESP); 
    327  
    328     /* Parrot_init_arg_nci(interp, &st, "S"); */ 
    329     /* args signature "S" */ 
    330     emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 16); 
    331     emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8); 
    332  
    333     /*&st*/ 
    334     emitm_lea_m_r(interp,  pc, emit_EAX, emit_EBP, 0, 1, st_offset); 
    335     emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4); 
    336  
    337     /*interpreter*/ 
    338     emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8); 
    339     emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0); 
    340  
    341     /* XXX FIXME This whole function require major rework */ 
    342     /* XXX FIXME if (sig && *sig) */ 
    343     /* XXX FIXME   emitm_call_cfunc(pc, Parrot_init_arg_nci); */ 
    344  
    345     while (*sig) { 
    346         emitm_movl_i_m(pc, arg_count, emit_EBP, 0, 1, temp_calls_offset + 8); 
    347  
    348         switch (*sig) { 
    349             case '0':    /* null ptr or such - doesn't consume a reg */ 
    350                 jit_emit_bxor_rr_i(interp, pc, emit_EAX, emit_EAX); 
    351                 emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 
    352                 break; 
    353             case 'f': 
    354                 /* FIXME emitm_call_cfunc(pc, get_nci_N); */ 
    355                 emitm_fstps(interp, pc, emit_EBP, 0, 1, args_offset); 
    356                 break; 
    357             case 'N': 
    358             case 'd': 
    359                 /* FIXME emitm_call_cfunc(pc, get_nci_N); */ 
    360                 emitm_fstpl(interp, pc, emit_EBP, 0, 1, args_offset); 
    361                 args_offset += 4; 
    362                 break; 
    363             case 'I':   /* INTVAL */ 
    364             case 'l':   /* long */ 
    365             case 'i':   /* int */ 
    366                 /* FIXME emitm_call_cfunc(pc, get_nci_I); */ 
    367                 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 
    368                 break; 
    369             case 't':   /* string, pass a cstring */ 
    370                 /* FIXME emitm_call_cfunc(pc, get_nci_S); */ 
    371                 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4); 
    372                 emitm_call_cfunc(pc, string_to_cstring_nullable); 
    373  
    374                 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 
    375                 /* save off temporary allocation address */ 
    376                 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, strings_offset); 
    377                 strings_offset += 4; 
    378  
    379                 /* reset ESP(4) */ 
    380                 emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset); 
    381                 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4); 
    382                 break; 
    383             case 's':   /* short: movswl intreg_o(base), %eax */ 
    384                 /* FIXME emitm_call_cfunc(pc, get_nci_I); */ 
    385                 emitm_movswl_r_r(pc, emit_EAX, emit_EAX); 
    386                 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 
    387                 break; 
    388             case 'c':   /* char: movsbl intreg_o(base), %eax */ 
    389                 /* emitm_call_cfunc(pc, get_nci_I); */ 
    390                 emitm_movsbl_r_r(pc, emit_EAX, emit_EAX); 
    391                 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 
    392                 break; 
    393             case 'J':   /* interpreter */ 
    394                 emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8); 
    395                 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 
    396                 arg_count--; 
    397                 break; 
    398             case 'p':   /* push pmc->data */ 
    399                 /* FIXME emitm_call_cfunc(pc, get_nci_p); */ 
    400                 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 
    401                 break; 
    402             case 'O':   /* push PMC * object in P2 */ 
    403             case 'P':   /* push PMC * */ 
    404             case '@': 
    405                 /* FIXME emitm_call_cfunc(pc, get_nci_P); */ 
    406                 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 
    407                 break; 
    408             case 'v': 
    409                 break; 
    410             case 'b':   /* buffer (void*) pass Buffer_bufstart(SReg) */ 
    411                 /* FIXME emitm_call_cfunc(pc, get_nci_S); */ 
    412                 emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, 
    413                                (size_t) &Buffer_bufstart((STRING *) NULL)); 
    414                 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 
    415                 break; 
    416             case 'B':   /* buffer (void**) pass &Buffer_bufstart(SReg) */ 
    417                 /* FIXME emitm_call_cfunc(pc, get_nci_S); */ 
    418                 emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, 
    419                               (size_t) &Buffer_bufstart((STRING *) NULL)); 
    420                 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 
    421                 break; 
    422             case 'S': 
    423                 /* FIXME emitm_call_cfunc(pc, get_nci_S); */ 
    424                 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 
    425                 break; 
    426  
    427  
    428             /* I have no idea how to handle these */ 
    429             case '2': 
    430             case '3': 
    431             case '4': 
    432             case 'V': 
    433                 mem_free_executable(execmem, JIT_ALLOC_SIZE); 
    434                 Parrot_str_free_cstring(signature_str); 
    435                 return NULL; 
    436                 break; 
    437             default: 
    438                 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 
    439                     "Unknown arg Signature %c\n", *sig); 
    440                 /* 
    441                  * oops unknown signature: 
    442                  * cleanup and try nci.c 
    443                  */ 
    444                 mem_free_executable(execmem, JIT_ALLOC_SIZE); 
    445                 Parrot_str_free_cstring(signature_str); 
    446                 return NULL; 
    447         } 
    448         args_offset +=4; 
    449         arg_count++; 
    450         sig++; 
    451     } 
    452  
    453     /* prepare to call VTABLE_get_pointer, set up args */ 
    454     /* interpreter - movl 8(%ebp), %eax */ 
    455     emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8); 
    456     emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0); 
    457  
    458     /* pmc - movl 12(%ebp), %eax */ 
    459     emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 12); 
    460     emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4); 
    461  
    462     /* get the get_pointer() pointer from the pmc's vtable */ 
    463     emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(PMC, vtable)); 
    464     emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(VTABLE, get_pointer)); 
    465  
    466     /* call get_pointer(), result goes into eax */ 
    467     emitm_callr(pc, emit_EAX); 
    468     emitm_addl_i_r(pc, 16, emit_ESP); 
    469  
    470     /* call the resulting function pointer */ 
    471     emitm_callr(pc, emit_EAX); 
    472     emitm_subl_i_r(pc, 16, emit_ESP); 
    473  
    474     /* SAVE OFF EAX */ 
    475     emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8); 
    476  
    477     /*&st*/ 
    478     emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset); 
    479     emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4); 
    480  
    481     /*interpreter*/ 
    482     emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8); 
    483     emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0); 
    484  
    485     /* RESTORE BACK EAX */ 
    486     emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8); 
    487  
    488     /* now place return value in registers */ 
    489     /* first in signature is the return value */ 
    490     sig = signature_str; /* the result */ 
    491     switch (*sig) { 
    492         /* I have no idea how to handle these */ 
    493         case '2': 
    494         case '3': 
    495         case '4': 
    496             /* get integer from pointer - untested */ 
    497             emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, 0); 
    498             if (*sig == 2)      /* short */ 
    499                 emitm_movswl_r_r(pc, emit_EAX, emit_EAX); 
    500             /* XXX FIXME emitm_call_cfunc(pc, set_nci_I);*/ 
    501             break; 
    502         case 'f': 
    503         case 'd': 
    504             jit_emit_fstore_mb_n(interp, pc, emit_EBP, temp_calls_offset + 8); 
    505             /* XXX FIXME emitm_call_cfunc(pc, set_nci_N); */ 
    506             /* pop num from st(0) and mov to reg */ 
    507             break; 
    508         case 's': 
    509             /* movswl %ax, %eax */ 
    510             emitm_movswl_r_r(pc, emit_EAX, emit_EAX); 
    511             emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8); 
    512             /* XXX FIXME emitm_call_cfunc(pc, set_nci_I); */ 
    513             break; 
    514         case 'c': 
    515             /* movsbl %al, %eax */ 
    516             emitm_movsbl_r_r(pc, emit_EAX, emit_EAX); 
    517             emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8); 
    518             /* XXX FIXME emitm_call_cfunc(pc, set_nci_I); */ 
    519             break; 
    520         case 'I':   /* INTVAL */ 
    521         case 'l': 
    522         case 'i': 
    523             emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8); 
    524            /* XXX FIXME emitm_call_cfunc(pc, set_nci_I); */ 
    525             break; 
    526         case 'v': /* void - do nothing */ 
    527             break; 
    528         case 'P': 
    529             emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8); 
    530             /* XXX FIXME emitm_call_cfunc(pc, set_nci_P); */ 
    531             break; 
    532         case 'p':   /* make a new unmanaged struct */ 
    533             /* save return value on stack */ 
    534  
    535             /* save pointer p */ 
    536             emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 12); 
    537  
    538             /* make new pmc */ 
    539             emitm_movl_i_m(pc, enum_class_UnManagedStruct, emit_EBP, 0, 1, temp_calls_offset + 4); 
    540             emitm_call_cfunc(pc, pmc_new); 
    541  
    542             /* restore pointer p to EDX */ 
    543             emitm_movl_m_r(interp, pc, emit_EDX, emit_EBP, 0, 1, temp_calls_offset + 12); 
    544  
    545             /* copy UnManagedStruct to stack for set_nci_P call */ 
    546             emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8); 
    547  
    548             /* eax = PMC, get return value into edx */ 
    549             /* mov data(%eax), %eax 
    550                mov %edx, ptr(%eax) */ 
    551             emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(struct PMC, data)); 
    552             emitm_movl_r_m(interp, pc, emit_EDX, emit_EAX, 0, 1, 
    553                            offsetof(struct Parrot_UnManagedStruct_attributes, ptr)); 
    554  
    555             /* reset EBP(4) */ 
    556             emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset); 
    557             emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4); 
    558  
    559             /* XXX FIXME emitm_call_cfunc(pc, set_nci_P); */ 
    560             break; 
    561         case 'S': 
    562             emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8); 
    563             /* XXX FIXME emitm_call_cfunc(pc, set_nci_S); */ 
    564             break; 
    565         case 't':   /* string */ 
    566             /* EAX is char* */ 
    567             emitm_movl_i_m(pc, 0, emit_EBP, 0, 1, temp_calls_offset + 8); /* len */ 
    568  
    569             /* overwrites address of st in EBP(4) */ 
    570             emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4); 
    571  
    572             emitm_call_cfunc(pc, Parrot_str_new); 
    573  
    574             emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8); 
    575  
    576             /* reset EBP(4) */ 
    577             emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset); 
    578             emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4); 
    579  
    580             /* XXX FIXME emitm_call_cfunc(pc, set_nci_S); */ 
    581             break; 
    582         default: 
    583             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 
    584                 "Unknown return Signature %c\n", *sig); 
    585             /* 
    586              * oops unknown signature: 
    587              * cleanup and try nci.c 
    588              */ 
    589             Parrot_str_free_cstring(signature_str); 
    590             mem_free_executable(execmem, JIT_ALLOC_SIZE); 
    591             return NULL; 
    592     } 
    593  
    594     /* free temporary strings */ 
    595     strings_offset = st_offset + ST_SIZE_OF; 
    596     for (i=0; i<string_buffer_count; i++) { 
    597         emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, strings_offset); 
    598         emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0); 
    599         emitm_call_cfunc(pc, Parrot_str_free_cstring); 
    600         strings_offset += 4; 
    601     } 
    602  
    603     jit_emit_stack_frame_leave(pc); 
    604     emitm_ret(pc); 
    605     PARROT_ASSERT(pc - execmem <= JIT_ALLOC_SIZE); 
    606  
    607     if (sizeptr) 
    608         *sizeptr = JIT_ALLOC_SIZE; 
    609     Parrot_str_free_cstring(signature_str); 
    610     return (void *)D2FPTR(execmem); 
    611 } 
    612  
    613 /* 
    614  * Local variables: 
    615  *   c-file-style: "parrot" 
    616  * End: 
    617  * vim: expandtab shiftwidth=4: 
    618  */ 
  • src/frame_builder.h

     
    11/* 
    22 * Copyright (C) 2002-2009, Parrot Foundation. 
    3  */ 
    4  
    5 /* 
     3 * 
    64 * frame_builder.h 
    75 * 
    8  * i386 
    9  * 
    106 * $Id$ 
    117 */ 
    128 
    13 #ifndef PARROT_I386_JIT_EMIT_H_GUARD 
    14 #define PARROT_I386_JIT_EMIT_H_GUARD 
     9#ifndef PARROT_FRAME_BUILDER_H_GUARD 
     10#define PARROT_FRAME_BUILDER_H_GUARD 
    1511 
    1612#if defined(__cplusplus) 
    1713#  define EXTERN extern "C" 
     
    2117 
    2218#include <assert.h> 
    2319#include "parrot/parrot.h" 
    24 #include "parrot/hash.h" 
    25 #include "parrot/oplib/ops.h" 
    2620 
    2721/* 
    2822 * NCI interface 
    2923 */ 
     24 
    3025void * 
    31 Parrot_jit_build_call_func(Interp *, PMC *, STRING *, int *); 
     26Parrot_jit_build_call_func(Interp *, PMC *, STRING *, void **); 
    3227 
    3328/* custom pmc callback functions */ 
    3429void 
     
    3732PMC* 
    3833Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv); 
    3934 
    40 struct jit_buffer_private_data { 
    41     int size; 
    42 }; 
    43  
    44 /* Scale factor values */ 
    45 #define emit_Scale(scale) ((scale) << 6) 
    46 #define emit_Scale_1 emit_Scale(0) 
    47 #define emit_Scale_2 emit_Scale(1) 
    48 #define emit_Scale_4 emit_Scale(2) 
    49 #define emit_Scale_8 emit_Scale(3) 
    50  
    51 /* ESIB byte */ 
    52 #define emit_reg_Index(x) (((x)-1) << 3) 
    53 #define emit_reg_Base(x) ((x)-1) 
    54 #define emit_Index_None ((emit_b100) << 3) 
    55  
    5635/* 
    5736 * helper funcs - get argument n 
    5837 */ 
    5938 
    60 /* 
    61  * if we have a delegated method like typeof_i_p, that returns an INTVAL 
    62  * and that is all in a sequence of JITted opcodes, and when these INTVAL 
    63  * is MAPped, we got a problem. So the EXT_CALL flag is disabled - mapped 
    64  * registers are saved/restored around vtable calls. 
    65  */ 
    66 #define  JIT_VTABLE_OPS 1 
     39#endif /* PARROT_FRAME_BUILDER_H_GUARD */ 
    6740 
    68 /* EXEC_SHARED generates code to be used with libparrot.so 
    69  * It grabs the real address of cgp_core from the gcc generated code 
    70  * x/1i cgp_code 
    71  *     jmp *0xXXXX 
    72  * x/1wx 0xXXXX 
    73  *     real address of cpg_core 
    74  * s. exec_emit_end 
    75  * XXX This should be a command line option. 
    76  */ 
    77 #undef EXEC_SHARED 
    78  
    79 extern UINTVAL ld(UINTVAL); 
    80  
    81 #define NEG_MINUS_ZERO 
    82 /* #define NEG_ZERO_SUB */ 
    83  
    84 /* Register codes */ 
    85 #define emit_None 0 
    86  
    87 /* These are + 1 the real values */ 
    88 #define emit_EAX 1 
    89 #define emit_ECX 2 
    90 #define emit_EDX 3 
    91 #define emit_EBX 4 
    92 #define emit_ESP 5 
    93 #define emit_EBP 6 
    94 #define emit_ESI 7 
    95 #define emit_EDI 8 
    96  
    97 /* Scratch register. */ 
    98  
    99 #define ISR1 emit_EAX 
    100 #define FSR1 0 
    101  
    102 #define emit_b00 0 
    103 #define emit_b01 1 
    104 #define emit_b10 2 
    105 #define emit_b11 3 
    106  
    107 #define emit_b000 0 
    108 #define emit_b001 1 
    109 #define emit_b010 2 
    110 #define emit_b011 3 
    111 #define emit_b100 4 
    112 #define emit_b101 5 
    113 #define emit_b110 6 
    114 #define emit_b111 7 
    115  
    116 /* Mod R/M byte */ 
    117 #define emit_reg(x) ((x) << 3) 
    118 #define emit_Mod(Mod) ((Mod) << 6) 
    119 #define emit_reg_rm(x) ((x)-1) 
    120  
    121 /* Mod values for Mod R/M Byte */ 
    122 #define emit_Mod_b00 emit_Mod(emit_b00) 
    123 #define emit_Mod_b01 emit_Mod(emit_b01) 
    124 #define emit_Mod_b10 emit_Mod(emit_b10) 
    125  
    126 /* special R/M values */ 
    127 #define emit_rm_b101 emit_b101 
    128 #define emit_rm_b100 emit_b100 
    129  
    130 #define emit_r_m(interp, pc, reg1, b, i, s, d) \ 
    131     emit_r_X((interp), (pc), emit_reg((reg1)-1), (b), (i), (s), (d)) 
    132  
    133 #define emit_alu_X_r(X, reg) ((emit_b11 << 6) | ((X) << 3) | ((reg) - 1)) 
    134  
    135 #define emit_alu_r_r(reg1, reg2) emit_alu_X_r(((reg1) - 1), (reg2)) 
    136  
    137 int emit_is8bit(long disp); 
    138  
    139 char * emit_disp8_32(char *pc, int disp); 
    140  
    141 void emit_sib(PARROT_INTERP, char *pc, int scale, int i, int base); 
    142  
    143 char * emit_r_X(PARROT_INTERP, char *pc, int reg_opcode, int base, int i, 
    144     int scale, long disp); 
    145  
    146 char * emit_shift_i_r(PARROT_INTERP, char *pc, int opcode, int imm, int reg); 
    147  
    148 char * emit_shift_i_m(PARROT_INTERP, char *pc, int opcode, int imm, 
    149                int base, int i, int scale, long disp); 
    150  
    151 char * emit_shift_r_r(PARROT_INTERP, char *pc, int opcode, int reg1, int reg2); 
    152  
    153 char * emit_shift_r_m(PARROT_INTERP, char *pc, int opcode, int reg, 
    154                int base, int i, int scale, long disp); 
    155  
    156 /* CDQ - need this to do multiply */ 
    157 #define emitm_cdq(pc) *((pc)++) = (char) 0x99 
    158  
    159 /* RET */ 
    160 #define emitm_ret(pc) *((pc)++) = (char) 0xc3 
    161  
    162 /* NOP */ 
    163 #define emit_nop(pc) *((pc)++) = (char) 0x90 
    164  
    165 /* PUSHes */ 
    166  
    167 #define emitm_pushl_r(pc, reg) \ 
    168     *((pc)++) = (char) 0x50 | ((reg) - 1) 
    169  
    170 #define emitm_pushl_i(pc, imm) { \ 
    171     *((pc)++) = (char) 0x68; \ 
    172     *(long *)(pc) = (long)(imm); \ 
    173     (pc) += 4; } 
    174  
    175 #define emitm_pushl_m(pc, mem) { \ 
    176        *((pc)++) = (char) 0xff; \ 
    177        *((pc)++) = (char) 0x35; \ 
    178        *(long *)(pc) = (long)(mem); \ 
    179        (pc) += 4; } 
    180  
    181 char * emit_pushl_m(PARROT_INTERP, char *pc, int base, int i, int scale, 
    182     long disp); 
    183  
    184 /* POPs */ 
    185  
    186 char * emit_popl_r(char *pc, int reg); 
    187  
    188 #  define emitm_popl_r(pc, reg) \ 
    189     (pc) = emit_popl_r((pc), (reg)) 
    190  
    191 char * emit_popl_m(PARROT_INTERP, char *pc, int base, int i, int scale, 
    192     long disp); 
    193  
    194 /* MOVes */ 
    195  
    196 char * emit_movb_r_r(char *pc, int reg1, int reg2); 
    197  
    198 #  define jit_emit_mov_rr_i(pc, reg2, reg1) if ((reg1) != (reg2)) { \ 
    199     *((pc)++) = (char) 0x89; \ 
    200     *((pc)++) = (char) emit_alu_r_r((reg1), (reg2)); } 
    201  
    202 #  define jit_emit_mov_ri_i(interp, pc, reg, imm) { \ 
    203     *((pc)++) = (char)(0xb8 | ((reg) - 1)); \ 
    204     *(long *)(pc) = (long)(imm); (pc) += 4; } 
    205  
    206 #  define emitm_movX_Y_Z(interp, op, pc, reg1, b, i, s, d) { \ 
    207     *((pc)++) = (char) (op); \ 
    208     (pc) = emit_r_m((interp), (pc), (reg1), (b), (i), (s), (long)(d)); } 
    209  
    210 #  define emitm_movb_r_m(interp, pc, reg1, b, i, s, d) \ 
    211     emitm_movX_Y_Z((interp), 0x88, (pc), (reg1), (b), (i), (s), (d)) 
    212  
    213 #  define emitm_movl_r_m(interp, pc, reg1, b, i, s, d) \ 
    214     emitm_movX_Y_Z((interp), 0x89, (pc), (reg1), (b), (i), (s), (d)) 
    215  
    216 /* move byte/word with sign extension */ 
    217 #  define emitm_movsbl_r_m(interp, pc, reg1, b, i, s, d) { \ 
    218     *((pc)++) = (char) 0x0f; \ 
    219     emitm_movX_Y_Z((interp), 0xBE, (pc), (reg1), (b), (i), (s), (d)); \ 
    220 } 
    221  
    222 #  define emitm_movswl_r_m(interp, pc, reg1, b, i, s, d) { \ 
    223     *((pc)++) = (char) 0x0f; \ 
    224     emitm_movX_Y_Z((interp), 0xBF, (pc), (reg1), (b), (i), (s), (d)); \ 
    225 } 
    226  
    227 #  define emitm_movsbl_r_r(pc, reg1, reg2) { \ 
    228     *((pc)++) = (char) 0x0f; \ 
    229     *((pc)++) = (char) 0xbe; \ 
    230     *((pc)++) = (char) emit_alu_r_r((reg1), (reg2)); \ 
    231 } 
    232  
    233 #  define emitm_movswl_r_r(pc, reg1, reg2) { \ 
    234     *((pc)++) = (char) 0x0f; \ 
    235     *((pc)++) = (char) 0xbf; \ 
    236     *((pc)++) = (char) emit_alu_r_r((reg1), (reg2)); \ 
    237 } 
    238  
    239 #  define emitm_movb_m_r(interp, pc, reg1, b, i, s, d) \ 
    240     emitm_movX_Y_Z((interp), 0x8a, (pc), (reg1), (b), (i), (s), (d)) 
    241  
    242 #  define emitm_movl_m_r(interp, pc, reg1, b, i, s, d) \ 
    243     emitm_movX_Y_Z((interp), 0x8b, (pc), (reg1), (b), (i), (s), (d)) 
    244  
    245 #  define emitm_lea_m_r(interp, pc, reg1, b, i, s, d) \ 
    246     emitm_movX_Y_Z((interp), 0x8d, (pc), (reg1), (b), (i), (s), (d)) 
    247  
    248 char * emit_movb_i_m(PARROT_INTERP, char *pc, char imm, int base, int i, 
    249     int scale, long disp); 
    250  
    251 #  define emitm_movl_i_m(pc, imm, b, i, s, d) { \ 
    252     *((pc)++) = (char) 0xc7; \ 
    253     (pc) = emit_r_X((interp), (pc), emit_reg(emit_b000), (b), (i), (s), (long)(d)); \ 
    254     *(long *)(pc) = (long)(imm); (pc) += 4; } 
    255  
    256 /* Various ALU formats */ 
    257  
    258 #  define emitm_alul_r_r(pc, op, reg1, reg2) { \ 
    259     *((pc)++) = (char) (op); *((pc)++) = (char) emit_alu_r_r((reg1), (reg2)); } 
    260  
    261 #  define emitm_alub_i_r(pc, op1, op2, imm, reg) { \ 
    262     *((pc)++) = (char) (op1); *((pc)++) = (char) emit_alu_X_r((op2), (reg)); *((pc)++) = (char)(imm); } 
    263  
    264 #  define emitm_alul_i_r(pc, op1, op2, imm, reg) { \ 
    265     *((pc)++) = (char) (op1); \ 
    266     *((pc)++) = (char) emit_alu_X_r((op2), (reg)); \ 
    267     *(long *)((pc)) = (long)(imm); (pc) += 4; } 
    268  
    269 #  define emitm_alul_i_m(pc, op1, op2, imm, b, i, s, d) { \ 
    270     *((pc)++) = (char) (op1); \ 
    271     (pc) = emit_r_X((interp), (pc), emit_reg(op2), (b), (i), (s), (d)); \ 
    272     *(long *)(pc) = (long)(imm); (pc) += 4; } 
    273  
    274 #  define emitm_alul_r_m(pc, op, reg, b, i, s, d) { \ 
    275     *((pc)++) = (char) (op); \ 
    276     (pc) = emit_r_X((interp), (pc), emit_reg((reg)-1), (b), (i), (s), (long)(d)); } 
    277  
    278 /* ADDs */ 
    279  
    280 #  define emitm_addb_r_r(pc, reg1, reg2) \ 
    281     emitm_alul_r_r((pc), 0x00, (reg1), (reg2)) 
    282  
    283 #  define emitm_addb_i_r(pc, imm, reg) \ 
    284     emitm_alub_i_r((pc), 0x83, emit_b000, (imm), (reg)) 
    285  
    286 #  define jit_emit_add_rr_i(interp, pc, reg1, reg2) \ 
    287     emitm_alul_r_r((pc), 0x01, (reg2), (reg1)) 
    288  
    289 #  define jit_emit_add_ri_i(interp, pc, reg, imm)   \ 
    290     emitm_alul_i_r((pc), 0x81, emit_b000, (imm), (reg)) 
    291  
    292 #  define emitm_addl_i_r(pc, imm, reg)   \ 
    293     emitm_alul_i_r((pc), 0x81, emit_b000, (imm), (reg)) 
    294  
    295 #  define emitm_addl_i_m(pc, imm, b, i, s, d) \ 
    296     emitm_alul_i_m((pc), 0x81, emit_b000, (imm), (b), (i), (s), (d)) 
    297  
    298 #  define emitm_addl_r_m(pc, reg, b, i, s, d) \ 
    299     emitm_alul_r_m((pc), 0x01, (reg), (b), (i), (s), (d)) 
    300  
    301 #  define emitm_addl_m_r(pc, reg, b, i, s, d) \ 
    302     emitm_alul_r_m((pc), 0x03, (reg), (b), (i), (s), (d)) 
    303  
    304 /* SUBs */ 
    305  
    306 #  define jit_emit_sub_rr_i(interp, pc, reg1, reg2) \ 
    307     emitm_alul_r_r((pc), 0x29, (reg2), (reg1)) 
    308  
    309 #  define emitm_subl_i_r(pc, imm, reg) \ 
    310     emitm_alul_i_r((pc), 0x81, emit_b101, (imm), (reg)) 
    311  
    312 #  define jit_emit_sub_ri_i(interp, pc, r, i) emitm_subl_i_r((pc), (i), (r)) 
    313  
    314 #  define emitm_subl_r_m(pc, reg, b, i, s, d) \ 
    315     emitm_alul_r_m((pc), 0x29, (reg), (b), (i), (s), (d)) 
    316  
    317 #  define emitm_subl_m_r(pc, reg, b, i, s, d) \ 
    318     emitm_alul_r_m((pc), 0x2b, (reg), (b), (i), (s), (d)) 
    319  
    320 #  define emitm_subl_i_m(pc, imm, b, i, s, d) \ 
    321     emitm_alul_i_m((pc), 0x81, emit_b101, (imm), (b), (i), (s), (d)) 
    322  
    323 /* These are used by both signed and unsigned EDIV, but only unsigned MUL */ 
    324 #  define emitm_alu_imp_r(pc, op, reg) { \ 
    325     *((pc)++) = (char) 0xf7; \ 
    326     *((pc)++) = (char) emit_alu_X_r((op), (reg)); } 
    327  
    328 #  define emitm_alu_imp_m(pc, op, b, i, s, d) { \ 
    329     *((pc)++) = (char) 0xf7; \ 
    330     (pc) = emit_r_X((interp), (pc), emit_reg(op), (b), (i), (s), (d)); } 
    331  
    332 /* Unsigned MUL and EDIV */ 
    333 /* EAX implicit destination in multiply and divide */ 
    334  
    335 #  define emitm_umull_r(pc, reg2) emitm_alu_imp_r((pc), emit_b100, (reg2)) 
    336  
    337 #  define emitm_udivl_r(pc, reg2) emitm_alu_imp_r((pc), emit_b110, (reg2)) 
    338  
    339 #  define emitm_umull_m(pc, b, i, s, d) \ 
    340     emitm_alu_imp_m((pc), emit_b100, (b), (i), (s), (d)) 
    341  
    342 #  define emitm_udivl_m(pc, b, i, s, d) \ 
    343     emitm_alu_imp_m((pc), emit_b110, (b), (i), (s), (d)) 
    344  
    345 /* Signed MUL and EDIV */ 
    346  
    347 #  define emitm_sdivl_r(pc, reg2) emitm_alu_imp_r((pc), emit_b111, (reg2)) 
    348  
    349 #  define emitm_sdivl_m(pc, b, i, s, d) \ 
    350     emitm_alu_imp_m((pc), emit_b111, (b), (i), (s), (d)) 
    351  
    352 #  define jit_emit_cdq(pc) *(pc)++ = 0x99 
    353  
    354 /* TEST for zero */ 
    355 #  define jit_emit_test_r_i(pc, reg1) emitm_alul_r_r((pc), 0x85, (reg1), (reg1)) 
    356  
    357 #  define emitm_smull_r(pc, reg2) emitm_alu_imp_r((pc), emit_b101, (reg2)) 
    358  
    359 #  define jit_emit_mul_rr_i(interp, pc, reg1, reg2) { \ 
    360     *(pc)++ = 0xf; \ 
    361     emitm_alul_r_r((pc), 0xaf, (reg1), (reg2)); } 
    362  
    363 #  define emitm_smull_r_m(pc, reg1, b, i, s, d) { \ 
    364     *(pc)++ = 0xf; \ 
    365     emitm_alul_r_m((pc), 0xaf, (reg1), (b), (i), (s), (d)); } 
    366  
    367 char * opt_mul(PARROT_INTERP, char *pc, int dest, INTVAL imm, int src); 
    368  
    369 #  define jit_emit_mul_rir_i(pc, dest, imm, src) \ 
    370        (pc) = opt_mul(interp, (pc), (dest), (imm), (src)) 
    371  
    372  
    373 #  define jit_emit_mul_ri_i(pc, r, imm) jit_emit_mul_rir_i((pc), (r), (imm), (r)) 
    374  
    375 #  define jit_emit_mul_RIM_ii(pc, reg, imm, ofs) \ 
    376     emitm_alul_r_m((pc), 0x69, (reg), emit_EBX, emit_None, 1, (ofs)); \ 
    377     *(long *)(pc) = (long)(imm); \ 
    378     (pc) += 4; 
    379  
    380 /* NEG */ 
    381  
    382 #  define jit_emit_neg_r_i(pc, reg) emitm_alu_imp_r((pc), emit_b011, (reg)) 
    383  
    384 #  define emitm_negl_m(pc, b, i, s, d) \ 
    385     emitm_alu_imp_m((pc), emit_b011, (b), (i), (s), (d)) 
    386  
    387 /* AND */ 
    388  
    389 #  define emit_andl_r_r(pc, reg1, reg2) emitm_alul_r_r((pc), 0x21, (reg1), (reg2)) 
    390 #  define jit_emit_band_rr_i(interp, pc, r1, r2) emit_andl_r_r((pc), (r2), (r1)) 
    391  
    392 #  define jit_emit_band_ri_i(interp, pc, reg, imm)  \ 
    393     emitm_alul_i_r((pc), 0x81, emit_b100, (imm), (reg)) 
    394  
    395 #  define emitm_andl_r_m(pc, reg, b, i, s, d) \ 
    396     emitm_alul_r_m((pc), 0x21, (reg), (b), (i), (s), (d)) 
    397  
    398 #  define emitm_andl_m_r(pc, reg, b, i, s, d) \ 
    399     emitm_alul_r_m((pc), 0x23, (reg), (b), (i), (s), (d)) 
    400  
    401 #  define emitm_andl_i_m(pc, imm, b, i, s, d) \ 
    402     emitm_alul_i_m((pc), 0x81, emit_b100, (imm), (b), (i), (s), (d)) 
    403  
    404 /* TEST op */ 
    405 #  define jit_emit_test_rr_i(pc, r1, r2) emitm_alul_r_r((pc), 0x85, (r1), (r2)) 
    406  
    407 #  define jit_emit_test_ri_i(pc, r, im)  \ 
    408            emitm_alul_i_r((pc), 0xF7, emit_b000, (im), (r)) 
    409  
    410 #  define jit_emit_test_RM_i(pc, r, offs)  \ 
    411            emitm_alul_r_m((pc), 0x85, (r), emit_EBX, 0, 1, (offs)) 
    412  
    413 /* OR */ 
    414  
    415 #  define jit_emit_bor_rr_i(interp, pc, reg1, reg2) emitm_alul_r_r((pc), 0x9, (reg2), (reg1)) 
    416  
    417 #  define jit_emit_bor_ri_i(interp, pc, reg, imm) \ 
    418     emitm_alul_i_r((pc), 0x81, emit_b001, (imm), (reg)) 
    419  
    420 #  define emitm_orl_r_m(pc, reg, b, i, s, d) \ 
    421     emitm_alul_r_m((pc), 0x09, (reg), (b), (i), (s), (d)) 
    422  
    423 #  define emitm_orl_m_r(pc, reg, b, i, s, d) \ 
    424     emitm_alul_r_m((pc), 0x0b, (reg), (b), (i), (s), (d)) 
    425  
    426 #  define emitm_orl_i_m(pc, imm, b, i, s, d) \ 
    427     emitm_alul_i_m((pc), 0x81, emit_b001, (imm), (b), (i), (s), (d)) 
    428  
    429 /* XOR */ 
    430  
    431 #  define jit_emit_bxor_rr_i(interp, pc, reg1, reg2) \ 
    432     emitm_alul_r_r((pc), 0x31, (reg2), (reg1)) 
    433  
    434 #  define jit_emit_bxor_ri_i(intepr, pc, reg, imm) \ 
    435     emitm_alul_i_r((pc), 0x81, emit_b110, (imm), (reg)) 
    436  
    437 #  define emitm_xorl_r_m(pc, reg, b, i, s, d) \ 
    438     emitm_alul_r_m((pc), 0x31, (reg), (b), (i), (s), (d)) 
    439  
    440 #  define emitm_xorl_m_r(pc, reg, b, i, s, d) \ 
    441     emitm_alul_r_m((pc), 0x33, (reg), (b), (i), (s), (d)) 
    442  
    443 #  define emitm_xorl_i_m(pc, imm, b, i, s, d) \ 
    444     emitm_alul_i_m((pc), 0x81, emit_b110, (imm), (b), (i), (s), (d)) 
    445  
    446 /* NOT */ 
    447  
    448 #  define jit_emit_not_r_i(pc, reg) emitm_alu_imp_r((pc), emit_b010, (reg)) 
    449 #  define emitm_notl_m(pc, b, i, s, d) \ 
    450     emitm_alu_imp_m((pc), emit_b010, (b), (i), (s), (d)) 
    451  
    452 #  define jit_emit_not_M_i(interp, pc, offs) emitm_notl_m((pc), emit_EBX, 0, 1, (offs)) 
    453  
    454 /* XCHG */ 
    455 #  define jit_emit_xchg_rr_i(interp, pc, r1, r2) { \ 
    456     if ((r1) != (r2)) { \ 
    457     *((pc)++) = (char) 0x87; \ 
    458     *((pc)++) = (char) emit_alu_r_r((r1), (r2)); \ 
    459     } \ 
    460 } 
    461  
    462 #  define jit_emit_xchg_rm_i(pc, r, m) { \ 
    463     emitm_alul_r_m((pc), 0x87, (r), emit_None, emit_None, emit_None, (m)) \ 
    464 } 
    465 #  define jit_emit_xchg_RM_i(interp, pc, r, offs) { \ 
    466     emitm_alul_r_m((pc), 0x87, (r), emit_EBX, emit_None, 1, (offs)) \ 
    467 } 
    468 #  define jit_emit_xchg_MR_i(interp, pc, offs, r) jit_emit_xchg_RM_i((interp), (pc), (r), (offs)) 
    469  
    470 /* SHL */ 
    471  
    472 #  define jit_emit_shl_ri_i(interp, pc, reg, imm) \ 
    473     { (pc) = emit_shift_i_r((interp), (pc), emit_b100, (imm), (reg)); } 
    474  
    475 #  define emitm_shll_i_m(pc, imm, b, i, s, d) \ 
    476     { (pc) = emit_shift_i_m((pc), emit_b100, (imm), (b), (i), (s), (d)); } 
    477  
    478 #  define emitm_shll_r_r(interp, pc, reg1, reg2) \ 
    479     { (pc) = emit_shift_r_r((interp), (pc), emit_b100, (reg1), (reg2)); } 
    480  
    481 #  define emitm_shll_r_m(pc, reg, b, i, s, d) \ 
    482     { (pc) = emit_shift_r_m((pc), emit_b100, (reg), (b), (i), (s), (d)); } 
    483  
    484 /* SHR */ 
    485  
    486 #  define jit_emit_lsr_ri_i(interp, pc, reg, imm) \ 
    487     { (pc) = emit_shift_i_r((interp), (pc), emit_b101, (imm), (reg)); } 
    488  
    489 #  define emitm_shrl_i_m(pc, imm, b, i, s, d) \ 
    490     { (pc) = emit_shift_i_m((pc), emit_b101, (imm), (b), (i), (s), (d)); } 
    491  
    492 #  define emitm_shrl_r_r(interp, pc, reg1, reg2) \ 
    493     { (pc) = emit_shift_r_r((interp), (pc), emit_b101, (reg1), (reg2)); } 
    494  
    495 #  define emitm_shrl_r_m(pc, reg, b, i, s, d) \ 
    496     { (pc) = emit_shift_r_m((pc), emit_b101, (reg), (b), (i), (s), (d)); } 
    497  
    498 /* SAL */ 
    499  
    500 #  define emitm_sall_i_r(interp, pc, imm, reg) \ 
    501     { (pc) = emit_shift_i_r((interp), (pc), emit_b100, (imm), (reg)); } 
    502  
    503 #  define emitm_sall_i_m(pc, imm, b, i, s, d) \ 
    504     { (pc) = emit_shift_i_m((pc), emit_b100, (imm), (b), (i), (s), (d)); } 
    505  
    506 #  define emitm_sall_r_r(interp, pc, reg1, reg2) \ 
    507     { (pc) = emit_shift_r_r((interp), (pc), emit_b100, (reg1), (reg2)); } 
    508  
    509 #  define emitm_sall_r_m(pc, reg, b, i, s, d) \ 
    510     { (pc) = emit_shift_r_m((pc), emit_b100, (reg), (b), (i), (s), (d)); } 
    511  
    512 /* SAR */ 
    513  
    514 #  define jit_emit_shr_ri_i(interp, pc, reg, imm) \ 
    515     { (pc) = emit_shift_i_r((interp), (pc), emit_b111, (imm), (reg)); } 
    516  
    517  
    518 #  define emitm_sarl_i_m(pc, imm, b, i, s, d) \ 
    519     { (pc) = emit_shift_i_m((pc), emit_b111, (imm), (b), (i), (s), (d)); } 
    520  
    521 #  define emitm_sarl_r_r(interp, pc, reg1, reg2) \ 
    522     { (pc) = emit_shift_r_r((interp), (pc), emit_b111, (reg1), (reg2)); } 
    523  
    524 #  define emitm_sarl_r_m(pc, reg, b, i, s, d) \ 
    525     { (pc) = emit_shift_r_m((pc), emit_b111, (reg), (b), (i), (s), (d)); } 
    526  
    527 /* rotate */ 
    528  
    529 #  define jit_emit_rol_ri_i(interp, pc, reg, imm) \ 
    530     { (pc) = emit_shift_i_r((interp), (pc), emit_b000, (imm), (reg)); } 
    531  
    532 #  define jit_emit_ror_ri_i(interp, pc, reg, imm) \ 
    533     { (pc) = emit_shift_i_r((interp), (pc), emit_b001, (imm), (reg)); } 
    534  
    535 /* interface, shift r1 by r2 bits */ 
    536  
    537 #  define jit_emit_shl_rr_i(interp, pc, r1, r2) \ 
    538     (pc) = opt_shift_rr((interp), jit_info, (r1), (r2), emit_b100) 
    539  
    540 #  define jit_emit_shl_RM_i(interp, pc, r1, offs)  \ 
    541     (pc) = opt_shift_rm((interp), jit_info, (r1), (offs), emit_b100) 
    542  
    543 /* shr seems to be the arithmetic shift */ 
    544 #  define jit_emit_shr_rr_i(interp, pc, r1, r2)  \ 
    545     (pc) = opt_shift_rr((interp), jit_info, (r1), (r2), emit_b111) 
    546  
    547 #  define jit_emit_shr_RM_i(interp, pc, r1, offs)  \ 
    548     (pc) = opt_shift_rm((interp), jit_info, (r1), (offs), emit_b111) 
    549  
    550 #  define jit_emit_lsr_rr_i(interp, pc, r1, r2)  \ 
    551     (pc) = opt_shift_rr((interp), jit_info, (r1), (r2), emit_b101) 
    552  
    553 #  define jit_emit_lsr_RM_i(interp, pc, r1, offs)  \ 
    554     (pc) = opt_shift_rm((interp), jit_info, (r1), (offs), emit_b101) 
    555  
    556 /* MOV (reg), reg */ 
    557 #  define emit_movm_r_r(pc, src, dest) \ 
    558     *((pc)++) = (char) 0x8b; \ 
    559     *((pc)++) = (char) (src) | (dest) << 3 
    560  
    561 /* MOV X(reg), reg */ 
    562 #  define emit_movb_i_r_r(pc, imm, src, dest) \ 
    563     *((pc)++) = (char)(0x8b); \ 
    564     *((p)c++) = (char)(0x40 | ((src) - 1) | ((dest) - 1) << 3); \ 
    565     *((pc)++) = (imm) 
    566  
    567 /* INC / DEC */ 
    568 #  define jit_emit_inc_r_i(pc, reg) *((pc)++) = (char)(0x40 | ((reg) - 1)) 
    569 #  define jit_emit_dec_r_i(pc, reg) *((pc)++) = (char)(0x48 | ((reg) - 1)) 
    570  
    571 /* Floating point ops */ 
    572  
    573 #  define emitm_floatop 0xd8  /* 11011000 */ 
    574 #  define jit_emit_dec_fsp(pc) { *((pc)++) = (char) 0xD9; *((pc)++) = (char) 0xF6; } 
    575 #  define jit_emit_inc_fsp(pc) { *((pc)++) = (char) 0xD9; *((pc)++) = (char) 0xF7; } 
    576  
    577 #  define emitm_fl_2(interp, pc, mf, opa, opb, b, i, s, d) { \ 
    578     *((pc)++) = (char)(emitm_floatop | ((mf) << 1) | (opa)); \ 
    579     (pc) = emit_r_X((interp), (pc), emit_reg(opb), (b), (i), (s), (long)(d)); } 
    580  
    581 #  define emitm_fl_3(pc, d_p_opa, opb_r, sti) { \ 
    582     *((pc)++) = (char)(emitm_floatop | (d_p_opa)); \ 
    583     *((pc)++) = (char)(0xc0 | ((opb_r) << 3) | (sti)); } 
    584  
    585 #  define emitm_fl_4(pc, op) { \ 
    586     *((pc)++) = (char)(emitm_floatop | emit_b001); \ 
    587     *((pc)++) = (char)(0xe0 | (op)); } 
    588  
    589 /* Integer loads and stores */ 
    590 #  define emitm_fildl(interp, pc, b, i, s, d) \ 
    591     emitm_fl_2((interp), (pc), emit_b01, 1, emit_b000, (b), (i), (s), (d)) 
    592  
    593 #  define emitm_fistpl(interp, pc, b, i, s, d) \ 
    594     emitm_fl_2((interp), (pc), emit_b01, 1, emit_b011, (b), (i), (s), (d)) 
    595  
    596 #  define emitm_fistl(interp, pc, b, i, s, d) \ 
    597     emitm_fl_2((interp), (pc), emit_b01, 1, emit_b010, (b), (i), (s), (d)) 
    598  
    599 /* long long integer load/store */ 
    600 #  define emitm_fildll(interp, pc, b, i, s, d) \ 
    601     emitm_fl_2((interp), (pc), emit_b11, 1, emit_b101, (b), (i), (s), (d)) 
    602  
    603 #  define emitm_fistpll(interp, pc, b, i, s, d) \ 
    604     emitm_fl_2((interp), (pc), emit_b11, 1, emit_b111, (b), (i), (s), (d)) 
    605  
    606 /* Double loads and stores */ 
    607 #  define emitm_fldl(interp, pc, b, i, s, d) \ 
    608     emitm_fl_2((interp), (pc), emit_b10, 1, emit_b000, (b), (i), (s), (d)) 
    609  
    610 #  define emitm_fstpl(interp, pc, b, i, s, d) \ 
    611     emitm_fl_2((interp), (pc), emit_b10, 1, emit_b011, (b), (i), (s), (d)) 
    612  
    613 #  define emitm_fstl(interp, pc, b, i, s, d) \ 
    614     emitm_fl_2((interp), (pc), emit_b10, 1, emit_b010, (b), (i), (s), (d)) 
    615  
    616 /* long double load / store */ 
    617 #  define emitm_fldt(interp, pc, b, i, s, d) \ 
    618     emitm_fl_2((interp), (pc), emit_b01, 1, emit_b101, (b), (i), (s), (d)) 
    619  
    620 #  define emitm_fstpt(interp, pc, b, i, s, d) \ 
    621     emitm_fl_2((interp), (pc), emit_b01, 1, emit_b111, (b), (i), (s), (d)) 
    622  
    623 /* short float load / store */ 
    624 #  define emitm_flds(interp, pc, b, i, s, d) \ 
    625     emitm_fl_2((interp), (pc), emit_b00, 1, emit_b000, (b), (i), (s), (d)) 
    626  
    627 #  define emitm_fstps(interp, pc, b, i, s, d) \ 
    628     emitm_fl_2((interp), (pc), emit_b00, 1, emit_b010, (b), (i), (s), (d)) 
    629  
    630 #if NUMVAL_SIZE == 8 
    631  
    632 #  define jit_emit_fload_m_n(interp, pc, address) \ 
    633       emitm_fldl((interp), (pc), emit_None, emit_None, emit_None, (address)) 
    634  
    635 #  define jit_emit_fload_mb_n(interp, pc, base, offs) \ 
    636       emitm_fldl((interp), (pc), (base), emit_None, 1, (offs)) 
    637  
    638 #  define jit_emit_fstore_m_n(interp, pc, address) \ 
    639       emitm_fstpl((interp), (pc), emit_None, emit_None, emit_None, (address)) 
    640  
    641 #  define jit_emit_fstore_mb_n(interp, pc, base, offs) \ 
    642       emitm_fstpl((interp), (pc), (base), emit_None, 1, (offs)) 
    643  
    644 #  define jit_emit_fst_mb_n(interp, pc, base, offs) \ 
    645       emitm_fstl((interp), (pc), (base), emit_None, 1, (offs)) 
    646  
    647 #else /* NUMVAL_SIZE */ 
    648  
    649 #  define jit_emit_fload_m_n(interp, pc, address) \ 
    650       emitm_fldt((pc), emit_None, emit_None, emit_None, (address)) 
    651  
    652 #  define jit_emit_fload_mb_n(interp, pc, base, offs) \ 
    653       emitm_fldt((pc), (base), emit_None, 1, (offs)) 
    654  
    655 #  define jit_emit_fstore_m_n(pc, address) \ 
    656       emitm_fstpt((pc), emit_None, emit_None, emit_None, (address)) 
    657  
    658 #  define jit_emit_fstore_mb_n(interp, pc, base, offs) \ 
    659       emitm_fstpt((pc), (base), emit_None, 1, (offs)) 
    660  
    661 #  define jit_emit_fst_mb_n(interp, pc, base, offs) \ 
    662       emitm_fstt((pc), (base), emit_None, 1, (offs)) 
    663  
    664 #endif /* NUMVAL_SIZE */ 
    665  
    666 #if INTVAL_SIZE == 4 
    667  
    668 #  define jit_emit_fload_m_i(interp, pc, address) \ 
    669       emitm_fildl((interp), (pc), emit_None, emit_None, emit_None, (address)) 
    670 #  define jit_emit_fload_mb_i(interp, pc, offs) \ 
    671       emitm_fildl((interp), (pc), emit_EBX, emit_None, 1, (offs)) 
    672 #  define jit_emit_fstore_m_i(pc, m) \ 
    673       emitm_fistpl((pc), emit_None, emit_None, emit_None, (m)) 
    674  
    675 #else /* INTVAL_SIZE */ 
    676  
    677 #  define jit_emit_fload_m_i(interp, pc, address) \ 
    678       emitm_fildll((interp), (pc), emit_None, emit_None, emit_None, (address)) 
    679 #  define jit_emit_fload_mb_i(interp, pc, offs) \ 
    680       emitm_fildll((interp), (pc), emit_EBX, emit_None, 1, (offs)) 
    681 #  define jit_emit_fstore_m_i(pc, m) \ 
    682       emitm_fistpll((pc), emit_None, emit_None, emit_None, (m)) 
    683  
    684 #endif /* INTVAL_SIZE */ 
    685  
    686 /* 0xD8 ops */ 
    687 #  define emitm_fadd(pc, sti) emitm_fl_3((pc), emit_b000, emit_b000, (sti)) 
    688 #  define emitm_fmul(pc, sti) emitm_fl_3((pc), emit_b000, emit_b001, (sti)) 
    689 #  define emitm_fsub(pc, sti) emitm_fl_3((pc), emit_b000, emit_b100, (sti)) 
    690 #  define emitm_fdiv(pc, sti) emitm_fl_3((pc), emit_b000, emit_b110, (sti)) 
    691  
    692 /* 0xD9 ops */ 
    693 #  define emitm_fldz(pc)  { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xee; } 
    694 #  define emitm_fld1(pc)  { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xe8; } 
    695 #  define emitm_fsqrt(pc) { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xfa; } 
    696 #  define emitm_fsin(pc)  { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xfe; } 
    697 #  define emitm_fcos(pc)  { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xff; } 
    698 #  define emitm_fxam(pc)  { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xe5; } 
    699  
    700 /* FXCH ST, ST(i) , optimize 2 consecutive fxch with same reg */ 
    701 #  define emitm_fxch(pc, sti) { \ 
    702     emitm_fl_3((pc), emit_b001, emit_b001, (sti)); \ 
    703 } 
    704  
    705 /* FLD ST, ST(i), optimized FSTP(N+1);FLD(N) => FST(N+1)  */ 
    706 extern unsigned char *lastpc; 
    707 #  define emitm_fld(pc, sti) do { \ 
    708      if ((unsigned char *)(pc) == (lastpc + 2) && \ 
    709        (int)(*lastpc) == (int)0xDD && \ 
    710        (int)lastpc[1] == (int)(0xD8+(sti)+1)) \ 
    711        lastpc[1] = 0xD0+(sti)+1; \ 
    712      else \ 
    713        emitm_fl_3((pc), emit_b001, emit_b000, (sti)); \ 
    714   } while (0) 
    715  
    716 /* 0xDA, 0xDB ops */ 
    717 /* FCMOV*, FCOMI PPRO */ 
    718  
    719 /* 0xDC like 0xD8 with reversed operands */ 
    720 #  define emitm_faddr(pc, sti) emitm_fl_3((pc), emit_b100, emit_b000, (sti)) 
    721 #  define emitm_fmulr(pc, sti) emitm_fl_3((pc), emit_b100, emit_b001, (sti)) 
    722 #  define emitm_fsubr(pc, sti) emitm_fl_3((pc), emit_b100, emit_b100, (sti)) 
    723  
    724 /* 0xDD ops */ 
    725 /* FFree ST(i) */ 
    726 #  define emitm_ffree(pc, sti) emitm_fl_3((pc), emit_b101, emit_b000, (sti)) 
    727  
    728 /* FST ST(i) = ST */ 
    729 #  define emitm_fst(pc, sti) emitm_fl_3((pc), emit_b101, emit_b010, (sti)) 
    730  
    731 /* FSTP ST(i) = ST, POP */ 
    732 #  define emitm_fstp(pc, sti) { \ 
    733     lastpc = (unsigned char*) (pc); \ 
    734     emitm_fl_3((pc), emit_b101, emit_b011, (sti)); \ 
    735 } 
    736  
    737 /* FUCOM ST(i) <=> ST  unordered compares */ 
    738 #  define emitm_fucom(pc, sti) emitm_fl_3((pc), emit_b101, emit_b100, (sti)) 
    739  
    740 /* FUCOMP ST(i) <=> ST, POP */ 
    741 #  define emitm_fucomp(pc, sti) emitm_fl_3((pc), emit_b101, emit_b101, (sti)) 
    742  
    743 /* 0xDE ops */ 
    744 /* FADDP Add ST(i) = ST + ST(i); POP  */ 
    745 #  define emitm_faddp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b000, (sti)) 
    746  
    747 /* FMULP Mul ST(i) = ST * ST(i); POP  */ 
    748 #  define emitm_fmulp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b001, (sti)) 
    749  
    750 /* FSUB ST = ST - ST(i) */ 
    751  
    752 /* FSUBRP SubR ST(i) = ST - ST(i); POP  */ 
    753 #  define emitm_fsubrp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b100, (sti)) 
    754  
    755 /* FSUBP Sub ST(i) = ST(i) - ST; POP  */ 
    756 #  define emitm_fsubp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b101, (sti)) 
    757  
    758 /* FDIVRP DivR ST(i) = ST(i) / ST(0); POP  */ 
    759 #  define emitm_fdivrp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b110, (sti)) 
    760  
    761 /* FDIVP Div ST(i) = ST(0) / ST(i); POP ST(0) */ 
    762 #  define emitm_fdivp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b111, (sti)) 
    763  
    764 /* 0xDF OPS: FCOMIP, FUCOMIP PPRO */ 
    765  
    766 /* Negate - called change sign */ 
    767 #  define emitm_fchs(pc) emitm_fl_4((pc), 0) 
    768  
    769 /* ABS - ST(0) = ABS(ST(0)) */ 
    770 #  define emitm_fabs(pc) emitm_fl_4((pc), 1) 
    771  
    772 /* Comparisons */ 
    773  
    774 #  define emitm_fcom(pc, sti) emitm_fl_3((pc), emit_b000, emit_b010, (sti)) 
    775  
    776 #  define emitm_fcomp(pc, sti) emitm_fl_3((pc), emit_b000, emit_b011, (sti)) 
    777  
    778 #ifdef PARROT_HAS_JIT_FCOMIP 
    779 #  define emitm_fcomip(pc, sti) emitm_fl_3((pc), emit_b111, emit_b110, (sti)) 
    780 #  define emitm_fcomi(pc, sti) emitm_fl_3((pc), emit_b011, emit_b110, (sti)) 
    781 #else 
    782 #  define emitm_fcomip(pc, sti) do { \ 
    783       emitm_fcomp((pc), (sti)); \ 
    784       emitm_fstw(pc); \ 
    785       emitm_sahf(pc); \ 
    786     } while (0) 
    787 #  define emitm_fcomi(pc, sti) do { \ 
    788       emitm_fcom((pc), (sti)); \ 
    789       emitm_fstw(pc); \ 
    790       emitm_sahf(pc); \ 
    791     } while (0) 
    792 #endif 
    793  
    794 #  define emitm_fcompp(pc) { *((pc)++) = (char) 0xde; *((pc)++) = (char) 0xd9; } 
    795  
    796 #  define emitm_fcom_m(interp, pc, b, i, s, d) \ 
    797     emitm_fl_2((interp), (pc), emit_b10, 0, emit_b010, (b), (i), (s), (d)) 
    798  
    799 #  define emitm_fcomp_m(interp, pc, b, i, s, d) \ 
    800     emitm_fl_2((interp), (pc), emit_b10, 0, emit_b011, (b), (i), (s), (d)) 
    801  
    802 /* ST -= real64 */ 
    803 #  define emitm_fsub_m(interp, pc, b, i, s, d) \ 
    804     emitm_fl_2((interp), (pc), emit_b10, 0, emit_b100, (b), (i), (s), (d)) 
    805  
    806 /* ST -= int32_mem */ 
    807 #  define emitm_fisub_m(interp, pc, b, i, s, d) \ 
    808     emitm_fl_2((interp), (pc), emit_b01, 0, emit_b100, (b), (i), (s), (d)) 
    809  
    810 #  define emitm_fadd_m(interp, pc, b, i, s, d) \ 
    811     emitm_fl_2((interp), (pc), emit_b10, 0, emit_b000, (b), (i), (s), (d)) 
    812  
    813 /* ST += int32_mem */ 
    814 #  define emitm_fiadd_m(interp, pc, b, i, s, d) \ 
    815     emitm_fl_2((interp), (pc), emit_b01, 0, emit_b000, (b), (i), (s), (d)) 
    816  
    817 /* ST *= real64 */ 
    818 #  define emitm_fmul_m(interp, pc, b, i, s, d) \ 
    819     emitm_fl_2((interp), (pc), emit_b10, 0, emit_b001, (b), (i), (s), (d)) 
    820  
    821 /* ST *= int32_mem */ 
    822 #  define emitm_fimul_m(interp, pc, b, i, s, d) \ 
    823     emitm_fl_2((interp), (pc), emit_b01, 0, emit_b001, (b), (i), (s), (d)) 
    824  
    825 /* ST /= real64 */ 
    826 #  define emitm_fdiv_m(interp, pc, b, i, s, d) \ 
    827     emitm_fl_2((interp), (pc), emit_b10, 0, emit_b110, (b), (i), (s), (d)) 
    828  
    829 /* ST /= int32_mem */ 
    830 #  define emitm_fidiv_m(interp, pc, b, i, s, d) \ 
    831     emitm_fl_2((interp), (pc), emit_b01, 0, emit_b110, (b), (i), (s), (d)) 
    832  
    833 /* Ops Needed to support loading EFLAGs for conditional branches */ 
    834 #  define emitm_fstw(pc) emitm_fl_3((pc), emit_b111, emit_b100, emit_b000) 
    835  
    836 #  define emitm_sahf(pc) *((pc)++) = (char) 0x9e 
    837  
    838 /* misc float */ 
    839 #  define emitm_ftst(pc) { *(pc)++ = 0xd9; *(pc)++ = 0xE4; } 
    840 #  define emitm_fprem(pc) { *(pc)++ = 0xd9; *(pc)++ = 0xF8; } 
    841 #  define emitm_fprem1(pc) { *(pc)++ = 0xd9; *(pc)++ = 0xF5; } 
    842  
    843 #  define emitm_fldcw(interp, pc, mem) \ 
    844     emitm_fl_2((interp), (pc), emit_b00, 1, emit_b101, 0, 0, 0, (mem)) 
    845  
    846 #if defined(NEG_MINUS_ZERO) 
    847 #  define jit_emit_neg_r_n(pc, r) { \ 
    848        if (r) { \ 
    849          emitm_fld((pc), (r)); \ 
    850        } \ 
    851        emitm_fchs(pc); \ 
    852        if (r) { \ 
    853          emitm_fstp((pc), ((r)+1)); \ 
    854        } \ 
    855      } 
    856  
    857 #  define jit_emit_neg_M_n(interp, pc, mem) { \ 
    858        jit_emit_fload_mb_n((interp), (pc), emit_EBX, (mem)); \ 
    859        emitm_fchs(pc); \ 
    860        jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (mem)); \ 
    861      } 
    862  
    863 #elif defined(NEG_ZERO_SUB) 
    864  
    865 #  define jit_emit_neg_r_n(pc, r) { \ 
    866        emitm_fldz(pc); \ 
    867        emitm_fsubrp((pc), ((r)+1)); \ 
    868      } 
    869  
    870 #  define jit_emit_neg_M_n(interp, pc, mem) { \ 
    871        jit_emit_fload_mb_n((interp), (pc), emit_EBX, (mem)); \ 
    872        emitm_fldz(pc); \ 
    873        emitm_fsubrp((pc), 1); \ 
    874        jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (mem)); \ 
    875      } 
    876 #else 
    877  
    878 #  define jit_emit_neg_r_n(pc, r) { \ 
    879        if (r) { \ 
    880          emitm_fld((pc), (r)); \ 
    881        } \ 
    882        emitm_ftst(pc); \ 
    883        emitm_fstw(pc); \ 
    884        emitm_sahf(pc); \ 
    885        emitm_jxs((pc), emitm_jz, 2); \ 
    886        emitm_fchs(pc); \ 
    887        if (r) { \ 
    888          emitm_fstp((pc), ((r)+1)); \ 
    889        } \ 
    890      } 
    891  
    892 #  define jit_emit_neg_M_n(interp, pc, mem) { \ 
    893        jit_emit_fload_mb_n((interp), (pc), emit_EBX, (mem)); \ 
    894        emitm_ftst(pc); \ 
    895        emitm_fstw(pc); \ 
    896        emitm_sahf(pc); \ 
    897        emitm_jxs((pc), emitm_jz, 2); \ 
    898        emitm_fchs(pc); \ 
    899        jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (mem)); \ 
    900      } 
    901 #endif 
    902  
    903 #  define jit_emit_sin_r_n(pc, r) \ 
    904      if (r) { \ 
    905        emitm_fld((pc), (r)); \ 
    906      } \ 
    907      emitm_fsin(pc); \ 
    908      if (r) { \ 
    909        emitm_fstp((pc), ((r)+1)); \ 
    910      } 
    911  
    912 #  define jit_emit_cos_r_n(pc, r) \ 
    913      if (r) { \ 
    914        emitm_fld((pc), (r)); \ 
    915      } \ 
    916      emitm_fcos(pc); \ 
    917      if (r) { \ 
    918        emitm_fstp((pc), ((r)+1)); \ 
    919      } 
    920  
    921 #  define jit_emit_sqrt_r_n(pc, r) \ 
    922      if (r) { \ 
    923        emitm_fld((pc), (r)); \ 
    924      } \ 
    925      emitm_fsqrt(pc); \ 
    926      if (r) { \ 
    927        emitm_fstp((pc), ((r)+1)); \ 
    928      } 
    929  
    930 #  define jit_emit_abs_r_n(pc, r) { \ 
    931      if (r) { \ 
    932        emitm_fld((pc), (r)); \ 
    933      } \ 
    934      emitm_fabs(pc); \ 
    935      if (r) { \ 
    936        emitm_fstp((pc), ((r)+1)); \ 
    937      } \ 
    938    } 
    939  
    940 #  define jit_emit_abs_r_i(pc, r) { \ 
    941      jit_emit_test_r_i((pc), (r)); \ 
    942      emitm_jxs((pc), emitm_jns, 3); \ 
    943      jit_emit_not_r_i((pc), (r)); \ 
    944      jit_emit_inc_r_i((pc), (r)); \ 
    945    } 
    946  
    947 #  define jit_emit_abs_m_n(interp, pc, mem) { \ 
    948      jit_emit_fload_m_n((interp), (pc), (mem)); \ 
    949      emitm_fabs(pc); \ 
    950      jit_emit_fstore_m_n((pc), (mem)); \ 
    951    } 
    952  
    953 /* Integer comparisons */ 
    954 #  define jit_emit_cmp_rr(pc, reg1, reg2) \ 
    955     emitm_alul_r_r((pc), 0x39, (reg2), (reg1)) 
    956 #  define jit_emit_cmp_rr_i(pc, r1, r2) jit_emit_cmp_rr((pc), (r1), (r2)) 
    957  
    958 #  define emitm_cmpl_r_m(pc, reg, b, i, s, d) \ 
    959     emitm_alul_r_m((pc), 0x3b, (reg), (b), (i), (s), (d)) 
    960  
    961 #  define emitm_cmpl_m_r(pc, reg, b, i, s, d) \ 
    962     emitm_alul_r_m((pc), 0x39, (reg), (b), (i), (s), (d)) 
    963  
    964 #  define jit_emit_cmp_ri_i(interp, pc, reg, imm) \ 
    965     emitm_alul_i_r((pc), 0x81, emit_b111, (imm), (reg)) 
    966  
    967 /* Unconditional Jump/Call */ 
    968  
    969 #  define emitm_call_cfunc(pc, func) emitm_calll((pc), (char *)(func) - (pc) - 4) 
    970  
    971 #  define emitm_calll(pc, disp) { \ 
    972     *((pc)++) = (char) 0xe8; \ 
    973     *(long *)(pc) = (disp); (pc) += 4; } 
    974  
    975 #  define emitm_callr(pc, reg) { \ 
    976     *((pc)++) = (char) 0xff; \ 
    977     *((pc)++) = (char) 0xd0 | ((reg) - 1); } 
    978  
    979 #  define emitm_callm(pc, b, i, s, d) { \ 
    980        *((pc)++) = (char) 0xff; \ 
    981        (pc) = emit_r_X((interp), (pc), emit_reg(emit_b010), (b), (i), (s), (d)); } 
    982  
    983 #  define emitm_jumps(pc, disp) { \ 
    984     *((pc)++) = (char) 0xeb; \ 
    985     *((pc)++) = (disp); } 
    986  
    987 #  define emitm_jumpl(pc, disp) { \ 
    988     *((pc)++) = (char) 0xe9; \ 
    989     *(long *)(pc) = (disp); (pc) += 4; } 
    990  
    991 #  define emitm_jumpr(pc, reg) { \ 
    992     *((pc)++) = (char) 0xff; \ 
    993     *((pc)++) = (char)(0xe0 | ((reg) - 1)); } 
    994  
    995 #  define emitm_jumpm(pc, b, i, s, d) { \ 
    996        *((pc)++) = (char) 0xff; \ 
    997        (pc) = emit_r_X((interp), (pc), emit_reg(emit_b100), (b), (i), (s), (d)); } 
    998  
    999 /* Conditional jumps */ 
    1000  
    1001 /* Short jump - 8 bit disp */ 
    1002 #  define emitm_jxs(pc, code, disp) { \ 
    1003     *((pc)++) = (char)(0x70 | (code)); \ 
    1004     *((pc)++) = (char)(disp); } 
    1005  
    1006 /* Long jump - 32 bit disp */ 
    1007 #  define emitm_jxl(pc, code, disp) { \ 
    1008     *((pc)++) = (char) 0x0f; \ 
    1009     *((pc)++) = (char)(0x80 | (code));  \ 
    1010     *(long *)(pc) = (disp); (pc) += 4; } 
    1011  
    1012 #  define emitm_jo   0 
    1013 #  define emitm_jno  1 
    1014 #  define emitm_jb   2 
    1015 #  define emitm_jnb  3 
    1016 #  define emitm_jz   4 
    1017 #  define emitm_je emitm_jz 
    1018 #  define emitm_jnz  5 
    1019 #  define emitm_jne emitm_jnz 
    1020 #  define emitm_jbe  6 
    1021 #  define emitm_ja   7 
    1022 #  define emitm_js   8 
    1023 #  define emitm_jns  9 
    1024 #  define emitm_jp  10 
    1025 #  define emitm_jnp 11 
    1026 #  define emitm_jl  12 
    1027 #  define emitm_jnl 13 
    1028 #  define emitm_jle 14 
    1029 #  define emitm_jg  15 
    1030  
    1031 /* set byte conditional */ 
    1032 #  define jit_emit_setcc_r(pc, cc, r) \ 
    1033     *(pc)++ = 0x0f; \ 
    1034     *(pc)++ = 0x90 + (cc); \ 
    1035     *(pc)++ = (char) emit_alu_X_r(0, (r)) 
    1036  
    103741/* 
    1038  * core.jit interface 
    1039  * 
    1040  * The new offset based versions have uppercase RM or MR inside 
    1041  * That's probably only during transition time 
    1042  */ 
    1043  
    1044 #  define jit_emit_mov_mi_i(pc, dest, immediate) \ 
    1045     emitm_movl_i_m((pc), (immediate), emit_None, emit_None, emit_None, (dest)) 
    1046  
    1047 #  define jit_emit_mov_MI_i(interp, pc, offs, immediate) \ 
    1048     emitm_movl_i_m((pc), (immediate), emit_EBX, emit_None, 1, (offs)) 
    1049  
    1050 #  define jit_emit_mov_rm_i(interp, pc, reg, address) \ 
    1051     emitm_movl_m_r((interp), (pc), (reg), emit_None, emit_None, emit_None, (address)) 
    1052  
    1053 #  define jit_emit_mov_RM_i(interp, pc, reg, offs) \ 
    1054     emitm_movl_m_r((interp), (pc), (reg), emit_EBX, emit_None, 1, (offs)) 
    1055  
    1056 #  define jit_emit_mov_mr_i(interp, pc, address, reg) \ 
    1057     emitm_movl_r_m((interp), (pc), (reg), emit_None, emit_None, emit_None, (address)) 
    1058  
    1059 #  define jit_emit_mov_MR_i(interp, pc, offs, reg) \ 
    1060     emitm_movl_r_m((interp), (pc), (reg), emit_EBX, emit_None, 1, (offs)) 
    1061  
    1062 #  define jit_emit_mul_RM_i(interp, pc, reg, offs) \ 
    1063     emitm_smull_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs)) 
    1064  
    1065 #  define jit_emit_sub_RM_i(interp, pc, reg, offs) \ 
    1066     emitm_subl_m_r((pc), (reg), emit_EBX, emit_None, 1, (offs)) 
    1067  
    1068 #  define jit_emit_sub_MR_i(interp, pc, offs, reg) \ 
    1069     emitm_subl_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs)) 
    1070  
    1071 #  define jit_emit_sub_MI_i(pc, offs, imm) \ 
    1072     emitm_subl_i_m((pc), (imm), emit_EBX, emit_None, 1, (offs)) 
    1073  
    1074 #  define jit_emit_add_RM_i(interp, pc, reg, offs) \ 
    1075     emitm_addl_m_r((pc), (reg), emit_EBX, emit_None, 1, (offs)) 
    1076  
    1077 #  define jit_emit_add_MR_i(interp, pc, offs, reg) \ 
    1078     emitm_addl_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs)) 
    1079  
    1080 #  define jit_emit_add_MI_i(pc, offs, imm) \ 
    1081     emitm_addl_i_m((pc), (imm), emit_EBX, emit_None, 1, (offs)) 
    1082  
    1083 #  define jit_emit_cmp_rm_i(pc, reg, address) \ 
    1084     emitm_cmpl_r_m((pc), (reg), emit_None, emit_None, emit_None, (address)) 
    1085  
    1086 #  define jit_emit_cmp_RM_i(interp, pc, reg, offs) \ 
    1087     emitm_cmpl_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs)) 
    1088  
    1089 #  define jit_emit_cmp_MR_i(interp, pc, offs, reg) \ 
    1090     emitm_cmpl_m_r((pc), (reg), emit_EBX, emit_None, 1, (offs)) 
    1091  
    1092 /* high level routines, behave like real 2 register FP */ 
    1093  
    1094 /* mapped float registers numbers are ST(1)-ST(4). 
    1095  * scratch register is ST(0) 
    1096  */ 
    1097  
    1098 /* ST(i) <- numvar */ 
    1099 #  define jit_emit_mov_RM_n(interp, pc, r, d) { \ 
    1100     jit_emit_fload_mb_n((interp), (pc), emit_EBX, (d)); \ 
    1101     emitm_fstp((pc), ((r)+1)); \ 
    1102 } 
    1103  
    1104 /* ST(i) <= NUM_CONST */ 
    1105 #  define jit_emit_mov_ri_n(interp, pc, r, i) { \ 
    1106     jit_emit_fload_m_n((interp), (pc), (i)); \ 
    1107     emitm_fstp((pc), ((r)+1)); \ 
    1108 } 
    1109  
    1110 /* ST(i) <= &INT_CONST */ 
    1111 #  define jit_emit_mov_ri_ni(interp, pc, r, i) { \ 
    1112     jit_emit_fload_m_i((interp), (pc), (i)); \ 
    1113     emitm_fstp((pc), ((r)+1)); \ 
    1114 } 
    1115  
    1116 /* ST(i) <= INT_REG */ 
    1117 #  define jit_emit_mov_RM_ni(interp, pc, r, i) { \ 
    1118     jit_emit_fload_mb_i((interp), (pc), (i)); \ 
    1119     emitm_fstp((pc), ((r)+1)); \ 
    1120 } 
    1121  
    1122 /* NUM_REG(i) <= &INT_CONST 
    1123  * the int const i is loaded from the code memory 
    1124  */ 
    1125 #  define jit_emit_mov_MI_ni(interp, pc, offs, i) { \ 
    1126     jit_emit_fload_m_i((interp), (pc), (i)); \ 
    1127     jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (offs)); \ 
    1128 } 
    1129  
    1130 /* INT_REG <= ST(i) */ 
    1131 #  define jit_emit_mov_mr_in(pc, mem, r) { \ 
    1132     emitm_fld((pc), (r)); \ 
    1133     jit_emit_fstore_m_i((pc), (mem)); \ 
    1134 } 
    1135  
    1136 /* numvar <- ST(i) */ 
    1137 #  define jit_emit_mov_mr_n(pc, d, r) { \ 
    1138     emitm_fld((pc), (r)); \ 
    1139     jit_emit_fstore_m_n((pc), (d)); \ 
    1140 } 
    1141  
    1142 #  define jit_emit_mov_MR_n(interp, pc, d, r) { \ 
    1143     if (r) { \ 
    1144         emitm_fld((pc), (r)); \ 
    1145         jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (d)); \ 
    1146     } \ 
    1147     else { \ 
    1148         jit_emit_fst_mb_n((interp), (pc), emit_EBX, (d)); \ 
    1149     } \ 
    1150 } 
    1151  
    1152 /* ST(r1) <= ST(r2) */ 
    1153 #  define jit_emit_mov_rr_n(pc, r1, r2) { \ 
    1154     if ((r1) != (r2)) { \ 
    1155       if (r2) { \ 
    1156         emitm_fld((pc), (r2)); \ 
    1157         emitm_fstp((pc), ((r1)+1)); \ 
    1158       } \ 
    1159       else { \ 
    1160         emitm_fst((pc), (r1)); \ 
    1161       } \ 
    1162     } \ 
    1163 } 
    1164  
    1165 /* ST(r1) xchg ST(r2) */ 
    1166 #  define jit_emit_xchg_rr_n(interp, pc, r1, r2) { \ 
    1167     if ((r1) != (r2)) { \ 
    1168       emitm_fld((pc), (r1)); \ 
    1169       emitm_fld((pc), ((r2)+1)); \ 
    1170       emitm_fstp((pc), ((r1)+2)); \ 
    1171       emitm_fstp((pc), ((r2)+1)); \ 
    1172     } \ 
    1173 } 
    1174  
    1175 #  define jit_emit_xchg_RM_n(interp, pc, r, offs) { \ 
    1176     emitm_fld((pc), (r)); \ 
    1177     jit_emit_fload_mb_n((interp), (pc), emit_EBX, (offs)); \ 
    1178     emitm_fstp((pc), ((r)+2)); \ 
    1179     jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (offs)); \ 
    1180 } 
    1181  
    1182 #  define jit_emit_xchg_MR_n(interp, pc, offs, r) { \ 
    1183     emitm_fld((pc), (r)); \ 
    1184     jit_emit_fload_mb_n((interp), (pc), emit_EBX, (offs)); \ 
    1185     emitm_fstp((pc), ((r)+2)); \ 
    1186     jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (offs)); \ 
    1187 } 
    1188  
    1189 #  define jit_emit_finit(pc) { *((pc)++) = (char) 0xdb; *((pc)++) = (char) 0xe3; } 
    1190  
    1191 /* ST(i) op= MEM */ 
    1192  
    1193 #  define jit_emit_xxx_rm_n(interp, op, pc, r, m) { \ 
    1194     jit_emit_fload_m_n((interp), (pc), (m)); \ 
    1195     emitm_f ## op ## p((pc), ((r)+1)); \ 
    1196 } 
    1197  
    1198 #  define jit_emit_xxx_RM_n(interp, op, pc, r, offs) { \ 
    1199     jit_emit_fload_mb_n((interp), (pc), emit_EBX, (offs)); \ 
    1200     emitm_f ## op ## p((pc), ((r)+1)); \ 
    1201 } 
    1202  
    1203 /* 
    1204  * float ops in two flavors: abs memory for constants, offsets for regs 
    1205  */ 
    1206  
    1207 #  define jit_emit_add_ri_n(interp, pc, r, m) jit_emit_xxx_rm_n((interp), add, (pc), (r), (m)) 
    1208 #  define jit_emit_sub_ri_n(interp, pc, r, m) jit_emit_xxx_rm_n((interp), sub, (pc), (r), (m)) 
    1209 #  define jit_emit_mul_ri_n(interp, pc, r, m) jit_emit_xxx_rm_n((interp), mul, (pc), (r), (m)) 
    1210  
    1211 #  define jit_emit_add_RM_n(interp, pc, r, o) jit_emit_xxx_RM_n((interp), add, (pc), (r), (o)) 
    1212 #  define jit_emit_sub_RM_n(interp, pc, r, o) jit_emit_xxx_RM_n((interp), sub, (pc), (r), (o)) 
    1213 #  define jit_emit_mul_RM_n(interp, pc, r, o) jit_emit_xxx_RM_n((interp), mul, (pc), (r), (o)) 
    1214  
    1215 /* ST(r1) += ST(r2) */ 
    1216 /* r1 == 0:  ST(0) <- ST(0) + ST(i) 
    1217  * r2 == 0:  ST(i) <- ST(0) + ST(i) 
    1218  */ 
    1219 #  define jit_emit_add_rr_n(interp, pc, r1, r2) do { \ 
    1220         if (!(r1)) { \ 
    1221           emitm_fadd((pc), (r2)); \ 
    1222         }  \ 
    1223         else if (!(r2)) { \ 
    1224           emitm_faddr((pc), (r1)); \ 
    1225         }  \ 
    1226         else { \ 
    1227             emitm_fld((pc), (r2)); \ 
    1228             emitm_faddp((pc), ((r1)+1)); \ 
    1229         } \ 
    1230     } \ 
    1231     while (0) 
    1232 /* 
    1233  * ST(r) += INT_REG 
    1234  */ 
    1235 #  define jit_emit_add_RM_ni(pc, r, offs) { \ 
    1236     emitm_fld((pc), (r)); \ 
    1237     emitm_fiadd_m((pc), emit_EBX, 0, 1, (offs)); \ 
    1238     emitm_fstp((pc), ((r)+1)); \ 
    1239 } 
    1240  
    1241 /* ST(r1) -= ST(r2) */ 
    1242 /* r1 == 0:  ST(0) <- ST(0) - ST(i) 
    1243  * r2 == 0:  ST(i) <- ST(i) - ST(0) 
    1244  */ 
    1245 #  define jit_emit_sub_rr_n(interp, pc, r1, r2) do { \ 
    1246         if (!(r1)) { \ 
    1247           emitm_fsub((pc), (r2)); \ 
    1248         }  \ 
    1249         else if (!(r2)) { \ 
    1250           emitm_fsubr((pc), (r1)); \ 
    1251         }  \ 
    1252         else { \ 
    1253             emitm_fld((pc), (r2)); \ 
    1254             emitm_fsubp((pc), ((r1)+1)); \ 
    1255         } \ 
    1256     } \ 
    1257     while (0) 
    1258  
    1259 /* 
    1260  * ST(r) -= INT_REG 
    1261  */ 
    1262 #  define jit_emit_sub_RM_ni(pc, r, offs) { \ 
    1263     emitm_fld((pc), (r)); \ 
    1264     emitm_fisub_m((pc), emit_EBX, 0, 1, (offs)); \ 
    1265     emitm_fstp((pc), ((r)+1)); \ 
    1266 } 
    1267  
    1268 #  define jit_emit_inc_r_n(pc, r) { \ 
    1269     emitm_fld1(pc); \ 
    1270     emitm_faddp((pc), ((r)+1)); \ 
    1271 } 
    1272  
    1273 #  define jit_emit_dec_r_n(pc, r) { \ 
    1274     emitm_fld1(pc); \ 
    1275     emitm_fsubp((pc), ((r)+1)); \ 
    1276 } 
    1277  
    1278 /* ST(r1) *= ST(r2) */ 
    1279 /* r1 == 0:  ST(0) <- ST(0) * ST(i) 
    1280  * r2 == 0:  ST(i) <- ST(0) * ST(i) 
    1281  */ 
    1282 #  define jit_emit_mul_rr_n(interp, pc, r1, r2) do { \ 
    1283         if (!(r1)) { \ 
    1284           emitm_fmul((pc), (r2)); \ 
    1285         }  \ 
    1286         else if (!(r2)) { \ 
    1287           emitm_fmulr((pc), (r1)); \ 
    1288         }  \ 
    1289         else { \ 
    1290             emitm_fld((pc), (r2)); \ 
    1291             emitm_fmulp((pc), ((r1)+1)); \ 
    1292         } \ 
    1293     } \ 
    1294     while (0) 
    1295  
    1296 /* 
    1297  * ST(r) *= INT_REG 
    1298  */ 
    1299 #  define jit_emit_mul_RM_ni(pc, r, offs) { \ 
    1300     emitm_fld((pc), (r)); \ 
    1301     emitm_fimul_m((pc), emit_EBX, 0, 1, (offs)); \ 
    1302     emitm_fstp((pc), ((r)+1)); \ 
    1303 } 
    1304  
    1305 /* 
    1306  * ST(r) /= INT_REG 
    1307  */ 
    1308 #  define jit_emit_div_RM_ni(pc, r, offs) { \ 
    1309     emitm_fld((pc), (r)); \ 
    1310     emitm_fidiv_m((pc), emit_EBX, 0, 1, (offs)); \ 
    1311     emitm_fstp((pc), ((r)+1)); \ 
    1312 } 
    1313  
    1314 /* test r for zero */ 
    1315 #  define jit_emit_test_r_n(pc, r) { \ 
    1316     if (r) { \ 
    1317       emitm_fxch((pc), (r)); \ 
    1318     } \ 
    1319     emitm_fxam(pc); \ 
    1320     emitm_fstw(pc); \ 
    1321     emitm_sahf(pc); \ 
    1322     if (r) { \ 
    1323       emitm_fxch((pc), (r)); \ 
    1324     } \ 
    1325 } 
    1326  
    1327 enum { JIT_X86BRANCH, JIT_X86JUMP, JIT_X86CALL }; 
    1328  
    1329 #  define jit_emit_stack_frame_enter(pc) do { \ 
    1330     emitm_pushl_r((pc), emit_EBP); \ 
    1331     jit_emit_mov_rr_i((pc), emit_EBP, emit_ESP); \ 
    1332 } while (0) 
    1333  
    1334 #  define jit_emit_stack_frame_leave(pc) do { \ 
    1335     jit_emit_mov_rr_i((pc), emit_ESP, emit_EBP); \ 
    1336     emitm_popl_r((pc), emit_EBP); \ 
    1337 } while (0) 
    1338  
    1339 #  define jit_emit_end(pc) { \ 
    1340        jit_emit_add_ri_i((interp), (pc), emit_ESP, 4); \ 
    1341        emitm_popl_r((pc), emit_EDI); \ 
    1342        emitm_popl_r((pc), emit_ESI); \ 
    1343        emitm_popl_r((pc), emit_EBX); \ 
    1344        emitm_popl_r((pc), emit_EBP); \ 
    1345        emitm_ret(pc); \ 
    1346      } 
    1347  
    1348 size_t calc_signature_needs(const char *sig, int *strings); 
    1349  
    1350 void * Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, 
    1351     STRING *signature, int *sizeptr); 
    1352  
    1353 /* 
    1354  * register usage 
    1355  * %edi, %esi ... mapped, preserved 
    1356  * %edx, %ecx ... mapped, not preserved 
    1357  * %ebx       ... base pointer for register access, preserved 
    1358  * %eax       ... scratch, return value register 
    1359  */ 
    1360  
    1361 #endif /* PARROT_I386_JIT_EMIT_H_GUARD */ 
    1362  
    1363 /* 
    136442 * Local variables: 
    136543 *   c-file-style: "parrot" 
    136644 * End: 
  • src/nci_test.c

     
    110110PARROT_DYNEXT_EXPORT void   nci_vfff(float, float, float); 
    111111PARROT_DYNEXT_EXPORT void   nci_vV(const char **); 
    112112PARROT_DYNEXT_EXPORT void   nci_vVVV(const char **, const char **, const char **); 
     113PARROT_DYNEXT_EXPORT int    nci_i20(int, int, int, int, int, int, int, int, int, int, int, int, 
     114                                    int, int, int, int, int, int, int); 
    113115 
    114116/* Declarations for callback tests */ 
    115117 
     
    11911193  *ptr3 = "Go suck a lemon.\n"; 
    11921194} 
    11931195 
     1196/* 
     1197 
     1198=item C<int 
     1199nci_i20(int sel, int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8, int v9, int v10, 
     1200        int v11, int v12, int v13, int v14, int v15, int v16, int v17, int v18)> 
     1201 
     1202Prints and returns the nth value in a list of integers. First argument is the selector; subsequents, 
     1203the list. 
     1204 
     1205This function is designed to be outside of the range of the static frame builder as an excercise for 
     1206the dynamic frame builder. 
     1207 
     1208=cut 
     1209 
     1210*/ 
     1211PARROT_DYNEXT_EXPORT int 
     1212nci_i20(int sel, int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8, int v9, int v10, 
     1213        int v11, int v12, int v13, int v14, int v15, int v16, int v17, int v18) { 
     1214    int *selected; 
     1215    switch ((sel < 0 ? -sel : sel) % 18) { 
     1216        case 0: selected = &v1; break; 
     1217        case 1: selected = &v2; break; 
     1218        case 2: selected = &v3; break; 
     1219        case 3: selected = &v4; break; 
     1220        case 4: selected = &v5; break; 
     1221        case 5: selected = &v6; break; 
     1222        case 6: selected = &v7; break; 
     1223        case 7: selected = &v8; break; 
     1224        case 8: selected = &v9; break; 
     1225        case 9: selected = &v10; break; 
     1226        case 10: selected = &v11; break; 
     1227        case 11: selected = &v12; break; 
     1228        case 12: selected = &v13; break; 
     1229        case 13: selected = &v14; break; 
     1230        case 14: selected = &v15; break; 
     1231        case 15: selected = &v16; break; 
     1232        case 16: selected = &v17; break; 
     1233        case 17: selected = &v18; break; 
     1234        default: printf("default case reached (should never happen)"); return -1; 
     1235    } 
     1236    printf("%d\n", *selected); 
     1237    return *selected; 
     1238} 
     1239 
    11941240#ifdef TEST 
    11951241 
    11961242char l2 = 4; 
  • src/extend.c

     
    17471747        (char *) NULL, 0); 
    17481748    Parrot_PMC sub = pmc_new(interp, enum_class_NCI); 
    17491749    VTABLE_set_pointer_keyed_str(interp, sub, sig, F2DPTR(func)); 
    1750     PObj_get_FLAGS(sub) |= PObj_private1_FLAG; 
    17511750    return sub; 
    17521751} 
    17531752 
  • tools/build/nativecall.pl

     
    3030use strict; 
    3131use warnings; 
    3232 
     33use lib 'lib'; 
     34use Parrot::NativeCall; 
     35 
    3336my $opt_warndups = 0; 
    3437 
    3538# This file will eventually be compiled 
     
    3740 
    3841print_head( \@ARGV ); 
    3942 
     43my %sig_table = %Parrot::NativeCall::signature_table; 
    4044 
    41 my %sig_table = ( 
    42     p => { 
    43         as_proto => "void *", 
    44         other_decl => "PMC * const final_destination = pmc_new(interp, enum_class_UnManagedStruct);", 
    45         sig_char => "P", 
    46         ret_assign => "VTABLE_set_pointer(interp, final_destination, return_data);\n    Parrot_pcc_fill_returns_from_c_args(interp, call_object, \"P\", final_destination);", 
    47     }, 
    48     i => { as_proto => "int",    sig_char => "I" }, 
    49     l => { as_proto => "long",   sig_char => "I" }, 
    50     c => { as_proto => "char",   sig_char => "I" }, 
    51     s => { as_proto => "short",  sig_char => "I" }, 
    52     f => { as_proto => "float",  sig_char => "N" }, 
    53     d => { as_proto => "double", sig_char => "N" }, 
    54     t => { as_proto => "char *", 
    55            other_decl => "STRING *final_destination;", 
    56            ret_assign => "final_destination = Parrot_str_new(interp, return_data, 0);\n    Parrot_pcc_fill_returns_from_c_args(interp, call_object, \"S\", final_destination);", 
    57            sig_char => "S" }, 
    58     v => { as_proto => "void", 
    59            return_type => "void *", 
    60            sig_char => "v", 
    61            ret_assign => "", 
    62            func_call_assign => "" 
    63          }, 
    64     P => { as_proto => "PMC *", sig_char => "P" }, 
    65     O => { as_proto => "PMC *", returns => "", sig_char => "Pi" }, 
    66     J => { as_proto => "PARROT_INTERP", returns => "", sig_char => "" }, 
    67     S => { as_proto => "STRING *", sig_char => "S" }, 
    68     I => { as_proto => "INTVAL", sig_char => "I" }, 
    69     N => { as_proto => "FLOATVAL", sig_char => "N" }, 
    70     b => { as_proto => "void *", as_return => "", sig_char => "S" }, 
    71     B => { as_proto => "char **", as_return => "", sig_char => "S" }, 
    72     # These should be replaced by modifiers in the future 
    73     2 => { as_proto => "short *",  sig_char => "P", return_type => "short", 
    74            ret_assign => 'Parrot_pcc_fill_returns_from_c_args(interp, call_object, "I", return_data);' }, 
    75     3 => { as_proto => "int *",  sig_char => "P", return_type => "int", 
    76            ret_assign => 'Parrot_pcc_fill_returns_from_c_args(interp, call_object, "I", return_data);' }, 
    77     4 => { as_proto => "long *",  sig_char => "P", return_type => "long", 
    78            ret_assign => 'Parrot_pcc_fill_returns_from_c_args(interp, call_object, "I", return_data);' }, 
    79     L => { as_proto => "long *", as_return => "" }, 
    80     T => { as_proto => "char **", as_return => "" }, 
    81     V => { as_proto => "void **", as_return => "", sig_char => "P" }, 
    82     '@' => { as_proto => "PMC *", as_return => "", cname => "xAT_", sig_char => 'Ps' }, 
    83 ); 
    84  
    85 for (values %sig_table) { 
    86     if (not exists $_->{as_return}) { $_->{as_return} = $_->{as_proto} } 
    87     if (not exists $_->{return_type}) { $_->{return_type} = $_->{as_proto} } 
    88     if (not exists $_->{return_type_decl}) { $_->{return_type_decl} = $_->{return_type} } 
    89     if (not exists $_->{ret_assign} and exists $_->{sig_char}) { 
    90         $_->{ret_assign} = 'Parrot_pcc_fill_returns_from_c_args(interp, call_object, "' 
    91                            . $_->{sig_char} . '", return_data);'; 
    92     } 
    93     if (not exists $_->{func_call_assign}) { 
    94         $_->{func_call_assign} = "return_data = " 
    95     } 
    96 } 
    97  
    98  
    9945my $temp_cnt = 0; 
    10046my (@put_pointer, @put_pointer_nci_too, @nci_defs); 
    10147my %seen; 
     
    494440        return F2DPTR(VTABLE_get_pointer(interp, b)); 
    495441    } 
    496442    else { 
    497         int jit_size; 
    498         void * const result = Parrot_jit_build_call_func(interp, pmc_nci, signature, &jit_size); 
     443        void *priv; 
     444        void * const result = Parrot_jit_build_call_func(interp, pmc_nci, signature, &priv); 
    499445        if (result) { 
    500             struct jit_buffer_private_data *priv; 
    501446            *jitted = 1; 
    502447            temp_pmc = pmc_new(interp, enum_class_ManagedStruct); 
    503448            VTABLE_set_pointer(interp, temp_pmc, (void *)result); 
    504449#ifdef PARROT_HAS_EXEC_PROTECT 
    505             priv = (struct jit_buffer_private_data *) 
    506                 mem_sys_allocate(sizeof(struct jit_buffer_private_data)); 
    507             priv->size = jit_size; 
    508450            SETATTR_ManagedStruct_custom_free_func(interp, temp_pmc, Parrot_jit_free_buffer); 
    509451            SETATTR_ManagedStruct_custom_free_priv(interp, temp_pmc, priv); 
    510452            SETATTR_ManagedStruct_custom_clone_func(interp, temp_pmc, Parrot_jit_clone_buffer); 
  • MANIFEST

     
    11# ex: set ro: 
    22# $Id$ 
    33# 
    4 # generated by tools/dev/mk_manifest_and_skip.pl Thu Nov  5 20:59:58 2009 UT 
     4# generated by tools/dev/mk_manifest_and_skip.pl Fri Nov  6 04:08:02 2009 UT 
    55# 
    66# See below for documentation on the format of this file. 
    77# 
     
    234234config/auto/env/test_unsetenv_c.in                          [] 
    235235config/auto/format.pm                                       [] 
    236236config/auto/frames.pm                                       [] 
    237 config/auto/frames/test_exec_cygwin_c.in                    [] 
    238 config/auto/frames/test_exec_linux_c.in                     [] 
    239 config/auto/frames/test_exec_openbsd_c.in                   [] 
    240237config/auto/gc.pm                                           [] 
    241238config/auto/gc/test_c.in                                    [] 
    242239config/auto/gcc.pm                                          [] 
     
    258255config/auto/isreg.pm                                        [] 
    259256config/auto/isreg/test_c.in                                 [] 
    260257config/auto/jit.pm                                          [] 
     258config/auto/libjit.pm                                       [] 
     259config/auto/libjit/libjit_c.in                              [] 
    261260config/auto/memalign.pm                                     [] 
    262261config/auto/memalign/test2_c.in                             [] 
    263262config/auto/memalign/test_c.in                              [] 
     
    310309config/gen/crypto.pm                                        [] 
    311310config/gen/crypto/digest_pmc.in                             [] 
    312311config/gen/crypto/digest_t.in                               [] 
     312config/gen/libjit.pm                                        [] 
     313config/gen/libjit/frame_builder_libjit_c.in                 [] 
     314config/gen/libjit/frame_builder_libjit_h.in                 [] 
    313315config/gen/makefiles.pm                                     [] 
    314316config/gen/makefiles/CFLAGS.in                              [] 
    315317config/gen/makefiles/data_json.in                           [] 
     
    10651067lib/Parrot/IO/Path.pm                                       [devel]lib 
    10661068lib/Parrot/Install.pm                                       [devel]lib 
    10671069lib/Parrot/Manifest.pm                                      [devel]lib 
     1070lib/Parrot/NativeCall.pm                                    [devel]lib 
    10681071lib/Parrot/Op.pm                                            [devel]lib 
    10691072lib/Parrot/OpTrans.pm                                       [devel]lib 
    10701073lib/Parrot/OpTrans/C.pm                                     [devel]lib 
     
    12691272src/exceptions.c                                            [] 
    12701273src/exit.c                                                  [] 
    12711274src/extend.c                                                [] 
    1272 src/frame_builder.c                                         [] 
    12731275src/frame_builder.h                                         [] 
    12741276src/gc/alloc_memory.c                                       [] 
    12751277src/gc/alloc_resources.c                                    [] 
     
    19401942t/steps/auto/inline-01.t                                    [test] 
    19411943t/steps/auto/isreg-01.t                                     [test] 
    19421944t/steps/auto/jit-01.t                                       [test] 
     1945t/steps/auto/libjit-01.t                                    [test] 
    19431946t/steps/auto/memalign-01.t                                  [test] 
    19441947t/steps/auto/msvc-01.t                                      [test] 
    19451948t/steps/auto/neg_0-01.t                                     [test] 
     
    19641967t/steps/gen/config_pm-01.t                                  [test] 
    19651968t/steps/gen/core_pmcs-01.t                                  [test] 
    19661969t/steps/gen/crypto-01.t                                     [test] 
     1970t/steps/gen/libjit-01.t                                     [test] 
    19671971t/steps/gen/makefiles-01.t                                  [test] 
    19681972t/steps/gen/opengl-01.t                                     [test] 
    19691973t/steps/gen/parrot_include-01.t                             [test] 
  • lib/Parrot/Configure/Options/Conf.pm

     
    105105   --without-gmp        Build parrot without GMP support 
    106106   --without-opengl     Build parrot without OpenGL support (GL/GLU/GLUT) 
    107107   --without-pcre       Build parrot without pcre support 
     108   --without-libjit     Build parrot without LibJIT support 
    108109 
    109110ICU Options: 
    110111 
  • lib/Parrot/Configure/Options/Conf/Shared.pm

     
    7575    without-gettext 
    7676    without-gmp 
    7777    without-icu 
     78    without-libjit 
    7879    without-opengl 
    7980    without-pcre 
    8081    without-threads 
  • lib/Parrot/Configure/Step/List.pm

     
    3939    auto::format 
    4040    auto::isreg 
    4141    auto::arch 
     42    auto::libjit 
    4243    auto::jit 
    4344    auto::frames 
    4445    auto::cpu 
     
    7071    gen::parrot_include 
    7172    gen::opengl 
    7273    gen::call_list 
     74    gen::libjit 
    7375    gen::makefiles 
    7476    gen::platform 
    7577    gen::config_pm 
    7678); 
    7779 
     80=pod 
     81 
     82=cut 
     83 
    7884sub get_steps_list { return @steps; } 
    7985 
    80861; 
  • lib/Parrot/Distribution.pm

     
    433433            include/parrot/config.h 
    434434            include/parrot/has_header.h 
    435435            src/gc/malloc.c 
     436            src/frame_builder_libjit.h 
     437            src/frame_builder_libjit.c 
    436438            } unless @exemptions; 
    437439 
    438440        my $path = -f $file ? $file : $file->path; 
  • lib/Parrot/NativeCall.pm

     
     1# Copyright (C) 2009, Parrot Foundation. 
     2# $Id$ 
     3 
     4package Parrot::NativeCall; 
     5 
     6use strict; 
     7use warnings; 
     8 
     9use base 'Exporter'; 
     10our @EXPORT_OK = qw{ signature_nci_to_pcc }; 
     11 
     12=head1 NAME 
     13 
     14Parrot::NativeCall - Tools for building native call routines 
     15 
     16=head1 SYNOPSIS 
     17 
     18  use Parrot::NativeCall 'signature_nci_to_pcc'; 
     19 
     20  my $pcc_sig = signature_nci_to_pcc("v  VVV"); 
     21 
     22=head1 DESCRIPTION 
     23 
     24C<Parrot::NativeCall> knows how to map NCI signatures to nci frame 
     25functions. 
     26 
     27=head1 GLOBAL VARIABLES 
     28 
     29=over 
     30 
     31=item C<%signature_table> 
     32 
     33Maps NCI signature items to elements of a native call routine. 
     34 
     35For use by F<tools/build/nativecall.pl>. New code should probably write 
     36a wrapper in this module to encapsulate the access. 
     37 
     38=cut 
     39 
     40our %signature_table = ( 
     41    p => { 
     42        as_proto => "void *", 
     43        other_decl => "PMC * const final_destination = pmc_new(interp, enum_class_UnManagedStruct);", 
     44        sig_char => "P", 
     45        ret_assign => "VTABLE_set_pointer(interp, final_destination, return_data);\n    Parrot_pcc_fill_returns_from_c_args(interp, call_object, \"P\", final_destination);", 
     46    }, 
     47    i => { as_proto => "int",    sig_char => "I" }, 
     48    l => { as_proto => "long",   sig_char => "I" }, 
     49    c => { as_proto => "char",   sig_char => "I" }, 
     50    s => { as_proto => "short",  sig_char => "I" }, 
     51    f => { as_proto => "float",  sig_char => "N" }, 
     52    d => { as_proto => "double", sig_char => "N" }, 
     53    t => { as_proto => "char *", 
     54           other_decl => "STRING *final_destination;", 
     55           ret_assign => "final_destination = Parrot_str_new(interp, return_data, 0);\n    Parrot_pcc_fill_returns_from_c_args(interp, call_object, \"S\", final_destination);", 
     56           sig_char => "S" }, 
     57    v => { as_proto => "void", 
     58           return_type => "void *", 
     59           sig_char => "v", 
     60           ret_assign => "", 
     61           func_call_assign => "" 
     62         }, 
     63    P => { as_proto => "PMC *", sig_char => "P" }, 
     64    O => { as_proto => "PMC *", returns => "", sig_char => "Pi" }, 
     65    J => { as_proto => "PARROT_INTERP", returns => "", sig_char => "" }, 
     66    S => { as_proto => "STRING *", sig_char => "S" }, 
     67    I => { as_proto => "INTVAL", sig_char => "I" }, 
     68    N => { as_proto => "FLOATVAL", sig_char => "N" }, 
     69    b => { as_proto => "void *", as_return => "", sig_char => "S" }, 
     70    B => { as_proto => "char **", as_return => "", sig_char => "S" }, 
     71    # These should be replaced by modifiers in the future 
     72    2 => { as_proto => "short *",  sig_char => "P", return_type => "short", 
     73           ret_assign => 'Parrot_pcc_fill_returns_from_c_args(interp, call_object, "I", return_data);' }, 
     74    3 => { as_proto => "int *",  sig_char => "P", return_type => "int", 
     75           ret_assign => 'Parrot_pcc_fill_returns_from_c_args(interp, call_object, "I", return_data);' }, 
     76    4 => { as_proto => "long *",  sig_char => "P", return_type => "long", 
     77           ret_assign => 'Parrot_pcc_fill_returns_from_c_args(interp, call_object, "I", return_data);' }, 
     78    L => { as_proto => "long *", as_return => "" }, 
     79    T => { as_proto => "char **", as_return => "" }, 
     80    V => { as_proto => "void **", as_return => "", sig_char => "P" }, 
     81    '@' => { as_proto => "PMC *", as_return => "", cname => "xAT_", sig_char => 'Ps' }, 
     82); 
     83 
     84for (values %signature_table) { 
     85    if (not exists $_->{as_return}) { $_->{as_return} = $_->{as_proto} } 
     86    if (not exists $_->{return_type}) { $_->{return_type} = $_->{as_proto} } 
     87    if (not exists $_->{return_type_decl}) { $_->{return_type_decl} = $_->{return_type} } 
     88    if (not exists $_->{ret_assign} and exists $_->{sig_char}) { 
     89        $_->{ret_assign} = 'Parrot_pcc_fill_returns_from_c_args(interp, call_object, "' 
     90                           . $_->{sig_char} . '", return_data);'; 
     91    } 
     92    if (not exists $_->{func_call_assign}) { 
     93        $_->{func_call_assign} = "return_data = " 
     94    } 
     95} 
     96 
     97=back 
     98 
     99=head1 FUNCTIONS 
     100 
     101=over 
     102 
     103=item C<signature_nci_to_pcc> 
     104 
     105Converts an NCI signature to a PCC signature. 
     106 
     107=cut 
     108 
     109sub signature_nci_to_pcc { 
     110    my $nci_sig = shift; 
     111    my ($nci_ret, $nci_params) = $nci_sig =~ /^(.)\s*(\S*)/; 
     112    my $pcc_ret =  $signature_table{$nci_ret}{sig_char}; 
     113    my $pcc_params = join '', map $signature_table{$_}{sig_char}, split //, $nci_params; 
     114    return "${pcc_params}->${pcc_ret}"; 
     115} 
     116 
     1171; 
     118 
     119=back 
     120 
     121=cut 
     122 
     123# Local Variables: 
     124#   mode: cperl 
     125#   cperl-indent-level: 4 
     126#   fill-column: 100 
     127# End: 
     128# vim: expandtab shiftwidth=4: 
  • include/parrot/nci.h

     
    1515 
    1616#include "parrot/parrot.h" 
    1717 
     18/* NCI PMC interface constants */ 
     19/* &gen_from_enum(nci.pasm) */ 
     20typedef enum { 
     21    PARROT_NCI_ARITY, 
     22    PARROT_NCI_PCC_SIGNATURE_PARAMS, 
     23    PARROT_NCI_PCC_SIGNATURE_RET, 
     24    PARROT_NCI_LONG_SIGNATURE, 
     25    PARROT_NCI_MULTI_SIG, 
     26} parrot_nci_enum_t; 
     27/* &end_gen */ 
     28 
    1829void *build_call_func(PARROT_INTERP, SHIM(PMC *pmc_nci), NOTNULL(STRING *signature), NOTNULL(int *jitted)); 
    1930 
    2031#endif /* PARROT_NCI_H_GUARD */ 
  • t/pmc/nci.t

     
    55use strict; 
    66use warnings; 
    77use lib qw( . lib ../lib ../../lib ); 
     8use Parrot::BuildUtil; 
     9use Parrot::NativeCall 'signature_nci_to_pcc'; 
     10 
     11my @nci_sigs; 
     12BEGIN { 
     13    @nci_sigs = 
     14        grep {$_} 
     15        map {chomp; s/^\s*//; s/\s*$//; s/#.*$//; $_} 
     16        split /\n/, Parrot::BuildUtil::slurp_file('src/call_list.txt'); 
     17} 
     18 
    819use Test::More; 
    9 use Parrot::Test tests => 70; 
     20use Parrot::Test tests => (71 + @nci_sigs); 
    1021use Parrot::Config qw(%PConfig); 
    1122 
    1223=head1 NAME 
     
    3243 
    3344$ENV{TEST_PROG_ARGS} ||= ''; 
    3445 
     46foreach my $nci_sig (@nci_sigs) { 
     47    my ($nci_ret, $nci_params) = $nci_sig =~ /\S+/g; 
     48    $nci_params ||= ''; 
     49    my $pcc_sig = signature_nci_to_pcc($nci_sig); 
     50    pir_output_is( << "CODE", "$pcc_sig\n", "NCI PMC signatures equivalent to nativecall.pl ('$nci_sig')" ); 
     51.include "nci.pasm" 
     52.sub test :main 
     53    .local pmc nci 
     54    nci = new ['NCI'] 
     55    nci = "${nci_ret}${nci_params}" 
     56    .local string s 
     57    s = nci[ .PARROT_NCI_PCC_SIGNATURE_PARAMS ] 
     58    print s 
     59    print "->" 
     60    s = nci[ .PARROT_NCI_PCC_SIGNATURE_RET ] 
     61    print s 
     62    print "\\n" 
     63.end 
     64CODE 
     65} 
     66 
    3567SKIP: { 
    3668    unless ( -e "runtime/parrot/dynext/libnci_test$PConfig{load_ext}" ) { 
    3769        skip( "Please make libnci_test$PConfig{load_ext}", Test::Builder->expected_tests() ); 
     
    27532785Go suck a lemon. 
    27542786OUTPUT 
    27552787 
     2788my $test_code = <<'CODE'; 
     2789.sub test :main 
     2790    .local pmc libnci_test 
     2791    $S0 = 'libnci_test' 
     2792    libnci_test = loadlib $S0 
     2793 
     2794    .local pmc nci_i20 
     2795    nci_i20 = dlfunc libnci_test, "nci_i20", "iiiiiiiiiiiiiiiiiiii" 
     2796 
     2797    .local pmc args 
     2798    args = new ['FixedIntegerArray'] 
     2799    args = 18 
     2800 
     2801    $I0 = 2 
     2802    args[0] = 1 
     2803    args[1] = 1 
     2804 
     2805LOOP1: 
     2806    $I1 = $I0 - 1 
     2807    $I1 = args[$I1] 
     2808 
     2809    $I2 = $I0 - 2 
     2810    $I2 = args[$I2] 
     2811 
     2812    $I3 = $I1 + $I2 
     2813    args[$I0] = $I3 
     2814    inc $I0 
     2815    if $I0 < 18 goto LOOP1 
     2816 
     2817    $I0 = args 
     2818    dec $I0 
     2819 
     2820    $I1 = args[0] 
     2821    $I2 = args[1] 
     2822    $I3 = args[2] 
     2823    $I4 = args[3] 
     2824    $I5 = args[4] 
     2825    $I6 = args[5] 
     2826    $I7 = args[6] 
     2827    $I8 = args[7] 
     2828    $I9 = args[8] 
     2829    $I10 = args[9] 
     2830    $I11 = args[10] 
     2831    $I12 = args[11] 
     2832    $I13 = args[12] 
     2833    $I14 = args[13] 
     2834    $I15 = args[14] 
     2835    $I16 = args[15] 
     2836    $I17 = args[16] 
     2837    $I18 = args[17] 
     2838 
     2839LOOP2: 
     2840    nci_i20($I0, $I1, $I2, $I3, $I4, $I5, $I6, $I7, $I8, $I9, $I10, $I11, $I12, $I13, $I14, $I15, $I16, $I17, $I18) 
     2841    $I0 = $I0 / 2 
     2842    if $I0 > 0 goto LOOP2 
     2843.end 
     2844CODE 
     2845if ($PConfig{cc_build_call_frames}) { 
     2846    pir_output_is($test_code, <<DYNAMIC_FRAMEBUILDER_OUTPUT, 'dynamic frame builder builds ridiculous call frames'); 
     28472584 
     284834 
     28495 
     28502 
     28511 
     2852DYNAMIC_FRAMEBUILDER_OUTPUT 
     2853} else { 
     2854    my $output_re = qr/^Parrot VM: PANIC: iiiiiiiiiiiiiiiiiiii is an unknown signature type./; 
     2855    pir_error_output_like($test_code, $output_re, "static frame builder can't build ridiculous signatures"); 
     2856} 
     2857 
    27562858# Local Variables: 
    27572859#   mode: cperl 
    27582860#   cperl-indent-level: 4 
  • t/steps/auto/libjit-01.t

     
     1#! perl 
     2# Copyright (C) 2009, Parrot Foundation. 
     3# $Id$ 
     4# auto/libjit-01.t 
     5 
     6use strict; 
     7use warnings; 
     8 
     9use Test::More tests => 34; 
     10use lib qw( lib t/configure/testlib ); 
     11use Parrot::Configure; 
     12use Parrot::Configure::Options 'process_options'; 
     13use Parrot::Configure::Test qw( 
     14    test_step_thru_runstep 
     15    rerun_defaults_for_testing 
     16    test_step_constructor_and_description 
     17); 
     18use IO::CaptureOutput qw( capture ); 
     19 
     20use_ok('config::init::defaults'); 
     21use_ok('config::auto::libjit'); 
     22 
     23my ($args, $step_list_ref) = process_options( { 
     24        argv => [ q{--without-libjit} ], 
     25        mode => 'configure', 
     26} ); 
     27 
     28my $conf = Parrot::Configure->new; 
     29 
     30my $serialized = $conf->pcfreeze(); 
     31 
     32test_step_thru_runstep( $conf, 'init::defaults', $args ); 
     33 
     34my $pkg = 'auto::libjit'; 
     35my ( $step, $ret ); 
     36 
     37$conf->add_steps($pkg); 
     38$conf->options->set(%$args); 
     39$step = test_step_constructor_and_description($conf); 
     40$ret = $step->runstep($conf); 
     41ok( $ret, "runstep() returned true value" ); 
     42is( $step->result(), 'no', "Result is 'no', as expected" ); 
     43is( $conf->data->get( 'HAS_LIBJIT' ), 0, 
     44   "Got expected result with --without-libjit option" ); 
     45$conf->cc_clean(); 
     46 
     47$conf->replenish($serialized); 
     48 
     49($args, $step_list_ref) = process_options( { 
     50    argv => [ ], 
     51    mode => q{configure}, 
     52} ); 
     53rerun_defaults_for_testing($conf, $args ); 
     54$conf->add_steps($pkg); 
     55$conf->options->set( %{$args} ); 
     56$step = test_step_constructor_and_description($conf); 
     57$ret = $step->runstep($conf); 
     58ok( $ret, "runstep() returned true value" ); 
     59like( $step->result(), qr/yes|no/, "Result is either 'yes' or 'no'" ); 
     60ok( defined( $conf->data->get( 'HAS_LIBJIT' ) ), 
     61   "'HAS_LIBJIT' has defined value" ); 
     62$conf->cc_clean(); 
     63 
     64########## _evaluate_cc_run ########## 
     65 
     66my ($test, $has_libjit, $verbose); 
     67 
     68$step->set_result( undef ); 
     69 
     70$test = q{USES INTERPRETER: 33}; 
     71$has_libjit = 0; 
     72$verbose = 0; 
     73$has_libjit = $step->_evaluate_cc_run($test, $has_libjit, $verbose); 
     74ok( $has_libjit, "_evaluate_cc_run() returned true value, as expected" ); 
     75is( $step->result(), 'yes', "result is yes, as expected" ); 
     76 
     77$step->set_result( undef ); 
     78 
     79$test = q{foobar}; 
     80$has_libjit = 0; 
     81$verbose = 0; 
     82$has_libjit = $step->_evaluate_cc_run($test, $has_libjit, $verbose); 
     83ok( ! $has_libjit, "_evaluate_cc_run() returned false value, as expected" ); 
     84ok( ! defined($step->result()), "result is undefined, as expected" ); 
     85 
     86$step->set_result( undef ); 
     87 
     88$test = q{USES INTERPRETER: 33}; 
     89$has_libjit = 0; 
     90$verbose = 1; 
     91{ 
     92    my ($stdout, $stderr); 
     93    capture( 
     94        sub { $has_libjit = 
     95            $step->_evaluate_cc_run($test, $has_libjit, $verbose); }, 
     96        \$stdout, 
     97        \$stderr, 
     98    ); 
     99    ok( $has_libjit, "_evaluate_cc_run() returned true value, as expected" ); 
     100    is( $step->result(), 'yes', "result is yes, as expected" ); 
     101    like( $stdout, qr/\(yes\)/, "Got expected verbose output" ); 
     102} 
     103 
     104########## _handle_has_libjit() ########## 
     105 
     106my $extra_libs; 
     107 
     108$conf->data->set( 'libjit_has_alloca' => undef ); 
     109$conf->data->set( 'libs' => '' ); 
     110 
     111$has_libjit = 1; 
     112$extra_libs = 'mylibs'; 
     113$conf->data->set( 'cpuarch' => 'i386' ); 
     114 
     115auto::libjit::_handle_has_libjit($conf, $has_libjit, $extra_libs); 
     116ok( $conf->data->get( 'libjit_has_alloca'), 
     117    "on i386 with libJIT, 'libjit_has_alloca' has true value" ); 
     118is( $conf->data->get( 'libs' ), " $extra_libs", 
     119    "Got expected value for libs" ); 
     120 
     121$conf->data->set( 'libjit_has_alloca' => undef ); 
     122$conf->data->set( 'libs' => '' ); 
     123 
     124$has_libjit = 1; 
     125$extra_libs = 'mylibs'; 
     126$conf->data->set( 'cpuarch' => 'ppc' ); 
     127 
     128auto::libjit::_handle_has_libjit($conf, $has_libjit, $extra_libs); 
     129ok( ! $conf->data->get( 'libjit_has_alloca'), 
     130    "on non-i386 with libJIT, 'libjit_has_alloca' has false value" ); 
     131is( $conf->data->get( 'libs' ), " $extra_libs", 
     132    "Got expected value for libs" ); 
     133 
     134$conf->data->set( 'libjit_has_alloca' => undef ); 
     135$conf->data->set( 'libs' => '' ); 
     136 
     137$has_libjit = 0; 
     138$extra_libs = 'mylibs'; 
     139 
     140auto::libjit::_handle_has_libjit($conf, $has_libjit, $extra_libs); 
     141ok( ! $conf->data->get( 'libjit_has_alloca'), 
     142    "without libJIT, 'libjit_has_alloca' has false value" ); 
     143is( $conf->data->get( 'libs' ), "", 
     144    "Got expected value for libs" ); 
     145 
     146################### DOCUMENTATION ################### 
     147 
     148=head1 NAME 
     149 
     150auto/libjit-01.t - test auto::libjit 
     151 
     152=head1 SYNOPSIS 
     153 
     154    % prove t/steps/auto/libjit-01.t 
     155 
     156=head1 DESCRIPTION 
     157 
     158The files in this directory test functionality used by F<Configure.pl>. 
     159 
     160The tests in this file test auto::libjit. 
     161 
     162=head1 SEE ALSO 
     163 
     164config::auto::libjit, F<Configure.pl>. 
     165 
     166=cut 
     167 
     168# Local Variables: 
     169#   mode: cperl 
     170#   cperl-indent-level: 4 
     171#   fill-column: 100 
     172# End: 
     173# vim: expandtab shiftwidth=4: 
  • t/steps/auto/frames-01.t

     
    55 
    66use strict; 
    77use warnings; 
    8 use Test::More tests => 27; 
     8use Test::More tests => 28; 
    99use lib qw( lib t/configure/testlib ); 
    1010use_ok('config::init::defaults'); 
    1111use_ok('config::auto::frames'); 
     
    3333$conf->options->set( %{$args} ); 
    3434my $step = test_step_constructor_and_description($conf); 
    3535 
    36 # To avoid a warning about an unitialized value, we will set nvsize to 8, 
    37 # cpuarch to i386 and osname to linux. 
     36# To avoid a warning about an uninitialized value, we will set osname to linux. 
    3837# This is normally done during earlier configuration steps. 
    39 $conf->data->set( nvsize => 8 ); 
    40 $conf->data->set( cpuarch => 'i386' ); 
    4138$conf->data->set( osname => 'linux' ); 
    4239 
     40$conf->data->set( HAS_LIBJIT => 1 ); 
    4341my $ret = $step->runstep($conf); 
    4442ok( $ret, "runstep() returned true value" ); 
    4543ok( defined ( $step->result() ), 
    4644    "Got defined result" ); 
    47 TODO: { 
    48     local $TODO = 
    49         'build frames temporarily disabled at pcc_reapply merge: TT #1132'; 
    50     is( $step->result(), 'yes', "Result is 'yes', as expected" ); 
    51 } 
     45is( $step->result(), 'yes', "Result is 'yes', as expected" ); 
     46 
     47$conf->data->set( HAS_LIBJIT => undef ); 
     48$ret = $step->runstep($conf); 
     49ok( $ret, "runstep() returned true value" ); 
     50ok( defined ( $step->result() ), 
     51    "Got defined result" ); 
     52is( $step->result(), 'no', "Result is 'no', as expected" ); 
     53 
    5254$conf->cc_clean(); 
    5355$step->set_result( undef ); 
    5456 
     
    6870ok( ! $can_build_call_frames, 
    6971    "_call_frames_buildable() returned false value, as expected" ); 
    7072 
     73$conf->data->set( HAS_LIBJIT => 1 ); 
    7174$conf->options->set( buildframes => undef ); 
    72 $conf->data->set( osname =>  'linux' ); 
    73 $conf->data->set( cpuarch =>  'i386' ); 
    74 $conf->data->set( nvsize =>  8 ); 
    7575$can_build_call_frames = auto::frames::_call_frames_buildable($conf); 
    76 TODO: { 
    77     local $TODO = 
    78         'build frames temporarily disabled at pcc_reapply merge: TT #1132'; 
    79     ok( $can_build_call_frames, 
    80         "_call_frames_buildable() returned true value, as expected (i386/non darwin/8)" 
    81     ); 
    82 } 
     76ok( $can_build_call_frames, 
     77    "_call_frames_buildable() returned true value, as expected" ); 
    8378 
    84 $conf->data->set( osname =>  'darwin' ); 
    85 $conf->data->set( cpuarch =>  'i386' ); 
    86 $conf->data->set( nvsize =>  8 ); 
     79$conf->data->set( HAS_LIBJIT => undef ); 
     80$conf->options->set( buildframes => 0 ); 
    8781$can_build_call_frames = auto::frames::_call_frames_buildable($conf); 
    8882ok( ! $can_build_call_frames, 
    89     "_call_frames_buildable() returned false value, as expected (i386/darwin/8)" ); 
     83    "_call_frames_buildable() returned false value, as expected" ); 
    9084 
    91 $conf->data->set( osname =>  'linux' ); 
    92 $conf->data->set( cpuarch =>  'ppc' ); 
    93 $conf->data->set( nvsize =>  8 ); 
    94 $can_build_call_frames = auto::frames::_call_frames_buildable($conf); 
    95 ok( ! $can_build_call_frames, 
    96     "_call_frames_buildable() returned false value, as expected (ppc/linux/8)" ); 
    97  
    98 $conf->data->set( osname =>  'linux' ); 
    99 $conf->data->set( cpuarch =>  'i386' ); 
    100 $conf->data->set( nvsize =>  4 ); 
    101 $can_build_call_frames = auto::frames::_call_frames_buildable($conf); 
    102 ok( ! $can_build_call_frames, 
    103     "_call_frames_buildable() returned false value, as expected (i386/linux/4)" ); 
    104  
    10585##### _handle_call_frames_buildable() ##### 
    10686 
    107 $conf->data->set( nvsize => 8 ); 
    108 $conf->data->set( cpuarch => 'i386' ); 
    109 $conf->data->set( osname => 'linux' ); 
    110  
    11187my $rv; 
    11288 
    11389$can_build_call_frames = 0; 
     
    12399$conf->data->set( 'has_exec_protect' => undef ); 
    124100 
    125101$can_build_call_frames = 1; 
    126 my $realos = $conf->data->get( 'osname' ); 
    127 $conf->data->set( 'osname' => 'foobar' ); 
    128102$rv = $step->_handle_can_build_call_frames( $conf, $can_build_call_frames ); 
    129103ok( $rv, "_handle_can_build_call_frames() returned true value" ); 
    130104is( $conf->data->get( 'cc_build_call_frames'), '-DCAN_BUILD_CALL_FRAMES', 
    131105    "cc_build_call_frames set to expected value" ); 
    132 is( $conf->data->get( 'has_exec_protect' ), 0, 
    133     "has_exec_protect is 0, as expected" ); 
     106is( $conf->data->get( 'has_exec_protect' ), 1, 
     107    "has_exec_protect is 1, as expected" ); 
    134108is( $step->result(), 'yes', "Result is 'yes', as expected" ); 
    135109 
    136110$conf->data->set( 'cc_build_call_frames' => undef ); 
    137111$conf->data->set( 'has_exec_protect' => undef ); 
    138 $conf->data->set( 'osname' => $realos ); 
    139112 
    140113pass("Completed all tests in $0"); 
    141114 
  • t/steps/gen/libjit-01.t

     
     1#! perl 
     2# Copyright (C) 2009, Parrot Foundation. 
     3# $Id$ 
     4# gen/libjit-01.t 
     5 
     6use strict; 
     7use warnings; 
     8 
     9use constant NUM_GENERATED_FILES => 2; 
     10# use Test::More tests => 8 + 2*NUM_GENERATED_FILES; 
     11use Test::More qw( no_plan ); 
     12 
     13use File::Copy 'move'; 
     14use File::Temp 'tempfile'; 
     15 
     16use lib 'lib'; 
     17use Parrot::Configure; 
     18use Parrot::Configure::Options 'process_options'; 
     19use Parrot::Configure::Test qw( 
     20    test_step_thru_runstep 
     21    rerun_defaults_for_testing 
     22    test_step_constructor_and_description 
     23); 
     24 
     25use_ok('config::gen::libjit'); 
     26 
     27my ($args, $step_list_ref) = process_options( 
     28    { 
     29        argv => [], 
     30        mode => 'configure', 
     31    } 
     32); 
     33 
     34my $conf = Parrot::Configure->new; 
     35 
     36my $serialized = $conf->pcfreeze(); 
     37 
     38my $pkg = 'gen::libjit'; 
     39$conf->add_steps($pkg); 
     40$conf->options->set( %$args ); 
     41my $step = test_step_constructor_and_description($conf); 
     42 
     43is( scalar keys %{$step->{targets}}, NUM_GENERATED_FILES, 
     44    "Expected number of generated files"); 
     45is_deeply([keys %{$step->{targets}}], [keys %{$step->{templates}}], 
     46    "Templates match targets"); 
     47 
     48foreach (keys %{$step->{templates}}) { 
     49    ok(-f $step->{templates}{$_}, "Able to locate $_ template") 
     50} 
     51 
     52my %orig_files; 
     53foreach (keys %{$step->{targets}}) { 
     54    if (-f (my $targ_name = $step->{targets}{$_})) { 
     55        $orig_files{$_} = tempfile(); 
     56        move($targ_name, $orig_files{$_}); 
     57    } 
     58} 
     59 
     60my %orig_conf = map { $_ => $conf->data->get($_) } qw[ iv nv ]; 
     61$conf->data->set( iv => 'int', nv => 'float' ); 
     62# Set a value for 'libjit_has_alloca' to avoid uninitialized value warning. 
     63$conf->data->set( 'libjit_has_alloca' => 1 ); 
     64my $ret = $step->runstep($conf); 
     65ok( $ret, "runstep() returned true value" ); 
     66foreach (keys %{$step->{targets}}) { 
     67    ok(-f $step->{targets}{$_}, "$_ target generated"); 
     68} 
     69 
     70# re-set for next test 
     71$conf->data->set(%orig_conf); 
     72$step->set_result( '' ); 
     73foreach (keys %{$step->{targets}}) { 
     74    if (exists $orig_files{$_}) { 
     75        move( $orig_files{$_}, $step->{targets}{$_} ); 
     76    } else { 
     77        unlink $_; 
     78    } 
     79} 
     80 
     81$conf->replenish($serialized); 
     82 
     83pass("Completed all tests in $0"); 
     84 
     85################### DOCUMENTATION ################### 
     86 
     87=head1 NAME 
     88 
     89  gen/libjit-01.t - test gen::libjit 
     90 
     91=head1 SYNOPSIS 
     92 
     93    % prove t/steps/gen/libjit-01.t 
     94 
     95=head1 DESCRIPTION 
     96 
     97The files in this directory test functionality used by F<Configure.pl>. 
     98 
     99The tests in this file test gen::libjit. 
     100 
     101=head1 SEE ALSO 
     102 
     103config::gen::libjit, F<Configure.pl>. 
     104 
     105=cut 
     106 
     107# Local Variables: 
     108#   mode: cperl 
     109#   cperl-indent-level: 4 
     110#   fill-column: 100 
     111# End: 
     112# vim: expandtab shiftwidth=4: 
  • config/auto/libjit.pm

     
     1# Copyright (C) 2009, Parrot Foundation. 
     2# $Id$ 
     3 
     4=head1 NAME 
     5 
     6config/auto/libjit - Check whether LibJIT is installed 
     7 
     8=head1 DESCRIPTION 
     9 
     10Determines whether libjit is present is installed and functional on the system. 
     11It is OK when it doesn't exist. 
     12 
     13The libjit library implements just-in-time compilation functionality. Unlike 
     14other JITs, this one is designed to be independent of any particular virtual 
     15machine bytecode format or language. 
     16 
     17libjit can be obtained from L<http://freshmeat.net/projects/libjit/> or through 
     18your distribution's package manager. Developer documentation is available from 
     19L<http://www.gnu.org/software/dotgnu/libjit-doc/libjit.html> 
     20 
     21=cut 
     22 
     23package auto::libjit; 
     24 
     25use strict; 
     26use warnings; 
     27 
     28use base 'Parrot::Configure::Step'; 
     29 
     30use Parrot::Configure::Utils ':auto'; 
     31 
     32sub _init { 
     33    my $self = shift; 
     34    my %data = ( 
     35        description => 'Is LibJIT installed', 
     36        result        => '', 
     37    ); 
     38    return \%data; 
     39} 
     40 
     41sub runstep { 
     42    my ($self, $conf) = @_; 
     43 
     44    my ($verbose, $without) = $conf->options->get( qw{ 
     45                                    verbose 
     46                                    without-libjit 
     47    }); 
     48 
     49    my ($has_libjit, $extra_libs); 
     50    if ($without) { 
     51        $has_libjit = 0; 
     52    } 
     53    else { 
     54        $extra_libs = $self->_select_lib( { 
     55            conf         => $conf, 
     56            osname       => $conf->data->get_p5('OSNAME'), 
     57            cc           => $conf->data->get('cc'), 
     58            win32_nongcc => 'libjit.lib', 
     59            default      => '-ljit', 
     60        } ); 
     61 
     62        $conf->cc_gen('config/auto/libjit/libjit_c.in'); 
     63        eval { $conf->cc_build('', $extra_libs) }; 
     64        if ($@) { 
     65            print "cc_build() failed: $@\n" if $verbose; 
     66            $has_libjit = 0; 
     67        } 
     68        else { 
     69            my $test; 
     70            eval { $test = $conf->cc_run(); }; 
     71            if ($@) { 
     72                print "cc_run() failed: $@\n" if $verbose; 
     73                $has_libjit = 0; 
     74            } 
     75            else { 
     76                $has_libjit = 
     77                    $self->_evaluate_cc_run($test, $has_libjit, $verbose); 
     78            } 
     79        } 
     80        $conf->cc_clean(); 
     81    } 
     82 
     83    $conf->data->set( HAS_LIBJIT => $has_libjit ); 
     84    _handle_has_libjit($conf, $has_libjit, $extra_libs); 
     85    $self->set_result( $has_libjit ? 'yes' : 'no' ); 
     86 
     87    return 1; 
     88} 
     89 
     90sub _evaluate_cc_run { 
     91    my ($self, $test, $has_libjit, $verbose) = @_; 
     92    if ($test =~ m/^USES INTERPRETER: \d+/ ) { 
     93        $has_libjit = 1; 
     94        print " (yes) " if $verbose; 
     95        $self->set_result("yes"); 
     96    } 
     97    return $has_libjit; 
     98} 
     99 
     100sub _handle_has_libjit { 
     101    my ($conf, $has_libjit, $extra_libs) = @_; 
     102    if ($has_libjit) { 
     103        $conf->data->set( 
     104            libjit_has_alloca    => ($conf->data->get('cpuarch') eq 'i386' ? '1' : '0'), 
     105        ); 
     106        $conf->data->add( ' ', libs => $extra_libs ); 
     107    } 
     108    else { 
     109        $conf->data->set( libjit_has_alloca => 0 ); 
     110    } 
     111} 
     112 
     1131; 
     114 
     115# Local Variables: 
     116#   mode: cperl 
     117#   cperl-indent-level: 4 
     118#   fill-column: 100 
     119# End: 
     120# vim: expandtab shiftwidth=4: 
  • config/auto/frames.pm

     
    4040 
    4141sub _call_frames_buildable { 
    4242    my $conf = shift; 
    43  
    44     my $osname  = $conf->data->get('osname'); 
    45     my $cpuarch = $conf->data->get('cpuarch'); 
    46     my $nvsize  = $conf->data->get('nvsize'); 
    4743    my $can_build_call_frames; 
    4844 
    4945    if (defined $conf->options->get('buildframes')) { 
    5046        $can_build_call_frames = $conf->options->get('buildframes'); 
    5147    } 
    5248    else { 
    53         # TT #1132 
    54         # Temporary disable build frames automatically. 
    55         #$can_build_call_frames = ($nvsize == 8 && $cpuarch eq 'i386' 
    56         #    && $osname ne 'darwin'); 
    57         $can_build_call_frames = 0; 
     49        $can_build_call_frames = $conf->data->get('HAS_LIBJIT'); 
    5850    } 
    5951    return $can_build_call_frames; 
    6052} 
     
    6355    my ($self, $conf, $can_build_call_frames) = @_; 
    6456    if ( $can_build_call_frames ) { 
    6557        $conf->data->set( 
    66             cc_build_call_frames  => '-DCAN_BUILD_CALL_FRAMES', 
     58            cc_build_call_frames => '-DCAN_BUILD_CALL_FRAMES', 
     59            has_exec_protect     => 1, 
    6760        ); 
    68         # test for executable malloced memory 
    69         my $osname = $conf->data->get( 'osname' ); 
    70         if ( -e "config/auto/frames/test_exec_${osname}_c.in" ) { 
    71             $conf->cc_gen("config/auto/frames/test_exec_${osname}_c.in"); 
    72             eval { $conf->cc_build(); }; 
    73             if ($@) { 
    74                 $conf->data->set( has_exec_protect => 0 ); 
    75             } 
    76             else { 
    77                 my $exec_protect_test = ( 
    78                     $conf->cc_run(0) !~ /ok/ && $conf->cc_run(1) =~ /ok/ 
    79                 ); 
    80                 if ($exec_protect_test) { 
    81                     $conf->data->set( has_exec_protect => 1 ); 
    82                 } 
    83                 else { 
    84                     $conf->data->set( has_exec_protect => 0 ); 
    85                 } 
    86             } 
    87             $conf->cc_clean(); 
    88         } 
    89         else { 
    90             $conf->data->set( has_exec_protect => 0 ); 
    91         } 
    9261        $self->set_result( 'yes' ); 
    9362    } 
    9463    else { 
    95         $conf->data->set( cc_build_call_frames  => ''); 
     64        $conf->data->set(cc_build_call_frames  => ''); 
    9665        $self->set_result( 'no' ); 
    9766    } 
    9867    return 1; 
  • config/auto/libjit/libjit_c.in

     
     1/* 
     2 * Copyright (C) 2009, Parrot Foundation. 
     3 * $Id$ 
     4 */ 
     5 
     6#include <stdlib.h> 
     7#include <stdio.h> 
     8#include <jit/jit.h> 
     9 
     10int 
     11main(int argc, char *argv[]) { 
     12    jit_init(); 
     13    printf("USES INTERPRETER: %i\n", jit_uses_interpreter()); 
     14    return EXIT_SUCCESS; 
     15} 
     16 
     17/* 
     18 * Local variables: 
     19 *   c-file-style: "parrot" 
     20 * End: 
     21 * vim: expandtab shiftwidth=4: 
     22 */ 
  • config/auto/frames/test_exec_openbsd_c.in

     
    1 /* 
    2 Copyright (C) 2004-2009, Parrot Foundation. 
    3 $Id$ 
    4  
    5 test for exec privs 
    6 */ 
    7  
    8 #include <stdio.h> 
    9 #include <stdlib.h> 
    10 #include <sys/mman.h> 
    11 #include <limits.h> 
    12 #include <errno.h> 
    13 #include <malloc.h> 
    14 #include <unistd.h> 
    15 #ifndef PAGE_SIZE 
    16 #  define PAGE_SIZE sysconf(_SC_PAGESIZE) 
    17 #endif 
    18  
    19 /* 
    20  * c equiv: 
    21   int t() { 
    22   return 1; 
    23 } 
    24 */ 
    25  
    26 char code[] = { 
    27     0xB8, 0x01, 0, 0, 0,    /* movl $1, %eax */ 
    28     0xC3                        /* ret */ 
    29 }; 
    30  
    31 typedef int (*pf)(void); 
    32  
    33 int 
    34 main(int argc, char *argv[]) 
    35 { 
    36     pf t; 
    37     char *p; 
    38     int rc; 
    39     int prot = PROT_READ; 
    40  
    41     if (argc != 2) { 
    42         fprintf(stderr, "usage: test 0 | 1\n"); 
    43         exit(1); 
    44     } 
    45     if (atoi(argv[1])) 
    46         prot |= PROT_EXEC; 
    47  
    48     p = malloc(PAGE_SIZE); 
    49     memcpy(p, code, sizeof (code)); 
    50     t  = (pf) p; 
    51     rc = mprotect(p, PAGE_SIZE, prot); 
    52     if (rc) { 
    53         fprintf(stderr, "p = %p  PAGE_SIZE = %d (0x%x)\n", p, 
    54             PAGE_SIZE, PAGE_SIZE); 
    55         perror("failure"); 
    56     } 
    57  
    58     if (t() == 1) 
    59         puts("ok"); 
    60     else 
    61         return 1; 
    62  
    63     return 0; 
    64 } 
    65  
    66 /* 
    67  * Local variables: 
    68  *   c-file-style: "parrot" 
    69  * End: 
    70  * vim: expandtab shiftwidth=4: 
    71  */ 
  • config/auto/frames/test_exec_linux_c.in

     
    1 /* 
    2 Copyright (C) 2004-2009, Parrot Foundation. 
    3 $Id$ 
    4  
    5 test for exec privs 
    6  */ 
    7  
    8 #include <stdio.h> 
    9 #include <stdlib.h> 
    10 #include <sys/mman.h> 
    11 #include <limits.h> 
    12 #include <errno.h> 
    13 #include <malloc.h> 
    14 #include <unistd.h> 
    15 #ifndef PAGE_SIZE 
    16 #  define PAGE_SIZE getpagesize() 
    17 #endif 
    18  
    19 /* 
    20  * c equiv: 
    21   int t() { 
    22   return 1; 
    23 } 
    24 */ 
    25  
    26 char code[] = { 
    27     0xB8, 0x01, 0, 0, 0,        /* movl $1, %eax */ 
    28     0xC3                        /* ret */ 
    29 }; 
    30  
    31 typedef int (*pf)(void); 
    32  
    33 int 
    34 main(int argc, char *argv[]) 
    35 { 
    36     pf t; 
    37     char *p; 
    38     int rc; 
    39     int prot = PROT_READ; 
    40  
    41     if (argc != 2) { 
    42         fprintf(stderr, "usage: test 0 | 1\n"); 
    43         exit(1); 
    44     } 
    45     if (atoi(argv[1])) 
    46         prot |= PROT_EXEC; 
    47  
    48     p = memalign(PAGE_SIZE, sizeof (code)); 
    49     memcpy(p, code, sizeof (code)); 
    50     t  = (pf) p; 
    51     rc = mprotect(p, PAGE_SIZE, prot); 
    52     if (rc) { 
    53         fprintf(stderr, "p = %p  PAGE_SIZE = %d (0x%x)\n", p, 
    54             PAGE_SIZE, PAGE_SIZE); 
    55         perror("failure"); 
    56     } 
    57  
    58     if (t() == 1) 
    59         puts("ok"); 
    60     else 
    61         return 1; 
    62  
    63     return 0; 
    64 } 
    65  
    66 /* 
    67  * Local variables: 
    68  *   c-file-style: "parrot" 
    69  * End: 
    70  * vim: expandtab shiftwidth=4: 
    71  */ 
  • config/auto/frames/test_exec_cygwin_c.in

     
    1 /* 
    2 Copyright (C) 2008-2009, Parrot Foundation. 
    3 $Id$ 
    4  
    5 test for exec privs 
    6 */ 
    7  
    8 #include <stdio.h> 
    9 #include <stdlib.h> 
    10 #include <sys/mman.h> 
    11 #include <limits.h> 
    12 #include <errno.h> 
    13 #include <malloc.h> 
    14 #include <unistd.h> 
    15 #include <string.h> 
    16 #ifndef PAGE_SIZE 
    17 #  define PAGE_SIZE getpagesize() 
    18 #endif 
    19 # 
    20  
    21 /* 
    22  * c equiv: 
    23   int t() { 
    24   return 1; 
    25 } 
    26 */ 
    27  
    28 char code[] = { 
    29     0xB8, 0x01, 0, 0, 0,        /* movl $1, %eax */ 
    30     0xC3                        /* ret */ 
    31 }; 
    32  
    33 typedef int (*pf)(void); 
    34  
    35 int 
    36 main(int argc, char *argv[]) 
    37 { 
    38     pf t; 
    39     char *p; 
    40     int rc; 
    41     int prot = PROT_READ; 
    42  
    43     if (argc != 2) { 
    44         fprintf(stderr, "usage: test 0 | 1\n"); 
    45         exit(1); 
    46     } 
    47  
    48     if (atoi(argv[1])) 
    49         prot |= PROT_EXEC; 
    50  
    51     p = memalign(PAGE_SIZE, PAGE_SIZE); 
    52     memcpy(p, code, sizeof (code)); 
    53  
    54     t  = (pf) p; 
    55     rc = mprotect(p, PAGE_SIZE, prot); 
    56  
    57     if (rc) { 
    58         fprintf(stderr, "p = %p  PAGE_SIZE = %d (0x%x)\n", p, 
    59             PAGE_SIZE, PAGE_SIZE); 
    60         perror("failure"); 
    61     } 
    62  
    63     if (t() == 1) 
    64         puts("ok"); 
    65     else 
    66         return 1; 
    67  
    68     return 0; 
    69 } 
    70  
    71 /* 
    72  * Local variables: 
    73  *   c-file-style: "parrot" 
    74  * End: 
    75  * vim: expandtab shiftwidth=4: 
    76  */ 
  • config/gen/parrot_include.pm

     
    3939        include/parrot/library.h 
    4040        include/parrot/longopt.h 
    4141        include/parrot/multidispatch.h 
     42        include/parrot/nci.h 
    4243        include/parrot/packfile.h 
    4344        include/parrot/stat.h 
    4445        include/parrot/string.h 
    4546        include/parrot/pmc.h 
    4647        include/parrot/warnings.h 
    4748        include/parrot/gc_api.h 
    48         src/pmc/timer.pmc 
    4949        src/utils.c 
    5050    ) ]; 
    5151    $data{generated_files} = [ qw( 
  • config/gen/libjit.pm

     
     1# Copyright (C) 2009, Parrot Foundation. 
     2# $Id$ 
     3 
     4=head1 NAME 
     5 
     6config/gen/libjit.pm - LibJIT Code Generation 
     7 
     8=head1 DESCRIPTION 
     9 
     10Populate F<config/gen/frame_builder_libjit_h.in> and 
     11F<configu/gen/frame_builder_libjit_c.in> with system appropriate 
     12type information and automatically generated parrot function and 
     13vtable jit wrappers. 
     14 
     15=cut 
     16 
     17package gen::libjit; 
     18 
     19use strict; 
     20use warnings; 
     21 
     22use base 'Parrot::Configure::Step'; 
     23 
     24use Parrot::Configure::Utils ':gen'; 
     25 
     26 
     27sub _init { 
     28    my $self = shift; 
     29    my %data = ( 
     30        description => 'Generate LibJIT specific code', 
     31        result => '', 
     32        targets => { 
     33            frame_builder_h => 'src/frame_builder_libjit.h', 
     34            frame_builder_c => 'src/frame_builder_libjit.c', 
     35        }, 
     36        templates => { 
     37            frame_builder_h => 'config/gen/libjit/frame_builder_libjit_h.in', 
     38            frame_builder_c => 'config/gen/libjit/frame_builder_libjit_c.in', 
     39        }, 
     40        wrapped_vtables => { 
     41            get_integer          => [ ()           => 'INTVAL' ], 
     42            set_integer_native   => [ ('INTVAL')   => 'void' ], 
     43            get_pointer          => [ ()           => 'void_ptr' ], 
     44            set_pointer          => [ ('void_ptr') => 'void' ], 
     45            get_string_keyed_int => [ ('INTVAL')   => 'void_ptr' ], 
     46        }, 
     47        wrapped_funcs => { 
     48            Parrot_pcc_fill_params_from_c_args => 
     49                [ qw(void_ptr void_ptr void_ptr ...) => 'void' ], 
     50            Parrot_pcc_fill_returns_from_c_args => 
     51                [ qw(void_ptr void_ptr void_ptr ...) => 'void' ], 
     52 
     53            Parrot_str_new          => 
     54                [ qw(void_ptr void_ptr UINTVAL) => 'void_ptr' ], 
     55            Parrot_str_to_cstring   => 
     56                [ qw(void_ptr void_ptr)         => 'void_ptr' ], 
     57            Parrot_str_free_cstring => 
     58                [ ('void_ptr')                  => 'void' ], 
     59 
     60            pmc_new_noinit      => 
     61                [ qw(void_ptr INTVAL)            => 'void_ptr' ], 
     62 
     63            mem_sys_allocate => [ ('long')     => 'void_ptr' ], 
     64            mem_sys_free     => [ ('void_ptr') => 'void' ], 
     65        }, 
     66    ); 
     67    return \%data; 
     68} 
     69 
     70sub runstep { 
     71    my ($self, $conf) = @_; 
     72 
     73    my ($libjit_iv, $libjit_uv) = @{ 
     74        my $iv = $conf->data->get('iv') || ''; 
     75        { 
     76            short       => [ 'jit_type_sys_short'   , 'jit_type_sys_ushort' ], 
     77            int         => [ 'jit_type_sys_int'     , 'jit_type_sys_uint' ], 
     78            long        => [ 'jit_type_sys_long'    , 'jit_type_sys_ulong' ], 
     79            'long long' => [ 'jit_type_sys_longlong', 'jit_type_sys_ulonglong' ], 
     80        }->{$iv} 
     81            or die "Couldn't determine libjity type for intval of type '$iv'"; 
     82    }; 
     83 
     84    my $libjit_nv = do { 
     85        my $nv = $conf->data->get('nv') || ''; 
     86        { 
     87            float         => 'jit_type_sys_float', 
     88            double        => 'jit_type_sys_double', 
     89            'long double' => 'jit_type_sys_long_double', 
     90        }->{$nv} 
     91            or die "Couldn't determine libjity type for floatval of type '$nv'"; 
     92    }; 
     93 
     94    $conf->data->set( libjit_iv => $libjit_iv, 
     95              libjit_uv => $libjit_uv, 
     96              libjit_nv => $libjit_nv, ); 
     97 
     98    my @vtable_wrappers   = 
     99        map {gen_vtable_wrapper($self, $_)}   keys %{$self->{wrapped_vtables}}; 
     100    my @function_wrappers = 
     101        map {gen_function_wrapper($self, $_)} keys %{$self->{wrapped_funcs}}; 
     102 
     103    $conf->data->set( 
     104        TEMP_vtable_wrap_decls => 
     105            (join "\n", map {$_->{decl}} @vtable_wrappers), 
     106        TEMP_vtable_wrap_defns => 
     107            (join "\n", map {$_->{defn}} @vtable_wrappers), 
     108        TEMP_func_wrap_decls   => 
     109            (join "\n", map {$_->{decl}} @function_wrappers), 
     110        TEMP_func_wrap_defns   => 
     111            (join "\n", map {$_->{defn}} @function_wrappers) 
     112    ); 
     113 
     114    foreach my $t (keys %{$self->{targets}}) { 
     115        $conf->genfile($self->{templates}{$t}, $self->{targets}{$t}); 
     116        $conf->append_configure_log($t); 
     117    } 
     118 
     119    return 1; 
     120} 
     121 
     122sub gen_vtable_wrapper { 
     123    my ($self, $entry_name) = @_; 
     124 
     125    my $entry_sig = $self->{wrapped_vtables}{$entry_name}; 
     126    $_ = jit_prefix_type($_) for @$entry_sig; 
     127 
     128    my $ret_t = pop @$entry_sig; 
     129    my $arg_t = join ", ", @$entry_sig; 
     130 
     131    my $n_args      = scalar @$entry_sig; 
     132    my $arg_decls_t = join ", ", map {'jit_value_t'}     1..$n_args; 
     133    my $arg_decls_v = join ", ", map {"jit_value_t v$_"} 1..$n_args; 
     134    my $arg_v       = join ", ", map {"v$_"}             1..$n_args; 
     135 
     136    my $_arg_decls_t = $n_args ? ", $arg_decls_t" : ""; 
     137    my $_arg_decls_v = $n_args ? ", $arg_decls_v" : ""; 
     138    my $_arg_t = $n_args ? ", $arg_t" : ""; 
     139    my $_arg_v = $n_args ? ", $arg_v" : ""; 
     140 
     141    return { decl => <<DECL, defn => <<DEFN }; 
     142static jit_value_t 
     143jit__vtable_$entry_name(jit_function_t, jit_value_t, jit_value_t $_arg_decls_t); 
     144DECL 
     145static jit_value_t 
     146jit__vtable_$entry_name(jit_function_t f, jit_value_t interp, jit_value_t self $_arg_decls_v) { 
     147    jit_type_t sig; 
     148    jit_value_t vtable, method; 
     149    jit_type_t  arg_t[] = { jit_type_void_ptr, jit_type_void_ptr $_arg_t }; 
     150    jit_value_t arg_v[] = { interp, self $_arg_v }; 
     151 
     152    sig = jit_type_create_signature(jit_abi_cdecl, $ret_t, arg_t, $n_args + 2, 1); 
     153 
     154    vtable = jit_insn_load_relative(f, self,   offsetof(PMC, vtable),         jit_type_void_ptr); 
     155    method = jit_insn_load_relative(f, vtable, offsetof(VTABLE, $entry_name), jit_type_void_ptr); 
     156 
     157    return jit_insn_call_indirect(f, method, sig, arg_v, $n_args + 2, 0); 
     158} 
     159DEFN 
     160} 
     161 
     162sub gen_function_wrapper { 
     163    my ($self, $func_name) = @_; 
     164 
     165    my $func_sig = $self->{wrapped_funcs}{$func_name}; 
     166    $_ = jit_prefix_type($_) for @$func_sig; 
     167 
     168    my $ret_t = pop @$func_sig; 
     169 
     170    my $vararg = 0; 
     171    if ($func_sig->[-1] eq '...') { 
     172        $vararg = 1; 
     173        pop @$func_sig; 
     174    } 
     175 
     176    my $arg_t = join ", ", @$func_sig; 
     177 
     178    my $n_args      = scalar @$func_sig; 
     179    my $arg_decls_t = join ", ", map {'jit_value_t'}     1..$n_args; 
     180    my $arg_decls_v = join ", ", map {"jit_value_t v$_"} 1..$n_args; 
     181    my $arg_v       = join ", ", map {"v$_"}             1..$n_args; 
     182 
     183    my ($decl, $defn); 
     184    if ($vararg) { 
     185        $decl = <<DECL; 
     186static jit_value_t 
     187jit__$func_name(jit_function_t, $arg_decls_t, jit_type_t *, jit_value_t *, int); 
     188DECL 
     189        $defn = <<DEFN; 
     190static jit_value_t 
     191jit__$func_name(jit_function_t f, $arg_decls_v, jit_type_t *va_t, jit_value_t *va_v, int va_n) { 
     192    int i; 
     193    int n_args           = $n_args + va_n; 
     194    jit_type_t sig; 
     195    jit_type_t  arg_t[n_args]; 
     196    jit_value_t arg_v[n_args]; 
     197    jit_type_t  carg_t[] = { $arg_t }; 
     198    jit_value_t carg_v[] = { $arg_v }; 
     199 
     200    for (i = 0; i < $n_args; i++) { 
     201        arg_t[i] = carg_t[i]; 
     202        arg_v[i] = carg_v[i]; 
     203    } 
     204    for (i = $n_args; i < n_args; i++) { 
     205        arg_t[i] = va_t[i - $n_args]; 
     206        arg_v[i] = va_v[i - $n_args]; 
     207    } 
     208 
     209    sig = jit_type_create_signature(jit_abi_cdecl, $ret_t, arg_t, n_args, 1); 
     210 
     211    return jit_insn_call_native(f, "$func_name", (void *)&$func_name, sig, arg_v, n_args, 0); 
     212} 
     213DEFN 
     214    } 
     215    else { 
     216        $decl = <<DECL; 
     217static jit_value_t 
     218jit__$func_name(jit_function_t, $arg_decls_t); 
     219DECL 
     220        $defn = <<DEFN; 
     221static jit_value_t 
     222jit__$func_name(jit_function_t f, $arg_decls_v) { 
     223    int n_args          = $n_args; 
     224    jit_type_t  sig; 
     225    jit_type_t  arg_t[] = { $arg_t }; 
     226    jit_value_t arg_v[] = { $arg_v }; 
     227 
     228    sig = jit_type_create_signature(jit_abi_cdecl, $ret_t, arg_t, n_args, 1); 
     229 
     230    return jit_insn_call_native(f, "$func_name", (void *)&$func_name, sig, arg_v, n_args, 0); 
     231} 
     232DEFN 
     233    } 
     234 
     235    return { decl => $decl, defn => $defn }; 
     236} 
     237 
     238sub jit_prefix_type { 
     239    my $type = shift; 
     240    if ($type =~ /^[_a-z]+$/) { 
     241        return "jit_type_$type"; 
     242    } 
     243    elsif ($type =~ /^[_A-Z]+$/) { 
     244        return "JIT_TYPE_$type"; 
     245    } 
     246    else { 
     247        return $type; 
     248    } 
     249} 
     250 
     2511; 
     252 
     253# Local Variables: 
     254#   mode: cperl 
     255#   cperl-indent-level: 4 
     256#   fill-column: 100 
     257# End: 
     258# vim: expandtab shiftwidth=4: 
  • config/gen/makefiles/root.in

     
    218218    myconfig  \ 
    219219    $(GEN_PASM_INCLUDES) \ 
    220220    $(SRC_DIR)/call_list.txt \ 
     221    $(SRC_DIR)/frame_builder_libjit.h \ 
     222    $(SRC_DIR)/frame_builder_libjit.c \ 
    221223    MANIFEST.configure.generated \ 
    222224    .configure_trace.sto \ 
    223225    .parrot_current_rev 
     
    442444    $(SRC_DIR)/longopt$(O) \ 
    443445    $(SRC_DIR)/misc$(O) \ 
    444446    $(SRC_DIR)/multidispatch$(O) \ 
    445     $(SRC_DIR)/frame_builder$(O) \ 
     447    $(SRC_DIR)/frame_builder_libjit$(O) \ 
    446448    $(SRC_DIR)/nci$(O) \ 
    447449    $(SRC_DIR)/oo$(O) \ 
    448450    $(SRC_DIR)/packfile$(O) \ 
     
    625627    $(SRC_DIR)/key.str \ 
    626628    $(SRC_DIR)/library.str \ 
    627629    $(SRC_DIR)/multidispatch.str \ 
    628     $(SRC_DIR)/frame_builder.str \ 
     630    $(SRC_DIR)/frame_builder_libjit.str \ 
    629631    $(SRC_DIR)/nci.str \ 
    630632    $(SRC_DIR)/packfile.str \ 
    631633    $(SRC_DIR)/pmc.str \ 
     
    12241226$(SRC_DIR)/exit$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/exit.c 
    12251227 
    12261228$(SRC_DIR)/nci$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/nci.c $(SRC_DIR)/nci.str \ 
    1227         $(SRC_DIR)/frame_builder.h \ 
     1229        $(SRC_DIR)/frame_builder_libjit.h \ 
    12281230        $(SRC_DIR)/pmc/pmc_context.h \ 
    12291231        $(SRC_DIR)/pmc/pmc_unmanagedstruct.h \ 
    12301232        $(SRC_DIR)/pmc/pmc_managedstruct.h \ 
    12311233        $(SRC_DIR)/pmc/pmc_nci.h \ 
    12321234        $(SRC_DIR)/pmc/pmc_pointer.h 
    12331235 
    1234 $(SRC_DIR)/frame_builder$(O) : $(SRC_DIR)/frame_builder.h $(GENERAL_H_FILES) \ 
    1235         $(SRC_DIR)/frame_builder.c \ 
    1236         $(SRC_DIR)/frame_builder.str \ 
     1236$(SRC_DIR)/frame_builder_libjit$(O) : $(SRC_DIR)/frame_builder_libjit.h $(GENERAL_H_FILES) \ 
     1237        $(SRC_DIR)/frame_builder_libjit.c \ 
     1238        $(SRC_DIR)/frame_builder_libjit.str \ 
    12371239        $(SRC_DIR)/pmc/pmc_fixedintegerarray.h \ 
    12381240        $(SRC_DIR)/pmc/pmc_unmanagedstruct.h \ 
    12391241        $(SRC_DIR)/pmc/pmc_managedstruct.h 
  • config/gen/libjit/frame_builder_libjit_c.in

     
     1/* 
     2Copyright (C) 2008-2009, Parrot Foundation. 
     3$Id$ 
     4*/ 
     5 
     6/* HEADERIZER HFILE: none */ 
     7/* HEADERIZER STOP */ 
     8 
     9#include "parrot/parrot.h" 
     10#include "pmc/pmc_context.h" 
     11#include "pmc/pmc_integer.h" 
     12#include "pmc/pmc_managedstruct.h" 
     13#include "pmc/pmc_unmanagedstruct.h" 
     14#include "frame_builder.h" 
     15#include "frame_builder_libjit.h" 
     16 
     17#ifdef PARROT_HAS_LIBJIT 
     18 
     19/* 
     20 
     21=over 4 
     22 
     23=item C<void *Parrot_jit_build_call_func(PARROT_INTERP, PMC *nci, STRING *sig, void **priv)> 
     24 
     25Public interface to NCI function interface builder. 
     26 
     27=cut 
     28 
     29*/ 
     30 
     31void * 
     32Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc, STRING *sig, void **priv) { 
     33    void *thunk; 
     34    char *sig_cstr; 
     35 
     36    sig_cstr = Parrot_str_to_cstring(interp, sig); 
     37    *priv    = mem_sys_allocate(sizeof (struct jit_buffer_private_data)); 
     38 
     39    thunk    = Parrot_jit_create_thunk(interp, sig_cstr, *priv); 
     40 
     41    Parrot_str_free_cstring(sig_cstr); 
     42 
     43    return thunk; 
     44} 
     45 
     46/* 
     47 
     48=item C<void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv)> 
     49 
     50This is a callback to implement the proper freeing semantics.  It is called by 
     51the ManagedStruct PMC as it is garbage collected. 
     52 
     53=cut 
     54 
     55*/ 
     56 
     57void 
     58Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv) 
     59{ 
     60    struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv; 
     61    jit_context_destroy(jit->ctx); 
     62    mem_sys_free(jit->sig); 
     63    mem_sys_free(priv); 
     64} 
     65 
     66/* 
     67 
     68=item C<PMC *Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv)> 
     69 
     70This is a callback to implement the proper cloning semantics for jit buffers. 
     71It is called by the ManagedStruct PMC's clone() function. 
     72 
     73=back 
     74 
     75=cut 
     76 
     77*/ 
     78 
     79PMC * 
     80Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv) 
     81{ 
     82    PMC * const rv = pmc_new(interp, pmc->vtable->base_type); 
     83 
     84    VTABLE_init(interp, rv); 
     85    /* copy the attributes */ 
     86    { 
     87        void (*tmpfreefunc)(PARROT_INTERP, void*, void*); 
     88        GETATTR_ManagedStruct_custom_free_func(interp, pmc, tmpfreefunc); 
     89        SETATTR_ManagedStruct_custom_free_func(interp, rv , tmpfreefunc); 
     90    } 
     91    { 
     92        PMC* (*tmpclonefunc)(PARROT_INTERP, PMC*, void*); 
     93        GETATTR_ManagedStruct_custom_clone_func(interp, pmc, tmpclonefunc); 
     94        SETATTR_ManagedStruct_custom_clone_func(interp, rv , tmpclonefunc); 
     95    } 
     96 
     97    /* compile a clone of the function */ 
     98    if (PARROT_MANAGEDSTRUCT(pmc)->ptr) { 
     99        void *rv_priv; 
     100        struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv; 
     101        STRING *sig                         = Parrot_str_new(interp, jit->sig, 0); 
     102        PARROT_MANAGEDSTRUCT(rv)->ptr       = Parrot_jit_build_call_func(interp, rv, sig, &rv_priv); 
     103    } 
     104 
     105    return rv; 
     106} 
     107 
     108/* 
     109 * JIT functions 
     110 */ 
     111 
     112static void * 
     113Parrot_jit_create_thunk(PARROT_INTERP, char *sig, void *priv) { 
     114    struct jit_buffer_private_data *p; 
     115    jit_function_t f; 
     116    jit_value_t jit_interp, jit_nci_pmc, jit_pcc_sig; 
     117    jit_value_t jit_func, jit_pcc_sig_args, jit_pcc_sig_ret; 
     118    jit_value_t jit_call_object; 
     119 
     120    /* populate private data */ 
     121    p      = (struct jit_buffer_private_data*)priv; 
     122    p->ctx = jit_context_create(); 
     123    p->sig = mem_sys_strdup(sig); 
     124 
     125    /* start compiling */ 
     126    jit_context_build_start(p->ctx); 
     127 
     128    /* start JIT function */ 
     129    { 
     130        jit_type_t arg_types[] = { 
     131            jit_type_void_ptr, /* interp */ 
     132            jit_type_void_ptr, /* nci_pmc */ 
     133        }; 
     134        jit_type_t f_sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void, arg_types, 2, 1); 
     135        f                = jit_function_create(p->ctx, f_sig); 
     136    } 
     137 
     138    /* get the incomming args */ 
     139    jit_interp  = jit_value_get_param(f, 0); 
     140    jit_nci_pmc = jit_value_get_param(f, 1); 
     141 
     142    /* get information out of the NCI object */ 
     143    jit_func         = jit__vtable_get_pointer(f, jit_interp, jit_nci_pmc); 
     144    { 
     145        jit_value_t temp = jit__vtable_get_string_keyed_int(f, jit_interp, jit_nci_pmc, 
     146                            jit_value_create_nint_constant(f, JIT_TYPE_INTVAL, PARROT_NCI_PCC_SIGNATURE_PARAMS)); 
     147        jit_pcc_sig_args = jit__Parrot_str_to_cstring(f, jit_interp, temp); 
     148    } 
     149    { 
     150        jit_value_t temp = jit__vtable_get_string_keyed_int(f, jit_interp, jit_nci_pmc, 
     151                            jit_value_create_nint_constant(f, JIT_TYPE_INTVAL, PARROT_NCI_PCC_SIGNATURE_RET)); 
     152        jit_pcc_sig_ret  = jit__Parrot_str_to_cstring(f, jit_interp, temp); 
     153    } 
     154 
     155    /* get call_object */ 
     156    { 
     157        jit_value_t ctx = jit__CURRENT_CONTEXT(f, jit_interp); 
     158        jit_call_object = jit__Parrot_pcc_get_signature(f, jit_interp, ctx); 
     159    } 
     160 
     161    /* get the outgoing args */ 
     162    { 
     163        int nargs = strlen(sig) - 1; 
     164 
     165        jit_type_t  jit_args_t[nargs]; 
     166        jit_value_t jit_args_v[nargs]; 
     167        jit_value_t jit_regs[nargs]; 
     168 
     169        Parrot_jit_parse_sig_args_pre(interp, sig, nargs, f, jit_interp, jit_call_object, jit_pcc_sig_args, 
     170                                      jit_args_t, jit_args_v, jit_regs); 
     171 
     172        /* get the return type */ 
     173        { 
     174            jit_type_t ret_t; 
     175            jit_value_t ret_v; 
     176 
     177            ret_t = Parrot_jit_parse_sig_ret_pre(interp, sig); 
     178 
     179            /* make the call */ 
     180            { 
     181                jit_type_t jit_sig 
     182                          = jit_type_create_signature(jit_abi_cdecl, ret_t, jit_args_t, nargs, 1); 
     183                ret_v     = jit_insn_call_indirect(f, jit_func, jit_sig, jit_args_v, nargs, 0); 
     184            } 
     185 
     186            /* get the incomming return */ 
     187            Parrot_jit_parse_sig_ret_post(interp, sig, f, jit_interp, jit_call_object, jit_pcc_sig_ret, ret_v); 
     188        } 
     189 
     190        /* clean up args */ 
     191        Parrot_jit_parse_sig_args_post(interp, sig, nargs, f, jit_interp, jit_args_v, jit_regs); 
     192    } 
     193 
     194    /* free PCC signature bits */ 
     195    jit__Parrot_str_free_cstring(f, jit_pcc_sig_args); 
     196    jit__Parrot_str_free_cstring(f, jit_pcc_sig_ret); 
     197 
     198    /* end JIT function */ 
     199    jit_insn_return(f, NULL); 
     200 
     201    /* compile to native callable func poitner */ 
     202    jit_function_compile(f); 
     203    jit_context_build_end(p->ctx); 
     204 
     205    return jit_function_to_closure(f); 
     206} 
     207 
     208static int 
     209Parrot_jit_create_arg_regs(PARROT_INTERP, char *sig, int nargs, 
     210                            jit_function_t f, jit_value_t *reg_v) { 
     211    int i, j; 
     212    for (i = 0, j = 0; i < nargs; i++) { 
     213        char c; 
     214        switch (c = sig[i]) { 
     215            case 'I': 
     216            case 'c': 
     217            case 's': 
     218            case 'i': 
     219            case 'l': 
     220                reg_v[j++] = jit_value_create(f, JIT_TYPE_INTVAL); 
     221                break; 
     222 
     223            case 'N': 
     224            case 'd': 
     225            case 'f': 
     226                reg_v[j++] = jit_value_create(f, JIT_TYPE_FLOATVAL); 
     227                break; 
     228 
     229            case 'S': 
     230            case 'B': 
     231            case 'b': 
     232            case 't': 
     233                reg_v[j++] = jit_value_create(f, jit_type_void_ptr); 
     234                break; 
     235 
     236            case 'p': 
     237            case 'P': 
     238            case 'O': 
     239            case '@': 
     240            case '2': 
     241            case '3': 
     242            case '4': 
     243            case 'V': 
     244                reg_v[j++] = jit_value_create(f, jit_type_void_ptr); 
     245                break; 
     246 
     247            default: 
     248                /* don't catch errors here; fail elsewhere */ 
     249                break; 
     250        } 
     251    } 
     252 
     253    return j; 
     254} 
     255 
     256static void 
     257Parrot_jit_fill_args(PARROT_INTERP, char *sig, int nargs, int nregs, 
     258                    jit_function_t f, jit_value_t jit_interp, jit_value_t call_object, jit_value_t jit_pcc_sig_args, 
     259                    jit_value_t *reg_v, jit_type_t *arg_t, jit_value_t *arg_v) { 
     260    int i, j; 
     261 
     262    /* fill argument registers */ 
     263    { 
     264        jit_type_t  jit_reg_addr_t[nregs]; 
     265        jit_value_t jit_reg_addr_v[nregs]; 
     266        for (i = 0; i < nregs; i++) { 
     267            jit_reg_addr_t[i] = jit_type_void_ptr; 
     268            jit_value_set_addressable(reg_v[i]); 
     269            jit_reg_addr_v[i] = jit_insn_address_of(f, reg_v[i]); 
     270        } 
     271        jit__Parrot_pcc_fill_params_from_c_args(f, jit_interp, call_object, jit_pcc_sig_args, 
     272                                                jit_reg_addr_t, jit_reg_addr_v, nregs); 
     273    } 
     274 
     275    for (i = 0, j = 0; i < nargs; i++) { 
     276        char c; 
     277        jit_type_t t1; 
     278        jit_label_t l1; 
     279        jit_value_t v1, v2, v3, v4; 
     280        switch (c = sig[i]) { 
     281            case 'I': 
     282                t1 = JIT_TYPE_INTVAL; 
     283                goto pop_reg; 
     284            case 'c': 
     285                t1 = jit_type_sys_char; 
     286                goto pop_reg; 
     287            case 's': 
     288                t1 = jit_type_sys_short; 
     289                goto pop_reg; 
     290            case 'i': 
     291                t1 = jit_type_sys_int; 
     292                goto pop_reg; 
     293            case 'l': 
     294                t1 = jit_type_sys_long; 
     295                goto pop_reg; 
     296            case 'N': 
     297                t1 = JIT_TYPE_FLOATVAL; 
     298                goto pop_reg; 
     299            case 'f': 
     300                t1 = jit_type_sys_float; 
     301                goto pop_reg; 
     302            case 'd': 
     303                t1 = jit_type_sys_double; 
     304                goto pop_reg; 
     305            case 'S': 
     306            case 'P': 
     307            case 'O': 
     308            case '@': 
     309                t1 = jit_type_void_ptr; 
     310            pop_reg: 
     311                arg_t[i] = t1; 
     312                arg_v[i] = jit_value_create(f, t1); 
     313                jit_insn_store(f, arg_v[i], reg_v[j]); 
     314                j++; 
     315                break; 
     316 
     317            case 't': 
     318                arg_t[i] = jit_type_void_ptr; 
     319                arg_v[i] = jit_value_create(f, jit_type_void_ptr); 
     320                jit_insn_store(f, arg_v[i], 
     321                                jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL)); 
     322                v1       = jit_insn_eq(f, reg_v[j], 
     323                                jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL)); 
     324                l1       = jit_label_undefined; 
     325                jit_insn_branch_if(f, v1, &l1); 
     326                jit_insn_store(f, arg_v[i], jit__Parrot_str_to_cstring(f, jit_interp, reg_v[j])); 
     327                jit_insn_label(f, &l1); 
     328 
     329                j++; 
     330                break; 
     331 
     332            case 'b': 
     333                arg_t[i] = jit_type_void_ptr; 
     334                arg_v[i] = jit__Buffer_bufstart(f, reg_v[j]); 
     335                j++; 
     336                break; 
     337 
     338            case 'B': 
     339                arg_t[i] = jit_type_void_ptr; 
     340                arg_v[i] = jit_value_create(f, jit_type_void_ptr); 
     341                jit_insn_store(f, arg_v[i], 
     342                                jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL)); 
     343                v1       = jit_insn_eq(f, reg_v[j], 
     344                                jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL)); 
     345                l1       = jit_label_undefined; 
     346                jit_insn_branch_if(f, v1, &l1); 
     347                v2       = jit__Parrot_str_to_cstring(f, jit_interp, reg_v[j]); 
     348                v3       = jit_value_create(f, jit_type_void_ptr); 
     349                jit_value_set_addressable(v3); 
     350                jit_insn_store(f, v3, v2); 
     351                jit_insn_store(f, arg_v[i], jit_insn_address_of(f, v3)); 
     352                jit_insn_label(f, &l1); 
     353                j++; 
     354                break; 
     355 
     356            case 'p': 
     357                arg_t[i] = jit_type_void_ptr; 
     358                arg_v[i] = jit_value_create(f, jit_type_void_ptr); 
     359                jit_insn_store(f, arg_v[i], 
     360                                jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL)); 
     361                v1       = jit__PMC_IS_NULL(f, reg_v[j]); 
     362                l1       = jit_label_undefined; 
     363                jit_insn_branch_if(f, v1, &l1); 
     364                v2       = jit__vtable_get_pointer(f, jit_interp, reg_v[j]); 
     365                jit_insn_store(f, arg_v[i], v2); 
     366                jit_insn_label(f, &l1); 
     367                j++; 
     368                break; 
     369 
     370            case '2': 
     371                t1 = jit_type_sys_short; 
     372                goto call_get_integer; 
     373            case '3': 
     374                t1 = jit_type_sys_int; 
     375                goto call_get_integer; 
     376            case '4': 
     377                t1 = jit_type_sys_long; 
     378            call_get_integer: 
     379                arg_t[i] = jit_type_void_ptr; 
     380                v1       = jit__vtable_get_integer(f, jit_interp, reg_v[j]); 
     381                v2       = jit_value_create(f, t1); 
     382                jit_value_set_addressable(v2); 
     383                jit_insn_store(f, v2, v1); 
     384                arg_v[i] = jit_insn_address_of(f, v2); 
     385                j++; 
     386                break; 
     387 
     388            case 'V': 
     389                arg_t[i] = jit_type_void_ptr; 
     390                v1       = jit__vtable_get_pointer(f, jit_interp, reg_v[j]); 
     391                v2       = jit_value_create(f, jit_type_void_ptr); 
     392                jit_value_set_addressable(v2); 
     393                jit_insn_store(f, v2, v1); 
     394                arg_v[i] = jit_insn_address_of(f, v2); 
     395                j++; 
     396                break; 
     397 
     398            case '0': 
     399                arg_t[i] = jit_type_void_ptr; 
     400                arg_v[i] = jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL); 
     401                break; 
     402 
     403            case 'J': 
     404                arg_t[i] = jit_type_void_ptr; 
     405                arg_v[i] = jit_interp; 
     406                break; 
     407 
     408            default: 
     409                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 
     410                    "unkown arg type '%c'", c); 
     411                return; 
     412        } 
     413    } 
     414} 
     415 
     416static void 
     417Parrot_jit_parse_sig_args_pre(PARROT_INTERP, char *sig, int nargs, 
     418                              jit_function_t f, jit_value_t jit_interp, jit_value_t call_object, jit_value_t jit_pcc_sig_args, 
     419                              jit_type_t  *jit_args_t, 
     420                              jit_value_t *jit_args_v, jit_value_t *jit_regs_v) { 
     421    int nregs; 
     422 
     423    sig += 1; /* ignore return character */ 
     424 
     425    nregs = Parrot_jit_create_arg_regs(interp, sig, nargs, f, jit_regs_v); 
     426    Parrot_jit_fill_args(interp, sig, nargs, nregs, f, jit_interp, call_object, jit_pcc_sig_args, 
     427                             jit_regs_v, jit_args_t, jit_args_v); 
     428} 
     429 
     430static jit_type_t 
     431Parrot_jit_parse_sig_ret_pre(PARROT_INTERP, char *sig) { 
     432    char c; 
     433    switch (c = sig[0]) { 
     434        case 'v': 
     435            return jit_type_void; 
     436 
     437        case 'I': 
     438            return JIT_TYPE_INTVAL; 
     439        case 'c': 
     440            return jit_type_sys_char; 
     441        case 's': 
     442            return jit_type_sys_short; 
     443        case 'i': 
     444            return jit_type_sys_int; 
     445        case 'l': 
     446            return jit_type_sys_long; 
     447 
     448        case 'N': 
     449            return JIT_TYPE_FLOATVAL; 
     450        case 'f': 
     451            return jit_type_sys_float; 
     452        case 'd': 
     453            return jit_type_sys_double; 
     454 
     455        case 'S': 
     456        case 't': 
     457            return jit_type_void_ptr; 
     458 
     459        case 'p': 
     460        case 'P': 
     461            return jit_type_void_ptr; 
     462 
     463        default: 
     464            /* FAIL */ 
     465            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 
     466                                        "unknown return type '%c'", c); 
     467            return NULL; 
     468    } 
     469} 
     470 
     471static void 
     472Parrot_jit_parse_sig_ret_post(PARROT_INTERP, char *sig, 
     473                              jit_function_t f, jit_value_t jit_interp, jit_value_t call_object, 
     474                              jit_value_t pcc_sig, jit_value_t retval) { 
     475    jit_type_t  ret_t[1]; 
     476    jit_value_t ret_v[1]; 
     477 
     478    jit_type_t t1; 
     479    jit_value_t v1, v2, v3; 
     480    switch (sig[0]) { 
     481        case 'v': 
     482            break; 
     483 
     484        case 'I': 
     485        case 'c': 
     486        case 's': 
     487        case 'i': 
     488        case 'l': 
     489            ret_t[0] = JIT_TYPE_INTVAL; 
     490            goto fill_ret; 
     491        case 'N': 
     492        case 'f': 
     493        case 'd': 
     494            ret_t[0] = JIT_TYPE_FLOATVAL; 
     495            goto fill_ret; 
     496        case 'S': 
     497        case 'P': 
     498            ret_t[0] = jit_type_void_ptr; 
     499            goto fill_ret; 
     500        case 't': 
     501            ret_t[0] = jit_type_void_ptr; 
     502            retval = jit__Parrot_str_new(f, jit_interp, retval, 
     503                        jit_value_create_nint_constant(f, jit_type_sys_int, 0)); 
     504            goto fill_ret; 
     505        case 'p': 
     506            ret_t[0] = jit_type_void_ptr; 
     507            v1 = jit__pmc_new_noinit(f, jit_interp, 
     508                    jit_value_create_intval_constant(f, enum_class_UnManagedStruct)); 
     509            jit__vtable_set_pointer(f, jit_interp, v1, retval); 
     510            retval = v1; 
     511            goto fill_ret; 
     512        case '2': 
     513            t1 = jit_type_sys_short; 
     514            goto create_int_pmc; 
     515        case '3': 
     516            t1 = jit_type_sys_int; 
     517            goto create_int_pmc; 
     518        case '4': 
     519            t1 = jit_type_sys_long; 
     520        create_int_pmc: 
     521            ret_t[0] = jit_type_void_ptr; 
     522            v1 = jit_insn_load_relative(f, retval, 0, t1); 
     523            v2 = jit__pmc_new_noinit(f, jit_interp, 
     524                    jit_value_create_intval_constant(f, enum_class_Integer)); 
     525            jit__vtable_set_integer_native(f, jit_interp, v2, v1); 
     526            retval = v2; 
     527        fill_ret: 
     528            ret_v[0] = jit_value_create(f, ret_t[0]); 
     529            jit_insn_store(f, ret_v[0], retval); 
     530            jit__Parrot_pcc_fill_returns_from_c_args(f, jit_interp, call_object, pcc_sig, ret_t, ret_v, 1); 
     531            break; 
     532 
     533        default: 
     534            /* ignore (failed elsewhere) */ 
     535            break; 
     536    } 
     537} 
     538 
     539static void 
     540Parrot_jit_parse_sig_args_post(PARROT_INTERP, char *sig, int nargs, 
     541                               jit_function_t f, jit_value_t jit_interp, 
     542                               jit_value_t *args, jit_value_t *regs) { 
     543    int i, j; 
     544 
     545    sig += 1; 
     546 
     547    for (i = 0, j = 0; i < nargs; i++) { 
     548        jit_type_t t1; 
     549        jit_value_t v1; 
     550        switch (sig[i]) { 
     551            case 't': 
     552                jit__Parrot_str_free_cstring(f, args[i]); 
     553                j++; 
     554                break; 
     555 
     556            case 'B': 
     557                v1 = jit_insn_load_relative(f, args[i], 0, jit_type_void_ptr); 
     558                jit__Parrot_str_free_cstring(f, v1); 
     559                j++; 
     560                break; 
     561 
     562            case '2': 
     563                t1 = jit_type_sys_short; 
     564                goto set_integer; 
     565            case '3': 
     566                t1 = jit_type_sys_int; 
     567                goto set_integer; 
     568            case '4': 
     569                t1 = jit_type_sys_long; 
     570            set_integer: 
     571                v1 = jit_insn_load_relative(f, args[i], 0, t1); 
     572                jit__vtable_set_integer_native(f, jit_interp, regs[j], v1); 
     573                j++; 
     574                break; 
     575 
     576            case 'V': 
     577                v1 = jit_insn_load_relative(f, args[i], 0, jit_type_void_ptr); 
     578                jit__vtable_set_pointer(f, jit_interp, regs[j], v1); 
     579                j++; 
     580                break; 
     581 
     582            case 'I': 
     583            case 'c': 
     584            case 'i': 
     585            case 'l': 
     586            case 'N': 
     587            case 'f': 
     588            case 'd': 
     589            case 'S': 
     590            case 'b': 
     591            case 'p': 
     592            case 'P': 
     593            case 'O': 
     594            case '@': 
     595                j++; 
     596                break; 
     597 
     598            default: 
     599                /* ignore */ 
     600                break; 
     601        } 
     602    } 
     603} 
     604 
     605static jit_value_t 
     606jit_value_create_intval_constant(jit_function_t f, INTVAL i) { 
     607    return jit_value_create_nint_constant(f, JIT_TYPE_INTVAL, i); 
     608} 
     609 
     610/* 
     611 * JIT wrappers 
     612 */ 
     613 
     614/* custom wrappers */ 
     615static jit_value_t 
     616jit__Buffer_bufstart(jit_function_t f, jit_value_t buf) { 
     617    return jit_insn_load_relative(f, buf, offsetof(Buffer, _bufstart), jit_type_void_ptr); 
     618} 
     619 
     620static jit_value_t 
     621jit__CURRENT_CONTEXT(jit_function_t f, jit_value_t interp) { 
     622    return jit_insn_load_relative(f, interp, offsetof(struct parrot_interp_t, ctx), jit_type_void_ptr); 
     623} 
     624 
     625static jit_value_t 
     626jit__PMC_IS_NULL(jit_function_t f, jit_value_t pmc) { 
     627    return jit_insn_or(f, 
     628            jit_insn_eq(f, pmc, 
     629                jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL)), 
     630            jit_insn_eq(f, pmc, 
     631                jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)PMCNULL))); 
     632} 
     633 
     634static jit_value_t 
     635jit__Parrot_pcc_get_signature(jit_function_t f, jit_value_t interp, jit_value_t ctx) { 
     636    return jit_insn_load_relative(f, 
     637                jit_insn_load_relative(f, ctx, offsetof(struct PMC, data), jit_type_void_ptr), 
     638                offsetof(struct Parrot_Context_attributes, current_sig), 
     639                jit_type_void_ptr); 
     640} 
     641 
     642/* vtable wrappers */ 
     643@TEMP_vtable_wrap_defns@ 
     644 
     645/* function wrappers */ 
     646@TEMP_func_wrap_defns@ 
     647 
     648#endif /* PARROT_HAS_LIBJIT */ 
     649 
     650/* 
     651 * Local variables: 
     652 *   c-file-style: "parrot" 
     653 * End: 
     654 * vim: expandtab shiftwidth=4: 
     655 */ 
  • config/gen/libjit/frame_builder_libjit_h.in

     
     1/* frame_builder_libjit.h 
     2 * $Id$ 
     3 * Copyright (C) 2009, Parrot Foundation. 
     4 */ 
     5 
     6#ifndef PARROT_FRAME_BUILDER_LIBJIT_H_GUARD 
     7#define PARROT_FRAME_BUILDER_LIBJIT_H_GUARD 
     8 
     9 
     10#if defined(__cplusplus) 
     11#  define EXTERN extern "C" 
     12#else 
     13#  define EXTERN 
     14#endif 
     15 
     16#include <assert.h> 
     17#include "parrot/parrot.h" 
     18#include "frame_builder.h" 
     19 
     20#ifdef PARROT_HAS_LIBJIT 
     21 
     22#  include <jit/jit.h> 
     23 
     24/* 
     25 * JITted function state data 
     26 */ 
     27struct jit_buffer_private_data { 
     28    jit_context_t ctx; 
     29    char *sig; 
     30}; 
     31 
     32/* 
     33 * JIT types 
     34 */ 
     35 
     36#  define JIT_TYPE_UINTVAL  @libjit_uv@ 
     37#  define JIT_TYPE_INTVAL   @libjit_iv@ 
     38#  define JIT_TYPE_FLOATVAL @libjit_nv@ 
     39 
     40/* 
     41 * JIT functions 
     42 */ 
     43 
     44static void * 
     45Parrot_jit_create_thunk(Interp *, char *, void *); 
     46 
     47static void 
     48Parrot_jit_parse_sig_args_pre(Interp *, char *, int, jit_function_t, jit_value_t, jit_value_t, jit_value_t, 
     49                              jit_type_t *, jit_value_t *, jit_value_t *); 
     50 
     51static jit_type_t 
     52Parrot_jit_parse_sig_ret_pre(Interp *, char *); 
     53 
     54static void 
     55Parrot_jit_parse_sig_ret_post(Interp *, char *, jit_function_t, jit_value_t, jit_value_t, jit_value_t, jit_value_t); 
     56 
     57static void 
     58Parrot_jit_parse_sig_args_post(Interp *, char *, int, jit_function_t, jit_value_t, jit_value_t *, jit_value_t *); 
     59 
     60static int 
     61Parrot_jit_create_arg_regs(Interp *, char *, int, jit_function_t, jit_value_t *); 
     62 
     63static void 
     64Parrot_jit_fill_args(Interp *, char *, int, int, jit_function_t, jit_value_t, jit_value_t, jit_value_t, 
     65                    jit_value_t *, jit_type_t *, jit_value_t *); 
     66 
     67static jit_value_t 
     68jit_value_create_intval_constant(jit_function_t, INTVAL); 
     69 
     70/* 
     71 * workaround for platforms that lack libjit alloca support 
     72 */ 
     73#  if @libjit_has_alloca@ 
     74#    define JIT_ALLOCA(f, n)      jit_insn_alloca((f), (n)) 
     75#    define JIT_ALLOCA_FREE(f, p) 
     76#  else 
     77#    define JIT_ALLOCA(f, n)      jit__mem_sys_allocate((f), (n)) 
     78#    define JIT_ALLOCA_FREE(f, p) jit__mem_sys_free((f), (p)) 
     79#  endif 
     80 
     81/* 
     82 * JIT wrappers 
     83 */ 
     84 
     85/* custom wrappers */ 
     86static jit_value_t 
     87jit__Buffer_bufstart(jit_function_t, jit_value_t); 
     88 
     89static jit_value_t 
     90jit__CURRENT_CONTEXT(jit_function_t, jit_value_t); 
     91 
     92static jit_value_t 
     93jit__PMC_IS_NULL(jit_function_t, jit_value_t); 
     94 
     95static jit_value_t 
     96jit__Parrot_pcc_get_signature(jit_function_t, jit_value_t, jit_value_t); 
     97 
     98/* vtable wrappers */ 
     99@TEMP_vtable_wrap_decls@ 
     100 
     101/* function wrappers */ 
     102@TEMP_func_wrap_decls@ 
     103 
     104#endif /* PARROT_HAS_LIBJIT */ 
     105#endif /* PARROT_FRAME_BUILDER_LIBJIT_H_GUARD */ 
     106 
     107/* 
     108 * Local variables: 
     109 *   c-file-style: "parrot" 
     110 * End: 
     111 * vim: expandtab shiftwidth=4: 
     112 */