[svn:parrot] r42314 - in branches/libjit_framebuilder: . config/auto config/auto/frames config/auto/libjit config/gen config/gen/libjit config/gen/makefiles include/parrot lib/Parrot lib/Parrot/Configure/Options lib/Parrot/Configure/Options/Conf lib/Parrot/Configure/Step src src/ops src/pmc t/pmc t/steps/auto t/steps/gen tools/build

darbelo at svn.parrot.org darbelo at svn.parrot.org
Fri Nov 6 19:11:05 UTC 2009


Author: darbelo
Date: Fri Nov  6 19:11:03 2009
New Revision: 42314
URL: https://trac.parrot.org/parrot/changeset/42314

Log:
This time with an all in one approach:
 - Apply patches from TT#1147 (update nci.pmc for pcc_reapply)
 - Bring over the changes made by the auto_libjit branch.
 - Fix errors introduced by the above.

Added:
   branches/libjit_framebuilder/config/auto/libjit/
   branches/libjit_framebuilder/config/auto/libjit.pm
   branches/libjit_framebuilder/config/auto/libjit/libjit_c.in
   branches/libjit_framebuilder/config/gen/libjit/
   branches/libjit_framebuilder/config/gen/libjit.pm
   branches/libjit_framebuilder/config/gen/libjit/frame_builder_libjit_c.in
   branches/libjit_framebuilder/config/gen/libjit/frame_builder_libjit_h.in
   branches/libjit_framebuilder/lib/Parrot/NativeCall.pm
   branches/libjit_framebuilder/t/steps/auto/libjit-01.t
   branches/libjit_framebuilder/t/steps/gen/libjit-01.t
Deleted:
   branches/libjit_framebuilder/config/auto/frames/
   branches/libjit_framebuilder/src/frame_builder.c
Modified:
   branches/libjit_framebuilder/DEPRECATED.pod
   branches/libjit_framebuilder/MANIFEST
   branches/libjit_framebuilder/config/auto/frames.pm
   branches/libjit_framebuilder/config/gen/makefiles/root.in
   branches/libjit_framebuilder/config/gen/parrot_include.pm
   branches/libjit_framebuilder/include/parrot/nci.h
   branches/libjit_framebuilder/lib/Parrot/Configure/Options/Conf.pm
   branches/libjit_framebuilder/lib/Parrot/Configure/Options/Conf/Shared.pm
   branches/libjit_framebuilder/lib/Parrot/Configure/Step/List.pm
   branches/libjit_framebuilder/lib/Parrot/Distribution.pm
   branches/libjit_framebuilder/src/extend.c
   branches/libjit_framebuilder/src/frame_builder.h
   branches/libjit_framebuilder/src/nci_test.c
   branches/libjit_framebuilder/src/ops/core.ops
   branches/libjit_framebuilder/src/pmc/nci.pmc
   branches/libjit_framebuilder/t/pmc/nci.t
   branches/libjit_framebuilder/t/steps/auto/frames-01.t
   branches/libjit_framebuilder/tools/build/nativecall.pl

Modified: branches/libjit_framebuilder/DEPRECATED.pod
==============================================================================
--- branches/libjit_framebuilder/DEPRECATED.pod	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/DEPRECATED.pod	Fri Nov  6 19:11:03 2009	(r42314)
@@ -74,6 +74,13 @@
 
 L<https://trac.parrot.org/parrot/ticket/918>
 
+=item Use of 'v' in NCI parameter lists [eligible in 2.1]
+
+An empty parameter list suffices to indicate no parameters to an NCI call.
+This has been marked as deprecated in PDD16 for 2 years.
+
+F<pdds/draft/pdd16_native_call.pod>
+
 =back
 
 =head1 Opcodes

Modified: branches/libjit_framebuilder/MANIFEST
==============================================================================
--- branches/libjit_framebuilder/MANIFEST	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/MANIFEST	Fri Nov  6 19:11:03 2009	(r42314)
@@ -234,9 +234,6 @@
 config/auto/env/test_unsetenv_c.in                          []
 config/auto/format.pm                                       []
 config/auto/frames.pm                                       []
-config/auto/frames/test_exec_cygwin_c.in                    []
-config/auto/frames/test_exec_linux_c.in                     []
-config/auto/frames/test_exec_openbsd_c.in                   []
 config/auto/gc.pm                                           []
 config/auto/gc/test_c.in                                    []
 config/auto/gcc.pm                                          []
@@ -258,6 +255,8 @@
 config/auto/isreg.pm                                        []
 config/auto/isreg/test_c.in                                 []
 config/auto/jit.pm                                          []
+config/auto/libjit.pm                                       []
+config/auto/libjit/libjit_c.in                              []
 config/auto/memalign.pm                                     []
 config/auto/memalign/test2_c.in                             []
 config/auto/memalign/test_c.in                              []
@@ -310,6 +309,9 @@
 config/gen/crypto.pm                                        []
 config/gen/crypto/digest_pmc.in                             []
 config/gen/crypto/digest_t.in                               []
+config/gen/libjit.pm                                        []
+config/gen/libjit/frame_builder_libjit_c.in                 []
+config/gen/libjit/frame_builder_libjit_h.in                 []
 config/gen/makefiles.pm                                     []
 config/gen/makefiles/CFLAGS.in                              []
 config/gen/makefiles/data_json.in                           []
@@ -1065,6 +1067,7 @@
 lib/Parrot/IO/Path.pm                                       [devel]lib
 lib/Parrot/Install.pm                                       [devel]lib
 lib/Parrot/Manifest.pm                                      [devel]lib
+lib/Parrot/NativeCall.pm                                    [devel]lib
 lib/Parrot/Op.pm                                            [devel]lib
 lib/Parrot/OpTrans.pm                                       [devel]lib
 lib/Parrot/OpTrans/C.pm                                     [devel]lib
@@ -1269,7 +1272,6 @@
 src/exceptions.c                                            []
 src/exit.c                                                  []
 src/extend.c                                                []
-src/frame_builder.c                                         []
 src/frame_builder.h                                         []
 src/gc/alloc_memory.c                                       []
 src/gc/alloc_resources.c                                    []
@@ -1941,6 +1943,7 @@
 t/steps/auto/inline-01.t                                    [test]
 t/steps/auto/isreg-01.t                                     [test]
 t/steps/auto/jit-01.t                                       [test]
+t/steps/auto/libjit-01.t                                    [test]
 t/steps/auto/memalign-01.t                                  [test]
 t/steps/auto/msvc-01.t                                      [test]
 t/steps/auto/neg_0-01.t                                     [test]
@@ -1965,6 +1968,7 @@
 t/steps/gen/config_pm-01.t                                  [test]
 t/steps/gen/core_pmcs-01.t                                  [test]
 t/steps/gen/crypto-01.t                                     [test]
+t/steps/gen/libjit-01.t                                     [test]
 t/steps/gen/makefiles-01.t                                  [test]
 t/steps/gen/opengl-01.t                                     [test]
 t/steps/gen/parrot_include-01.t                             [test]

Modified: branches/libjit_framebuilder/config/auto/frames.pm
==============================================================================
--- branches/libjit_framebuilder/config/auto/frames.pm	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/config/auto/frames.pm	Fri Nov  6 19:11:03 2009	(r42314)
@@ -40,21 +40,13 @@
 
 sub _call_frames_buildable {
     my $conf = shift;
-
-    my $osname  = $conf->data->get('osname');
-    my $cpuarch = $conf->data->get('cpuarch');
-    my $nvsize  = $conf->data->get('nvsize');
     my $can_build_call_frames;
 
     if (defined $conf->options->get('buildframes')) {
         $can_build_call_frames = $conf->options->get('buildframes');
     }
     else {
-        # TT #1132
-        # Temporary disable build frames automatically.
-        #$can_build_call_frames = ($nvsize == 8 && $cpuarch eq 'i386'
-        #    && $osname ne 'darwin');
-        $can_build_call_frames = 0;
+        $can_build_call_frames = $conf->data->get('HAS_LIBJIT');
     }
     return $can_build_call_frames;
 }
@@ -63,36 +55,13 @@
     my ($self, $conf, $can_build_call_frames) = @_;
     if ( $can_build_call_frames ) {
         $conf->data->set(
-            cc_build_call_frames  => '-DCAN_BUILD_CALL_FRAMES',
+            cc_build_call_frames => '-DCAN_BUILD_CALL_FRAMES',
+            has_exec_protect     => 1,
         );
-        # test for executable malloced memory
-        my $osname = $conf->data->get( 'osname' );
-        if ( -e "config/auto/frames/test_exec_${osname}_c.in" ) {
-            $conf->cc_gen("config/auto/frames/test_exec_${osname}_c.in");
-            eval { $conf->cc_build(); };
-            if ($@) {
-                $conf->data->set( has_exec_protect => 0 );
-            }
-            else {
-                my $exec_protect_test = (
-                    $conf->cc_run(0) !~ /ok/ && $conf->cc_run(1) =~ /ok/
-                );
-                if ($exec_protect_test) {
-                    $conf->data->set( has_exec_protect => 1 );
-                }
-                else {
-                    $conf->data->set( has_exec_protect => 0 );
-                }
-            }
-            $conf->cc_clean();
-        }
-        else {
-            $conf->data->set( has_exec_protect => 0 );
-        }
         $self->set_result( 'yes' );
     }
     else {
-        $conf->data->set( cc_build_call_frames  => '');
+        $conf->data->set(cc_build_call_frames  => '');
         $self->set_result( 'no' );
     }
     return 1;

Added: branches/libjit_framebuilder/config/auto/libjit.pm
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/libjit_framebuilder/config/auto/libjit.pm	Fri Nov  6 19:11:03 2009	(r42314)
@@ -0,0 +1,120 @@
+# Copyright (C) 2009, Parrot Foundation.
+# $Id$
+
+=head1 NAME
+
+config/auto/libjit - Check whether LibJIT is installed
+
+=head1 DESCRIPTION
+
+Determines whether libjit is present is installed and functional on the system.
+It is OK when it doesn't exist.
+
+The libjit library implements just-in-time compilation functionality. Unlike
+other JITs, this one is designed to be independent of any particular virtual
+machine bytecode format or language.
+
+libjit can be obtained from L<http://freshmeat.net/projects/libjit/> or through
+your distribution's package manager. Developer documentation is available from
+L<http://www.gnu.org/software/dotgnu/libjit-doc/libjit.html>
+
+=cut
+
+package auto::libjit;
+
+use strict;
+use warnings;
+
+use base 'Parrot::Configure::Step';
+
+use Parrot::Configure::Utils ':auto';
+
+sub _init {
+    my $self = shift;
+    my %data = (
+        description => 'Is LibJIT installed',
+        result        => '',
+    );
+    return \%data;
+}
+
+sub runstep {
+    my ($self, $conf) = @_;
+
+    my ($verbose, $without) = $conf->options->get( qw{
+                                    verbose
+                                    without-libjit
+    });
+
+    my ($has_libjit, $extra_libs);
+    if ($without) {
+        $has_libjit = 0;
+    }
+    else {
+        $extra_libs = $self->_select_lib( {
+            conf         => $conf,
+            osname       => $conf->data->get_p5('OSNAME'),
+            cc           => $conf->data->get('cc'),
+            win32_nongcc => 'libjit.lib',
+            default      => '-ljit',
+        } );
+
+        $conf->cc_gen('config/auto/libjit/libjit_c.in');
+        eval { $conf->cc_build('', $extra_libs) };
+        if ($@) {
+            print "cc_build() failed: $@\n" if $verbose;
+            $has_libjit = 0;
+        }
+        else {
+            my $test;
+            eval { $test = $conf->cc_run(); };
+            if ($@) {
+                print "cc_run() failed: $@\n" if $verbose;
+                $has_libjit = 0;
+            }
+            else {
+                $has_libjit =
+                    $self->_evaluate_cc_run($test, $has_libjit, $verbose);
+            }
+        }
+        $conf->cc_clean();
+    }
+
+    $conf->data->set( HAS_LIBJIT => $has_libjit );
+    _handle_has_libjit($conf, $has_libjit, $extra_libs);
+    $self->set_result( $has_libjit ? 'yes' : 'no' );
+
+    return 1;
+}
+
+sub _evaluate_cc_run {
+    my ($self, $test, $has_libjit, $verbose) = @_;
+    if ($test =~ m/^USES INTERPRETER: \d+/ ) {
+        $has_libjit = 1;
+        print " (yes) " if $verbose;
+        $self->set_result("yes");
+    }
+    return $has_libjit;
+}
+
+sub _handle_has_libjit {
+    my ($conf, $has_libjit, $extra_libs) = @_;
+    if ($has_libjit) {
+        $conf->data->set(
+            libjit_has_alloca    => ($conf->data->get('cpuarch') eq 'i386' ? '1' : '0'),
+        );
+        $conf->data->add( ' ', libs => $extra_libs );
+    }
+    else {
+        $conf->data->set( libjit_has_alloca => 0 );
+    }
+}
+
+1;
+
+# Local Variables:
+#   mode: cperl
+#   cperl-indent-level: 4
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:

Added: branches/libjit_framebuilder/config/auto/libjit/libjit_c.in
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/libjit_framebuilder/config/auto/libjit/libjit_c.in	Fri Nov  6 19:11:03 2009	(r42314)
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2009, Parrot Foundation.
+ * $Id$
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <jit/jit.h>
+
+int
+main(int argc, char *argv[]) {
+    jit_init();
+    printf("USES INTERPRETER: %i\n", jit_uses_interpreter());
+    return EXIT_SUCCESS;
+}
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */

Added: branches/libjit_framebuilder/config/gen/libjit.pm
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/libjit_framebuilder/config/gen/libjit.pm	Fri Nov  6 19:11:03 2009	(r42314)
@@ -0,0 +1,258 @@
+# Copyright (C) 2009, Parrot Foundation.
+# $Id$
+
+=head1 NAME
+
+config/gen/libjit.pm - LibJIT Code Generation
+
+=head1 DESCRIPTION
+
+Populate F<config/gen/frame_builder_libjit_h.in> and
+F<configu/gen/frame_builder_libjit_c.in> with system appropriate
+type information and automatically generated parrot function and
+vtable jit wrappers.
+
+=cut
+
+package gen::libjit;
+
+use strict;
+use warnings;
+
+use base 'Parrot::Configure::Step';
+
+use Parrot::Configure::Utils ':gen';
+
+
+sub _init {
+    my $self = shift;
+    my %data = (
+        description => 'Generate LibJIT specific code',
+        result => '',
+        targets => {
+            frame_builder_h => 'src/frame_builder_libjit.h',
+            frame_builder_c => 'src/frame_builder_libjit.c',
+        },
+        templates => {
+            frame_builder_h => 'config/gen/libjit/frame_builder_libjit_h.in',
+            frame_builder_c => 'config/gen/libjit/frame_builder_libjit_c.in',
+        },
+        wrapped_vtables => {
+            get_integer          => [ ()           => 'INTVAL' ],
+            set_integer_native   => [ ('INTVAL')   => 'void' ],
+            get_pointer          => [ ()           => 'void_ptr' ],
+            set_pointer          => [ ('void_ptr') => 'void' ],
+            get_string_keyed_int => [ ('INTVAL')   => 'void_ptr' ],
+        },
+        wrapped_funcs => {
+            Parrot_pcc_fill_params_from_c_args =>
+                [ qw(void_ptr void_ptr void_ptr ...) => 'void' ],
+            Parrot_pcc_fill_returns_from_c_args =>
+                [ qw(void_ptr void_ptr void_ptr ...) => 'void' ],
+
+            Parrot_str_new          =>
+                [ qw(void_ptr void_ptr UINTVAL) => 'void_ptr' ],
+            Parrot_str_to_cstring   =>
+                [ qw(void_ptr void_ptr)         => 'void_ptr' ],
+            Parrot_str_free_cstring =>
+                [ ('void_ptr')                  => 'void' ],
+
+            pmc_new_noinit      =>
+                [ qw(void_ptr INTVAL)            => 'void_ptr' ],
+
+            mem_sys_allocate => [ ('long')     => 'void_ptr' ],
+            mem_sys_free     => [ ('void_ptr') => 'void' ],
+        },
+    );
+    return \%data;
+}
+
+sub runstep {
+    my ($self, $conf) = @_;
+
+    my ($libjit_iv, $libjit_uv) = @{
+        my $iv = $conf->data->get('iv') || '';
+        {
+            short       => [ 'jit_type_sys_short'   , 'jit_type_sys_ushort' ],
+            int         => [ 'jit_type_sys_int'     , 'jit_type_sys_uint' ],
+            long        => [ 'jit_type_sys_long'    , 'jit_type_sys_ulong' ],
+            'long long' => [ 'jit_type_sys_longlong', 'jit_type_sys_ulonglong' ],
+        }->{$iv}
+            or die "Couldn't determine libjity type for intval of type '$iv'";
+    };
+
+    my $libjit_nv = do {
+        my $nv = $conf->data->get('nv') || '';
+        {
+            float         => 'jit_type_sys_float',
+            double        => 'jit_type_sys_double',
+            'long double' => 'jit_type_sys_long_double',
+        }->{$nv}
+            or die "Couldn't determine libjity type for floatval of type '$nv'";
+    };
+
+    $conf->data->set( libjit_iv => $libjit_iv,
+              libjit_uv => $libjit_uv,
+              libjit_nv => $libjit_nv, );
+
+    my @vtable_wrappers   =
+        map {gen_vtable_wrapper($self, $_)}   keys %{$self->{wrapped_vtables}};
+    my @function_wrappers =
+        map {gen_function_wrapper($self, $_)} keys %{$self->{wrapped_funcs}};
+
+    $conf->data->set(
+        TEMP_vtable_wrap_decls =>
+            (join "\n", map {$_->{decl}} @vtable_wrappers),
+        TEMP_vtable_wrap_defns =>
+            (join "\n", map {$_->{defn}} @vtable_wrappers),
+        TEMP_func_wrap_decls   =>
+            (join "\n", map {$_->{decl}} @function_wrappers),
+        TEMP_func_wrap_defns   =>
+            (join "\n", map {$_->{defn}} @function_wrappers)
+    );
+
+    foreach my $t (keys %{$self->{targets}}) {
+        $conf->genfile($self->{templates}{$t}, $self->{targets}{$t});
+        $conf->append_configure_log($t);
+    }
+
+    return 1;
+}
+
+sub gen_vtable_wrapper {
+    my ($self, $entry_name) = @_;
+
+    my $entry_sig = $self->{wrapped_vtables}{$entry_name};
+    $_ = jit_prefix_type($_) for @$entry_sig;
+
+    my $ret_t = pop @$entry_sig;
+    my $arg_t = join ", ", @$entry_sig;
+
+    my $n_args      = scalar @$entry_sig;
+    my $arg_decls_t = join ", ", map {'jit_value_t'}     1..$n_args;
+    my $arg_decls_v = join ", ", map {"jit_value_t v$_"} 1..$n_args;
+    my $arg_v       = join ", ", map {"v$_"}             1..$n_args;
+
+    my $_arg_decls_t = $n_args ? ", $arg_decls_t" : "";
+    my $_arg_decls_v = $n_args ? ", $arg_decls_v" : "";
+    my $_arg_t = $n_args ? ", $arg_t" : "";
+    my $_arg_v = $n_args ? ", $arg_v" : "";
+
+    return { decl => <<DECL, defn => <<DEFN };
+static jit_value_t
+jit__vtable_$entry_name(jit_function_t, jit_value_t, jit_value_t $_arg_decls_t);
+DECL
+static jit_value_t
+jit__vtable_$entry_name(jit_function_t f, jit_value_t interp, jit_value_t self $_arg_decls_v) {
+    jit_type_t sig;
+    jit_value_t vtable, method;
+    jit_type_t  arg_t[] = { jit_type_void_ptr, jit_type_void_ptr $_arg_t };
+    jit_value_t arg_v[] = { interp, self $_arg_v };
+
+    sig = jit_type_create_signature(jit_abi_cdecl, $ret_t, arg_t, $n_args + 2, 1);
+
+    vtable = jit_insn_load_relative(f, self,   offsetof(PMC, vtable),         jit_type_void_ptr);
+    method = jit_insn_load_relative(f, vtable, offsetof(VTABLE, $entry_name), jit_type_void_ptr);
+
+    return jit_insn_call_indirect(f, method, sig, arg_v, $n_args + 2, 0);
+}
+DEFN
+}
+
+sub gen_function_wrapper {
+    my ($self, $func_name) = @_;
+
+    my $func_sig = $self->{wrapped_funcs}{$func_name};
+    $_ = jit_prefix_type($_) for @$func_sig;
+
+    my $ret_t = pop @$func_sig;
+
+    my $vararg = 0;
+    if ($func_sig->[-1] eq '...') {
+        $vararg = 1;
+        pop @$func_sig;
+    }
+
+    my $arg_t = join ", ", @$func_sig;
+
+    my $n_args      = scalar @$func_sig;
+    my $arg_decls_t = join ", ", map {'jit_value_t'}     1..$n_args;
+    my $arg_decls_v = join ", ", map {"jit_value_t v$_"} 1..$n_args;
+    my $arg_v       = join ", ", map {"v$_"}             1..$n_args;
+
+    my ($decl, $defn);
+    if ($vararg) {
+        $decl = <<DECL;
+static jit_value_t
+jit__$func_name(jit_function_t, $arg_decls_t, jit_type_t *, jit_value_t *, int);
+DECL
+        $defn = <<DEFN;
+static jit_value_t
+jit__$func_name(jit_function_t f, $arg_decls_v, jit_type_t *va_t, jit_value_t *va_v, int va_n) {
+    int i;
+    int n_args           = $n_args + va_n;
+    jit_type_t sig;
+    jit_type_t  arg_t[n_args];
+    jit_value_t arg_v[n_args];
+    jit_type_t  carg_t[] = { $arg_t };
+    jit_value_t carg_v[] = { $arg_v };
+
+    for (i = 0; i < $n_args; i++) {
+        arg_t[i] = carg_t[i];
+        arg_v[i] = carg_v[i];
+    }
+    for (i = $n_args; i < n_args; i++) {
+        arg_t[i] = va_t[i - $n_args];
+        arg_v[i] = va_v[i - $n_args];
+    }
+
+    sig = jit_type_create_signature(jit_abi_cdecl, $ret_t, arg_t, n_args, 1);
+
+    return jit_insn_call_native(f, "$func_name", (void *)&$func_name, sig, arg_v, n_args, 0);
+}
+DEFN
+    }
+    else {
+        $decl = <<DECL;
+static jit_value_t
+jit__$func_name(jit_function_t, $arg_decls_t);
+DECL
+        $defn = <<DEFN;
+static jit_value_t
+jit__$func_name(jit_function_t f, $arg_decls_v) {
+    int n_args          = $n_args;
+    jit_type_t  sig;
+    jit_type_t  arg_t[] = { $arg_t };
+    jit_value_t arg_v[] = { $arg_v };
+
+    sig = jit_type_create_signature(jit_abi_cdecl, $ret_t, arg_t, n_args, 1);
+
+    return jit_insn_call_native(f, "$func_name", (void *)&$func_name, sig, arg_v, n_args, 0);
+}
+DEFN
+    }
+
+    return { decl => $decl, defn => $defn };
+}
+
+sub jit_prefix_type {
+    my $type = shift;
+    if ($type =~ /^[_a-z]+$/) {
+        return "jit_type_$type";
+    }
+    elsif ($type =~ /^[_A-Z]+$/) {
+        return "JIT_TYPE_$type";
+    }
+    else {
+        return $type;
+    }
+}
+
+1;
+
+# Local Variables:
+#   mode: cperl
+#   cperl-indent-level: 4
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:

