| 1 | This page provides some details on migrating external code to use the new Parrot calling conventions implementation. The core focus of this change was to move all sub or method calls throughout the system to store their arguments and returns in a CallSignature PMC, instead of various different ways depending on how the sub/method was called (varargs list, call state struct, direct pointer to the memory location of the opcode where the args were passed, in the interpreter structure, etc). |
| 2 | |
| 3 | == PIR/PASM/PBC interface == |
| 4 | |
| 5 | Unchanged. The opcodes for sub and method calls are the same, called in the same order. The PIR syntactic sugar for sub and method calls is the same. (This is to meet the Parrot support policy, there will be some small changes to the opcode order after 2.0.) |
| 6 | |
| 7 | == C API Functions == |
| 8 | |
| 9 | The following functions have been preserved for backward compatibility with the existing defined C API. The internals of the functions have been completely replaced, but they exactly preserve the old interface, including accepting only old-style signature strings (with the return value type as the first character in the string). |
| 10 | |
| 11 | {{{ |
| 12 | src/extend.c: |
| 13 | Parrot_call_sub |
| 14 | Parrot_call_sub_ret_int |
| 15 | Parrot_call_sub_ret_float |
| 16 | Parrot_call_method |
| 17 | Parrot_call_method_ret_int |
| 18 | Parrot_call_method_ret_float |
| 19 | }}} |
| 20 | |
| 21 | These functions are only preserved for backward compatibility under the support policy, and have been deprecated to be removed after 2.0. (See TT #1145.) The replacement function is 'Parrot_ext_call', and it handles all the cases that the previous set of functions handled. (Recommended to go ahead and migrate to the new function, even though the old functions will be around until 2.0.) |
| 22 | |
| 23 | 'Parrot_ext_call' takes a new-style signature string, where the return value type(s) are listed at the end of the signature, separated from the args by an arrow ('->'). The variables for the return values to be stored in are also passed as references after all the arguments in the call. (See the documentation for 'Parrot_ext_call' for more details.) |
| 24 | |
| 25 | {{{ |
| 26 | INTVAL result; |
| 27 | Parrot_ext_call(interp, cmp, "PP->I", a, b, &result); |
| 28 | return result; |
| 29 | }}} |
| 30 | |
| 31 | The following functions have been deprecated and removed. Calls to any of these functions can be replaced by a call to 'Parrot_ext_call' (with an appropriate signature string). |
| 32 | |
| 33 | {{{ |
| 34 | src/call/ops.c: |
| 35 | runops_args |
| 36 | Parrot_run_meth_fromc |
| 37 | Parrot_runops_fromc_args |
| 38 | Parrot_runops_fromc_args_event |
| 39 | Parrot_runops_fromc_args_reti |
| 40 | Parrot_runops_fromc_args_retf |
| 41 | Parrot_run_meth_fromc_args |
| 42 | Parrot_run_meth_fromc_args_reti |
| 43 | Parrot_run_meth_fromc_args_retf |
| 44 | Parrot_runops_fromc_arglist |
| 45 | Parrot_runops_fromc_arglist_reti |
| 46 | Parrot_runops_fromc_arglist_retf |
| 47 | Parrot_run_meth_fromc_arglist |
| 48 | Parrot_run_meth_fromc_arglist_reti |
| 49 | Parrot_run_meth_fromc_arglist_retf |
| 50 | }}} |
| 51 | |
| 52 | The following functions have been deprecated and removed. They were only used internally, so shouldn't require migration, but if you were using them for any reason, there's a good chance you'll what to move to 'Parrot_ext_call' instead. |
| 53 | |
| 54 | {{{ |
| 55 | src/call/pcc.c: |
| 56 | parrot_pass_args |
| 57 | parrot_pass_args_fromc |
| 58 | Parrot_init_ret_nci |
| 59 | Parrot_init_arg_nci |
| 60 | }}} |
| 61 | |
| 62 | 'parrot_pass_args' has been replaced by 'Parrot_pcc_fill_params_from_op', and 'parrot_pass_args_fromc' has been replaced by 'Parrot_pcc_fill_params_from_c_args'. |
| 63 | |
| 64 | The following functions will be deprecated in the future: |
| 65 | |
| 66 | {{{ |
| 67 | src/call/pcc.c: |
| 68 | Parrot_pcc_invoke_sub_from_c_args |
| 69 | Parrot_PCCINVOKE |
| 70 | }}} |
| 71 | |
| 72 | 'Parrot_pcc_invoke_sub_from_c_args' is exactly the same as 'Parrot_ext_call', but with a worse name, so use 'Parrot_ext_call' instead. 'Parrot_PCCINVOKE' is exactly the same as 'Parrot_pcc_invoke_method_from_c_args', but with a worse name. (See TT #443.) |
| 73 | |
| 74 | == Other C API pieces == |
| 75 | |
| 76 | The interpreter structure no longer has 'interp->current_args', 'interp->current_params', 'interp->current_returns', 'interp->args_signature', 'interp->params_signature', or 'interp->returns_signature' elements. The closest equivalent is 'CURRENT_CONTEXT(interp)->current_sig' (that is, the 'current_sig' element of the current context) which is the CallSignature PMC for the current call (and contains the arguments and results). Don't access this struct element directly, use the interface functions 'Parrot_pcc_get_signature' and 'Parrot_pcc_set_signature' instead. |
| 77 | |
| 78 | {{{ |
| 79 | PMC * const this_call_sig = Parrot_pcc_get_signature(interp, ctx); |
| 80 | }}} |
| 81 | |
| 82 | The 'interp->current_object' element still exists, but will go away once we merge all calls to store the object for method invocations in the CallSignature. (Certain parts of IMCC were left unchanged for now.) |
| 83 | |
| 84 | == Testing == |
| 85 | |
| 86 | Added a 'throws_substring' test function to Test::More, to capture inexact exception messages without depending on PGE in the core tests. |