Ticket #1549: native_pcc_method.patch
File native_pcc_method.patch, 13.9 KB (added by plobsing, 12 years ago) |
---|
-
src/multidispatch.c
43 43 #include "parrot/oplib/ops.h" 44 44 #include "multidispatch.str" 45 45 #include "pmc/pmc_nci.h" 46 #include "pmc/pmc_nativepccmethod.h" 46 47 #include "pmc/pmc_sub.h" 47 48 #include "pmc/pmc_callcontext.h" 48 49 … … 590 591 Parrot_Sub_attributes *sub; 591 592 INTVAL args, dist, i, j, n, m; 592 593 593 /* has to be a builtin multi method */ 594 if (pmc->vtable->base_type == enum_class_NCI) { 594 if (pmc->vtable->base_type == enum_class_NativePCCMethod) { 595 GETATTR_NativePCCMethod_mmd_multi_sig(interp, pmc, multi_sig); 596 if (PMC_IS_NULL(multi_sig)) { 597 STRING *long_sig; 598 599 GETATTR_NativePCCMethod_mmd_long_signature(interp, pmc, long_sig); 600 multi_sig = mmd_build_type_tuple_from_long_sig(interp, long_sig); 601 SETATTR_NativePCCMethod_mmd_multi_sig(interp, pmc, multi_sig); 602 } 603 } 604 else if (pmc->vtable->base_type == enum_class_NCI) { 595 605 GETATTR_NCI_multi_sig(interp, pmc, multi_sig); 596 606 if (PMC_IS_NULL(multi_sig)) { 597 607 STRING *long_sig; … … 602 612 } 603 613 } 604 614 else { 605 /* not a multi; no distance */606 615 PMC_get_sub(interp, pmc, sub); 616 607 617 if (!sub->multi_signature) 608 return 0; 618 return 0; /* not a multi; no distance */ 609 619 610 620 multi_sig = Parrot_mmd_get_cached_multi_sig(interp, pmc); 611 621 } … … 970 980 /* Attach a type tuple array to the sub for multi dispatch */ 971 981 PMC *multi_sig = mmd_build_type_tuple_from_type_list(interp, type_list); 972 982 973 if (sub_obj->vtable->base_type == enum_class_NCI) { 983 if (sub_obj->vtable->base_type == enum_class_NativePCCMethod) { 984 SETATTR_NativePCCMethod_mmd_multi_sig(interp, sub_obj, multi_sig); 985 } 986 else if (sub_obj->vtable->base_type == enum_class_NCI) { 974 987 SETATTR_NCI_multi_sig(interp, sub_obj, multi_sig); 975 988 } 976 989 else if (VTABLE_isa(interp, sub_obj, sub_str) -
src/oo.c
998 998 class_name = _class->vtable->whoami; 999 999 1000 1000 if (sub) { 1001 if (sub->vtable->base_type == enum_class_NCI) 1001 if (sub->vtable->base_type == enum_class_NativePCCMethod) 1002 result = "NativePCCMethod"; 1003 else if (sub->vtable->base_type == enum_class_NCI) 1002 1004 result = "NCI"; 1003 1005 else 1004 1006 result = "Sub"; -
src/pmc/nativepccmethod.pmc
1 /* 2 Copyright (C) 2010, Parrot Foundation. 3 $Id$ 4 5 =head1 NAME 6 7 src/pmc/nativepccmethod.pmc - Native PCC Method PMC 8 9 =head1 DESCRIPTION 10 11 Container for native functions that handle PCC on their own. 12 13 =head2 Methods 14 15 =over 4 16 17 =cut 18 19 */ 20 21 /* HEADERIZER HFILE: none */ 22 23 pmclass NativePCCMethod auto_attrs { 24 ATTR STRING *signature; 25 ATTR void *func; 26 27 /* MMD fields */ 28 ATTR STRING *mmd_long_signature; 29 ATTR PMC *mmd_multi_sig; 30 31 /* 32 33 =item C<void init()> 34 35 Initializes the PMC with a C<NULL> function pointer. 36 37 =cut 38 39 */ 40 41 VTABLE void init() { 42 Parrot_NativePCCMethod_attributes *attrs = PARROT_NATIVEPCCMETHOD(SELF); 43 44 attrs->func = NULL; 45 attrs->signature = STRINGNULL; 46 attrs->mmd_long_signature = STRINGNULL; 47 attrs->mmd_multi_sig = PMCNULL; 48 49 PObj_custom_mark_SET(SELF); 50 } 51 52 /* 53 54 =item C<void *get_pointer()> 55 56 Get the pointer to the native function. 57 58 =item C<void set_pointer_keyed_str(STRING *sig, void *func)> 59 60 Set the pointer to the native function and the PCC signature. 61 62 =cut 63 64 */ 65 66 67 VTABLE void *get_pointer() { 68 return PARROT_NATIVEPCCMETHOD(SELF)->func; 69 } 70 71 VTABLE void set_pointer_keyed_str(STRING *sig, void *func) { 72 PARROT_NATIVEPCCMETHOD(SELF)->signature = sig; 73 PARROT_NATIVEPCCMETHOD(SELF)->func = func; 74 } 75 76 /* 77 78 =item C<INTVAL defined()> 79 80 =item C<INTVAL get_bool()> 81 82 NULLness check. 83 84 =cut 85 86 */ 87 88 VTABLE INTVAL defined() { 89 return !! PARROT_NATIVEPCCMETHOD(SELF)->func; 90 } 91 92 VTABLE INTVAL get_bool() { 93 return STATICSELF.defined(); 94 } 95 96 /* 97 98 =item C<opcode_t *invoke(void *next)> 99 100 Call the function pointer. 101 102 =cut 103 104 */ 105 106 VTABLE opcode_t *invoke(void *next) { 107 void *func; 108 native_pcc_method_t fptr; 109 110 GET_ATTR_func(INTERP, SELF, func); 111 if (!func) 112 Parrot_ex_throw_from_c_args(INTERP, NULL, 113 EXCEPTION_INVALID_OPERATION, 114 "attempt to call NULL native function"); 115 116 fptr = D2FPTR(func); 117 fptr(INTERP); 118 119 /* 120 * If this function was tailcalled, the return result 121 * is already passed back to the caller of this frame. 122 * We therefore invoke the return continuation here, 123 * which gets rid of this frame and returns the real 124 * return address. 125 */ 126 { 127 PMC *cont = INTERP->current_cont; 128 129 if (cont && cont != NEED_CONTINUATION 130 && (PObj_get_FLAGS(cont) & SUB_FLAG_TAILCALL)) { 131 cont = Parrot_pcc_get_continuation(interp, CURRENT_CONTEXT(interp)); 132 next = VTABLE_invoke(INTERP, cont, next); 133 } 134 } 135 136 return (opcode_t *)next; 137 } 138 139 /* 140 141 =item C<void mark()> 142 143 Mark contained elements for GC. 144 145 =cut 146 147 */ 148 149 VTABLE void mark() { 150 Parrot_NativePCCMethod_attributes *attrs = PARROT_NATIVEPCCMETHOD(SELF); 151 152 Parrot_gc_mark_STRING_alive(interp, attrs->signature); 153 Parrot_gc_mark_STRING_alive(interp, attrs->mmd_long_signature); 154 Parrot_gc_mark_PMC_alive(interp, attrs->mmd_multi_sig); 155 } 156 157 /* 158 159 =item C<PMC *clone()> 160 161 Create a clone of this PMC. 162 163 =cut 164 165 */ 166 167 VTABLE PMC *clone() { 168 PMC *ret = Parrot_pmc_new(INTERP, SELF->vtable->base_type); 169 Parrot_NativePCCMethod_attributes *self_attrs = PARROT_NATIVEPCCMETHOD(SELF); 170 Parrot_NativePCCMethod_attributes *ret_attrs = PARROT_NATIVEPCCMETHOD(ret); 171 172 ret_attrs->func = self_attrs->func; 173 ret_attrs->signature = self_attrs->signature; 174 ret_attrs->mmd_long_signature = self_attrs->mmd_long_signature; 175 ret_attrs->mmd_multi_sig = self_attrs->mmd_multi_sig; 176 177 return ret; 178 } 179 } 180 181 /* 182 183 =back 184 185 =head1 SEE ALSO 186 187 F<docs/pdds/pdd03_calling_conventions.pod>. 188 189 =cut 190 191 */ 192 193 /* 194 * Local variables: 195 * c-file-style: "parrot" 196 * End: 197 * vim: expandtab shiftwidth=4: 198 */ -
src/pmc/namespace.pmc
32 32 __attribute__nonnull__(2) 33 33 __attribute__nonnull__(3); 34 34 35 static void add_n ci_to_namespace(PARROT_INTERP,35 static void add_native_to_namespace(PARROT_INTERP, 36 36 ARGIN(PMC *SELF), 37 37 ARGIN(STRING *key), 38 38 ARGIN_NULLOK(PMC *value)) … … 76 76 PARROT_ASSERT_ARG(interp) \ 77 77 , PARROT_ASSERT_ARG(SELF) \ 78 78 , PARROT_ASSERT_ARG(key)) 79 #define ASSERT_ARGS_add_n ci_to_namespace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\79 #define ASSERT_ARGS_add_native_to_namespace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 80 80 PARROT_ASSERT_ARG(interp) \ 81 81 , PARROT_ASSERT_ARG(SELF) \ 82 82 , PARROT_ASSERT_ARG(key)) … … 199 199 } 200 200 201 201 static void 202 add_n ci_to_namespace(PARROT_INTERP, ARGIN(PMC *SELF), ARGIN(STRING *key),202 add_native_to_namespace(PARROT_INTERP, ARGIN(PMC *SELF), ARGIN(STRING *key), 203 203 ARGIN_NULLOK(PMC *value)) 204 204 { 205 ASSERT_ARGS(add_n ci_to_namespace)205 ASSERT_ARGS(add_native_to_namespace) 206 206 207 STRING * const nci_str = CONST_STRING(interp, "NCI");208 209 207 if (!PMC_IS_NULL(value) 210 && VTABLE_isa(interp, value, nci_str)) { 208 && (value->vtable->base_type == enum_class_NativePCCMethod || 209 value->vtable->base_type == enum_class_NCI)) { 211 210 Parrot_NameSpace_attributes * const nsinfo = PARROT_NAMESPACE(SELF); 212 211 PMC * const classobj = VTABLE_get_class(interp, SELF); 213 212 … … 388 387 if (maybe_add_sub_to_namespace(INTERP, SELF, key, value)) 389 388 return; 390 389 391 /* If it's an NCImethod */392 add_n ci_to_namespace(INTERP, SELF, key, value);390 /* If it's an native method */ 391 add_native_to_namespace(INTERP, SELF, key, value); 393 392 394 393 /* If it's a multi-sub and the first in this NS... */ 395 394 add_multi_to_namespace(INTERP, SELF, key, value); -
src/interp/inter_misc.c
68 68 69 69 /* 70 70 71 =item C<void register_ raw_nci_method_in_ns(PARROT_INTERP, const int type, void72 *func, STRING *name)>71 =item C<void register_native_pcc_method_in_ns(PARROT_INTERP, const int type, 72 void *func, STRING *name, STRING *signature)> 73 73 74 74 Create an entry in the C<nci_method_table> for the given raw NCI method 75 75 of PMC class C<type>. … … 80 80 81 81 PARROT_EXPORT 82 82 void 83 register_ raw_nci_method_in_ns(PARROT_INTERP, const int type, ARGIN(void *func),84 ARGIN(STRING *name) )83 register_native_pcc_method_in_ns(PARROT_INTERP, const int type, ARGIN(void *func), 84 ARGIN(STRING *name), ARGIN(STRING *signature)) 85 85 { 86 ASSERT_ARGS(register_ raw_nci_method_in_ns)87 PMC * const method = Parrot_pmc_new(interp, enum_class_NCI);86 ASSERT_ARGS(register_native_pcc_method_in_ns) 87 PMC * method = Parrot_pmc_new(interp, enum_class_NativePCCMethod); 88 88 89 89 /* setup call func */ 90 VTABLE_set_pointer (interp, method, func);90 VTABLE_set_pointer_keyed_str(interp, method, signature, func); 91 91 92 92 /* insert it into namespace */ 93 93 VTABLE_set_pmc_keyed_str(interp, interp->vtables[type]->_namespace, -
lib/Parrot/Pmc2c/PMCEmitter.pm
666 666 next unless $method->type eq Parrot::Pmc2c::Method::NON_VTABLE; 667 667 668 668 #these differ for METHODs 669 my $method_name = $method->name; 670 my $symbol_name = $method->symbol; 669 my $method_name = $method->name; 670 my $symbol_name = $method->symbol; 671 my ($pcc_signature) = $method->pcc_signature; 671 672 672 673 $cout .= <<"EOC"; 673 register_raw_nci_method_in_ns(interp, entry, F2DPTR(Parrot_${classname}_${method_name}), CONST_STRING_GEN(interp, "$symbol_name")); 674 { 675 STRING *method_name = CONST_STRING_GEN(interp, "$symbol_name"); 676 STRING *signature = CONST_STRING_GEN(interp, "$pcc_signature"); 677 register_native_pcc_method_in_ns(interp, entry, 678 F2DPTR(Parrot_${classname}_${method_name}), 679 method_name, signature); 680 } 674 681 EOC 675 682 if ( $method->{attrs}{write} ) { 676 683 $cout .= <<"EOC"; -
include/parrot/interpreter.h
503 503 __attribute__nonnull__(3); 504 504 505 505 PARROT_EXPORT 506 void register_n ci_method(PARROT_INTERP,506 void register_native_pcc_method_in_ns(PARROT_INTERP, 507 507 const int type, 508 508 ARGIN(void *func), 509 ARGIN( const char*name),510 ARGIN( const char *proto))509 ARGIN(STRING *name), 510 ARGIN(STRING *signature)) 511 511 __attribute__nonnull__(1) 512 512 __attribute__nonnull__(3) 513 513 __attribute__nonnull__(4) 514 514 __attribute__nonnull__(5); 515 515 516 516 PARROT_EXPORT 517 void register_ raw_nci_method_in_ns(PARROT_INTERP,517 void register_nci_method(PARROT_INTERP, 518 518 const int type, 519 519 ARGIN(void *func), 520 ARGIN(STRING *name)) 520 ARGIN(const char *name), 521 ARGIN(const char *proto)) 521 522 __attribute__nonnull__(1) 522 523 __attribute__nonnull__(3) 523 __attribute__nonnull__(4); 524 __attribute__nonnull__(4) 525 __attribute__nonnull__(5); 524 526 525 527 PARROT_WARN_UNUSED_RESULT 526 528 INTVAL sysinfo_i(SHIM_INTERP, INTVAL info_wanted); … … 547 549 #define ASSERT_ARGS_Parrot_mark_method_writes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 548 550 PARROT_ASSERT_ARG(interp) \ 549 551 , PARROT_ASSERT_ARG(name)) 552 #define ASSERT_ARGS_register_native_pcc_method_in_ns \ 553 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 554 PARROT_ASSERT_ARG(interp) \ 555 , PARROT_ASSERT_ARG(func) \ 556 , PARROT_ASSERT_ARG(name) \ 557 , PARROT_ASSERT_ARG(signature)) 550 558 #define ASSERT_ARGS_register_nci_method __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 551 559 PARROT_ASSERT_ARG(interp) \ 552 560 , PARROT_ASSERT_ARG(func) \ 553 561 , PARROT_ASSERT_ARG(name) \ 554 562 , PARROT_ASSERT_ARG(proto)) 555 #define ASSERT_ARGS_register_raw_nci_method_in_ns __attribute__unused__ int _ASSERT_ARGS_CHECK = (\556 PARROT_ASSERT_ARG(interp) \557 , PARROT_ASSERT_ARG(func) \558 , PARROT_ASSERT_ARG(name))559 563 #define ASSERT_ARGS_sysinfo_i __attribute__unused__ int _ASSERT_ARGS_CHECK = (0) 560 564 #define ASSERT_ARGS_sysinfo_s __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 561 565 PARROT_ASSERT_ARG(interp)) -
include/parrot/nci.h
17 17 18 18 typedef PMC *(*nci_fb_func_t)(PARROT_INTERP, PMC *user_data, STRING *signature); 19 19 typedef void (*nci_thunk_t)(PARROT_INTERP, PMC *, PMC *); 20 typedef void (*native_pcc_method_t)(PARROT_INTERP); 20 21 21 22 void Parrot_nci_load_core_thunks(PARROT_INTERP); 22 23 void Parrot_nci_load_extra_thunks(PARROT_INTERP);