Added: branches/libjit_framebuilder/config/gen/libjit/frame_builder_libjit_c.in
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/libjit_framebuilder/config/gen/libjit/frame_builder_libjit_c.in	Fri Nov  6 19:11:03 2009	(r42314)
@@ -0,0 +1,655 @@
+/*
+Copyright (C) 2008-2009, Parrot Foundation.
+$Id$
+*/
+
+/* HEADERIZER HFILE: none */
+/* HEADERIZER STOP */
+
+#include "parrot/parrot.h"
+#include "pmc/pmc_context.h"
+#include "pmc/pmc_integer.h"
+#include "pmc/pmc_managedstruct.h"
+#include "pmc/pmc_unmanagedstruct.h"
+#include "frame_builder.h"
+#include "frame_builder_libjit.h"
+
+#ifdef PARROT_HAS_LIBJIT
+
+/*
+
+=over 4
+
+=item C<void *Parrot_jit_build_call_func(PARROT_INTERP, PMC *nci, STRING *sig, void **priv)>
+
+Public interface to NCI function interface builder.
+
+=cut
+
+*/
+
+void *
+Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc, STRING *sig, void **priv) {
+    void *thunk;
+    char *sig_cstr;
+
+    sig_cstr = Parrot_str_to_cstring(interp, sig);
+    *priv    = mem_sys_allocate(sizeof (struct jit_buffer_private_data));
+
+    thunk    = Parrot_jit_create_thunk(interp, sig_cstr, *priv);
+
+    Parrot_str_free_cstring(sig_cstr);
+
+    return thunk;
+}
+
+/*
+
+=item C<void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv)>
+
+This is a callback to implement the proper freeing semantics.  It is called by
+the ManagedStruct PMC as it is garbage collected.
+
+=cut
+
+*/
+
+void
+Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv)
+{
+    struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv;
+    jit_context_destroy(jit->ctx);
+    mem_sys_free(jit->sig);
+    mem_sys_free(priv);
+}
+
+/*
+
+=item C<PMC *Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv)>
+
+This is a callback to implement the proper cloning semantics for jit buffers.
+It is called by the ManagedStruct PMC's clone() function.
+
+=back
+
+=cut
+
+*/
+
+PMC *
+Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv)
+{
+    PMC * const rv = pmc_new(interp, pmc->vtable->base_type);
+
+    VTABLE_init(interp, rv);
+    /* copy the attributes */
+    {
+        void (*tmpfreefunc)(PARROT_INTERP, void*, void*);
+        GETATTR_ManagedStruct_custom_free_func(interp, pmc, tmpfreefunc);
+        SETATTR_ManagedStruct_custom_free_func(interp, rv , tmpfreefunc);
+    }
+    {
+        PMC* (*tmpclonefunc)(PARROT_INTERP, PMC*, void*);
+        GETATTR_ManagedStruct_custom_clone_func(interp, pmc, tmpclonefunc);
+        SETATTR_ManagedStruct_custom_clone_func(interp, rv , tmpclonefunc);
+    }
+
+    /* compile a clone of the function */
+    if (PARROT_MANAGEDSTRUCT(pmc)->ptr) {
+        void *rv_priv;
+        struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv;
+        STRING *sig                         = Parrot_str_new(interp, jit->sig, 0);
+        PARROT_MANAGEDSTRUCT(rv)->ptr       = Parrot_jit_build_call_func(interp, rv, sig, &rv_priv);
+    }
+
+    return rv;
+}
+
+/*
+ * JIT functions
+ */
+
+static void *
+Parrot_jit_create_thunk(PARROT_INTERP, char *sig, void *priv) {
+    struct jit_buffer_private_data *p;
+    jit_function_t f;
+    jit_value_t jit_interp, jit_nci_pmc, jit_pcc_sig;
+    jit_value_t jit_func, jit_pcc_sig_args, jit_pcc_sig_ret;
+    jit_value_t jit_call_object;
+
+    /* populate private data */
+    p      = (struct jit_buffer_private_data*)priv;
+    p->ctx = jit_context_create();
+    p->sig = mem_sys_strdup(sig);
+
+    /* start compiling */
+    jit_context_build_start(p->ctx);
+
+    /* start JIT function */
+    {
+        jit_type_t arg_types[] = {
+            jit_type_void_ptr, /* interp */
+            jit_type_void_ptr, /* nci_pmc */
+        };
+        jit_type_t f_sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void, arg_types, 2, 1);
+        f                = jit_function_create(p->ctx, f_sig);
+    }
+
+    /* get the incomming args */
+    jit_interp  = jit_value_get_param(f, 0);
+    jit_nci_pmc = jit_value_get_param(f, 1);
+
+    /* get information out of the NCI object */
+    jit_func         = jit__vtable_get_pointer(f, jit_interp, jit_nci_pmc);
+    {
+        jit_value_t temp = jit__vtable_get_string_keyed_int(f, jit_interp, jit_nci_pmc,
+                            jit_value_create_nint_constant(f, JIT_TYPE_INTVAL, PARROT_NCI_PCC_SIGNATURE_PARAMS));
+        jit_pcc_sig_args = jit__Parrot_str_to_cstring(f, jit_interp, temp);
+    }
+    {
+        jit_value_t temp = jit__vtable_get_string_keyed_int(f, jit_interp, jit_nci_pmc,
+                            jit_value_create_nint_constant(f, JIT_TYPE_INTVAL, PARROT_NCI_PCC_SIGNATURE_RET));
+        jit_pcc_sig_ret  = jit__Parrot_str_to_cstring(f, jit_interp, temp);
+    }
+
+    /* get call_object */
+    {
+        jit_value_t ctx = jit__CURRENT_CONTEXT(f, jit_interp);
+        jit_call_object = jit__Parrot_pcc_get_signature(f, jit_interp, ctx);
+    }
+
+    /* get the outgoing args */
+    {
+        int nargs = strlen(sig) - 1;
+
+        jit_type_t  jit_args_t[nargs];
+        jit_value_t jit_args_v[nargs];
+        jit_value_t jit_regs[nargs];
+
+        Parrot_jit_parse_sig_args_pre(interp, sig, nargs, f, jit_interp, jit_call_object, jit_pcc_sig_args,
+                                      jit_args_t, jit_args_v, jit_regs);
+
+        /* get the return type */
+        {
+            jit_type_t ret_t;
+            jit_value_t ret_v;
+
+            ret_t = Parrot_jit_parse_sig_ret_pre(interp, sig);
+
+            /* make the call */
+            {
+                jit_type_t jit_sig
+                          = jit_type_create_signature(jit_abi_cdecl, ret_t, jit_args_t, nargs, 1);
+                ret_v     = jit_insn_call_indirect(f, jit_func, jit_sig, jit_args_v, nargs, 0);
+            }
+
+            /* get the incomming return */
+            Parrot_jit_parse_sig_ret_post(interp, sig, f, jit_interp, jit_call_object, jit_pcc_sig_ret, ret_v);
+        }
+
+        /* clean up args */
+        Parrot_jit_parse_sig_args_post(interp, sig, nargs, f, jit_interp, jit_args_v, jit_regs);
+    }
+
+    /* free PCC signature bits */
+    jit__Parrot_str_free_cstring(f, jit_pcc_sig_args);
+    jit__Parrot_str_free_cstring(f, jit_pcc_sig_ret);
+
+    /* end JIT function */
+    jit_insn_return(f, NULL);
+
+    /* compile to native callable func poitner */
+    jit_function_compile(f);
+    jit_context_build_end(p->ctx);
+
+    return jit_function_to_closure(f);
+}
+
+static int
+Parrot_jit_create_arg_regs(PARROT_INTERP, char *sig, int nargs,
+                            jit_function_t f, jit_value_t *reg_v) {
+    int i, j;
+    for (i = 0, j = 0; i < nargs; i++) {
+        char c;
+        switch (c = sig[i]) {
+            case 'I':
+            case 'c':
+            case 's':
+            case 'i':
+            case 'l':
+                reg_v[j++] = jit_value_create(f, JIT_TYPE_INTVAL);
+                break;
+
+            case 'N':
+            case 'd':
+            case 'f':
+                reg_v[j++] = jit_value_create(f, JIT_TYPE_FLOATVAL);
+                break;
+
+            case 'S':
+            case 'B':
+            case 'b':
+            case 't':
+                reg_v[j++] = jit_value_create(f, jit_type_void_ptr);
+                break;
+
+            case 'p':
+            case 'P':
+            case 'O':
+            case '@':
+            case '2':
+            case '3':
+            case '4':
+            case 'V':
+                reg_v[j++] = jit_value_create(f, jit_type_void_ptr);
+                break;
+
+            default:
+                /* don't catch errors here; fail elsewhere */
+                break;
+        }
+    }
+
+    return j;
+}
+
+static void
+Parrot_jit_fill_args(PARROT_INTERP, char *sig, int nargs, int nregs,
+                    jit_function_t f, jit_value_t jit_interp, jit_value_t call_object, jit_value_t jit_pcc_sig_args,
+                    jit_value_t *reg_v, jit_type_t *arg_t, jit_value_t *arg_v) {
+    int i, j;
+
+    /* fill argument registers */
+    {
+        jit_type_t  jit_reg_addr_t[nregs];
+        jit_value_t jit_reg_addr_v[nregs];
+        for (i = 0; i < nregs; i++) {
+            jit_reg_addr_t[i] = jit_type_void_ptr;
+            jit_value_set_addressable(reg_v[i]);
+            jit_reg_addr_v[i] = jit_insn_address_of(f, reg_v[i]);
+        }
+        jit__Parrot_pcc_fill_params_from_c_args(f, jit_interp, call_object, jit_pcc_sig_args,
+                                                jit_reg_addr_t, jit_reg_addr_v, nregs);
+    }
+
+    for (i = 0, j = 0; i < nargs; i++) {
+        char c;
+        jit_type_t t1;
+        jit_label_t l1;
+        jit_value_t v1, v2, v3, v4;
+        switch (c = sig[i]) {
+            case 'I':
+                t1 = JIT_TYPE_INTVAL;
+                goto pop_reg;
+            case 'c':
+                t1 = jit_type_sys_char;
+                goto pop_reg;
+            case 's':
+                t1 = jit_type_sys_short;
+                goto pop_reg;
+            case 'i':
+                t1 = jit_type_sys_int;
+                goto pop_reg;
+            case 'l':
+                t1 = jit_type_sys_long;
+                goto pop_reg;
+            case 'N':
+                t1 = JIT_TYPE_FLOATVAL;
+                goto pop_reg;
+            case 'f':
+                t1 = jit_type_sys_float;
+                goto pop_reg;
+            case 'd':
+                t1 = jit_type_sys_double;
+                goto pop_reg;
+            case 'S':
+            case 'P':
+            case 'O':
+            case '@':
+                t1 = jit_type_void_ptr;
+            pop_reg:
+                arg_t[i] = t1;
+                arg_v[i] = jit_value_create(f, t1);
+                jit_insn_store(f, arg_v[i], reg_v[j]);
+                j++;
+                break;
+
+            case 't':
+                arg_t[i] = jit_type_void_ptr;
+                arg_v[i] = jit_value_create(f, jit_type_void_ptr);
+                jit_insn_store(f, arg_v[i],
+                                jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL));
+                v1       = jit_insn_eq(f, reg_v[j],
+                                jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL));
+                l1       = jit_label_undefined;
+                jit_insn_branch_if(f, v1, &l1);
+                jit_insn_store(f, arg_v[i], jit__Parrot_str_to_cstring(f, jit_interp, reg_v[j]));
+                jit_insn_label(f, &l1);
+
+                j++;
+                break;
+
+            case 'b':
+                arg_t[i] = jit_type_void_ptr;
+                arg_v[i] = jit__Buffer_bufstart(f, reg_v[j]);
+                j++;
+                break;
+
+            case 'B':
+                arg_t[i] = jit_type_void_ptr;
+                arg_v[i] = jit_value_create(f, jit_type_void_ptr);
+                jit_insn_store(f, arg_v[i],
+                                jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL));
+                v1       = jit_insn_eq(f, reg_v[j],
+                                jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL));
+                l1       = jit_label_undefined;
+                jit_insn_branch_if(f, v1, &l1);
+                v2       = jit__Parrot_str_to_cstring(f, jit_interp, reg_v[j]);
+                v3       = jit_value_create(f, jit_type_void_ptr);
+                jit_value_set_addressable(v3);
+                jit_insn_store(f, v3, v2);
+                jit_insn_store(f, arg_v[i], jit_insn_address_of(f, v3));
+                jit_insn_label(f, &l1);
+                j++;
+                break;
+
+            case 'p':
+                arg_t[i] = jit_type_void_ptr;
+                arg_v[i] = jit_value_create(f, jit_type_void_ptr);
+                jit_insn_store(f, arg_v[i],
+                                jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL));
+                v1       = jit__PMC_IS_NULL(f, reg_v[j]);
+                l1       = jit_label_undefined;
+                jit_insn_branch_if(f, v1, &l1);
+                v2       = jit__vtable_get_pointer(f, jit_interp, reg_v[j]);
+                jit_insn_store(f, arg_v[i], v2);
+                jit_insn_label(f, &l1);
+                j++;
+                break;
+
+            case '2':
+                t1 = jit_type_sys_short;
+                goto call_get_integer;
+            case '3':
+                t1 = jit_type_sys_int;
+                goto call_get_integer;
+            case '4':
+                t1 = jit_type_sys_long;
+            call_get_integer:
+                arg_t[i] = jit_type_void_ptr;
+                v1       = jit__vtable_get_integer(f, jit_interp, reg_v[j]);
+                v2       = jit_value_create(f, t1);
+                jit_value_set_addressable(v2);
+                jit_insn_store(f, v2, v1);
+                arg_v[i] = jit_insn_address_of(f, v2);
+                j++;
+                break;
+
+            case 'V':
+                arg_t[i] = jit_type_void_ptr;
+                v1       = jit__vtable_get_pointer(f, jit_interp, reg_v[j]);
+                v2       = jit_value_create(f, jit_type_void_ptr);
+                jit_value_set_addressable(v2);
+                jit_insn_store(f, v2, v1);
+                arg_v[i] = jit_insn_address_of(f, v2);
+                j++;
+                break;
+
+            case '0':
+                arg_t[i] = jit_type_void_ptr;
+                arg_v[i] = jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL);
+                break;
+
+            case 'J':
+                arg_t[i] = jit_type_void_ptr;
+                arg_v[i] = jit_interp;
+                break;
+
+            default:
+                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
+                    "unkown arg type '%c'", c);
+                return;
+        }
+    }
+}
+
+static void
+Parrot_jit_parse_sig_args_pre(PARROT_INTERP, char *sig, int nargs,
+                              jit_function_t f, jit_value_t jit_interp, jit_value_t call_object, jit_value_t jit_pcc_sig_args,
+                              jit_type_t  *jit_args_t,
+                              jit_value_t *jit_args_v, jit_value_t *jit_regs_v) {
+    int nregs;
+
+    sig += 1; /* ignore return character */
+
+    nregs = Parrot_jit_create_arg_regs(interp, sig, nargs, f, jit_regs_v);
+    Parrot_jit_fill_args(interp, sig, nargs, nregs, f, jit_interp, call_object, jit_pcc_sig_args,
+                             jit_regs_v, jit_args_t, jit_args_v);
+}
+
+static jit_type_t
+Parrot_jit_parse_sig_ret_pre(PARROT_INTERP, char *sig) {
+    char c;
+    switch (c = sig[0]) {
+        case 'v':
+            return jit_type_void;
+
+        case 'I':
+            return JIT_TYPE_INTVAL;
+        case 'c':
+            return jit_type_sys_char;
+        case 's':
+            return jit_type_sys_short;
+        case 'i':
+            return jit_type_sys_int;
+        case 'l':
+            return jit_type_sys_long;
+
+        case 'N':
+            return JIT_TYPE_FLOATVAL;
+        case 'f':
+            return jit_type_sys_float;
+        case 'd':
+            return jit_type_sys_double;
+
+        case 'S':
+        case 't':
+            return jit_type_void_ptr;
+
+        case 'p':
+        case 'P':
+            return jit_type_void_ptr;
+
+        default:
+            /* FAIL */
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
+                                        "unknown return type '%c'", c);
+            return NULL;
+    }
+}
+
+static void
+Parrot_jit_parse_sig_ret_post(PARROT_INTERP, char *sig,
+                              jit_function_t f, jit_value_t jit_interp, jit_value_t call_object,
+                              jit_value_t pcc_sig, jit_value_t retval) {
+    jit_type_t  ret_t[1];
+    jit_value_t ret_v[1];
+
+    jit_type_t t1;
+    jit_value_t v1, v2, v3;
+    switch (sig[0]) {
+        case 'v':
+            break;
+
+        case 'I':
+        case 'c':
+        case 's':
+        case 'i':
+        case 'l':
+            ret_t[0] = JIT_TYPE_INTVAL;
+            goto fill_ret;
+        case 'N':
+        case 'f':
+        case 'd':
+            ret_t[0] = JIT_TYPE_FLOATVAL;
+            goto fill_ret;
+        case 'S':
+        case 'P':
+            ret_t[0] = jit_type_void_ptr;
+            goto fill_ret;
+        case 't':
+            ret_t[0] = jit_type_void_ptr;
+            retval = jit__Parrot_str_new(f, jit_interp, retval,
+                        jit_value_create_nint_constant(f, jit_type_sys_int, 0));
+            goto fill_ret;
+        case 'p':
+            ret_t[0] = jit_type_void_ptr;
+            v1 = jit__pmc_new_noinit(f, jit_interp,
+                    jit_value_create_intval_constant(f, enum_class_UnManagedStruct));
+            jit__vtable_set_pointer(f, jit_interp, v1, retval);
+            retval = v1;
+            goto fill_ret;
+        case '2':
+            t1 = jit_type_sys_short;
+            goto create_int_pmc;
+        case '3':
+            t1 = jit_type_sys_int;
+            goto create_int_pmc;
+        case '4':
+            t1 = jit_type_sys_long;
+        create_int_pmc:
+            ret_t[0] = jit_type_void_ptr;
+            v1 = jit_insn_load_relative(f, retval, 0, t1);
+            v2 = jit__pmc_new_noinit(f, jit_interp,
+                    jit_value_create_intval_constant(f, enum_class_Integer));
+            jit__vtable_set_integer_native(f, jit_interp, v2, v1);
+            retval = v2;
+        fill_ret:
+            ret_v[0] = jit_value_create(f, ret_t[0]);
+            jit_insn_store(f, ret_v[0], retval);
+            jit__Parrot_pcc_fill_returns_from_c_args(f, jit_interp, call_object, pcc_sig, ret_t, ret_v, 1);
+            break;
+
+        default:
+            /* ignore (failed elsewhere) */
+            break;
+    }
+}
+
+static void
+Parrot_jit_parse_sig_args_post(PARROT_INTERP, char *sig, int nargs,
+                               jit_function_t f, jit_value_t jit_interp,
+                               jit_value_t *args, jit_value_t *regs) {
+    int i, j;
+
+    sig += 1;
+
+    for (i = 0, j = 0; i < nargs; i++) {
+        jit_type_t t1;
+        jit_value_t v1;
+        switch (sig[i]) {
+            case 't':
+                jit__Parrot_str_free_cstring(f, args[i]);
+                j++;
+                break;
+
+            case 'B':
+                v1 = jit_insn_load_relative(f, args[i], 0, jit_type_void_ptr);
+                jit__Parrot_str_free_cstring(f, v1);
+                j++;
+                break;
+
+            case '2':
+                t1 = jit_type_sys_short;
+                goto set_integer;
+            case '3':
+                t1 = jit_type_sys_int;
+                goto set_integer;
+            case '4':
+                t1 = jit_type_sys_long;
+            set_integer:
+                v1 = jit_insn_load_relative(f, args[i], 0, t1);
+                jit__vtable_set_integer_native(f, jit_interp, regs[j], v1);
+                j++;
+                break;
+
+            case 'V':
+                v1 = jit_insn_load_relative(f, args[i], 0, jit_type_void_ptr);
+                jit__vtable_set_pointer(f, jit_interp, regs[j], v1);
+                j++;
+                break;
+
+            case 'I':
+            case 'c':
+            case 'i':
+            case 'l':
+            case 'N':
+            case 'f':
+            case 'd':
+            case 'S':
+            case 'b':
+            case 'p':
+            case 'P':
+            case 'O':
+            case '@':
+                j++;
+                break;
+
+            default:
+                /* ignore */
+                break;
+        }
+    }
+}
+
+static jit_value_t
+jit_value_create_intval_constant(jit_function_t f, INTVAL i) {
+    return jit_value_create_nint_constant(f, JIT_TYPE_INTVAL, i);
+}
+
+/*
+ * JIT wrappers
+ */
+
+/* custom wrappers */
+static jit_value_t
+jit__Buffer_bufstart(jit_function_t f, jit_value_t buf) {
+    return jit_insn_load_relative(f, buf, offsetof(Buffer, _bufstart), jit_type_void_ptr);
+}
+
+static jit_value_t
+jit__CURRENT_CONTEXT(jit_function_t f, jit_value_t interp) {
+    return jit_insn_load_relative(f, interp, offsetof(struct parrot_interp_t, ctx), jit_type_void_ptr);
+}
+
+static jit_value_t
+jit__PMC_IS_NULL(jit_function_t f, jit_value_t pmc) {
+    return jit_insn_or(f,
+            jit_insn_eq(f, pmc,
+                jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL)),
+            jit_insn_eq(f, pmc,
+                jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)PMCNULL)));
+}
+
+static jit_value_t
+jit__Parrot_pcc_get_signature(jit_function_t f, jit_value_t interp, jit_value_t ctx) {
+    return jit_insn_load_relative(f,
+                jit_insn_load_relative(f, ctx, offsetof(struct PMC, data), jit_type_void_ptr),
+                offsetof(struct Parrot_Context_attributes, current_sig),
+                jit_type_void_ptr);
+}
+
+/* vtable wrappers */
+ at TEMP_vtable_wrap_defns@
+
+/* function wrappers */
+ at TEMP_func_wrap_defns@
+
+#endif /* PARROT_HAS_LIBJIT */
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */

