On Fri, 2004-08-13 at 11:58, Leopold Toetsch wrote: > When that's fixed (or hash's memory is malloced) then the keys have to > be declared with CONST_STRING() or - as these are C strings in the first > place, you create a custom hash with C-string keys. See the API in > hash.c:new_hash_x() or just new_cstring_hash()
I suspect CONST_STRING() would work better, but a C-string hash makes for cleaner generated code. *where to store the hash of functions* > interpreter->iglobals e.g. where BTW the entry #3 "Env" is history and > unused ;) Yeah, that was a tricky bit. I kept seeing segfaults and uninitialized interpreter->iglobals during the first call to build_call_func() until I looked in init_world(). A couple of PMCs actually build NCI funcs during initialize_core_pmcs(). There's an order of operations thing here that someone besides me may want to sort out. The resulting patch isn't yet perfect, but it's a fair stab closer and works with GC_DEBUG enabled on my box. It also throws a lot of "discards qualifiers from pointer type" warnings due to hash_put() taking a void pointer and me passing in a constant string, but that's beyond my ken to fix this afternoon. -- c
Index: build_tools/build_nativecall.pl =================================================================== RCS file: /cvs/public/parrot/build_tools/build_nativecall.pl,v retrieving revision 1.49 diff -u -u -r1.49 build_nativecall.pl --- build_tools/build_nativecall.pl 9 Aug 2004 21:20:12 -0000 1.49 +++ build_tools/build_nativecall.pl 13 Aug 2004 22:13:36 -0000 @@ -175,6 +175,7 @@ * References: */ #include "parrot/parrot.h" +#include "parrot/hash.h" /* * if the architecture can build some or all of these signatures @@ -245,10 +246,14 @@ build_call_func(Interp *interpreter, PMC *pmc_nci, STRING *signature) { - STRING *ns; - STRING *message; - char *c; - void *result = NULL; + char *c; + STRING *ns, *message; + void *result = NULL; + Hash *known_frames; + HashBucket *b; + PMC *iglobals; + PMC *HashPointer = NULL; + #if defined(CAN_BUILD_CALL_FRAMES) /* Try if JIT code can build that signature, @@ -264,8 +269,29 @@ "here there be hacks" */ UNUSED(pmc_nci); if (0 == string_length(interpreter, signature)) return F2DPTR(pcf_v_v); - $icky_global_bit + iglobals = interpreter->iglobals; + + if (iglobals) + HashPointer = VTABLE_get_pmc_keyed_int(interpreter, iglobals, + IGLOBALS_NCI_FUNCS); + + if (!HashPointer) + { + new_cstring_hash( interpreter, &known_frames ); + +$icky_global_bit + } + else + { + known_frames = PMC_data( HashPointer ); + } + + b = hash_get_bucket(interpreter, known_frames, + string_to_cstring(interpreter, signature)); + + if (b) + return F2DPTR( b->value ); /* These three lines have been added to aid debugging. I want to be able to @@ -437,21 +463,12 @@ HEADER } - if (defined $params) { - push @icky_global_variable, <<CALL; - if (!string_compare(interpreter, signature, - string_from_cstring(interpreter, "$return$params", 0))) - return F2DPTR(pcf_${return}_$params); -CALL - } - else { - push @icky_global_variable, <<CALL; - if (!string_compare(interpreter, signature, - string_from_cstring(interpreter, "$return", 0))) - return F2DPTR(pcf_${return}); -CALL - } + my ($key, $value) = (defined $params ? + ( "$return$params", "pcf_${return}_$params" ) : + ( "$return", "pcf_${return}" )); + push @icky_global_variable, + qq| hash_put( interpreter, known_frames, "$key", $value );|; } Index: include/parrot/interpreter.h =================================================================== RCS file: /cvs/public/parrot/include/parrot/interpreter.h,v retrieving revision 1.149 diff -u -u -r1.149 interpreter.h --- include/parrot/interpreter.h 26 Jul 2004 07:34:33 -0000 1.149 +++ include/parrot/interpreter.h 13 Aug 2004 22:13:36 -0000 @@ -267,6 +267,7 @@ IGLOBALS_INTERPRETER, IGLOBALS_DYN_LIBS, IGLOBALS_RUNTIME_LIBRARY, + IGLOBALS_NCI_FUNCS, IGLOBALS_SIZE } iglobals_enum;