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;

Reply via email to