Added: branches/libjit_framebuilder/config/gen/libjit/frame_builder_libjit_h.in
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/libjit_framebuilder/config/gen/libjit/frame_builder_libjit_h.in	Fri Nov  6 19:11:03 2009	(r42314)
@@ -0,0 +1,112 @@
+/* frame_builder_libjit.h
+ * $Id$
+ * Copyright (C) 2009, Parrot Foundation.
+ */
+
+#ifndef PARROT_FRAME_BUILDER_LIBJIT_H_GUARD
+#define PARROT_FRAME_BUILDER_LIBJIT_H_GUARD
+
+
+#if defined(__cplusplus)
+#  define EXTERN extern "C"
+#else
+#  define EXTERN
+#endif
+
+#include <assert.h>
+#include "parrot/parrot.h"
+#include "frame_builder.h"
+
+#ifdef PARROT_HAS_LIBJIT
+
+#  include <jit/jit.h>
+
+/*
+ * JITted function state data
+ */
+struct jit_buffer_private_data {
+    jit_context_t ctx;
+    char *sig;
+};
+
+/*
+ * JIT types
+ */
+
+#  define JIT_TYPE_UINTVAL  @libjit_uv@
+#  define JIT_TYPE_INTVAL   @libjit_iv@
+#  define JIT_TYPE_FLOATVAL @libjit_nv@
+
+/*
+ * JIT functions
+ */
+
+static void *
+Parrot_jit_create_thunk(Interp *, char *, void *);
+
+static void
+Parrot_jit_parse_sig_args_pre(Interp *, char *, int, jit_function_t, jit_value_t, jit_value_t, jit_value_t,
+                              jit_type_t *, jit_value_t *, jit_value_t *);
+
+static jit_type_t
+Parrot_jit_parse_sig_ret_pre(Interp *, char *);
+
+static void
+Parrot_jit_parse_sig_ret_post(Interp *, char *, jit_function_t, jit_value_t, jit_value_t, jit_value_t, jit_value_t);
+
+static void
+Parrot_jit_parse_sig_args_post(Interp *, char *, int, jit_function_t, jit_value_t, jit_value_t *, jit_value_t *);
+
+static int
+Parrot_jit_create_arg_regs(Interp *, char *, int, jit_function_t, jit_value_t *);
+
+static void
+Parrot_jit_fill_args(Interp *, char *, int, int, jit_function_t, jit_value_t, jit_value_t, jit_value_t,
+                    jit_value_t *, jit_type_t *, jit_value_t *);
+
+static jit_value_t
+jit_value_create_intval_constant(jit_function_t, INTVAL);
+
+/*
+ * workaround for platforms that lack libjit alloca support
+ */
+#  if @libjit_has_alloca@
+#    define JIT_ALLOCA(f, n)      jit_insn_alloca((f), (n))
+#    define JIT_ALLOCA_FREE(f, p)
+#  else
+#    define JIT_ALLOCA(f, n)      jit__mem_sys_allocate((f), (n))
+#    define JIT_ALLOCA_FREE(f, p) jit__mem_sys_free((f), (p))
+#  endif
+
+/*
+ * JIT wrappers
+ */
+
+/* custom wrappers */
+static jit_value_t
+jit__Buffer_bufstart(jit_function_t, jit_value_t);
+
+static jit_value_t
+jit__CURRENT_CONTEXT(jit_function_t, jit_value_t);
+
+static jit_value_t
+jit__PMC_IS_NULL(jit_function_t, jit_value_t);
+
+static jit_value_t
+jit__Parrot_pcc_get_signature(jit_function_t, jit_value_t, jit_value_t);
+
+/* vtable wrappers */
+ at TEMP_vtable_wrap_decls@
+
+/* function wrappers */
+ at TEMP_func_wrap_decls@
+
+#endif /* PARROT_HAS_LIBJIT */
+#endif /* PARROT_FRAME_BUILDER_LIBJIT_H_GUARD */
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */

Modified: branches/libjit_framebuilder/config/gen/makefiles/root.in
==============================================================================
--- branches/libjit_framebuilder/config/gen/makefiles/root.in	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/config/gen/makefiles/root.in	Fri Nov  6 19:11:03 2009	(r42314)
@@ -218,6 +218,8 @@
     myconfig  \
     $(GEN_PASM_INCLUDES) \
     $(SRC_DIR)/call_list.txt \
+    $(SRC_DIR)/frame_builder_libjit.h \
+    $(SRC_DIR)/frame_builder_libjit.c \
     MANIFEST.configure.generated \
     .configure_trace.sto \
     .parrot_current_rev
@@ -442,7 +444,7 @@
     $(SRC_DIR)/longopt$(O) \
     $(SRC_DIR)/misc$(O) \
     $(SRC_DIR)/multidispatch$(O) \
-    $(SRC_DIR)/frame_builder$(O) \
+    $(SRC_DIR)/frame_builder_libjit$(O) \
     $(SRC_DIR)/nci$(O) \
     $(SRC_DIR)/oo$(O) \
     $(SRC_DIR)/packfile$(O) \
@@ -625,7 +627,7 @@
     $(SRC_DIR)/key.str \
     $(SRC_DIR)/library.str \
     $(SRC_DIR)/multidispatch.str \
-    $(SRC_DIR)/frame_builder.str \
+    $(SRC_DIR)/frame_builder_libjit.str \
     $(SRC_DIR)/nci.str \
     $(SRC_DIR)/packfile.str \
     $(SRC_DIR)/pmc.str \
@@ -1224,16 +1226,16 @@
 $(SRC_DIR)/exit$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/exit.c
 
 $(SRC_DIR)/nci$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/nci.c $(SRC_DIR)/nci.str \
-        $(SRC_DIR)/frame_builder.h \
+        $(SRC_DIR)/frame_builder_libjit.h \
         $(SRC_DIR)/pmc/pmc_context.h \
         $(SRC_DIR)/pmc/pmc_unmanagedstruct.h \
         $(SRC_DIR)/pmc/pmc_managedstruct.h \
         $(SRC_DIR)/pmc/pmc_nci.h \
         $(SRC_DIR)/pmc/pmc_pointer.h
 
-$(SRC_DIR)/frame_builder$(O) : $(SRC_DIR)/frame_builder.h $(GENERAL_H_FILES) \
-        $(SRC_DIR)/frame_builder.c \
-        $(SRC_DIR)/frame_builder.str \
+$(SRC_DIR)/frame_builder_libjit$(O) : $(SRC_DIR)/frame_builder_libjit.h $(GENERAL_H_FILES) \
+        $(SRC_DIR)/frame_builder_libjit.c \
+        $(SRC_DIR)/frame_builder_libjit.str \
         $(SRC_DIR)/pmc/pmc_fixedintegerarray.h \
         $(SRC_DIR)/pmc/pmc_unmanagedstruct.h \
         $(SRC_DIR)/pmc/pmc_managedstruct.h

Modified: branches/libjit_framebuilder/config/gen/parrot_include.pm
==============================================================================
--- branches/libjit_framebuilder/config/gen/parrot_include.pm	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/config/gen/parrot_include.pm	Fri Nov  6 19:11:03 2009	(r42314)
@@ -39,13 +39,13 @@
         include/parrot/library.h
         include/parrot/longopt.h
         include/parrot/multidispatch.h
+        include/parrot/nci.h
         include/parrot/packfile.h
         include/parrot/stat.h
         include/parrot/string.h
         include/parrot/pmc.h
         include/parrot/warnings.h
         include/parrot/gc_api.h
-        src/pmc/timer.pmc
         src/utils.c
     ) ];
     $data{generated_files} = [ qw(

Modified: branches/libjit_framebuilder/include/parrot/nci.h
==============================================================================
--- branches/libjit_framebuilder/include/parrot/nci.h	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/include/parrot/nci.h	Fri Nov  6 19:11:03 2009	(r42314)
@@ -15,6 +15,17 @@
 
 #include "parrot/parrot.h"
 
+/* NCI PMC interface constants */
+/* &gen_from_enum(nci.pasm) */
+typedef enum {
+    PARROT_NCI_ARITY,
+    PARROT_NCI_PCC_SIGNATURE_PARAMS,
+    PARROT_NCI_PCC_SIGNATURE_RET,
+    PARROT_NCI_LONG_SIGNATURE,
+    PARROT_NCI_MULTI_SIG,
+} parrot_nci_enum_t;
+/* &end_gen */
+
 void *build_call_func(PARROT_INTERP, SHIM(PMC *pmc_nci), NOTNULL(STRING *signature), NOTNULL(int *jitted));
 
 #endif /* PARROT_NCI_H_GUARD */

Modified: branches/libjit_framebuilder/lib/Parrot/Configure/Options/Conf.pm
==============================================================================
--- branches/libjit_framebuilder/lib/Parrot/Configure/Options/Conf.pm	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/lib/Parrot/Configure/Options/Conf.pm	Fri Nov  6 19:11:03 2009	(r42314)
@@ -105,6 +105,7 @@
    --without-gmp        Build parrot without GMP support
    --without-opengl     Build parrot without OpenGL support (GL/GLU/GLUT)
    --without-pcre       Build parrot without pcre support
+   --without-libjit     Build parrot without LibJIT support
 
 ICU Options:
 

Modified: branches/libjit_framebuilder/lib/Parrot/Configure/Options/Conf/Shared.pm
==============================================================================
--- branches/libjit_framebuilder/lib/Parrot/Configure/Options/Conf/Shared.pm	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/lib/Parrot/Configure/Options/Conf/Shared.pm	Fri Nov  6 19:11:03 2009	(r42314)
@@ -75,6 +75,7 @@
     without-gettext
     without-gmp
     without-icu
+    without-libjit
     without-opengl
     without-pcre
     without-threads

Modified: branches/libjit_framebuilder/lib/Parrot/Configure/Step/List.pm
==============================================================================
--- branches/libjit_framebuilder/lib/Parrot/Configure/Step/List.pm	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/lib/Parrot/Configure/Step/List.pm	Fri Nov  6 19:11:03 2009	(r42314)
@@ -39,6 +39,7 @@
     auto::format
     auto::isreg
     auto::arch
+    auto::libjit
     auto::jit
     auto::frames
     auto::cpu
@@ -70,11 +71,16 @@
     gen::parrot_include
     gen::opengl
     gen::call_list
+    gen::libjit
     gen::makefiles
     gen::platform
     gen::config_pm
 );
 
+=pod
+
+=cut
+
 sub get_steps_list { return @steps; }
 
 1;

Modified: branches/libjit_framebuilder/lib/Parrot/Distribution.pm
==============================================================================
--- branches/libjit_framebuilder/lib/Parrot/Distribution.pm	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/lib/Parrot/Distribution.pm	Fri Nov  6 19:11:03 2009	(r42314)
@@ -433,6 +433,8 @@
             include/parrot/config.h
             include/parrot/has_header.h
             src/gc/malloc.c
+            src/frame_builder_libjit.h
+            src/frame_builder_libjit.c
             } unless @exemptions;
 
         my $path = -f $file ? $file : $file->path;

Added: branches/libjit_framebuilder/lib/Parrot/NativeCall.pm
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/libjit_framebuilder/lib/Parrot/NativeCall.pm	Fri Nov  6 19:11:03 2009	(r42314)
@@ -0,0 +1,128 @@
+# Copyright (C) 2009, Parrot Foundation.
+# $Id$
+
+package Parrot::NativeCall;
+
+use strict;
+use warnings;
+
+use base 'Exporter';
+our @EXPORT_OK = qw{ signature_nci_to_pcc };
+
+=head1 NAME
+
+Parrot::NativeCall - Tools for building native call routines
+
+=head1 SYNOPSIS
+
+  use Parrot::NativeCall 'signature_nci_to_pcc';
+
+  my $pcc_sig = signature_nci_to_pcc("v  VVV");
+
+=head1 DESCRIPTION
+
+C<Parrot::NativeCall> knows how to map NCI signatures to nci frame
+functions.
+
+=head1 GLOBAL VARIABLES
+
+=over
+
+=item C<%signature_table>
+
+Maps NCI signature items to elements of a native call routine.
+
+For use by F<tools/build/nativecall.pl>. New code should probably write
+a wrapper in this module to encapsulate the access.
+
+=cut
+
+our %signature_table = (
+    p => {
+        as_proto => "void *",
+        other_decl => "PMC * const final_destination = pmc_new(interp, enum_class_UnManagedStruct);",
+        sig_char => "P",
+        ret_assign => "VTABLE_set_pointer(interp, final_destination, return_data);\n    Parrot_pcc_fill_returns_from_c_args(interp, call_object, \"P\", final_destination);",
+    },
+    i => { as_proto => "int",    sig_char => "I" },
+    l => { as_proto => "long",   sig_char => "I" },
+    c => { as_proto => "char",   sig_char => "I" },
+    s => { as_proto => "short",  sig_char => "I" },
+    f => { as_proto => "float",  sig_char => "N" },
+    d => { as_proto => "double", sig_char => "N" },
+    t => { as_proto => "char *",
+           other_decl => "STRING *final_destination;",
+           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);",
+           sig_char => "S" },
+    v => { as_proto => "void",
+           return_type => "void *",
+           sig_char => "v",
+           ret_assign => "",
+           func_call_assign => ""
+         },
+    P => { as_proto => "PMC *", sig_char => "P" },
+    O => { as_proto => "PMC *", returns => "", sig_char => "Pi" },
+    J => { as_proto => "PARROT_INTERP", returns => "", sig_char => "" },
+    S => { as_proto => "STRING *", sig_char => "S" },
+    I => { as_proto => "INTVAL", sig_char => "I" },
+    N => { as_proto => "FLOATVAL", sig_char => "N" },
+    b => { as_proto => "void *", as_return => "", sig_char => "S" },
+    B => { as_proto => "char **", as_return => "", sig_char => "S" },
+    # These should be replaced by modifiers in the future
+    2 => { as_proto => "short *",  sig_char => "P", return_type => "short",
+           ret_assign => 'Parrot_pcc_fill_returns_from_c_args(interp, call_object, "I", return_data);' },
+    3 => { as_proto => "int *",  sig_char => "P", return_type => "int",
+           ret_assign => 'Parrot_pcc_fill_returns_from_c_args(interp, call_object, "I", return_data);' },
+    4 => { as_proto => "long *",  sig_char => "P", return_type => "long",
+           ret_assign => 'Parrot_pcc_fill_returns_from_c_args(interp, call_object, "I", return_data);' },
+    L => { as_proto => "long *", as_return => "" },
+    T => { as_proto => "char **", as_return => "" },
+    V => { as_proto => "void **", as_return => "", sig_char => "P" },
+    '@' => { as_proto => "PMC *", as_return => "", cname => "xAT_", sig_char => 'Ps' },
+);
+
+for (values %signature_table) {
+    if (not exists $_->{as_return}) { $_->{as_return} = $_->{as_proto} }
+    if (not exists $_->{return_type}) { $_->{return_type} = $_->{as_proto} }
+    if (not exists $_->{return_type_decl}) { $_->{return_type_decl} = $_->{return_type} }
+    if (not exists $_->{ret_assign} and exists $_->{sig_char}) {
+        $_->{ret_assign} = 'Parrot_pcc_fill_returns_from_c_args(interp, call_object, "'
+                           . $_->{sig_char} . '", return_data);';
+    }
+    if (not exists $_->{func_call_assign}) {
+        $_->{func_call_assign} = "return_data = "
+    }
+}
+
+=back
+
+=head1 FUNCTIONS
+
+=over
+
+=item C<signature_nci_to_pcc>
+
+Converts an NCI signature to a PCC signature.
+
+=cut
+
+sub signature_nci_to_pcc {
+    my $nci_sig = shift;
+    my ($nci_ret, $nci_params) = $nci_sig =~ /^(.)\s*(\S*)/;
+    my $pcc_ret =  $signature_table{$nci_ret}{sig_char};
+    my $pcc_params = join '', map $signature_table{$_}{sig_char}, split //, $nci_params;
+    return "${pcc_params}->${pcc_ret}";
+}
+
+1;
+
+=back
+
+=cut
+
+# Local Variables:
+#   mode: cperl
+#   cperl-indent-level: 4
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:

Modified: branches/libjit_framebuilder/src/extend.c
==============================================================================
--- branches/libjit_framebuilder/src/extend.c	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/src/extend.c	Fri Nov  6 19:11:03 2009	(r42314)
@@ -1747,7 +1747,6 @@
         (char *) NULL, 0);
     Parrot_PMC sub = pmc_new(interp, enum_class_NCI);
     VTABLE_set_pointer_keyed_str(interp, sub, sig, F2DPTR(func));
-    PObj_get_FLAGS(sub) |= PObj_private1_FLAG;
     return sub;
 }
 

