Permalink
Browse files

Step 1 in changes to CompiledMethod

A slightly new marshaling for CompiledMethod.
  • Loading branch information...
1 parent 453b001 commit 18faa98fb00c97462128dc5cdeac567ac3498c9a @evanphx evanphx committed Nov 17, 2007
Showing with 293 additions and 8 deletions.
  1. +63 −6 shotgun/lib/cpu_marshal.c
  2. +194 −0 shotgun/lib/primitive_names.rb
  3. +36 −2 shotgun/lib/primitives.rb
View
@@ -12,6 +12,8 @@
#include <sys/stat.h>
#include <unistd.h>
+#include "primitive_util.h"
+
static OBJECT string_newfrombstr(STATE, bstring output)
{
return string_new2(state, bdata(output), blength(output));
@@ -312,16 +314,67 @@ static OBJECT unmarshal_iseq(STATE, struct marshal_state *ms) {
return obj;
}
-static void marshal_cmethod(STATE, OBJECT obj, bstring buf, struct marshal_state *ms) {
- marshal_fields_as(state, obj, buf, 'm', ms);
-}
-
static OBJECT unmarshal_cmethod(STATE, struct marshal_state *ms) {
int sz;
- OBJECT cm;
+ OBJECT cm, prim;
sz = unmarshal_num_fields(ms);
cm = cmethod_allocate(state);
unmarshal_into_fields(state, sz, cm, ms);
+
+ /* fixups */
+ prim = cmethod_get_primitive(cm);
+ if(SYMBOL_P(prim)) {
+ int idx = calc_primitive_index(state, symbol_to_string(state, prim));
+ sassert(idx >= 0);
+ cmethod_set_primitive(cm, I2N(idx));
+ } else if(NIL_P(prim)) {
+ cmethod_set_primitive(cm, I2N(-1));
+ }
+ return cm;
+}
+
+static void marshal_cmethod(STATE, OBJECT obj, bstring buf, struct marshal_state *ms) {
+
+ marshal_fields_as(state, obj, buf, 'm', ms);
+}
+
+static void marshal_cmethod2(STATE, OBJECT obj, bstring buf, struct marshal_state *ms) {
+
+ int i;
+ append_c('M');
+ /* rather than a size, we use a version id */
+ append_sz(1);
+
+ for(i = 0; i < 16; i++) {
+ marshal(state, NTH_FIELD(obj, i), buf, ms);
+ }
+}
+
+
+static OBJECT unmarshal_cmethod2(STATE, struct marshal_state *ms) {
+ int ver;
+ OBJECT cm, prim, o;
+
+ ver = unmarshal_num_fields(ms);
+ cm = cmethod_allocate(state);
+
+ unmarshal_into_fields(state, 16, cm, ms);
+
+ /* fixups */
+ prim = cmethod_get_primitive(cm);
+ if(SYMBOL_P(prim)) {
+ int idx = calc_primitive_index(state, symbol_to_string(state, prim));
+ sassert(idx >= 0);
+ cmethod_set_primitive(cm, I2N(idx));
+ } else if(NIL_P(prim)) {
+ cmethod_set_primitive(cm, I2N(-1));
+ }
+
+ o = cmethod_get_cache(cm);
+ if(FIXNUM_P(o)) {
+ cmethod_set_cache(cm, tuple_new(state, FIXNUM_TO_INT(o)));
+ }
+
return cm;
}
@@ -357,6 +410,10 @@ static OBJECT unmarshal(STATE, struct marshal_state *ms) {
o = unmarshal_cmethod(state, ms);
_add_object(o, ms);
break;
+ case 'M':
+ o = unmarshal_cmethod2(state, ms);
+ _add_object(o, ms);
+ break;
case 'B':
o = unmarshal_bignum(state, ms);
_add_object(o, ms);
@@ -413,7 +470,7 @@ static void marshal(STATE, OBJECT obj, bstring buf, struct marshal_state *ms) {
} else if(kls == state->global->tuple) {
marshal_tup(state, obj, buf, ms);
} else if(kls == state->global->cmethod) {
- marshal_cmethod(state, obj, buf, ms);
+ marshal_cmethod2(state, obj, buf, ms);
} else if(kls == state->global->bytearray) {
marshal_bytes(state, obj, buf);
} else if(kls == state->global->iseq) {
@@ -0,0 +1,194 @@
+module Bytecode
+ class Compiler
+ Primitives = [
+ :add,
+ :sub,
+ :equal,
+ :compare,
+ :at,
+ :put,
+ :fields,
+ :allocate,
+ :allocate_count,
+ :allocate_bytes,
+ nil, # was create_block
+ :block_given,
+ :block_call,
+ :string_to_sexp,
+ :load_file,
+ :io_write,
+ :io_read,
+ :fixnum_to_s,
+ :logical_class,
+ :object_id,
+ :hash_set,
+ :hash_get,
+ :hash_object,
+ :symbol_index,
+ :symbol_lookup,
+ :dup_into,
+ :fetch_bytes,
+ :compare_bytes,
+ :create_pipe,
+ :gettimeofday,
+ :strftime,
+ :bytes_dup_into,
+ :activate_as_script,
+ :stat_file,
+ :io_open,
+ :process_exit,
+ :io_close,
+ :object_equal,
+ :activate_context,
+ :context_sender,
+ :micro_sleep,
+ :fixnum_mul,
+ :bignum_to_s,
+ :bignum_add,
+ :bignum_sub,
+ :bignum_mul,
+ :bignum_equal,
+ :regexp_new,
+ nil,
+ :tuple_shifted,
+ :gc_start,
+ :file_to_sexp,
+ :get_byte,
+ :iseq_compile,
+ :task_raise,
+ :fixnum_modulo,
+ :bytearray_size,
+ :terminal_raw,
+ :terminal_normal,
+ :fixnum_div,
+ :marshal_object,
+ :unmarshal_object,
+ :marshal_to_file,
+ :unmarshal_from_file,
+ :archive_files,
+ :archive_get_file,
+ :archive_get_object,
+ :archive_add_file,
+ :archive_add_object,
+ :archive_delete_file,
+ :fixnum_and,
+ :object_dup,
+ :save_encloser_path,
+ :restore_encloser_path,
+ nil, # :float_add,
+ nil, # :float_sub,
+ nil, # :float_mul,
+ nil, # :float_equal,
+ :fixnum_size,
+ :file_unlink,
+ :fixnum_or,
+ :fixnum_xor,
+ :fixnum_invert,
+ :fixnum_neg,
+ :bignum_new,
+ :bignum_to_float,
+ :bignum_and,
+ :bignum_or,
+ :bignum_xor,
+ :bignum_neg,
+ :bignum_invert,
+ nil, # :float_nan_p,
+ nil, # :float_infinite_p,
+ nil, # :float_div,
+ nil, # :float_uminus,
+ :bignum_div,
+ nil, # :float_pow,
+ nil, # :float_to_i,
+ :numeric_coerce,
+ :hash_delete,
+ :bignum_compare,
+ nil, # :float_compare,
+ :fixnum_to_f,
+ :string_to_f,
+ nil, # :float_divmod,
+ :fixnum_divmod,
+ :set_byte,
+ nil, # :float_round,
+ :find_method,
+ :bignum_left_shift,
+ :bignum_right_shift,
+ :bignum_divmod,
+ :regexp_options,
+ :object_untaint,
+ :object_taint,
+ :object_tainted_p,
+ :object_freeze,
+ :object_frozen_p,
+ :fastctx_get_field,
+ nil,
+ :fixnum_right_shift,
+ :fixnum_left_shift,
+ :vm_stats,
+ :nmethod_call,
+ :load_library,
+ :dir_glob,
+ :dir_chdir,
+ nil, # :float_sprintf,
+ :make_weak_ref,
+ :fastctx_set_field,
+ :fastctx_dup,
+ :gc_collect_references,
+ :task_dup,
+ :task_set_current,
+ :task_associate,
+ :task_current,
+ :task_at,
+ :channel_new,
+ :channel_send,
+ :channel_receive,
+ :thread_new,
+ :thread_run,
+ :thread_current,
+ :thread_schedule,
+ :thread_yield,
+ :object_become,
+ :channel_send_in_microseconds,
+ :channel_send_on_readable,
+ :channel_send_on_writable,
+ :channel_send_on_signal,
+ :channel_receive_many,
+ :sampler_activate,
+ :sampler_stop,
+ :replace_process,
+ :fork_process,
+ :channel_send_on_stopped,
+ :io_reopen,
+ :hash_value_set,
+ :ivar_set,
+ :ivar_get,
+ :ivars_get,
+ :str_crypt,
+ :nfunc_call,
+ :nfunc_add,
+ :nfunc_call_object,
+ :env_get,
+ :env_set,
+ nil,
+ :env_as_hash,
+ :task_set_debugging,
+ :mktime,
+ :time_switch,
+ :bignum_size,
+ :reset_method_cache,
+ nil,
+ :regexp_match_region,
+ :bignum_from_float
+ ]
+
+ FirstRuntimePrimitive = 1024
+
+ RuntimePrimitives = [
+ :set_ivar,
+ :get_ivar,
+ :set_index,
+ :get_index,
+ :dispatch_as_method
+ ]
+
+ end
+end
View
@@ -1,4 +1,4 @@
-require File.dirname(__FILE__) + '/../../compiler/bytecode/primitive_names'
+require File.dirname(__FILE__) + '/primitive_names'
require File.dirname(__FILE__) + '/primitive_generator'
class ShotgunPrimitives
@@ -33,6 +33,9 @@ def generate_select(fd, op="prim")
i += 1
end
+ fd.puts "default:"
+ fd.puts 'printf("Error: Primitive index out of range for this VM\n");'
+ fd.puts "sassert(0);"
fd.puts "}"
fd.puts
@@ -56,7 +59,7 @@ def generate_select(fd, op="prim")
f.puts "default:"
f.puts 'printf("Error: Primitive index out of range for this VM\n");'
- f.puts "abort();"
+ f.puts "sassert(0);"
f.puts "}"
f.puts
end
@@ -71,6 +74,37 @@ def generate_select(fd, op="prim")
f.puts "#define CPU_PRIMITIVE_#{name.to_s.upcase} #{i}"
i += 1
end
+
+ end
+
+ File.open("primitive_util.h", "w") do |f|
+ size = Bytecode::Compiler::Primitives.size
+ f.puts "struct prim2index { char *name; int index; };"
+ f.puts
+ f.puts "static int calc_primitive_index(STATE, OBJECT str) {"
+ f.puts " static struct prim2index pi[] = {"
+
+ i = 1
+ Bytecode::Compiler::Primitives.each do |name|
+ unless name
+ i += 1
+ next
+ end
+ f.puts %Q! { "#{name}", #{i} },!
+ i += 1
+ end
+
+ f.puts " { NULL, 0 } };"
+ f.puts <<-CODE
+ int i;
+ char *target = string_byte_address(state, str);
+ for(i = 0; pi[i].name; i++) {
+ if(!strcmp(target, pi[i].name)) return pi[i].index;
+ }
+
+ return -1;
+ }
+ CODE
end
end

0 comments on commit 18faa98

Please sign in to comment.