Deleted: branches/libjit_framebuilder/src/frame_builder.c
==============================================================================
--- branches/libjit_framebuilder/src/frame_builder.c	Fri Nov  6 19:11:03 2009	(r42313)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,618 +0,0 @@
-/*
-Copyright (C) 2008-2009, Parrot Foundation.
-$Id$
-*/
-
-/* HEADERIZER HFILE: none */
-/* HEADERIZER STOP */
-
-#include "parrot/parrot.h"
-#include "pmc/pmc_fixedintegerarray.h"
-#include "pmc/pmc_unmanagedstruct.h"
-#include "pmc/pmc_managedstruct.h"
-#include "frame_builder.h"
-
-/*
-
-=over 4
-
-=item C<void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv)>
-
-This is a callback to implement the proper freeing semantics.  It is called by
-the ManagedStruct PMC as it is garbage collected.
-
-=cut
-
-*/
-
-void
-Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv)
-{
-    const struct jit_buffer_private_data * const jit = (struct jit_buffer_private_data*)priv;
-    mem_free_executable(ptr, jit->size);
-    free(priv);
-}
-
-/*
-
-=item C<PMC *Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv)>
-
-This is a callback to implement the proper cloning semantics for jit buffers.
-It is called by the ManagedStruct PMC's clone() function.
-
-=back
-
-=cut
-
-*/
-
-PMC *
-Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv)
-{
-    PMC * const rv = pmc_new(interp, pmc->vtable->base_type);
-
-    VTABLE_init(interp, rv);
-    /* copy the attributes */
-    {
-        void (*tmpfreefunc)(PARROT_INTERP, void*, void*);
-        GETATTR_ManagedStruct_custom_free_func(interp, pmc, tmpfreefunc);
-        SETATTR_ManagedStruct_custom_free_func(interp, rv , tmpfreefunc);
-    }
-    {
-        PMC* (*tmpclonefunc)(PARROT_INTERP, PMC*, void*);
-        GETATTR_ManagedStruct_custom_clone_func(interp, pmc, tmpclonefunc);
-        SETATTR_ManagedStruct_custom_clone_func(interp, rv , tmpclonefunc);
-    }
-
-    {
-        void *freepriv, *clonepriv;
-        GETATTR_ManagedStruct_custom_free_priv(interp , pmc, freepriv);
-        GETATTR_ManagedStruct_custom_clone_priv(interp, pmc, clonepriv);
-        if (freepriv) {
-            void *tmp = mem_sys_allocate(sizeof (struct jit_buffer_private_data));
-            memcpy(tmp, freepriv, sizeof (struct jit_buffer_private_data));
-            SETATTR_ManagedStruct_custom_free_priv(interp, rv , tmp);
-            if (clonepriv == freepriv) {
-                /* clonepriv is a copy of freepriv, make it a copy in the clone too. */
-                SETATTR_ManagedStruct_custom_clone_priv(interp, rv , tmp);
-                clonepriv = NULL; /* disable the clonepriv copying below */
-            }
-        }
-        if (clonepriv) {
-            void *tmp = mem_sys_allocate(sizeof (struct jit_buffer_private_data));
-            memcpy(tmp, clonepriv, sizeof (struct jit_buffer_private_data));
-            SETATTR_ManagedStruct_custom_clone_priv(interp, rv , tmp);
-        }
-    }
-
-    /* copy the execmem buffer */
-    if (PARROT_MANAGEDSTRUCT(pmc)->ptr) {
-        struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv;
-        void *ptr = PARROT_MANAGEDSTRUCT(pmc)->ptr;
-        void *newptr = mem_alloc_executable(jit->size);
-        if (!newptr)
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
-                    "Cannot allocate executable memory");
-        memcpy(newptr, ptr, jit->size);
-        PARROT_MANAGEDSTRUCT(rv)->ptr = newptr;
-    }
-
-    return rv;
-}
-
-
-int
-emit_is8bit(long disp)
-{
-    return disp >= -128 && disp <= 127;
-}
-
-char *
-emit_disp8_32(char *pc, int disp)
-{
-    if (emit_is8bit(disp)) {
-        *(pc++) = (char)disp;
-        return pc;
-    }
-    else {
-        *(long *)pc = disp;
-        return pc + 4;
-    }
-}
-
-void
-emit_sib(PARROT_INTERP, char *pc, int scale, int i, int base)
-{
-    int scale_byte;
-
-    switch (scale) {
-        case 1:
-            scale_byte = emit_Scale_1;
-            break;
-        case 2:
-            scale_byte = emit_Scale_2;
-            break;
-        case 4:
-            scale_byte = emit_Scale_4;
-            break;
-        case 8:
-            scale_byte = emit_Scale_8;
-            break;
-        default:
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
-                "Invalid scale factor %d\n", scale);
-            return;
-    }
-
-    *pc = (char)(scale_byte | (i == emit_None ? emit_Index_None : emit_reg_Index(i)) |
-            emit_reg_Base(base));
-}
-
-char *
-emit_r_X(PARROT_INTERP, char *pc, int reg_opcode, int base, int i, int scale, long disp)
-{
-    if (i && !scale)
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
-            "emit_r_X passed invalid scale+index combo\n");
-
-    if (base == emit_EBP) {
-    /* modrm disp */
-        if (i == emit_None) {
-            *(pc++) = (char)((emit_is8bit(disp) ? emit_Mod_b01 : emit_Mod_b10)
-                    | reg_opcode | emit_reg_rm(emit_EBP));
-            return emit_disp8_32(pc, disp);
-        }
-        /* modrm sib disp */
-        else {
-            *(pc++) = (char)((emit_is8bit(disp) ? emit_Mod_b01 : emit_Mod_b10)
-                    | reg_opcode | emit_b100);
-            emit_sib(interp, pc++, scale, i, base);
-            return emit_disp8_32(pc, disp);
-        }
-    }
-
-    /* modrm sib disp */
-    if (base == emit_ESP) {
-        *(pc++) = (char)((emit_is8bit(disp) ? emit_Mod_b01 : emit_Mod_b10)
-                | reg_opcode | emit_rm_b100);
-        emit_sib(interp, pc++, scale, i, emit_ESP);
-        return emit_disp8_32(pc, disp);
-    }
-
-    /* modrm disp32 */
-    if (!base && !(i && scale)) {
-        *(pc++) = (char)(emit_Mod_b00 | reg_opcode | emit_rm_b101);
-        *(long *)pc = disp;
-        return pc + 4;
-    }
-
-    /* Ok, everything should be more regular here */
-    *(pc++) = (char)((disp == 0 ? emit_Mod_b00 :
-              (emit_is8bit(disp) ?
-               emit_Mod_b01 : emit_Mod_b10)) |
-               reg_opcode |
-               (!base || (scale && i) ? emit_rm_b100 : emit_reg_rm(base)));
-
-    if (!base || (scale && i)) {
-        emit_sib(interp, pc++, scale, i, base);
-    }
-    if (disp)
-        pc = emit_disp8_32(pc, disp);
-
-    return pc;
-}
-
-char *
-emit_shift_i_r(PARROT_INTERP, char *pc, int opcode, int imm, int reg)
-{
-    if (opcode == emit_b000 && imm < 0) {
-        opcode = emit_b001;     /* -rol => 32 + ror */
-        imm = -imm;
-    }
-
-    if (imm == 0) {
-        /* noop */
-    }
-    else if (imm == 1) {
-        *(pc++) = (char) 0xd1;
-        *(pc++) = (char) emit_alu_X_r(opcode,  reg);
-    }
-    else if (imm > 1 && imm < 33) {
-        *(pc++) = (char) 0xc1;
-        *(pc++) = (char) emit_alu_X_r(opcode,  reg);
-        *(pc++) = (char)imm;
-    }
-    else {
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
-            "emit_shift_i_r passed invalid shift\n");
-    }
-
-    return pc;
-}
-
-char *
-emit_popl_r(char *pc, int reg)
-{
-    *(pc++) = (char)(0x58 | (reg - 1));
-    return pc;
-}
-
-unsigned char *lastpc;
-
-size_t
-calc_signature_needs(const char *sig, int *strings)
-{
-    size_t stack_size = 0;
-    while (*sig) {
-        switch (*sig) {
-            case 't':
-                (*strings)++;
-                stack_size +=4;
-                break;
-            case 'd':
-                stack_size +=8;
-                break;
-            default:
-                stack_size +=4;
-                break;
-        }
-        sig++;
-    }
-    return stack_size;
-
-}
-
-/*
- * The function generated here is called as func(interp, nci_info)
- * interp   ...  8(%ebp)
- * nci_info ... 12(%ebp)
- *
- * The generate function for a specific signature looks quite similar to
- * an optimized compile of src/nci.c:pcf_x_yy(). In case of any troubles
- * just compare the disassembly.
- *
- * If a non-NULL sizeptr is passed, the integer it points to will be written
- * with the size of the allocated execmem buffer.
- */
-
-void *
-Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature, int *sizeptr)
-{
-    char     *pc;
-    char     *execmem;
-    int       i                    = 0;
-    int       arg_count            = 0;
-    int       string_buffer_count  = 0;
-    const int ST_SIZE_OF           = 124;
-    const int JIT_ALLOC_SIZE       = 1024;
-
-    char      *signature_str      = Parrot_str_to_cstring(interp, signature);
-    /* skip over the result */
-    char      *sig                = signature_str + 1;
-    size_t     stack_space_needed = calc_signature_needs(sig,
-                                        &string_buffer_count);
-
-    int base_offset        = 0;
-    int strings_offset     = base_offset - (sizeof (char *) * string_buffer_count);
-    int st_offset          = strings_offset - ST_SIZE_OF;
-    int args_offset        = st_offset - stack_space_needed;
-    int temp_calls_offset  = args_offset - 16;
-    int total_stack_needed = -temp_calls_offset;
-
-    /*
-     * ESP
-     * 0-15, 16 bytes for utility calls
-     * stack_space_needed for actual NCI call
-     * st
-     * STRINGS -> char * holding space
-     * EBP
-     */
-
-    /* this ought to be enough - the caller of this function
-     * should free the function pointer returned here
-     */
-    pc = execmem = (char *)mem_alloc_executable(JIT_ALLOC_SIZE);
-    if (! pc)
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
-                "Cannot allocate executable memory");
-
-
-    /* this generated jit function will be called as (INTERP (EBP 8), func_ptr
-    * (ESP 12), args signature (ESP 16)) */
-
-    /* make stack frame, preserve %ebx */
-    jit_emit_stack_frame_enter(pc);
-
-    emitm_subl_i_r(pc, total_stack_needed, emit_ESP);
-
-    /* Parrot_init_arg_nci(interp, &st, "S"); */
-    /* args signature "S" */
-    emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 16);
-    emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
-
-    /*&st*/
-    emitm_lea_m_r(interp,  pc, emit_EAX, emit_EBP, 0, 1, st_offset);
-    emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
-
-    /*interpreter*/
-    emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
-    emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0);
-
-    /* XXX FIXME This whole function require major rework */
-    /* XXX FIXME if (sig && *sig) */
-    /* XXX FIXME   emitm_call_cfunc(pc, Parrot_init_arg_nci); */
-
-    while (*sig) {
-        emitm_movl_i_m(pc, arg_count, emit_EBP, 0, 1, temp_calls_offset + 8);
-
-        switch (*sig) {
-            case '0':    /* null ptr or such - doesn't consume a reg */
-                jit_emit_bxor_rr_i(interp, pc, emit_EAX, emit_EAX);
-                emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
-                break;
-            case 'f':
-                /* FIXME emitm_call_cfunc(pc, get_nci_N); */
-                emitm_fstps(interp, pc, emit_EBP, 0, 1, args_offset);
-                break;
-            case 'N':
-            case 'd':
-                /* FIXME emitm_call_cfunc(pc, get_nci_N); */
-                emitm_fstpl(interp, pc, emit_EBP, 0, 1, args_offset);
-                args_offset += 4;
-                break;
-            case 'I':   /* INTVAL */
-            case 'l':   /* long */
-            case 'i':   /* int */
-                /* FIXME emitm_call_cfunc(pc, get_nci_I); */
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
-                break;
-            case 't':   /* string, pass a cstring */
-                /* FIXME emitm_call_cfunc(pc, get_nci_S); */
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
-                emitm_call_cfunc(pc, string_to_cstring_nullable);
-
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
-                /* save off temporary allocation address */
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, strings_offset);
-                strings_offset += 4;
-
-                /* reset ESP(4) */
-                emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
-                break;
-            case 's':   /* short: movswl intreg_o(base), %eax */
-                /* FIXME emitm_call_cfunc(pc, get_nci_I); */
-                emitm_movswl_r_r(pc, emit_EAX, emit_EAX);
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
-                break;
-            case 'c':   /* char: movsbl intreg_o(base), %eax */
-                /* emitm_call_cfunc(pc, get_nci_I); */
-                emitm_movsbl_r_r(pc, emit_EAX, emit_EAX);
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
-                break;
-            case 'J':   /* interpreter */
-                emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
-                arg_count--;
-                break;
-            case 'p':   /* push pmc->data */
-                /* FIXME emitm_call_cfunc(pc, get_nci_p); */
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
-                break;
-            case 'O':   /* push PMC * object in P2 */
-            case 'P':   /* push PMC * */
-            case '@':
-                /* FIXME emitm_call_cfunc(pc, get_nci_P); */
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
-                break;
-            case 'v':
-                break;
-            case 'b':   /* buffer (void*) pass Buffer_bufstart(SReg) */
-                /* FIXME emitm_call_cfunc(pc, get_nci_S); */
-                emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1,
-                               (size_t) &Buffer_bufstart((STRING *) NULL));
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
-                break;
-            case 'B':   /* buffer (void**) pass &Buffer_bufstart(SReg) */
-                /* FIXME emitm_call_cfunc(pc, get_nci_S); */
-                emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1,
-                              (size_t) &Buffer_bufstart((STRING *) NULL));
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
-                break;
-            case 'S':
-                /* FIXME emitm_call_cfunc(pc, get_nci_S); */
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
-                break;
-
-
-            /* I have no idea how to handle these */
-            case '2':
-            case '3':
-            case '4':
-            case 'V':
-                mem_free_executable(execmem, JIT_ALLOC_SIZE);
-                Parrot_str_free_cstring(signature_str);
-                return NULL;
-                break;
-            default:
-                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
-                    "Unknown arg Signature %c\n", *sig);
-                /*
-                 * oops unknown signature:
-                 * cleanup and try nci.c
-                 */
-                mem_free_executable(execmem, JIT_ALLOC_SIZE);
-                Parrot_str_free_cstring(signature_str);
-                return NULL;
-        }
-        args_offset +=4;
-        arg_count++;
-        sig++;
-    }
-
-    /* prepare to call VTABLE_get_pointer, set up args */
-    /* interpreter - movl 8(%ebp), %eax */
-    emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
-    emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0);
-
-    /* pmc - movl 12(%ebp), %eax */
-    emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 12);
-    emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
-
-    /* get the get_pointer() pointer from the pmc's vtable */
-    emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(PMC, vtable));
-    emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(VTABLE, get_pointer));
-
-    /* call get_pointer(), result goes into eax */
-    emitm_callr(pc, emit_EAX);
-    emitm_addl_i_r(pc, 16, emit_ESP);
-
-    /* call the resulting function pointer */
-    emitm_callr(pc, emit_EAX);
-    emitm_subl_i_r(pc, 16, emit_ESP);
-
-    /* SAVE OFF EAX */
-    emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
-
-    /*&st*/
-    emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);
-    emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
-
-    /*interpreter*/
-    emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
-    emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0);
-
-    /* RESTORE BACK EAX */
-    emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
-
-    /* now place return value in registers */
-    /* first in signature is the return value */
-    sig = signature_str; /* the result */
-    switch (*sig) {
-        /* I have no idea how to handle these */
-        case '2':
-        case '3':
-        case '4':
-            /* get integer from pointer - untested */
-            emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, 0);
-            if (*sig == 2)      /* short */
-                emitm_movswl_r_r(pc, emit_EAX, emit_EAX);
-            /* XXX FIXME emitm_call_cfunc(pc, set_nci_I);*/
-            break;
-        case 'f':
-        case 'd':
-            jit_emit_fstore_mb_n(interp, pc, emit_EBP, temp_calls_offset + 8);
-            /* XXX FIXME emitm_call_cfunc(pc, set_nci_N); */
-            /* pop num from st(0) and mov to reg */
-            break;
-        case 's':
-            /* movswl %ax, %eax */
-            emitm_movswl_r_r(pc, emit_EAX, emit_EAX);
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
-            /* XXX FIXME emitm_call_cfunc(pc, set_nci_I); */
-            break;
-        case 'c':
-            /* movsbl %al, %eax */
-            emitm_movsbl_r_r(pc, emit_EAX, emit_EAX);
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
-            /* XXX FIXME emitm_call_cfunc(pc, set_nci_I); */
-            break;
-        case 'I':   /* INTVAL */
-        case 'l':
-        case 'i':
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
-           /* XXX FIXME emitm_call_cfunc(pc, set_nci_I); */
-            break;
-        case 'v': /* void - do nothing */
-            break;
-        case 'P':
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
-            /* XXX FIXME emitm_call_cfunc(pc, set_nci_P); */
-            break;
-        case 'p':   /* make a new unmanaged struct */
-            /* save return value on stack */
-
-            /* save pointer p */
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 12);
-
-            /* make new pmc */
-            emitm_movl_i_m(pc, enum_class_UnManagedStruct, emit_EBP, 0, 1, temp_calls_offset + 4);
-            emitm_call_cfunc(pc, pmc_new);
-
-            /* restore pointer p to EDX */
-            emitm_movl_m_r(interp, pc, emit_EDX, emit_EBP, 0, 1, temp_calls_offset + 12);
-
-            /* copy UnManagedStruct to stack for set_nci_P call */
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
-
-            /* eax = PMC, get return value into edx */
-            /* mov data(%eax), %eax
-               mov %edx, ptr(%eax) */
-            emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(struct PMC, data));
-            emitm_movl_r_m(interp, pc, emit_EDX, emit_EAX, 0, 1,
-                           offsetof(struct Parrot_UnManagedStruct_attributes, ptr));
-
-            /* reset EBP(4) */
-            emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
-
-            /* XXX FIXME emitm_call_cfunc(pc, set_nci_P); */
-            break;
-        case 'S':
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
-            /* XXX FIXME emitm_call_cfunc(pc, set_nci_S); */
-            break;
-        case 't':   /* string */
-            /* EAX is char* */
-            emitm_movl_i_m(pc, 0, emit_EBP, 0, 1, temp_calls_offset + 8); /* len */
-
-            /* overwrites address of st in EBP(4) */
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
-
-            emitm_call_cfunc(pc, Parrot_str_new);
-
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
-
-            /* reset EBP(4) */
-            emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
-
-            /* XXX FIXME emitm_call_cfunc(pc, set_nci_S); */
-            break;
-        default:
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
-                "Unknown return Signature %c\n", *sig);
-            /*
-             * oops unknown signature:
-             * cleanup and try nci.c
-             */
-            Parrot_str_free_cstring(signature_str);
-            mem_free_executable(execmem, JIT_ALLOC_SIZE);
-            return NULL;
-    }
-
-    /* free temporary strings */
-    strings_offset = st_offset + ST_SIZE_OF;
-    for (i=0; i<string_buffer_count; i++) {
-        emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, strings_offset);
-        emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0);
-        emitm_call_cfunc(pc, Parrot_str_free_cstring);
-        strings_offset += 4;
-    }
-
-    jit_emit_stack_frame_leave(pc);
-    emitm_ret(pc);
-    PARROT_ASSERT(pc - execmem <= JIT_ALLOC_SIZE);
-
-    if (sizeptr)
-        *sizeptr = JIT_ALLOC_SIZE;
-    Parrot_str_free_cstring(signature_str);
-    return (void *)D2FPTR(execmem);
-}
-
-/*
- * Local variables:
- *   c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */

Modified: branches/libjit_framebuilder/src/frame_builder.h
==============================================================================
--- branches/libjit_framebuilder/src/frame_builder.h	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/src/frame_builder.h	Fri Nov  6 19:11:03 2009	(r42314)
@@ -21,14 +21,13 @@
 
 #include <assert.h>
 #include "parrot/parrot.h"
-#include "parrot/hash.h"
-#include "parrot/oplib/ops.h"
 
 /*
  * NCI interface
  */
+
 void *
-Parrot_jit_build_call_func(Interp *, PMC *, STRING *, int *);
+Parrot_jit_build_call_func(Interp *, PMC *, STRING *, void **);
 
 /* custom pmc callback functions */
 void
@@ -37,1328 +36,11 @@
 PMC*
 Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv);
 
-struct jit_buffer_private_data {
-    int size;
-};
-
-/* Scale factor values */
-#define emit_Scale(scale) ((scale) << 6)
-#define emit_Scale_1 emit_Scale(0)
-#define emit_Scale_2 emit_Scale(1)
-#define emit_Scale_4 emit_Scale(2)
-#define emit_Scale_8 emit_Scale(3)
-
-/* ESIB byte */
-#define emit_reg_Index(x) (((x)-1) << 3)
-#define emit_reg_Base(x) ((x)-1)
-#define emit_Index_None ((emit_b100) << 3)
-
 /*
  * helper funcs - get argument n
  */
 
-/*
- * if we have a delegated method like typeof_i_p, that returns an INTVAL
- * and that is all in a sequence of JITted opcodes, and when these INTVAL
- * is MAPped, we got a problem. So the EXT_CALL flag is disabled - mapped
- * registers are saved/restored around vtable calls.
- */
-#define  JIT_VTABLE_OPS 1
-
-/* EXEC_SHARED generates code to be used with libparrot.so
- * It grabs the real address of cgp_core from the gcc generated code
- * x/1i cgp_code
- *     jmp *0xXXXX
- * x/1wx 0xXXXX
- *     real address of cpg_core
- * s. exec_emit_end
- * XXX This should be a command line option.
- */
-#undef EXEC_SHARED
-
-extern UINTVAL ld(UINTVAL);
-
-#define NEG_MINUS_ZERO
-/* #define NEG_ZERO_SUB */
-
-/* Register codes */
-#define emit_None 0
-
-/* These are + 1 the real values */
-#define emit_EAX 1
-#define emit_ECX 2
-#define emit_EDX 3
-#define emit_EBX 4
-#define emit_ESP 5
-#define emit_EBP 6
-#define emit_ESI 7
-#define emit_EDI 8
-
-/* Scratch register. */
-
-#define ISR1 emit_EAX
-#define FSR1 0
-
-#define emit_b00 0
-#define emit_b01 1
-#define emit_b10 2
-#define emit_b11 3
-
-#define emit_b000 0
-#define emit_b001 1
-#define emit_b010 2
-#define emit_b011 3
-#define emit_b100 4
-#define emit_b101 5
-#define emit_b110 6
-#define emit_b111 7
-
-/* Mod R/M byte */
-#define emit_reg(x) ((x) << 3)
-#define emit_Mod(Mod) ((Mod) << 6)
-#define emit_reg_rm(x) ((x)-1)
-
-/* Mod values for Mod R/M Byte */
-#define emit_Mod_b00 emit_Mod(emit_b00)
-#define emit_Mod_b01 emit_Mod(emit_b01)
-#define emit_Mod_b10 emit_Mod(emit_b10)
-
-/* special R/M values */
-#define emit_rm_b101 emit_b101
-#define emit_rm_b100 emit_b100
-
-#define emit_r_m(interp, pc, reg1, b, i, s, d) \
-    emit_r_X((interp), (pc), emit_reg((reg1)-1), (b), (i), (s), (d))
-
-#define emit_alu_X_r(X, reg) ((emit_b11 << 6) | ((X) << 3) | ((reg) - 1))
-
-#define emit_alu_r_r(reg1, reg2) emit_alu_X_r(((reg1) - 1), (reg2))
-
-int emit_is8bit(long disp);
-
-char * emit_disp8_32(char *pc, int disp);
-
-void emit_sib(PARROT_INTERP, char *pc, int scale, int i, int base);
-
-char * emit_r_X(PARROT_INTERP, char *pc, int reg_opcode, int base, int i,
-    int scale, long disp);
-
-char * emit_shift_i_r(PARROT_INTERP, char *pc, int opcode, int imm, int reg);
-
-char * emit_shift_i_m(PARROT_INTERP, char *pc, int opcode, int imm,
-               int base, int i, int scale, long disp);
-
-char * emit_shift_r_r(PARROT_INTERP, char *pc, int opcode, int reg1, int reg2);
-
-char * emit_shift_r_m(PARROT_INTERP, char *pc, int opcode, int reg,
-               int base, int i, int scale, long disp);
-
-/* CDQ - need this to do multiply */
-#define emitm_cdq(pc) *((pc)++) = (char) 0x99
-
-/* RET */
-#define emitm_ret(pc) *((pc)++) = (char) 0xc3
-
-/* NOP */
-#define emit_nop(pc) *((pc)++) = (char) 0x90
-
-/* PUSHes */
-
-#define emitm_pushl_r(pc, reg) \
-    *((pc)++) = (char) 0x50 | ((reg) - 1)
-
-#define emitm_pushl_i(pc, imm) { \
-    *((pc)++) = (char) 0x68; \
-    *(long *)(pc) = (long)(imm); \
-    (pc) += 4; }
-
-#define emitm_pushl_m(pc, mem) { \
-       *((pc)++) = (char) 0xff; \
-       *((pc)++) = (char) 0x35; \
-       *(long *)(pc) = (long)(mem); \
-       (pc) += 4; }
-
-char * emit_pushl_m(PARROT_INTERP, char *pc, int base, int i, int scale,
-    long disp);
-
-/* POPs */
-
-char * emit_popl_r(char *pc, int reg);
-
-#  define emitm_popl_r(pc, reg) \
-    (pc) = emit_popl_r((pc), (reg))
-
-char * emit_popl_m(PARROT_INTERP, char *pc, int base, int i, int scale,
-    long disp);
-
-/* MOVes */
-
-char * emit_movb_r_r(char *pc, int reg1, int reg2);
-
-#  define jit_emit_mov_rr_i(pc, reg2, reg1) if ((reg1) != (reg2)) { \
-    *((pc)++) = (char) 0x89; \
-    *((pc)++) = (char) emit_alu_r_r((reg1), (reg2)); }
-
-#  define jit_emit_mov_ri_i(interp, pc, reg, imm) { \
-    *((pc)++) = (char)(0xb8 | ((reg) - 1)); \
-    *(long *)(pc) = (long)(imm); (pc) += 4; }
-
-#  define emitm_movX_Y_Z(interp, op, pc, reg1, b, i, s, d) { \
-    *((pc)++) = (char) (op); \
-    (pc) = emit_r_m((interp), (pc), (reg1), (b), (i), (s), (long)(d)); }
-
-#  define emitm_movb_r_m(interp, pc, reg1, b, i, s, d) \
-    emitm_movX_Y_Z((interp), 0x88, (pc), (reg1), (b), (i), (s), (d))
-
-#  define emitm_movl_r_m(interp, pc, reg1, b, i, s, d) \
-    emitm_movX_Y_Z((interp), 0x89, (pc), (reg1), (b), (i), (s), (d))
-
-/* move byte/word with sign extension */
-#  define emitm_movsbl_r_m(interp, pc, reg1, b, i, s, d) { \
-    *((pc)++) = (char) 0x0f; \
-    emitm_movX_Y_Z((interp), 0xBE, (pc), (reg1), (b), (i), (s), (d)); \
-}
-
-#  define emitm_movswl_r_m(interp, pc, reg1, b, i, s, d) { \
-    *((pc)++) = (char) 0x0f; \
-    emitm_movX_Y_Z((interp), 0xBF, (pc), (reg1), (b), (i), (s), (d)); \
-}
-
-#  define emitm_movsbl_r_r(pc, reg1, reg2) { \
-    *((pc)++) = (char) 0x0f; \
-    *((pc)++) = (char) 0xbe; \
-    *((pc)++) = (char) emit_alu_r_r((reg1), (reg2)); \
-}
-
-#  define emitm_movswl_r_r(pc, reg1, reg2) { \
-    *((pc)++) = (char) 0x0f; \
-    *((pc)++) = (char) 0xbf; \
-    *((pc)++) = (char) emit_alu_r_r((reg1), (reg2)); \
-}
-
-#  define emitm_movb_m_r(interp, pc, reg1, b, i, s, d) \
-    emitm_movX_Y_Z((interp), 0x8a, (pc), (reg1), (b), (i), (s), (d))
-
-#  define emitm_movl_m_r(interp, pc, reg1, b, i, s, d) \
-    emitm_movX_Y_Z((interp), 0x8b, (pc), (reg1), (b), (i), (s), (d))
-
-#  define emitm_lea_m_r(interp, pc, reg1, b, i, s, d) \
-    emitm_movX_Y_Z((interp), 0x8d, (pc), (reg1), (b), (i), (s), (d))
-
-char * emit_movb_i_m(PARROT_INTERP, char *pc, char imm, int base, int i,
-    int scale, long disp);
-
-#  define emitm_movl_i_m(pc, imm, b, i, s, d) { \
-    *((pc)++) = (char) 0xc7; \
-    (pc) = emit_r_X((interp), (pc), emit_reg(emit_b000), (b), (i), (s), (long)(d)); \
-    *(long *)(pc) = (long)(imm); (pc) += 4; }
-
-/* Various ALU formats */
-
-#  define emitm_alul_r_r(pc, op, reg1, reg2) { \
-    *((pc)++) = (char) (op); *((pc)++) = (char) emit_alu_r_r((reg1), (reg2)); }
-
-#  define emitm_alub_i_r(pc, op1, op2, imm, reg) { \
-    *((pc)++) = (char) (op1); *((pc)++) = (char) emit_alu_X_r((op2), (reg)); *((pc)++) = (char)(imm); }
-
-#  define emitm_alul_i_r(pc, op1, op2, imm, reg) { \
-    *((pc)++) = (char) (op1); \
-    *((pc)++) = (char) emit_alu_X_r((op2), (reg)); \
-    *(long *)((pc)) = (long)(imm); (pc) += 4; }
-
-#  define emitm_alul_i_m(pc, op1, op2, imm, b, i, s, d) { \
-    *((pc)++) = (char) (op1); \
-    (pc) = emit_r_X((interp), (pc), emit_reg(op2), (b), (i), (s), (d)); \
-    *(long *)(pc) = (long)(imm); (pc) += 4; }
-
-#  define emitm_alul_r_m(pc, op, reg, b, i, s, d) { \
-    *((pc)++) = (char) (op); \
-    (pc) = emit_r_X((interp), (pc), emit_reg((reg)-1), (b), (i), (s), (long)(d)); }
-
-/* ADDs */
-
-#  define emitm_addb_r_r(pc, reg1, reg2) \
-    emitm_alul_r_r((pc), 0x00, (reg1), (reg2))
-
-#  define emitm_addb_i_r(pc, imm, reg) \
-    emitm_alub_i_r((pc), 0x83, emit_b000, (imm), (reg))
-
-#  define jit_emit_add_rr_i(interp, pc, reg1, reg2) \
-    emitm_alul_r_r((pc), 0x01, (reg2), (reg1))
-
-#  define jit_emit_add_ri_i(interp, pc, reg, imm)   \
-    emitm_alul_i_r((pc), 0x81, emit_b000, (imm), (reg))
-
-#  define emitm_addl_i_r(pc, imm, reg)   \
-    emitm_alul_i_r((pc), 0x81, emit_b000, (imm), (reg))
-
-#  define emitm_addl_i_m(pc, imm, b, i, s, d) \
-    emitm_alul_i_m((pc), 0x81, emit_b000, (imm), (b), (i), (s), (d))
-
-#  define emitm_addl_r_m(pc, reg, b, i, s, d) \
-    emitm_alul_r_m((pc), 0x01, (reg), (b), (i), (s), (d))
-
-#  define emitm_addl_m_r(pc, reg, b, i, s, d) \
-    emitm_alul_r_m((pc), 0x03, (reg), (b), (i), (s), (d))
-
-/* SUBs */
-
-#  define jit_emit_sub_rr_i(interp, pc, reg1, reg2) \
-    emitm_alul_r_r((pc), 0x29, (reg2), (reg1))
-
-#  define emitm_subl_i_r(pc, imm, reg) \
-    emitm_alul_i_r((pc), 0x81, emit_b101, (imm), (reg))
-
-#  define jit_emit_sub_ri_i(interp, pc, r, i) emitm_subl_i_r((pc), (i), (r))
-
-#  define emitm_subl_r_m(pc, reg, b, i, s, d) \
-    emitm_alul_r_m((pc), 0x29, (reg), (b), (i), (s), (d))
-
-#  define emitm_subl_m_r(pc, reg, b, i, s, d) \
-    emitm_alul_r_m((pc), 0x2b, (reg), (b), (i), (s), (d))
-
-#  define emitm_subl_i_m(pc, imm, b, i, s, d) \
-    emitm_alul_i_m((pc), 0x81, emit_b101, (imm), (b), (i), (s), (d))
-
-/* These are used by both signed and unsigned EDIV, but only unsigned MUL */
-#  define emitm_alu_imp_r(pc, op, reg) { \
-    *((pc)++) = (char) 0xf7; \
-    *((pc)++) = (char) emit_alu_X_r((op), (reg)); }
-
-#  define emitm_alu_imp_m(pc, op, b, i, s, d) { \
-    *((pc)++) = (char) 0xf7; \
-    (pc) = emit_r_X((interp), (pc), emit_reg(op), (b), (i), (s), (d)); }
-
-/* Unsigned MUL and EDIV */
-/* EAX implicit destination in multiply and divide */
-
-#  define emitm_umull_r(pc, reg2) emitm_alu_imp_r((pc), emit_b100, (reg2))
-
-#  define emitm_udivl_r(pc, reg2) emitm_alu_imp_r((pc), emit_b110, (reg2))
-
-#  define emitm_umull_m(pc, b, i, s, d) \
-    emitm_alu_imp_m((pc), emit_b100, (b), (i), (s), (d))
-
-#  define emitm_udivl_m(pc, b, i, s, d) \
-    emitm_alu_imp_m((pc), emit_b110, (b), (i), (s), (d))
-
-/* Signed MUL and EDIV */
-
-#  define emitm_sdivl_r(pc, reg2) emitm_alu_imp_r((pc), emit_b111, (reg2))
-
-#  define emitm_sdivl_m(pc, b, i, s, d) \
-    emitm_alu_imp_m((pc), emit_b111, (b), (i), (s), (d))
-
-#  define jit_emit_cdq(pc) *(pc)++ = 0x99
-
-/* TEST for zero */
-#  define jit_emit_test_r_i(pc, reg1) emitm_alul_r_r((pc), 0x85, (reg1), (reg1))
-
-#  define emitm_smull_r(pc, reg2) emitm_alu_imp_r((pc), emit_b101, (reg2))
-
-#  define jit_emit_mul_rr_i(interp, pc, reg1, reg2) { \
-    *(pc)++ = 0xf; \
-    emitm_alul_r_r((pc), 0xaf, (reg1), (reg2)); }
-
-#  define emitm_smull_r_m(pc, reg1, b, i, s, d) { \
-    *(pc)++ = 0xf; \
-    emitm_alul_r_m((pc), 0xaf, (reg1), (b), (i), (s), (d)); }
-
-char * opt_mul(PARROT_INTERP, char *pc, int dest, INTVAL imm, int src);
-
-#  define jit_emit_mul_rir_i(pc, dest, imm, src) \
-       (pc) = opt_mul(interp, (pc), (dest), (imm), (src))
-
-
-#  define jit_emit_mul_ri_i(pc, r, imm) jit_emit_mul_rir_i((pc), (r), (imm), (r))
-
-#  define jit_emit_mul_RIM_ii(pc, reg, imm, ofs) \
-    emitm_alul_r_m((pc), 0x69, (reg), emit_EBX, emit_None, 1, (ofs)); \
-    *(long *)(pc) = (long)(imm); \
-    (pc) += 4;
-
-/* NEG */
-
-#  define jit_emit_neg_r_i(pc, reg) emitm_alu_imp_r((pc), emit_b011, (reg))
-
-#  define emitm_negl_m(pc, b, i, s, d) \
-    emitm_alu_imp_m((pc), emit_b011, (b), (i), (s), (d))
-
-/* AND */
-
-#  define emit_andl_r_r(pc, reg1, reg2) emitm_alul_r_r((pc), 0x21, (reg1), (reg2))
-#  define jit_emit_band_rr_i(interp, pc, r1, r2) emit_andl_r_r((pc), (r2), (r1))
-
-#  define jit_emit_band_ri_i(interp, pc, reg, imm)  \
-    emitm_alul_i_r((pc), 0x81, emit_b100, (imm), (reg))
-
-#  define emitm_andl_r_m(pc, reg, b, i, s, d) \
-    emitm_alul_r_m((pc), 0x21, (reg), (b), (i), (s), (d))
-
-#  define emitm_andl_m_r(pc, reg, b, i, s, d) \
-    emitm_alul_r_m((pc), 0x23, (reg), (b), (i), (s), (d))
-
-#  define emitm_andl_i_m(pc, imm, b, i, s, d) \
-    emitm_alul_i_m((pc), 0x81, emit_b100, (imm), (b), (i), (s), (d))
-
-/* TEST op */
-#  define jit_emit_test_rr_i(pc, r1, r2) emitm_alul_r_r((pc), 0x85, (r1), (r2))
-
-#  define jit_emit_test_ri_i(pc, r, im)  \
-           emitm_alul_i_r((pc), 0xF7, emit_b000, (im), (r))
-
-#  define jit_emit_test_RM_i(pc, r, offs)  \
-           emitm_alul_r_m((pc), 0x85, (r), emit_EBX, 0, 1, (offs))
-
-/* OR */
-
-#  define jit_emit_bor_rr_i(interp, pc, reg1, reg2) emitm_alul_r_r((pc), 0x9, (reg2), (reg1))
-
-#  define jit_emit_bor_ri_i(interp, pc, reg, imm) \
-    emitm_alul_i_r((pc), 0x81, emit_b001, (imm), (reg))
-
-#  define emitm_orl_r_m(pc, reg, b, i, s, d) \
-    emitm_alul_r_m((pc), 0x09, (reg), (b), (i), (s), (d))
-
-#  define emitm_orl_m_r(pc, reg, b, i, s, d) \
-    emitm_alul_r_m((pc), 0x0b, (reg), (b), (i), (s), (d))
-
-#  define emitm_orl_i_m(pc, imm, b, i, s, d) \
-    emitm_alul_i_m((pc), 0x81, emit_b001, (imm), (b), (i), (s), (d))
-
-/* XOR */
-
-#  define jit_emit_bxor_rr_i(interp, pc, reg1, reg2) \
-    emitm_alul_r_r((pc), 0x31, (reg2), (reg1))
-
-#  define jit_emit_bxor_ri_i(intepr, pc, reg, imm) \
-    emitm_alul_i_r((pc), 0x81, emit_b110, (imm), (reg))
-
-#  define emitm_xorl_r_m(pc, reg, b, i, s, d) \
-    emitm_alul_r_m((pc), 0x31, (reg), (b), (i), (s), (d))
-
-#  define emitm_xorl_m_r(pc, reg, b, i, s, d) \
-    emitm_alul_r_m((pc), 0x33, (reg), (b), (i), (s), (d))
-
-#  define emitm_xorl_i_m(pc, imm, b, i, s, d) \
-    emitm_alul_i_m((pc), 0x81, emit_b110, (imm), (b), (i), (s), (d))
-
-/* NOT */
-
-#  define jit_emit_not_r_i(pc, reg) emitm_alu_imp_r((pc), emit_b010, (reg))
-#  define emitm_notl_m(pc, b, i, s, d) \
-    emitm_alu_imp_m((pc), emit_b010, (b), (i), (s), (d))
-
-#  define jit_emit_not_M_i(interp, pc, offs) emitm_notl_m((pc), emit_EBX, 0, 1, (offs))
-
-/* XCHG */
-#  define jit_emit_xchg_rr_i(interp, pc, r1, r2) { \
-    if ((r1) != (r2)) { \
-    *((pc)++) = (char) 0x87; \
-    *((pc)++) = (char) emit_alu_r_r((r1), (r2)); \
-    } \
-}
-
-#  define jit_emit_xchg_rm_i(pc, r, m) { \
-    emitm_alul_r_m((pc), 0x87, (r), emit_None, emit_None, emit_None, (m)) \
-}
-#  define jit_emit_xchg_RM_i(interp, pc, r, offs) { \
-    emitm_alul_r_m((pc), 0x87, (r), emit_EBX, emit_None, 1, (offs)) \
-}
-#  define jit_emit_xchg_MR_i(interp, pc, offs, r) jit_emit_xchg_RM_i((interp), (pc), (r), (offs))
-
-/* SHL */
-
-#  define jit_emit_shl_ri_i(interp, pc, reg, imm) \
-    { (pc) = emit_shift_i_r((interp), (pc), emit_b100, (imm), (reg)); }
-
-#  define emitm_shll_i_m(pc, imm, b, i, s, d) \
-    { (pc) = emit_shift_i_m((pc), emit_b100, (imm), (b), (i), (s), (d)); }
-
-#  define emitm_shll_r_r(interp, pc, reg1, reg2) \
-    { (pc) = emit_shift_r_r((interp), (pc), emit_b100, (reg1), (reg2)); }
-
-#  define emitm_shll_r_m(pc, reg, b, i, s, d) \
-    { (pc) = emit_shift_r_m((pc), emit_b100, (reg), (b), (i), (s), (d)); }
-
-/* SHR */
-
-#  define jit_emit_lsr_ri_i(interp, pc, reg, imm) \
-    { (pc) = emit_shift_i_r((interp), (pc), emit_b101, (imm), (reg)); }
-
-#  define emitm_shrl_i_m(pc, imm, b, i, s, d) \
-    { (pc) = emit_shift_i_m((pc), emit_b101, (imm), (b), (i), (s), (d)); }
-
-#  define emitm_shrl_r_r(interp, pc, reg1, reg2) \
-    { (pc) = emit_shift_r_r((interp), (pc), emit_b101, (reg1), (reg2)); }
-
-#  define emitm_shrl_r_m(pc, reg, b, i, s, d) \
-    { (pc) = emit_shift_r_m((pc), emit_b101, (reg), (b), (i), (s), (d)); }
-
-/* SAL */
-
-#  define emitm_sall_i_r(interp, pc, imm, reg) \
-    { (pc) = emit_shift_i_r((interp), (pc), emit_b100, (imm), (reg)); }
-
-#  define emitm_sall_i_m(pc, imm, b, i, s, d) \
-    { (pc) = emit_shift_i_m((pc), emit_b100, (imm), (b), (i), (s), (d)); }
-
-#  define emitm_sall_r_r(interp, pc, reg1, reg2) \
-    { (pc) = emit_shift_r_r((interp), (pc), emit_b100, (reg1), (reg2)); }
-
-#  define emitm_sall_r_m(pc, reg, b, i, s, d) \
-    { (pc) = emit_shift_r_m((pc), emit_b100, (reg), (b), (i), (s), (d)); }
-
-/* SAR */
-
-#  define jit_emit_shr_ri_i(interp, pc, reg, imm) \
-    { (pc) = emit_shift_i_r((interp), (pc), emit_b111, (imm), (reg)); }
-
-
-#  define emitm_sarl_i_m(pc, imm, b, i, s, d) \
-    { (pc) = emit_shift_i_m((pc), emit_b111, (imm), (b), (i), (s), (d)); }
-
-#  define emitm_sarl_r_r(interp, pc, reg1, reg2) \
-    { (pc) = emit_shift_r_r((interp), (pc), emit_b111, (reg1), (reg2)); }
-
-#  define emitm_sarl_r_m(pc, reg, b, i, s, d) \
-    { (pc) = emit_shift_r_m((pc), emit_b111, (reg), (b), (i), (s), (d)); }
-
-/* rotate */
-
-#  define jit_emit_rol_ri_i(interp, pc, reg, imm) \
-    { (pc) = emit_shift_i_r((interp), (pc), emit_b000, (imm), (reg)); }
-
-#  define jit_emit_ror_ri_i(interp, pc, reg, imm) \
-    { (pc) = emit_shift_i_r((interp), (pc), emit_b001, (imm), (reg)); }
-
-/* interface, shift r1 by r2 bits */
-
-#  define jit_emit_shl_rr_i(interp, pc, r1, r2) \
-    (pc) = opt_shift_rr((interp), jit_info, (r1), (r2), emit_b100)
-
-#  define jit_emit_shl_RM_i(interp, pc, r1, offs)  \
-    (pc) = opt_shift_rm((interp), jit_info, (r1), (offs), emit_b100)
-
-/* shr seems to be the arithmetic shift */
-#  define jit_emit_shr_rr_i(interp, pc, r1, r2)  \
-    (pc) = opt_shift_rr((interp), jit_info, (r1), (r2), emit_b111)
-
-#  define jit_emit_shr_RM_i(interp, pc, r1, offs)  \
-    (pc) = opt_shift_rm((interp), jit_info, (r1), (offs), emit_b111)
-
-#  define jit_emit_lsr_rr_i(interp, pc, r1, r2)  \
-    (pc) = opt_shift_rr((interp), jit_info, (r1), (r2), emit_b101)
-
-#  define jit_emit_lsr_RM_i(interp, pc, r1, offs)  \
-    (pc) = opt_shift_rm((interp), jit_info, (r1), (offs), emit_b101)
-
-/* MOV (reg), reg */
-#  define emit_movm_r_r(pc, src, dest) \
-    *((pc)++) = (char) 0x8b; \
-    *((pc)++) = (char) (src) | (dest) << 3
-
-/* MOV X(reg), reg */
-#  define emit_movb_i_r_r(pc, imm, src, dest) \
-    *((pc)++) = (char)(0x8b); \
-    *((p)c++) = (char)(0x40 | ((src) - 1) | ((dest) - 1) << 3); \
-    *((pc)++) = (imm)
-
-/* INC / DEC */
-#  define jit_emit_inc_r_i(pc, reg) *((pc)++) = (char)(0x40 | ((reg) - 1))
-#  define jit_emit_dec_r_i(pc, reg) *((pc)++) = (char)(0x48 | ((reg) - 1))
-
-/* Floating point ops */
-
-#  define emitm_floatop 0xd8  /* 11011000 */
-#  define jit_emit_dec_fsp(pc) { *((pc)++) = (char) 0xD9; *((pc)++) = (char) 0xF6; }
-#  define jit_emit_inc_fsp(pc) { *((pc)++) = (char) 0xD9; *((pc)++) = (char) 0xF7; }
-
-#  define emitm_fl_2(interp, pc, mf, opa, opb, b, i, s, d) { \
-    *((pc)++) = (char)(emitm_floatop | ((mf) << 1) | (opa)); \
-    (pc) = emit_r_X((interp), (pc), emit_reg(opb), (b), (i), (s), (long)(d)); }
-
-#  define emitm_fl_3(pc, d_p_opa, opb_r, sti) { \
-    *((pc)++) = (char)(emitm_floatop | (d_p_opa)); \
-    *((pc)++) = (char)(0xc0 | ((opb_r) << 3) | (sti)); }
-
-#  define emitm_fl_4(pc, op) { \
-    *((pc)++) = (char)(emitm_floatop | emit_b001); \
-    *((pc)++) = (char)(0xe0 | (op)); }
-
-/* Integer loads and stores */
-#  define emitm_fildl(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b01, 1, emit_b000, (b), (i), (s), (d))
-
-#  define emitm_fistpl(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b01, 1, emit_b011, (b), (i), (s), (d))
-
-#  define emitm_fistl(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b01, 1, emit_b010, (b), (i), (s), (d))
-
-/* long long integer load/store */
-#  define emitm_fildll(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b11, 1, emit_b101, (b), (i), (s), (d))
-
-#  define emitm_fistpll(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b11, 1, emit_b111, (b), (i), (s), (d))
-
-/* Double loads and stores */
-#  define emitm_fldl(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b10, 1, emit_b000, (b), (i), (s), (d))
-
-#  define emitm_fstpl(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b10, 1, emit_b011, (b), (i), (s), (d))
-
-#  define emitm_fstl(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b10, 1, emit_b010, (b), (i), (s), (d))
-
-/* long double load / store */
-#  define emitm_fldt(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b01, 1, emit_b101, (b), (i), (s), (d))
-
-#  define emitm_fstpt(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b01, 1, emit_b111, (b), (i), (s), (d))
-
-/* short float load / store */
-#  define emitm_flds(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b00, 1, emit_b000, (b), (i), (s), (d))
-
-#  define emitm_fstps(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b00, 1, emit_b010, (b), (i), (s), (d))
-
-#if NUMVAL_SIZE == 8
-
-#  define jit_emit_fload_m_n(interp, pc, address) \
-      emitm_fldl((interp), (pc), emit_None, emit_None, emit_None, (address))
-
-#  define jit_emit_fload_mb_n(interp, pc, base, offs) \
-      emitm_fldl((interp), (pc), (base), emit_None, 1, (offs))
-
-#  define jit_emit_fstore_m_n(interp, pc, address) \
-      emitm_fstpl((interp), (pc), emit_None, emit_None, emit_None, (address))
-
-#  define jit_emit_fstore_mb_n(interp, pc, base, offs) \
-      emitm_fstpl((interp), (pc), (base), emit_None, 1, (offs))
-
-#  define jit_emit_fst_mb_n(interp, pc, base, offs) \
-      emitm_fstl((interp), (pc), (base), emit_None, 1, (offs))
-
-#else /* NUMVAL_SIZE */
-
-#  define jit_emit_fload_m_n(interp, pc, address) \
-      emitm_fldt((pc), emit_None, emit_None, emit_None, (address))
-
-#  define jit_emit_fload_mb_n(interp, pc, base, offs) \
-      emitm_fldt((pc), (base), emit_None, 1, (offs))
-
-#  define jit_emit_fstore_m_n(pc, address) \
-      emitm_fstpt((pc), emit_None, emit_None, emit_None, (address))
-
-#  define jit_emit_fstore_mb_n(interp, pc, base, offs) \
-      emitm_fstpt((pc), (base), emit_None, 1, (offs))
-
-#  define jit_emit_fst_mb_n(interp, pc, base, offs) \
-      emitm_fstt((pc), (base), emit_None, 1, (offs))
-
-#endif /* NUMVAL_SIZE */
-
-#if INTVAL_SIZE == 4
-
-#  define jit_emit_fload_m_i(interp, pc, address) \
-      emitm_fildl((interp), (pc), emit_None, emit_None, emit_None, (address))
-#  define jit_emit_fload_mb_i(interp, pc, offs) \
-      emitm_fildl((interp), (pc), emit_EBX, emit_None, 1, (offs))
-#  define jit_emit_fstore_m_i(pc, m) \
-      emitm_fistpl((pc), emit_None, emit_None, emit_None, (m))
-
-#else /* INTVAL_SIZE */
-
-#  define jit_emit_fload_m_i(interp, pc, address) \
-      emitm_fildll((interp), (pc), emit_None, emit_None, emit_None, (address))
-#  define jit_emit_fload_mb_i(interp, pc, offs) \
-      emitm_fildll((interp), (pc), emit_EBX, emit_None, 1, (offs))
-#  define jit_emit_fstore_m_i(pc, m) \
-      emitm_fistpll((pc), emit_None, emit_None, emit_None, (m))
-
-#endif /* INTVAL_SIZE */
-
-/* 0xD8 ops */
-#  define emitm_fadd(pc, sti) emitm_fl_3((pc), emit_b000, emit_b000, (sti))
-#  define emitm_fmul(pc, sti) emitm_fl_3((pc), emit_b000, emit_b001, (sti))
-#  define emitm_fsub(pc, sti) emitm_fl_3((pc), emit_b000, emit_b100, (sti))
-#  define emitm_fdiv(pc, sti) emitm_fl_3((pc), emit_b000, emit_b110, (sti))
-
-/* 0xD9 ops */
-#  define emitm_fldz(pc)  { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xee; }
-#  define emitm_fld1(pc)  { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xe8; }
-#  define emitm_fsqrt(pc) { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xfa; }
-#  define emitm_fsin(pc)  { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xfe; }
-#  define emitm_fcos(pc)  { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xff; }
-#  define emitm_fxam(pc)  { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xe5; }
-
-/* FXCH ST, ST(i) , optimize 2 consecutive fxch with same reg */
-#  define emitm_fxch(pc, sti) { \
-    emitm_fl_3((pc), emit_b001, emit_b001, (sti)); \
-}
-
-/* FLD ST, ST(i), optimized FSTP(N+1);FLD(N) => FST(N+1)  */
-extern unsigned char *lastpc;
-#  define emitm_fld(pc, sti) do { \
-     if ((unsigned char *)(pc) == (lastpc + 2) && \
-       (int)(*lastpc) == (int)0xDD && \
-       (int)lastpc[1] == (int)(0xD8+(sti)+1)) \
-       lastpc[1] = 0xD0+(sti)+1; \
-     else \
-       emitm_fl_3((pc), emit_b001, emit_b000, (sti)); \
-  } while (0)
-
-/* 0xDA, 0xDB ops */
-/* FCMOV*, FCOMI PPRO */
-
-/* 0xDC like 0xD8 with reversed operands */
-#  define emitm_faddr(pc, sti) emitm_fl_3((pc), emit_b100, emit_b000, (sti))
-#  define emitm_fmulr(pc, sti) emitm_fl_3((pc), emit_b100, emit_b001, (sti))
-#  define emitm_fsubr(pc, sti) emitm_fl_3((pc), emit_b100, emit_b100, (sti))
-
-/* 0xDD ops */
-/* FFree ST(i) */
-#  define emitm_ffree(pc, sti) emitm_fl_3((pc), emit_b101, emit_b000, (sti))
-
-/* FST ST(i) = ST */
-#  define emitm_fst(pc, sti) emitm_fl_3((pc), emit_b101, emit_b010, (sti))
-
-/* FSTP ST(i) = ST, POP */
-#  define emitm_fstp(pc, sti) { \
-    lastpc = (unsigned char*) (pc); \
-    emitm_fl_3((pc), emit_b101, emit_b011, (sti)); \
-}
-
-/* FUCOM ST(i) <=> ST  unordered compares */
-#  define emitm_fucom(pc, sti) emitm_fl_3((pc), emit_b101, emit_b100, (sti))
-
-/* FUCOMP ST(i) <=> ST, POP */
-#  define emitm_fucomp(pc, sti) emitm_fl_3((pc), emit_b101, emit_b101, (sti))
-
-/* 0xDE ops */
-/* FADDP Add ST(i) = ST + ST(i); POP  */
-#  define emitm_faddp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b000, (sti))
-
-/* FMULP Mul ST(i) = ST * ST(i); POP  */
-#  define emitm_fmulp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b001, (sti))
-
-/* FSUB ST = ST - ST(i) */
-
-/* FSUBRP SubR ST(i) = ST - ST(i); POP  */
-#  define emitm_fsubrp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b100, (sti))
-
-/* FSUBP Sub ST(i) = ST(i) - ST; POP  */
-#  define emitm_fsubp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b101, (sti))
-
-/* FDIVRP DivR ST(i) = ST(i) / ST(0); POP  */
-#  define emitm_fdivrp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b110, (sti))
-
-/* FDIVP Div ST(i) = ST(0) / ST(i); POP ST(0) */
-#  define emitm_fdivp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b111, (sti))
-
-/* 0xDF OPS: FCOMIP, FUCOMIP PPRO */
-
-/* Negate - called change sign */
-#  define emitm_fchs(pc) emitm_fl_4((pc), 0)
-
-/* ABS - ST(0) = ABS(ST(0)) */
-#  define emitm_fabs(pc) emitm_fl_4((pc), 1)
-
-/* Comparisons */
-
-#  define emitm_fcom(pc, sti) emitm_fl_3((pc), emit_b000, emit_b010, (sti))
-
-#  define emitm_fcomp(pc, sti) emitm_fl_3((pc), emit_b000, emit_b011, (sti))
-
-#ifdef PARROT_HAS_JIT_FCOMIP
-#  define emitm_fcomip(pc, sti) emitm_fl_3((pc), emit_b111, emit_b110, (sti))
-#  define emitm_fcomi(pc, sti) emitm_fl_3((pc), emit_b011, emit_b110, (sti))
-#else
-#  define emitm_fcomip(pc, sti) do { \
-      emitm_fcomp((pc), (sti)); \
-      emitm_fstw(pc); \
-      emitm_sahf(pc); \
-    } while (0)
-#  define emitm_fcomi(pc, sti) do { \
-      emitm_fcom((pc), (sti)); \
-      emitm_fstw(pc); \
-      emitm_sahf(pc); \
-    } while (0)
-#endif
-
-#  define emitm_fcompp(pc) { *((pc)++) = (char) 0xde; *((pc)++) = (char) 0xd9; }
-
-#  define emitm_fcom_m(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b10, 0, emit_b010, (b), (i), (s), (d))
-
-#  define emitm_fcomp_m(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b10, 0, emit_b011, (b), (i), (s), (d))
-
-/* ST -= real64 */
-#  define emitm_fsub_m(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b10, 0, emit_b100, (b), (i), (s), (d))
-
-/* ST -= int32_mem */
-#  define emitm_fisub_m(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b01, 0, emit_b100, (b), (i), (s), (d))
-
-#  define emitm_fadd_m(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b10, 0, emit_b000, (b), (i), (s), (d))
-
-/* ST += int32_mem */
-#  define emitm_fiadd_m(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b01, 0, emit_b000, (b), (i), (s), (d))
-
-/* ST *= real64 */
-#  define emitm_fmul_m(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b10, 0, emit_b001, (b), (i), (s), (d))
-
-/* ST *= int32_mem */
-#  define emitm_fimul_m(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b01, 0, emit_b001, (b), (i), (s), (d))
-
-/* ST /= real64 */
-#  define emitm_fdiv_m(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b10, 0, emit_b110, (b), (i), (s), (d))
-
-/* ST /= int32_mem */
-#  define emitm_fidiv_m(interp, pc, b, i, s, d) \
-    emitm_fl_2((interp), (pc), emit_b01, 0, emit_b110, (b), (i), (s), (d))
-
-/* Ops Needed to support loading EFLAGs for conditional branches */
-#  define emitm_fstw(pc) emitm_fl_3((pc), emit_b111, emit_b100, emit_b000)
-
-#  define emitm_sahf(pc) *((pc)++) = (char) 0x9e
-
-/* misc float */
-#  define emitm_ftst(pc) { *(pc)++ = 0xd9; *(pc)++ = 0xE4; }
-#  define emitm_fprem(pc) { *(pc)++ = 0xd9; *(pc)++ = 0xF8; }
-#  define emitm_fprem1(pc) { *(pc)++ = 0xd9; *(pc)++ = 0xF5; }
-
-#  define emitm_fldcw(interp, pc, mem) \
-    emitm_fl_2((interp), (pc), emit_b00, 1, emit_b101, 0, 0, 0, (mem))
-
-#if defined(NEG_MINUS_ZERO)
-#  define jit_emit_neg_r_n(pc, r) { \
-       if (r) { \
-         emitm_fld((pc), (r)); \
-       } \
-       emitm_fchs(pc); \
-       if (r) { \
-         emitm_fstp((pc), ((r)+1)); \
-       } \
-     }
-
-#  define jit_emit_neg_M_n(interp, pc, mem) { \
-       jit_emit_fload_mb_n((interp), (pc), emit_EBX, (mem)); \
-       emitm_fchs(pc); \
-       jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (mem)); \
-     }
-
-#elif defined(NEG_ZERO_SUB)
-
-#  define jit_emit_neg_r_n(pc, r) { \
-       emitm_fldz(pc); \
-       emitm_fsubrp((pc), ((r)+1)); \
-     }
-
-#  define jit_emit_neg_M_n(interp, pc, mem) { \
-       jit_emit_fload_mb_n((interp), (pc), emit_EBX, (mem)); \
-       emitm_fldz(pc); \
-       emitm_fsubrp((pc), 1); \
-       jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (mem)); \
-     }
-#else
-
-#  define jit_emit_neg_r_n(pc, r) { \
-       if (r) { \
-         emitm_fld((pc), (r)); \
-       } \
-       emitm_ftst(pc); \
-       emitm_fstw(pc); \
-       emitm_sahf(pc); \
-       emitm_jxs((pc), emitm_jz, 2); \
-       emitm_fchs(pc); \
-       if (r) { \
-         emitm_fstp((pc), ((r)+1)); \
-       } \
-     }
-
-#  define jit_emit_neg_M_n(interp, pc, mem) { \
-       jit_emit_fload_mb_n((interp), (pc), emit_EBX, (mem)); \
-       emitm_ftst(pc); \
-       emitm_fstw(pc); \
-       emitm_sahf(pc); \
-       emitm_jxs((pc), emitm_jz, 2); \
-       emitm_fchs(pc); \
-       jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (mem)); \
-     }
-#endif
-
-#  define jit_emit_sin_r_n(pc, r) \
-     if (r) { \
-       emitm_fld((pc), (r)); \
-     } \
-     emitm_fsin(pc); \
-     if (r) { \
-       emitm_fstp((pc), ((r)+1)); \
-     }
-
-#  define jit_emit_cos_r_n(pc, r) \
-     if (r) { \
-       emitm_fld((pc), (r)); \
-     } \
-     emitm_fcos(pc); \
-     if (r) { \
-       emitm_fstp((pc), ((r)+1)); \
-     }
-
-#  define jit_emit_sqrt_r_n(pc, r) \
-     if (r) { \
-       emitm_fld((pc), (r)); \
-     } \
-     emitm_fsqrt(pc); \
-     if (r) { \
-       emitm_fstp((pc), ((r)+1)); \
-     }
-
-#  define jit_emit_abs_r_n(pc, r) { \
-     if (r) { \
-       emitm_fld((pc), (r)); \
-     } \
-     emitm_fabs(pc); \
-     if (r) { \
-       emitm_fstp((pc), ((r)+1)); \
-     } \
-   }
-
-#  define jit_emit_abs_r_i(pc, r) { \
-     jit_emit_test_r_i((pc), (r)); \
-     emitm_jxs((pc), emitm_jns, 3); \
-     jit_emit_not_r_i((pc), (r)); \
-     jit_emit_inc_r_i((pc), (r)); \
-   }
-
-#  define jit_emit_abs_m_n(interp, pc, mem) { \
-     jit_emit_fload_m_n((interp), (pc), (mem)); \
-     emitm_fabs(pc); \
-     jit_emit_fstore_m_n((pc), (mem)); \
-   }
-
-/* Integer comparisons */
-#  define jit_emit_cmp_rr(pc, reg1, reg2) \
-    emitm_alul_r_r((pc), 0x39, (reg2), (reg1))
-#  define jit_emit_cmp_rr_i(pc, r1, r2) jit_emit_cmp_rr((pc), (r1), (r2))
-
-#  define emitm_cmpl_r_m(pc, reg, b, i, s, d) \
-    emitm_alul_r_m((pc), 0x3b, (reg), (b), (i), (s), (d))
-
-#  define emitm_cmpl_m_r(pc, reg, b, i, s, d) \
-    emitm_alul_r_m((pc), 0x39, (reg), (b), (i), (s), (d))
-
-#  define jit_emit_cmp_ri_i(interp, pc, reg, imm) \
-    emitm_alul_i_r((pc), 0x81, emit_b111, (imm), (reg))
-
-/* Unconditional Jump/Call */
-
-#  define emitm_call_cfunc(pc, func) emitm_calll((pc), (char *)(func) - (pc) - 4)
-
-#  define emitm_calll(pc, disp) { \
-    *((pc)++) = (char) 0xe8; \
-    *(long *)(pc) = (disp); (pc) += 4; }
-
-#  define emitm_callr(pc, reg) { \
-    *((pc)++) = (char) 0xff; \
-    *((pc)++) = (char) 0xd0 | ((reg) - 1); }
-
-#  define emitm_callm(pc, b, i, s, d) { \
-       *((pc)++) = (char) 0xff; \
-       (pc) = emit_r_X((interp), (pc), emit_reg(emit_b010), (b), (i), (s), (d)); }
-
-#  define emitm_jumps(pc, disp) { \
-    *((pc)++) = (char) 0xeb; \
-    *((pc)++) = (disp); }
-
-#  define emitm_jumpl(pc, disp) { \
-    *((pc)++) = (char) 0xe9; \
-    *(long *)(pc) = (disp); (pc) += 4; }
-
-#  define emitm_jumpr(pc, reg) { \
-    *((pc)++) = (char) 0xff; \
-    *((pc)++) = (char)(0xe0 | ((reg) - 1)); }
-
-#  define emitm_jumpm(pc, b, i, s, d) { \
-       *((pc)++) = (char) 0xff; \
-       (pc) = emit_r_X((interp), (pc), emit_reg(emit_b100), (b), (i), (s), (d)); }
-
-/* Conditional jumps */
-
-/* Short jump - 8 bit disp */
-#  define emitm_jxs(pc, code, disp) { \
-    *((pc)++) = (char)(0x70 | (code)); \
-    *((pc)++) = (char)(disp); }
-
-/* Long jump - 32 bit disp */
-#  define emitm_jxl(pc, code, disp) { \
-    *((pc)++) = (char) 0x0f; \
-    *((pc)++) = (char)(0x80 | (code));  \
-    *(long *)(pc) = (disp); (pc) += 4; }
-
-#  define emitm_jo   0
-#  define emitm_jno  1
-#  define emitm_jb   2
-#  define emitm_jnb  3
-#  define emitm_jz   4
-#  define emitm_je emitm_jz
-#  define emitm_jnz  5
-#  define emitm_jne emitm_jnz
-#  define emitm_jbe  6
-#  define emitm_ja   7
-#  define emitm_js   8
-#  define emitm_jns  9
-#  define emitm_jp  10
-#  define emitm_jnp 11
-#  define emitm_jl  12
-#  define emitm_jnl 13
-#  define emitm_jle 14
-#  define emitm_jg  15
-
-/* set byte conditional */
-#  define jit_emit_setcc_r(pc, cc, r) \
-    *(pc)++ = 0x0f; \
-    *(pc)++ = 0x90 + (cc); \
-    *(pc)++ = (char) emit_alu_X_r(0, (r))
-
-/*
- * core.jit interface
- *
- * The new offset based versions have uppercase RM or MR inside
- * That's probably only during transition time
- */
-
-#  define jit_emit_mov_mi_i(pc, dest, immediate) \
-    emitm_movl_i_m((pc), (immediate), emit_None, emit_None, emit_None, (dest))
-
-#  define jit_emit_mov_MI_i(interp, pc, offs, immediate) \
-    emitm_movl_i_m((pc), (immediate), emit_EBX, emit_None, 1, (offs))
-
-#  define jit_emit_mov_rm_i(interp, pc, reg, address) \
-    emitm_movl_m_r((interp), (pc), (reg), emit_None, emit_None, emit_None, (address))
-
-#  define jit_emit_mov_RM_i(interp, pc, reg, offs) \
-    emitm_movl_m_r((interp), (pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-#  define jit_emit_mov_mr_i(interp, pc, address, reg) \
-    emitm_movl_r_m((interp), (pc), (reg), emit_None, emit_None, emit_None, (address))
-
-#  define jit_emit_mov_MR_i(interp, pc, offs, reg) \
-    emitm_movl_r_m((interp), (pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-#  define jit_emit_mul_RM_i(interp, pc, reg, offs) \
-    emitm_smull_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-#  define jit_emit_sub_RM_i(interp, pc, reg, offs) \
-    emitm_subl_m_r((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-#  define jit_emit_sub_MR_i(interp, pc, offs, reg) \
-    emitm_subl_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-#  define jit_emit_sub_MI_i(pc, offs, imm) \
-    emitm_subl_i_m((pc), (imm), emit_EBX, emit_None, 1, (offs))
-
-#  define jit_emit_add_RM_i(interp, pc, reg, offs) \
-    emitm_addl_m_r((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-#  define jit_emit_add_MR_i(interp, pc, offs, reg) \
-    emitm_addl_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-#  define jit_emit_add_MI_i(pc, offs, imm) \
-    emitm_addl_i_m((pc), (imm), emit_EBX, emit_None, 1, (offs))
-
-#  define jit_emit_cmp_rm_i(pc, reg, address) \
-    emitm_cmpl_r_m((pc), (reg), emit_None, emit_None, emit_None, (address))
-
-#  define jit_emit_cmp_RM_i(interp, pc, reg, offs) \
-    emitm_cmpl_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-#  define jit_emit_cmp_MR_i(interp, pc, offs, reg) \
-    emitm_cmpl_m_r((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-/* high level routines, behave like real 2 register FP */
-
-/* mapped float registers numbers are ST(1)-ST(4).
- * scratch register is ST(0)
- */
-
-/* ST(i) <- numvar */
-#  define jit_emit_mov_RM_n(interp, pc, r, d) { \
-    jit_emit_fload_mb_n((interp), (pc), emit_EBX, (d)); \
-    emitm_fstp((pc), ((r)+1)); \
-}
-
-/* ST(i) <= NUM_CONST */
-#  define jit_emit_mov_ri_n(interp, pc, r, i) { \
-    jit_emit_fload_m_n((interp), (pc), (i)); \
-    emitm_fstp((pc), ((r)+1)); \
-}
-
-/* ST(i) <= &INT_CONST */
-#  define jit_emit_mov_ri_ni(interp, pc, r, i) { \
-    jit_emit_fload_m_i((interp), (pc), (i)); \
-    emitm_fstp((pc), ((r)+1)); \
-}
-
-/* ST(i) <= INT_REG */
-#  define jit_emit_mov_RM_ni(interp, pc, r, i) { \
-    jit_emit_fload_mb_i((interp), (pc), (i)); \
-    emitm_fstp((pc), ((r)+1)); \
-}
-
-/* NUM_REG(i) <= &INT_CONST
- * the int const i is loaded from the code memory
- */
-#  define jit_emit_mov_MI_ni(interp, pc, offs, i) { \
-    jit_emit_fload_m_i((interp), (pc), (i)); \
-    jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (offs)); \
-}
-
-/* INT_REG <= ST(i) */
-#  define jit_emit_mov_mr_in(pc, mem, r) { \
-    emitm_fld((pc), (r)); \
-    jit_emit_fstore_m_i((pc), (mem)); \
-}
-
-/* numvar <- ST(i) */
-#  define jit_emit_mov_mr_n(pc, d, r) { \
-    emitm_fld((pc), (r)); \
-    jit_emit_fstore_m_n((pc), (d)); \
-}
-
-#  define jit_emit_mov_MR_n(interp, pc, d, r) { \
-    if (r) { \
-        emitm_fld((pc), (r)); \
-        jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (d)); \
-    } \
-    else { \
-        jit_emit_fst_mb_n((interp), (pc), emit_EBX, (d)); \
-    } \
-}
-
-/* ST(r1) <= ST(r2) */
-#  define jit_emit_mov_rr_n(pc, r1, r2) { \
-    if ((r1) != (r2)) { \
-      if (r2) { \
-        emitm_fld((pc), (r2)); \
-        emitm_fstp((pc), ((r1)+1)); \
-      } \
-      else { \
-        emitm_fst((pc), (r1)); \
-      } \
-    } \
-}
-
-/* ST(r1) xchg ST(r2) */
-#  define jit_emit_xchg_rr_n(interp, pc, r1, r2) { \
-    if ((r1) != (r2)) { \
-      emitm_fld((pc), (r1)); \
-      emitm_fld((pc), ((r2)+1)); \
-      emitm_fstp((pc), ((r1)+2)); \
-      emitm_fstp((pc), ((r2)+1)); \
-    } \
-}
-
-#  define jit_emit_xchg_RM_n(interp, pc, r, offs) { \
-    emitm_fld((pc), (r)); \
-    jit_emit_fload_mb_n((interp), (pc), emit_EBX, (offs)); \
-    emitm_fstp((pc), ((r)+2)); \
-    jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (offs)); \
-}
-
-#  define jit_emit_xchg_MR_n(interp, pc, offs, r) { \
-    emitm_fld((pc), (r)); \
-    jit_emit_fload_mb_n((interp), (pc), emit_EBX, (offs)); \
-    emitm_fstp((pc), ((r)+2)); \
-    jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (offs)); \
-}
-
-#  define jit_emit_finit(pc) { *((pc)++) = (char) 0xdb; *((pc)++) = (char) 0xe3; }
-
-/* ST(i) op= MEM */
-
-#  define jit_emit_xxx_rm_n(interp, op, pc, r, m) { \
-    jit_emit_fload_m_n((interp), (pc), (m)); \
-    emitm_f ## op ## p((pc), ((r)+1)); \
-}
-
-#  define jit_emit_xxx_RM_n(interp, op, pc, r, offs) { \
-    jit_emit_fload_mb_n((interp), (pc), emit_EBX, (offs)); \
-    emitm_f ## op ## p((pc), ((r)+1)); \
-}
-
-/*
- * float ops in two flavors: abs memory for constants, offsets for regs
- */
-
-#  define jit_emit_add_ri_n(interp, pc, r, m) jit_emit_xxx_rm_n((interp), add, (pc), (r), (m))
-#  define jit_emit_sub_ri_n(interp, pc, r, m) jit_emit_xxx_rm_n((interp), sub, (pc), (r), (m))
-#  define jit_emit_mul_ri_n(interp, pc, r, m) jit_emit_xxx_rm_n((interp), mul, (pc), (r), (m))
-
-#  define jit_emit_add_RM_n(interp, pc, r, o) jit_emit_xxx_RM_n((interp), add, (pc), (r), (o))
-#  define jit_emit_sub_RM_n(interp, pc, r, o) jit_emit_xxx_RM_n((interp), sub, (pc), (r), (o))
-#  define jit_emit_mul_RM_n(interp, pc, r, o) jit_emit_xxx_RM_n((interp), mul, (pc), (r), (o))
-
-/* ST(r1) += ST(r2) */
-/* r1 == 0:  ST(0) <- ST(0) + ST(i)
- * r2 == 0:  ST(i) <- ST(0) + ST(i)
- */
-#  define jit_emit_add_rr_n(interp, pc, r1, r2) do { \
-        if (!(r1)) { \
-          emitm_fadd((pc), (r2)); \
-        }  \
-        else if (!(r2)) { \
-          emitm_faddr((pc), (r1)); \
-        }  \
-        else { \
-            emitm_fld((pc), (r2)); \
-            emitm_faddp((pc), ((r1)+1)); \
-        } \
-    } \
-    while (0)
-/*
- * ST(r) += INT_REG
- */
-#  define jit_emit_add_RM_ni(pc, r, offs) { \
-    emitm_fld((pc), (r)); \
-    emitm_fiadd_m((pc), emit_EBX, 0, 1, (offs)); \
-    emitm_fstp((pc), ((r)+1)); \
-}
-
-/* ST(r1) -= ST(r2) */
-/* r1 == 0:  ST(0) <- ST(0) - ST(i)
- * r2 == 0:  ST(i) <- ST(i) - ST(0)
- */
-#  define jit_emit_sub_rr_n(interp, pc, r1, r2) do { \
-        if (!(r1)) { \
-          emitm_fsub((pc), (r2)); \
-        }  \
-        else if (!(r2)) { \
-          emitm_fsubr((pc), (r1)); \
-        }  \
-        else { \
-            emitm_fld((pc), (r2)); \
-            emitm_fsubp((pc), ((r1)+1)); \
-        } \
-    } \
-    while (0)
-
-/*
- * ST(r) -= INT_REG
- */
-#  define jit_emit_sub_RM_ni(pc, r, offs) { \
-    emitm_fld((pc), (r)); \
-    emitm_fisub_m((pc), emit_EBX, 0, 1, (offs)); \
-    emitm_fstp((pc), ((r)+1)); \
-}
-
-#  define jit_emit_inc_r_n(pc, r) { \
-    emitm_fld1(pc); \
-    emitm_faddp((pc), ((r)+1)); \
-}
-
-#  define jit_emit_dec_r_n(pc, r) { \
-    emitm_fld1(pc); \
-    emitm_fsubp((pc), ((r)+1)); \
-}
-
-/* ST(r1) *= ST(r2) */
-/* r1 == 0:  ST(0) <- ST(0) * ST(i)
- * r2 == 0:  ST(i) <- ST(0) * ST(i)
- */
-#  define jit_emit_mul_rr_n(interp, pc, r1, r2) do { \
-        if (!(r1)) { \
-          emitm_fmul((pc), (r2)); \
-        }  \
-        else if (!(r2)) { \
-          emitm_fmulr((pc), (r1)); \
-        }  \
-        else { \
-            emitm_fld((pc), (r2)); \
-            emitm_fmulp((pc), ((r1)+1)); \
-        } \
-    } \
-    while (0)
-
-/*
- * ST(r) *= INT_REG
- */
-#  define jit_emit_mul_RM_ni(pc, r, offs) { \
-    emitm_fld((pc), (r)); \
-    emitm_fimul_m((pc), emit_EBX, 0, 1, (offs)); \
-    emitm_fstp((pc), ((r)+1)); \
-}
-
-/*
- * ST(r) /= INT_REG
- */
-#  define jit_emit_div_RM_ni(pc, r, offs) { \
-    emitm_fld((pc), (r)); \
-    emitm_fidiv_m((pc), emit_EBX, 0, 1, (offs)); \
-    emitm_fstp((pc), ((r)+1)); \
-}
-
-/* test r for zero */
-#  define jit_emit_test_r_n(pc, r) { \
-    if (r) { \
-      emitm_fxch((pc), (r)); \
-    } \
-    emitm_fxam(pc); \
-    emitm_fstw(pc); \
-    emitm_sahf(pc); \
-    if (r) { \
-      emitm_fxch((pc), (r)); \
-    } \
-}
-
-enum { JIT_X86BRANCH, JIT_X86JUMP, JIT_X86CALL };
-
-#  define jit_emit_stack_frame_enter(pc) do { \
-    emitm_pushl_r((pc), emit_EBP); \
-    jit_emit_mov_rr_i((pc), emit_EBP, emit_ESP); \
-} while (0)
-
-#  define jit_emit_stack_frame_leave(pc) do { \
-    jit_emit_mov_rr_i((pc), emit_ESP, emit_EBP); \
-    emitm_popl_r((pc), emit_EBP); \
-} while (0)
-
-#  define jit_emit_end(pc) { \
-       jit_emit_add_ri_i((interp), (pc), emit_ESP, 4); \
-       emitm_popl_r((pc), emit_EDI); \
-       emitm_popl_r((pc), emit_ESI); \
-       emitm_popl_r((pc), emit_EBX); \
-       emitm_popl_r((pc), emit_EBP); \
-       emitm_ret(pc); \
-     }
-
-size_t calc_signature_needs(const char *sig, int *strings);
-
-void * Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci,
-    STRING *signature, int *sizeptr);
-
-/*
- * register usage
- * %edi, %esi ... mapped, preserved
- * %edx, %ecx ... mapped, not preserved
- * %ebx       ... base pointer for register access, preserved
- * %eax       ... scratch, return value register
- */
-
-#endif /* PARROT_I386_JIT_EMIT_H_GUARD */
+#endif /* PARROT_FRAME_BUILDER_H_GUARD */
 
 /*
  * Local variables:

Modified: branches/libjit_framebuilder/src/nci_test.c
==============================================================================
--- branches/libjit_framebuilder/src/nci_test.c	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/src/nci_test.c	Fri Nov  6 19:11:03 2009	(r42314)
@@ -110,6 +110,8 @@
 PARROT_DYNEXT_EXPORT void   nci_vfff(float, float, float);
 PARROT_DYNEXT_EXPORT void   nci_vV(const char **);
 PARROT_DYNEXT_EXPORT void   nci_vVVV(const char **, const char **, const char **);
+PARROT_DYNEXT_EXPORT int    nci_i20(int, int, int, int, int, int, int, int, int, int, int, int,
+                                    int, int, int, int, int, int, int);
 
 /* Declarations for callback tests */
 
@@ -1191,6 +1193,50 @@
   *ptr3 = "Go suck a lemon.\n";
 }
 
+/*
+
+=item C<int
+nci_i20(int sel, int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8, int v9, int v10,
+        int v11, int v12, int v13, int v14, int v15, int v16, int v17, int v18)>
+
+Prints and returns the nth value in a list of integers. First argument is the selector; subsequents,
+the list.
+
+This function is designed to be outside of the range of the static frame builder as an excercise for
+the dynamic frame builder.
+
+=cut
+
+*/
+PARROT_DYNEXT_EXPORT int
+nci_i20(int sel, int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8, int v9, int v10,
+        int v11, int v12, int v13, int v14, int v15, int v16, int v17, int v18) {
+    int *selected;
+    switch ((sel < 0 ? -sel : sel) % 18) {
+        case 0: selected = &v1; break;
+        case 1: selected = &v2; break;
+        case 2: selected = &v3; break;
+        case 3: selected = &v4; break;
+        case 4: selected = &v5; break;
+        case 5: selected = &v6; break;
+        case 6: selected = &v7; break;
+        case 7: selected = &v8; break;
+        case 8: selected = &v9; break;
+        case 9: selected = &v10; break;
+        case 10: selected = &v11; break;
+        case 11: selected = &v12; break;
+        case 12: selected = &v13; break;
+        case 13: selected = &v14; break;
+        case 14: selected = &v15; break;
+        case 15: selected = &v16; break;
+        case 16: selected = &v17; break;
+        case 17: selected = &v18; break;
+        default: printf("default case reached (should never happen)"); return -1;
+    }
+    printf("%d\n", *selected);
+    return *selected;
+}
+
 #ifdef TEST
 
 char l2 = 4;

Modified: branches/libjit_framebuilder/src/ops/core.ops
==============================================================================
--- branches/libjit_framebuilder/src/ops/core.ops	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/src/ops/core.ops	Fri Nov  6 19:11:03 2009	(r42314)
@@ -1322,7 +1322,6 @@
     else {
         $1 = pmc_new(interp, enum_class_NCI);
         VTABLE_set_pointer_keyed_str(interp, $1, $4, F2DPTR(p));
-        PObj_get_FLAGS($1) |= PObj_private1_FLAG;
     }
     Parrot_str_free_cstring(name);
 }

Modified: branches/libjit_framebuilder/src/pmc/nci.pmc
==============================================================================
--- branches/libjit_framebuilder/src/pmc/nci.pmc	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/src/pmc/nci.pmc	Fri Nov  6 19:11:03 2009	(r42314)
@@ -18,86 +18,116 @@
 
 */
 
+#include "parrot/nci.h"
+
 typedef INTVAL (*nci_sub_t)(PARROT_INTERP, PMC *);
-typedef INTVAL (*nci_jit_sub_t)(PARROT_INTERP, PMC *, char *);
+typedef nci_sub_t nci_jit_sub_t;
 
-void pcc_params(PARROT_INTERP, STRING *sig, Parrot_NCI_attributes * const nci_info,
-                size_t sig_length);
-void pcc_params(PARROT_INTERP, STRING *sig, Parrot_NCI_attributes * const nci_info,
-                size_t sig_length) {
-    char    param_buf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-    char   *param_sig    = sig_length <= 7
-                         ? param_buf
-                         : mem_allocate_n_typed(sig_length, char);
-    size_t  j            = 0;
-    size_t  i;
+#define NCI_raw_FLAG    PObj_private0_FLAG
 
-    for (i = 1; i < sig_length; i++) {
-        INTVAL c = Parrot_str_indexed(interp, sig, i);
+STRING *pcc_sig_params(PARROT_INTERP, STRING *sig);
+STRING *pcc_sig_params(PARROT_INTERP, STRING *sig) {
+    size_t sig_len = Parrot_str_byte_length(interp, sig);
+    char param_buf[sig_len*2];
 
-        switch (c) {
-            case (INTVAL)'0':    /* null ptr or such - doesn't consume a reg */
-                break;
-            case (INTVAL)'f':
-            case (INTVAL)'N':
-            case (INTVAL)'d':
-                param_sig[j++] = 'N';
-                break;
-            case (INTVAL)'I':   /* INTVAL */
-            case (INTVAL)'l':   /* long */
-            case (INTVAL)'i':   /* int */
-            case (INTVAL)'s':   /* short */
-            case (INTVAL)'c':   /* char */
-                param_sig[j++] = 'I';
-                break;
-            case (INTVAL)'S':
-            case (INTVAL)'t':   /* string, pass a cstring */
-                param_sig[j++] = 'S';
-                break;
-            case (INTVAL)'J':   /* interpreter */
-                break;
-            case (INTVAL)'p':   /* push pmc->data */
-            case (INTVAL)'O':   /* push PMC * object in P2 */
-            case (INTVAL)'P':   /* push PMC * */
-            case (INTVAL)'V':   /* push PMC * */
-                param_sig[j++] = 'P';
-            case (INTVAL)'v':
-                break;
-                /* I have no idea how to handle these */
-            case (INTVAL)'2':
-            case (INTVAL)'3':
-            case (INTVAL)'4':
-                param_sig[j++] = 'I';
-                break;
-            case (INTVAL)'@':
-                param_sig[j++] = '@';
-                break;
-            case (INTVAL)'b': /* buffer (void*) pass Buffer_bufstart(SReg) */
-            case (INTVAL)'B': /* buffer (void**) pass &Buffer_bufstart(SReg) */
-                param_sig[j++] = 'S';
-                break;
-            default:
-                if (sig_length > 7)
-                    mem_sys_free(param_sig);
-                Parrot_ex_throw_from_c_args(interp, NULL,
+    size_t i, j;
+
+    for (i = 1, j = 0; i < sig_len; i++) {
+        INTVAL c = Parrot_str_indexed(interp, sig, i);
+        if (c > 127) {
+            Parrot_ex_throw_from_c_args(interp, NULL,
                     EXCEPTION_JIT_ERROR,
-                    "Unknown param Signature %c\n", (char)c);
-                break;
+                    "Unknown param type at %d in signature '%S' (way too big)\n", i, sig);
+        }
+        else {
+            switch ((char)c) {
+                case 'v':
+                case '0':
+                case 'J':
+                    break;
+                case 'N':
+                case 'd':
+                case 'f':
+                    param_buf[j++] = 'N';
+                    break;
+                case 'I':
+                case 'l':
+                case 'i':
+                case 's':
+                case 'c':
+                    param_buf[j++] = 'I';
+                    break;
+                case 'S':
+                case 't':
+                case 'b':
+                case 'B':
+                    param_buf[j++] = 'S';
+                    break;
+                case 'P':
+                case 'p':
+                case 'V':
+                case '2':
+                case '3':
+                case '4':
+                    param_buf[j++] = 'P';
+                    break;
+                case 'O':
+                    param_buf[j++] = 'P';
+                    param_buf[j++] = 'i';
+                    break;
+                case '@':
+                    param_buf[j++] = 'P';
+                    param_buf[j++] = 's';
+                    break;
+                default:
+                    Parrot_ex_throw_from_c_args(interp, NULL,
+                            EXCEPTION_JIT_ERROR,
+                            "Unknown param type at %d in signature '%S'\n", i, sig);
+            }
         }
     }
 
-    PARROT_ASSERT(j <= sig_length);
+    return string_make(interp, param_buf, j, NULL, PObj_constant_FLAG);
+}
 
-    /* use only the signature-significant part of the string buffer */
-    if (j) {
-        nci_info->pcc_params_signature = string_make(interp, param_sig, j,
-            NULL, PObj_constant_FLAG);
+STRING *pcc_sig_ret(PARROT_INTERP, STRING *sig);
+STRING *pcc_sig_ret(PARROT_INTERP, STRING *sig) {
+    INTVAL c = Parrot_str_indexed(interp, sig, 0);
+    if (c > 127) {
+        Parrot_ex_throw_from_c_args(interp, NULL,
+                EXCEPTION_JIT_ERROR,
+                "Unknown return type at %d in signature '%S' (way too big)\n", 0, sig);
+    }
+    else {
+        switch ((char)c) {
+            case 'v':
+                return CONST_STRING(interp, "v");
+            case 'N':
+            case 'f':
+            case 'd':
+                return CONST_STRING(interp, "N");
+            case 'I':
+            case 'l':
+            case 'i':
+            case 's':
+            case 'c':
+                return CONST_STRING(interp, "I");
+            case 'S':
+            case 't':
+                return CONST_STRING(interp, "S");
+            case 'p':
+            case 'P':
+                return CONST_STRING(interp, "P");
+            case '2':
+            case '3':
+            case '4':
+                return CONST_STRING(interp, "P");
+            default:
+                Parrot_ex_throw_from_c_args(interp, NULL,
+                        EXCEPTION_JIT_ERROR,
+                        "Unknown return type at %d in signature '%S'\n", 0, sig);
+        }
     }
-    else
-        nci_info->pcc_params_signature = CONST_STRING(interp, "");
-
-    if (sig_length > 7)
-        mem_sys_free(param_sig);
 }
 
 /* actually build the NCI thunk */
@@ -106,33 +136,31 @@
 static
 nci_sub_t build_func(PARROT_INTERP, PMC *pmc, Parrot_NCI_attributes *nci_info)
 {
-    STRING    *key        = nci_info->signature;
-    size_t     key_length = Parrot_str_byte_length(interp, key);
+    STRING    *key        = nci_info->nci_signature;
     int       jitted      = 0;
 
-    pcc_params(interp, key, nci_info, key_length);
-
-    /* Arity is length of that string minus one (the return type). */
-    nci_info->arity       = key_length - 1;
-
     /* Build call function. */
     nci_info->func        = (PMC *)(build_call_func(interp, pmc, key, &jitted));
-    nci_info->jitted      = jitted;
 
     return (nci_sub_t)nci_info->func;
 }
 
 
 pmclass NCI auto_attrs {
-    ATTR STRING    *signature;              /* The signature. */
-    ATTR void      *func;                   /* Function pointer to call. */
-    ATTR void      *orig_func;              /* Function pointer
-                                             * used to create func */
-    ATTR STRING    *pcc_params_signature;   /* The signature. */
-    ATTR STRING    *long_signature;         /* The full signature. */
-    ATTR PMC       *multi_sig;              /* type tuple array (?) */
-    ATTR INTVAL     arity;                  /* Cached arity of the NCI. */
-    ATTR INTVAL     jitted;                 /* Is this a jitted NCI stub. */
+    /* Signature Attributes */
+    ATTR STRING    *nci_signature;          /* The NCI signature */
+    ATTR STRING    *pcc_signature_ret;      /* The PCC return signature */
+    ATTR STRING    *pcc_signature_param;    /* The PCC param signature */
+
+    /* Function Pointers */
+    ATTR void      *func;                   /* Function pointer to call */
+    ATTR void      *orig_func;              /* Function pointer being wrapped */
+
+    /* Sub PMC Attributes */
+    ATTR INTVAL     arity;                  /* Number of params taken */
+    /* MMD Attributes */
+    ATTR PMC       *multi_sig;
+    ATTR STRING    *long_signature;
 
 /*
 
@@ -147,8 +175,9 @@
     METHOD get_multisig() {
         PMC *sig;
         GET_ATTR_multi_sig(INTERP, SELF, sig);
-        if (PMC_IS_NULL(sig))
+        if (sig == NULL) {
             sig = PMCNULL;
+        }
         RETURN(PMC *sig);
     }
 
@@ -178,15 +207,19 @@
 
     VTABLE void init() {
         /* Mark that we're not a raw NCI. */
-        PObj_flag_CLEAR(private2, SELF);
+        PObj_get_FLAGS(SELF) &= ~NCI_raw_FLAG;
+        /* Mark that we have a custom gc marker */
         PObj_custom_mark_SET(SELF);
     }
 
 /*
 
-=item C<void set_pointer_keyed_str(STRING *key, void *func)>
+=item C<void *get_pointer()>
+
+=item C<void set_pointer(void *ptr)>
 
-Sets the specified function pointer and signature (C<*key>).
+Get/Set the pointer being wrapped. Setting through this interface sets
+the raw flag.
 
 =cut
 
@@ -194,29 +227,57 @@
 
     VTABLE void set_pointer(void *ptr) {
         SET_ATTR_orig_func(INTERP, SELF, ptr);
-        PObj_flag_SET(private2, SELF);
+        PObj_get_FLAGS(SELF) |= NCI_raw_FLAG;
     }
 
     VTABLE void *get_pointer() {
         return PARROT_NCI(SELF)->orig_func;
     }
 
+/*
+
+=item C<void set_pointer_keyed_str(STRING *key, void *func)>
+
+Roughly equivalent to C<set_string(key)> and C<set_pointer(func)>.
+Setting through this interface clears the raw flag.
+
+=cut
+
+*/
+
     VTABLE void set_pointer_keyed_str(STRING *key, void *func) {
-        Parrot_NCI_attributes * const nci_info   = PARROT_NCI(SELF);
+        SELF.set_string_native(key);
+        SELF.set_pointer(func);
+        PObj_get_FLAGS(SELF) &= ~NCI_raw_FLAG;
+    }
+
+/*
 
-        /* Store the original function and signature. */
-        SET_ATTR_orig_func(INTERP, SELF, func);
+=item C<STRING *get_string()>
 
-        /* ensure that the STRING signature is constant */
-        if (!PObj_constant_TEST(key)) {
-            char * const key_c      = Parrot_str_to_cstring(INTERP, key);
-            size_t       key_length = Parrot_str_byte_length(interp, key);
-            key                     = string_make(interp, key_c, key_length,
-                                        NULL, PObj_constant_FLAG);
-            Parrot_str_free_cstring(key_c);
+=item C<void set_string(STRING *str)>
+
+Get/Set the NCI signature.
+
+=cut
+
+*/
+
+    VTABLE STRING *get_string() {
+        return PARROT_NCI(SELF)->nci_signature;
+    }
+
+    VTABLE void set_string_native(STRING *str) {
+        if (!PObj_constant_TEST(str)) {
+            str = Parrot_str_copy(INTERP, str);
         }
+        SET_ATTR_nci_signature(INTERP, SELF, str);
 
-        nci_info->signature = key;
+        /* set up derivative attributes */
+        SET_ATTR_pcc_signature_param(INTERP, SELF, pcc_sig_params(INTERP, str));
+        SET_ATTR_pcc_signature_ret(INTERP, SELF, pcc_sig_ret(INTERP, str));
+        /* Arity is length of the NCI signature minus one (the return type). */
+        SET_ATTR_arity(INTERP, SELF, Parrot_str_byte_length(INTERP, str) - 1);
     }
 
 /*
@@ -232,8 +293,9 @@
         if (PARROT_NCI(SELF)) {
             Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
 
-            Parrot_gc_mark_STRING_alive(interp, nci_info->signature);
-            Parrot_gc_mark_STRING_alive(interp, nci_info->pcc_params_signature);
+            Parrot_gc_mark_STRING_alive(interp, nci_info->nci_signature);
+            Parrot_gc_mark_STRING_alive(interp, nci_info->pcc_signature_param);
+            Parrot_gc_mark_STRING_alive(interp, nci_info->pcc_signature_ret);
             Parrot_gc_mark_STRING_alive(interp, nci_info->long_signature);
             Parrot_gc_mark_PMC_alive(interp, nci_info->multi_sig);
         }
@@ -262,11 +324,13 @@
          * ManagedStruct or Buffer?
          */
         nci_info_ret->func                  = nci_info_self->func;
-        nci_info_ret->orig_func             = nci_info_self->orig_func;
-        nci_info_ret->signature             = nci_info_self->signature;
-        nci_info_ret->pcc_params_signature  = nci_info_self->pcc_params_signature;
+        nci_info_ret->orig_func              = nci_info_self->orig_func;
+        nci_info_ret->nci_signature         = nci_info_self->nci_signature;
+        nci_info_ret->pcc_signature_param   = nci_info_self->pcc_signature_param;
+        nci_info_ret->pcc_signature_ret     = nci_info_self->pcc_signature_ret;
+        nci_info_ret->long_signature        = nci_info_self->long_signature;
+        nci_info_ret->multi_sig             = nci_info_self->multi_sig;
         nci_info_ret->arity                 = nci_info_self->arity;
-        nci_info_ret->jitted                = nci_info_self->jitted;
         PObj_get_FLAGS(ret)                |= (PObj_get_FLAGS(SELF) & 0x7);
 
         return ret;
@@ -306,7 +370,7 @@
         PMC                          *cont;
 
         GET_ATTR_orig_func(INTERP, SELF, orig_func);
-        func = PObj_flag_TEST(private2, SELF)
+        func = PObj_get_FLAGS(SELF) & NCI_raw_FLAG
             ? (nci_sub_t) D2FPTR(orig_func)
             : (nci_sub_t) D2FPTR(nci_info->func);
 
@@ -320,23 +384,8 @@
                     "attempt to call NULL function");
         }
 
-        if (nci_info->jitted) {
-            nci_jit_sub_t jit_func = (nci_jit_sub_t) D2FPTR(nci_info->func);
+        func(INTERP, SELF);
 
-            /* Parrot_eprintf(interp, "JITTED %S\n", nci_info->signature); */
-            sig_str = Parrot_str_to_cstring(interp, nci_info->pcc_params_signature);
-            jit_func(INTERP, SELF, sig_str);
-            Parrot_str_free_cstring(sig_str);
-        }
-        else {
-            if (PObj_flag_TEST(private2, SELF)) {
-                /* Parrot_eprintf(interp, "RAW NCI CALL\n"); */
-            }
-            else {
-                /* Parrot_eprintf(interp, "HACKED %S\n", nci_info->signature); */
-            }
-            func(INTERP, SELF);
-        }
         cont = INTERP->current_cont;
 
         /*
@@ -397,21 +446,84 @@
 
 */
     METHOD arity() {
-        Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
-        INTVAL arity = 0;
+        INTVAL arity;
+        GET_ATTR_arity(INTERP, SELF, arity);
+        RETURN(INTVAL arity);
+    }
 
-        if (nci_info) {
-            if (!nci_info->func)
-                build_func(INTERP, SELF, nci_info);
-            if (nci_info->func) {
-                arity = nci_info->arity;
-                RETURN(INTVAL arity);
-            }
+/*
+
+=item C<INTVAL get_integer_keyed_int(INTVAL key)>
+
+=item C<STRING *get_string_keyed_int(INTVAL key)>
+
+=item C<PMC *get_pmc_keyed_int(INTVAL key)>
+
+Accessors for all attributes of this class not otherwise accessible through VTABLES.
+Integers are used for keys to make access easier for JIT. These are also available to
+PIR from F<runtime/parrot/include/nci.pasm>
+
+=over
+
+=item INTVAL keys
+
+C<PARROT_NCI_ARITY>
+
+=item STRING keys
+
+C<PARROT_NCI_PCC_SIGNATURE_PARAMS>, C<PARROT_NCI_PCC_SIGNATURE_RET>,
+C<PARROT_LONG_SIGNATURE>
+
+=item PMC keys
+
+C<PARROT_NCI_MULTI_SIG>
+
+=back
+
+=cut
+
+*/
+
+    VTABLE INTVAL get_integer_keyed_int(INTVAL key) {
+        switch (key) {
+            case PARROT_NCI_ARITY:
+                return PARROT_NCI(SELF)->arity;
+            default:
+                Parrot_ex_throw_from_c_args(INTERP, NULL,
+                    EXCEPTION_INVALID_OPERATION,
+                    "Bad index for NCI.get_integer_keyed_int()");
+        }
+    }
+
+    VTABLE STRING *get_string_keyed_int(INTVAL key) {
+        switch (key) {
+            case PARROT_NCI_PCC_SIGNATURE_PARAMS:
+                return PARROT_NCI(SELF)->pcc_signature_param;
+            case PARROT_NCI_PCC_SIGNATURE_RET:
+                return PARROT_NCI(SELF)->pcc_signature_ret;
+            case PARROT_NCI_LONG_SIGNATURE:
+                return PARROT_NCI(SELF)->long_signature;
+            default:
+                Parrot_ex_throw_from_c_args(INTERP, NULL,
+                    EXCEPTION_INVALID_OPERATION,
+                    "Bad index for NCI.get_string_keyed_int()");
         }
+    }
 
-        Parrot_ex_throw_from_c_args(INTERP, NULL,
-            EXCEPTION_INVALID_OPERATION,
-            "You cannot get the arity of an undefined NCI.");
+    VTABLE PMC *get_pmc_keyed_int(INTVAL key) {
+        PMC *retval;
+        switch (key) {
+            case PARROT_NCI_MULTI_SIG:
+                GET_ATTR_multi_sig(INTERP, SELF, retval);
+            default:
+                Parrot_ex_throw_from_c_args(INTERP, NULL,
+                    EXCEPTION_INVALID_OPERATION,
+                    "Bad index for NCI.get_pmc_keyed_int()");
+        }
+        if (retval == NULL) {
+            retval = PMCNULL;
+        }
+        return retval;
     }
 }
 

Modified: branches/libjit_framebuilder/t/pmc/nci.t
==============================================================================
--- branches/libjit_framebuilder/t/pmc/nci.t	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/t/pmc/nci.t	Fri Nov  6 19:11:03 2009	(r42314)
@@ -5,8 +5,19 @@
 use strict;
 use warnings;
 use lib qw( . lib ../lib ../../lib );
+use Parrot::BuildUtil;
+use Parrot::NativeCall 'signature_nci_to_pcc';
+
+my @nci_sigs;
+BEGIN {
+    @nci_sigs =
+        grep {$_}
+        map {chomp; s/^\s*//; s/\s*$//; s/#.*$//; $_}
+        split /\n/, Parrot::BuildUtil::slurp_file('src/call_list.txt');
+}
+
 use Test::More;
-use Parrot::Test tests => 70;
+use Parrot::Test tests => (71 + @nci_sigs);
 use Parrot::Config qw(%PConfig);
 
 =head1 NAME
@@ -32,6 +43,27 @@
 
 $ENV{TEST_PROG_ARGS} ||= '';
 
+foreach my $nci_sig (@nci_sigs) {
+    my ($nci_ret, $nci_params) = $nci_sig =~ /\S+/g;
+    $nci_params ||= '';
+    my $pcc_sig = signature_nci_to_pcc($nci_sig);
+    pir_output_is( << "CODE", "$pcc_sig\n", "NCI PMC signatures equivalent to nativecall.pl ('$nci_sig')" );
+.include "nci.pasm"
+.sub test :main
+    .local pmc nci
+    nci = new ['NCI']
+    nci = "${nci_ret}${nci_params}"
+    .local string s
+    s = nci[ .PARROT_NCI_PCC_SIGNATURE_PARAMS ]
+    print s
+    print "->"
+    s = nci[ .PARROT_NCI_PCC_SIGNATURE_RET ]
+    print s
+    print "\\n"
+.end
+CODE
+}
+
 SKIP: {
     unless ( -e "runtime/parrot/dynext/libnci_test$PConfig{load_ext}" ) {
         skip( "Please make libnci_test$PConfig{load_ext}", Test::Builder->expected_tests() );
@@ -2753,6 +2785,76 @@
 Go suck a lemon.
 OUTPUT
 
+my $test_code = <<'CODE';
+.sub test :main
+    .local pmc libnci_test
+    $S0 = 'libnci_test'
+    libnci_test = loadlib $S0
+
+    .local pmc nci_i20
+    nci_i20 = dlfunc libnci_test, "nci_i20", "iiiiiiiiiiiiiiiiiiii"
+
+    .local pmc args
+    args = new ['FixedIntegerArray']
+    args = 18
+
+    $I0 = 2
+    args[0] = 1
+    args[1] = 1
+
+LOOP1:
+    $I1 = $I0 - 1
+    $I1 = args[$I1]
+
+    $I2 = $I0 - 2
+    $I2 = args[$I2]
+
+    $I3 = $I1 + $I2
+    args[$I0] = $I3
+    inc $I0
+    if $I0 < 18 goto LOOP1
+
+    $I0 = args
+    dec $I0
+
+    $I1 = args[0]
+    $I2 = args[1]
+    $I3 = args[2]
+    $I4 = args[3]
+    $I5 = args[4]
+    $I6 = args[5]
+    $I7 = args[6]
+    $I8 = args[7]
+    $I9 = args[8]
+    $I10 = args[9]
+    $I11 = args[10]
+    $I12 = args[11]
+    $I13 = args[12]
+    $I14 = args[13]
+    $I15 = args[14]
+    $I16 = args[15]
+    $I17 = args[16]
+    $I18 = args[17]
+
+LOOP2:
+    nci_i20($I0, $I1, $I2, $I3, $I4, $I5, $I6, $I7, $I8, $I9, $I10, $I11, $I12, $I13, $I14, $I15, $I16, $I17, $I18)
+    $I0 = $I0 / 2
+    if $I0 > 0 goto LOOP2
+.end
+CODE
+if ($PConfig{cc_build_call_frames}) {
+    pir_output_is($test_code, <<DYNAMIC_FRAMEBUILDER_OUTPUT, 'dynamic frame builder builds ridiculous call frames');
+2584
+34
+5
+2
+1
+DYNAMIC_FRAMEBUILDER_OUTPUT
+} else {
+    my $output_re = qr/^Parrot VM: PANIC: iiiiiiiiiiiiiiiiiiii is an unknown signature type./;
+    pir_error_output_like($test_code, $output_re, "static frame builder can't build ridiculous signatures");
+}
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4

Modified: branches/libjit_framebuilder/t/steps/auto/frames-01.t
==============================================================================
--- branches/libjit_framebuilder/t/steps/auto/frames-01.t	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/t/steps/auto/frames-01.t	Fri Nov  6 19:11:03 2009	(r42314)
@@ -5,7 +5,7 @@
 
 use strict;
 use warnings;
-use Test::More tests => 27;
+use Test::More tests => 28;
 use lib qw( lib t/configure/testlib );
 use_ok('config::init::defaults');
 use_ok('config::auto::frames');
@@ -33,22 +33,24 @@
 $conf->options->set( %{$args} );
 my $step = test_step_constructor_and_description($conf);
 
-# To avoid a warning about an unitialized value, we will set nvsize to 8,
-# cpuarch to i386 and osname to linux.
+# To avoid a warning about an uninitialized value, we will set osname to linux.
 # This is normally done during earlier configuration steps.
-$conf->data->set( nvsize => 8 );
-$conf->data->set( cpuarch => 'i386' );
 $conf->data->set( osname => 'linux' );
 
+$conf->data->set( HAS_LIBJIT => 1 );
 my $ret = $step->runstep($conf);
 ok( $ret, "runstep() returned true value" );
 ok( defined ( $step->result() ),
     "Got defined result" );
-TODO: {
-    local $TODO =
-        'build frames temporarily disabled at pcc_reapply merge: TT #1132';
-    is( $step->result(), 'yes', "Result is 'yes', as expected" );
-}
+is( $step->result(), 'yes', "Result is 'yes', as expected" );
+
+$conf->data->set( HAS_LIBJIT => undef );
+$ret = $step->runstep($conf);
+ok( $ret, "runstep() returned true value" );
+ok( defined ( $step->result() ),
+    "Got defined result" );
+is( $step->result(), 'no', "Result is 'no', as expected" );
+
 $conf->cc_clean();
 $step->set_result( undef );
 
@@ -68,46 +70,20 @@
 ok( ! $can_build_call_frames,
     "_call_frames_buildable() returned false value, as expected" );
 
+$conf->data->set( HAS_LIBJIT => 1 );
 $conf->options->set( buildframes => undef );
-$conf->data->set( osname =>  'linux' );
-$conf->data->set( cpuarch =>  'i386' );
-$conf->data->set( nvsize =>  8 );
-$can_build_call_frames = auto::frames::_call_frames_buildable($conf);
-TODO: {
-    local $TODO =
-        'build frames temporarily disabled at pcc_reapply merge: TT #1132';
-    ok( $can_build_call_frames,
-        "_call_frames_buildable() returned true value, as expected (i386/non darwin/8)"
-    );
-}
-
-$conf->data->set( osname =>  'darwin' );
-$conf->data->set( cpuarch =>  'i386' );
-$conf->data->set( nvsize =>  8 );
-$can_build_call_frames = auto::frames::_call_frames_buildable($conf);
-ok( ! $can_build_call_frames,
-    "_call_frames_buildable() returned false value, as expected (i386/darwin/8)" );
-
-$conf->data->set( osname =>  'linux' );
-$conf->data->set( cpuarch =>  'ppc' );
-$conf->data->set( nvsize =>  8 );
 $can_build_call_frames = auto::frames::_call_frames_buildable($conf);
-ok( ! $can_build_call_frames,
-    "_call_frames_buildable() returned false value, as expected (ppc/linux/8)" );
+ok( $can_build_call_frames,
+    "_call_frames_buildable() returned true value, as expected" );
 
-$conf->data->set( osname =>  'linux' );
-$conf->data->set( cpuarch =>  'i386' );
-$conf->data->set( nvsize =>  4 );
+$conf->data->set( HAS_LIBJIT => undef );
+$conf->options->set( buildframes => 0 );
 $can_build_call_frames = auto::frames::_call_frames_buildable($conf);
 ok( ! $can_build_call_frames,
-    "_call_frames_buildable() returned false value, as expected (i386/linux/4)" );
+    "_call_frames_buildable() returned false value, as expected" );
 
 ##### _handle_call_frames_buildable() #####
 
-$conf->data->set( nvsize => 8 );
-$conf->data->set( cpuarch => 'i386' );
-$conf->data->set( osname => 'linux' );
-
 my $rv;
 
 $can_build_call_frames = 0;
@@ -123,19 +99,16 @@
 $conf->data->set( 'has_exec_protect' => undef );
 
 $can_build_call_frames = 1;
-my $realos = $conf->data->get( 'osname' );
-$conf->data->set( 'osname' => 'foobar' );
 $rv = $step->_handle_can_build_call_frames( $conf, $can_build_call_frames );
 ok( $rv, "_handle_can_build_call_frames() returned true value" );
 is( $conf->data->get( 'cc_build_call_frames'), '-DCAN_BUILD_CALL_FRAMES',
     "cc_build_call_frames set to expected value" );
-is( $conf->data->get( 'has_exec_protect' ), 0,
-    "has_exec_protect is 0, as expected" );
+is( $conf->data->get( 'has_exec_protect' ), 1,
+    "has_exec_protect is 1, as expected" );
 is( $step->result(), 'yes', "Result is 'yes', as expected" );
 
 $conf->data->set( 'cc_build_call_frames' => undef );
 $conf->data->set( 'has_exec_protect' => undef );
-$conf->data->set( 'osname' => $realos );
 
 pass("Completed all tests in $0");
 

Added: branches/libjit_framebuilder/t/steps/auto/libjit-01.t
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/libjit_framebuilder/t/steps/auto/libjit-01.t	Fri Nov  6 19:11:03 2009	(r42314)
@@ -0,0 +1,173 @@
+#! perl
+# Copyright (C) 2009, Parrot Foundation.
+# $Id$
+# auto/libjit-01.t
+
+use strict;
+use warnings;
+
+use Test::More tests => 34;
+use lib qw( lib t/configure/testlib );
+use Parrot::Configure;
+use Parrot::Configure::Options 'process_options';
+use Parrot::Configure::Test qw(
+    test_step_thru_runstep
+    rerun_defaults_for_testing
+    test_step_constructor_and_description
+);
+use IO::CaptureOutput qw( capture );
+
+use_ok('config::init::defaults');
+use_ok('config::auto::libjit');
+
+my ($args, $step_list_ref) = process_options( {
+        argv => [ q{--without-libjit} ],
+        mode => 'configure',
+} );
+
+my $conf = Parrot::Configure->new;
+
+my $serialized = $conf->pcfreeze();
+
+test_step_thru_runstep( $conf, 'init::defaults', $args );
+
+my $pkg = 'auto::libjit';
+my ( $step, $ret );
+
+$conf->add_steps($pkg);
+$conf->options->set(%$args);
+$step = test_step_constructor_and_description($conf);
+$ret = $step->runstep($conf);
+ok( $ret, "runstep() returned true value" );
+is( $step->result(), 'no', "Result is 'no', as expected" );
+is( $conf->data->get( 'HAS_LIBJIT' ), 0,
+   "Got expected result with --without-libjit option" );
+$conf->cc_clean();
+
+$conf->replenish($serialized);
+
+($args, $step_list_ref) = process_options( {
+    argv => [ ],
+    mode => q{configure},
+} );
+rerun_defaults_for_testing($conf, $args );
+$conf->add_steps($pkg);
+$conf->options->set( %{$args} );
+$step = test_step_constructor_and_description($conf);
+$ret = $step->runstep($conf);
+ok( $ret, "runstep() returned true value" );
+like( $step->result(), qr/yes|no/, "Result is either 'yes' or 'no'" );
+ok( defined( $conf->data->get( 'HAS_LIBJIT' ) ),
+   "'HAS_LIBJIT' has defined value" );
+$conf->cc_clean();
+
+########## _evaluate_cc_run ##########
+
+my ($test, $has_libjit, $verbose);
+
+$step->set_result( undef );
+
+$test = q{USES INTERPRETER: 33};
+$has_libjit = 0;
+$verbose = 0;
+$has_libjit = $step->_evaluate_cc_run($test, $has_libjit, $verbose);
+ok( $has_libjit, "_evaluate_cc_run() returned true value, as expected" );
+is( $step->result(), 'yes', "result is yes, as expected" );
+
+$step->set_result( undef );
+
+$test = q{foobar};
+$has_libjit = 0;
+$verbose = 0;
+$has_libjit = $step->_evaluate_cc_run($test, $has_libjit, $verbose);
+ok( ! $has_libjit, "_evaluate_cc_run() returned false value, as expected" );
+ok( ! defined($step->result()), "result is undefined, as expected" );
+
+$step->set_result( undef );
+
+$test = q{USES INTERPRETER: 33};
+$has_libjit = 0;
+$verbose = 1;
+{
+    my ($stdout, $stderr);
+    capture(
+        sub { $has_libjit =
+            $step->_evaluate_cc_run($test, $has_libjit, $verbose); },
+        \$stdout,
+        \$stderr,
+    );
+    ok( $has_libjit, "_evaluate_cc_run() returned true value, as expected" );
+    is( $step->result(), 'yes', "result is yes, as expected" );
+    like( $stdout, qr/\(yes\)/, "Got expected verbose output" );
+}
+
+########## _handle_has_libjit() ##########
+
+my $extra_libs;
+
+$conf->data->set( 'libjit_has_alloca' => undef );
+$conf->data->set( 'libs' => '' );
+
+$has_libjit = 1;
+$extra_libs = 'mylibs';
+$conf->data->set( 'cpuarch' => 'i386' );
+
+auto::libjit::_handle_has_libjit($conf, $has_libjit, $extra_libs);
+ok( $conf->data->get( 'libjit_has_alloca'),
+    "on i386 with libJIT, 'libjit_has_alloca' has true value" );
+is( $conf->data->get( 'libs' ), " $extra_libs",
+    "Got expected value for libs" );
+
+$conf->data->set( 'libjit_has_alloca' => undef );
+$conf->data->set( 'libs' => '' );
+
+$has_libjit = 1;
+$extra_libs = 'mylibs';
+$conf->data->set( 'cpuarch' => 'ppc' );
+
+auto::libjit::_handle_has_libjit($conf, $has_libjit, $extra_libs);
+ok( ! $conf->data->get( 'libjit_has_alloca'),
+    "on non-i386 with libJIT, 'libjit_has_alloca' has false value" );
+is( $conf->data->get( 'libs' ), " $extra_libs",
+    "Got expected value for libs" );
+
+$conf->data->set( 'libjit_has_alloca' => undef );
+$conf->data->set( 'libs' => '' );
+
+$has_libjit = 0;
+$extra_libs = 'mylibs';
+
+auto::libjit::_handle_has_libjit($conf, $has_libjit, $extra_libs);
+ok( ! $conf->data->get( 'libjit_has_alloca'),
+    "without libJIT, 'libjit_has_alloca' has false value" );
+is( $conf->data->get( 'libs' ), "",
+    "Got expected value for libs" );
+
+################### DOCUMENTATION ###################
+
+=head1 NAME
+
+auto/libjit-01.t - test auto::libjit
+
+=head1 SYNOPSIS
+
+    % prove t/steps/auto/libjit-01.t
+
+=head1 DESCRIPTION
+
+The files in this directory test functionality used by F<Configure.pl>.
+
+The tests in this file test auto::libjit.
+
+=head1 SEE ALSO
+
+config::auto::libjit, F<Configure.pl>.
+
+=cut
+
+# Local Variables:
+#   mode: cperl
+#   cperl-indent-level: 4
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:

Added: branches/libjit_framebuilder/t/steps/gen/libjit-01.t
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/libjit_framebuilder/t/steps/gen/libjit-01.t	Fri Nov  6 19:11:03 2009	(r42314)
@@ -0,0 +1,112 @@
+#! perl
+# Copyright (C) 2009, Parrot Foundation.
+# $Id$
+# gen/libjit-01.t
+
+use strict;
+use warnings;
+
+use constant NUM_GENERATED_FILES => 2;
+# use Test::More tests => 8 + 2*NUM_GENERATED_FILES;
+use Test::More qw( no_plan );
+
+use File::Copy 'move';
+use File::Temp 'tempfile';
+
+use lib 'lib';
+use Parrot::Configure;
+use Parrot::Configure::Options 'process_options';
+use Parrot::Configure::Test qw(
+    test_step_thru_runstep
+    rerun_defaults_for_testing
+    test_step_constructor_and_description
+);
+
+use_ok('config::gen::libjit');
+
+my ($args, $step_list_ref) = process_options(
+    {
+	argv => [],
+	mode => 'configure',
+    }
+);
+
+my $conf = Parrot::Configure->new;
+
+my $serialized = $conf->pcfreeze();
+
+my $pkg = 'gen::libjit';
+$conf->add_steps($pkg);
+$conf->options->set( %$args );
+my $step = test_step_constructor_and_description($conf);
+
+is( scalar keys %{$step->{targets}}, NUM_GENERATED_FILES,
+    "Expected number of generated files");
+is_deeply([keys %{$step->{targets}}], [keys %{$step->{templates}}],
+    "Templates match targets");
+
+foreach (keys %{$step->{templates}}) {
+    ok(-f $step->{templates}{$_}, "Able to locate $_ template")
+}
+
+my %orig_files;
+foreach (keys %{$step->{targets}}) {
+    if (-f (my $targ_name = $step->{targets}{$_})) {
+        $orig_files{$_} = tempfile();
+        move($targ_name, $orig_files{$_});
+    }
+}
+
+my %orig_conf = map { $_ => $conf->data->get($_) } qw[ iv nv ];
+$conf->data->set( iv => 'int', nv => 'float' );
+# Set a value for 'libjit_has_alloca' to avoid uninitialized value warning.
+$conf->data->set( 'libjit_has_alloca' => 1 );
+my $ret = $step->runstep($conf);
+ok( $ret, "runstep() returned true value" );
+foreach (keys %{$step->{targets}}) {
+    ok(-f $step->{targets}{$_}, "$_ target generated");
+}
+
+# re-set for next test
+$conf->data->set(%orig_conf);
+$step->set_result( '' );
+foreach (keys %{$step->{targets}}) {
+    if (exists $orig_files{$_}) {
+        move( $orig_files{$_}, $step->{targets}{$_} );
+    } else {
+        unlink $_;
+    }
+}
+
+$conf->replenish($serialized);
+
+pass("Completed all tests in $0");
+
+################### DOCUMENTATION ###################
+
+=head1 NAME
+
+  gen/libjit-01.t - test gen::libjit
+
+=head1 SYNOPSIS
+
+    % prove t/steps/gen/libjit-01.t
+
+=head1 DESCRIPTION
+
+The files in this directory test functionality used by F<Configure.pl>.
+
+The tests in this file test gen::libjit.
+
+=head1 SEE ALSO
+
+config::gen::libjit, F<Configure.pl>.
+
+=cut
+
+# Local Variables:
+#   mode: cperl
+#   cperl-indent-level: 4
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:

Modified: branches/libjit_framebuilder/tools/build/nativecall.pl
==============================================================================
--- branches/libjit_framebuilder/tools/build/nativecall.pl	Fri Nov  6 18:47:52 2009	(r42313)
+++ branches/libjit_framebuilder/tools/build/nativecall.pl	Fri Nov  6 19:11:03 2009	(r42314)
@@ -30,6 +30,9 @@
 use strict;
 use warnings;
 
+use lib 'lib';
+use Parrot::NativeCall;
+
 my $opt_warndups = 0;
 
 # This file will eventually be compiled
@@ -37,64 +40,7 @@
 
 print_head( \@ARGV );
 
-
-my %sig_table = (
-    p => {
-        as_proto => "void *",
-        other_decl => "PMC * const final_destination = pmc_new(interp, enum_class_UnManagedStruct);",
-        sig_char => "P",
-        ret_assign => "VTABLE_set_pointer(interp, final_destination, return_data);\n    Parrot_pcc_fill_returns_from_c_args(interp, call_object, \"P\", final_destination);",
-    },
-    i => { as_proto => "int",    sig_char => "I" },
-    l => { as_proto => "long",   sig_char => "I" },
-    c => { as_proto => "char",   sig_char => "I" },
-    s => { as_proto => "short",  sig_char => "I" },
-    f => { as_proto => "float",  sig_char => "N" },
-    d => { as_proto => "double", sig_char => "N" },
-    t => { as_proto => "char *",
-           other_decl => "STRING *final_destination;",
-           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);",
-           sig_char => "S" },
-    v => { as_proto => "void",
-           return_type => "void *",
-           sig_char => "v",
-           ret_assign => "",
-           func_call_assign => ""
-         },
-    P => { as_proto => "PMC *", sig_char => "P" },
-    O => { as_proto => "PMC *", returns => "", sig_char => "Pi" },
-    J => { as_proto => "PARROT_INTERP", returns => "", sig_char => "" },
-    S => { as_proto => "STRING *", sig_char => "S" },
-    I => { as_proto => "INTVAL", sig_char => "I" },
-    N => { as_proto => "FLOATVAL", sig_char => "N" },
-    b => { as_proto => "void *", as_return => "", sig_char => "S" },
-    B => { as_proto => "char **", as_return => "", sig_char => "S" },
-    # These should be replaced by modifiers in the future
-    2 => { as_proto => "short *",  sig_char => "P", return_type => "short",
-           ret_assign => 'Parrot_pcc_fill_returns_from_c_args(interp, call_object, "I", return_data);' },
-    3 => { as_proto => "int *",  sig_char => "P", return_type => "int",
-           ret_assign => 'Parrot_pcc_fill_returns_from_c_args(interp, call_object, "I", return_data);' },
-    4 => { as_proto => "long *",  sig_char => "P", return_type => "long",
-           ret_assign => 'Parrot_pcc_fill_returns_from_c_args(interp, call_object, "I", return_data);' },
-    L => { as_proto => "long *", as_return => "" },
-    T => { as_proto => "char **", as_return => "" },
-    V => { as_proto => "void **", as_return => "", sig_char => "P" },
-    '@' => { as_proto => "PMC *", as_return => "", cname => "xAT_", sig_char => 'Ps' },
-);
-
-for (values %sig_table) {
-    if (not exists $_->{as_return}) { $_->{as_return} = $_->{as_proto} }
-    if (not exists $_->{return_type}) { $_->{return_type} = $_->{as_proto} }
-    if (not exists $_->{return_type_decl}) { $_->{return_type_decl} = $_->{return_type} }
-    if (not exists $_->{ret_assign} and exists $_->{sig_char}) {
-        $_->{ret_assign} = 'Parrot_pcc_fill_returns_from_c_args(interp, call_object, "'
-                           . $_->{sig_char} . '", return_data);';
-    }
-    if (not exists $_->{func_call_assign}) {
-        $_->{func_call_assign} = "return_data = "
-    }
-}
-
+my %sig_table = %Parrot::NativeCall::signature_table;
 
 my $temp_cnt = 0;
 my (@put_pointer, @put_pointer_nci_too, @nci_defs);
@@ -494,17 +440,13 @@
         return F2DPTR(VTABLE_get_pointer(interp, b));
     }
     else {
-        int jit_size;
-        void * const result = Parrot_jit_build_call_func(interp, pmc_nci, signature, &jit_size);
+        void *priv;
+        void * const result = Parrot_jit_build_call_func(interp, pmc_nci, signature, &priv);
         if (result) {
-            struct jit_buffer_private_data *priv;
             *jitted = 1;
             temp_pmc = pmc_new(interp, enum_class_ManagedStruct);
             VTABLE_set_pointer(interp, temp_pmc, (void *)result);
 #ifdef PARROT_HAS_EXEC_PROTECT
-            priv = (struct jit_buffer_private_data *)
-                mem_sys_allocate(sizeof(struct jit_buffer_private_data));
-            priv->size = jit_size;
             SETATTR_ManagedStruct_custom_free_func(interp, temp_pmc, Parrot_jit_free_buffer);
             SETATTR_ManagedStruct_custom_free_priv(interp, temp_pmc, priv);
             SETATTR_ManagedStruct_custom_clone_func(interp, temp_pmc, Parrot_jit_clone_buffer);


More information about the parrot-commits mailing list