johnson 1.1.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +12 -0
 - data/Manifest.txt +6 -4
 - data/README.rdoc +2 -8
 - data/Rakefile +11 -11
 - data/bin/johnson +1 -3
 - data/ext/spidermonkey/context.c +3 -2
 - data/ext/spidermonkey/conversions.c +61 -27
 - data/ext/spidermonkey/conversions.h +13 -0
 - data/ext/spidermonkey/debugger.c +13 -5
 - data/ext/spidermonkey/debugger.h +1 -0
 - data/ext/spidermonkey/extconf.rb +2 -3
 - data/ext/spidermonkey/jroot.h +11 -1
 - data/ext/spidermonkey/js_land_proxy.c +21 -11
 - data/ext/spidermonkey/ruby_land_proxy.c +116 -41
 - data/ext/spidermonkey/ruby_land_proxy.h +21 -0
 - data/ext/spidermonkey/runtime.c +85 -19
 - data/ext/spidermonkey/runtime.h +2 -0
 - data/ext/spidermonkey/spidermonkey.c +3 -1
 - data/lib/johnson.rb +19 -27
 - data/lib/johnson/cli.rb +2 -1
 - data/{js/johnson → lib/johnson/js}/cli.js +0 -0
 - data/lib/johnson/js/core.js +34 -0
 - data/lib/johnson/js/prelude.js +149 -0
 - data/lib/johnson/ruby_land_proxy.rb +113 -0
 - data/lib/johnson/runtime.rb +92 -33
 - data/lib/johnson/spidermonkey.rb +12 -0
 - data/lib/johnson/spidermonkey/js_land_proxy.rb +10 -8
 - data/lib/johnson/spidermonkey/ruby_land_proxy.rb +10 -47
 - data/lib/johnson/spidermonkey/runtime.rb +11 -31
 - data/test/johnson/conversions/array_test.rb +41 -3
 - data/test/johnson/conversions/string_test.rb +12 -0
 - data/test/johnson/custom_conversions_test.rb +50 -0
 - data/test/johnson/prelude_test.rb +23 -0
 - data/test/johnson/runtime_test.rb +82 -2
 - data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +17 -1
 - data/test/johnson/spidermonkey/runtime_test.rb +24 -0
 - data/vendor/spidermonkey/jsprf.c +2 -0
 - metadata +22 -9
 - data/js/johnson/prelude.js +0 -80
 - data/lib/johnson/version.rb +0 -3
 - data/lib/rails/init.rb +0 -37
 
| 
         @@ -559,17 +559,22 @@ static void finalize(JSContext* js_context, JSObject* obj) 
     | 
|
| 
       559 
559 
     | 
    
         | 
| 
       560 
560 
     | 
    
         
             
            JSBool make_js_land_proxy(JohnsonRuntime* runtime, VALUE value, jsval* retval)
         
     | 
| 
       561 
561 
     | 
    
         
             
            {
         
     | 
| 
       562 
     | 
    
         
            -
               
     | 
| 
       563 
     | 
    
         
            -
             
     | 
| 
       564 
     | 
    
         
            -
               
     | 
| 
      
 562 
     | 
    
         
            +
              jsval base_value = (jsval)JS_HashTableLookup(runtime->rbids, (void *)value);
         
     | 
| 
      
 563 
     | 
    
         
            +
             
     | 
| 
      
 564 
     | 
    
         
            +
              JSContext * context = johnson_get_current_context(runtime);
         
     | 
| 
      
 565 
     | 
    
         
            +
              PREPARE_JROOTS(context, 2);
         
     | 
| 
      
 566 
     | 
    
         
            +
             
     | 
| 
      
 567 
     | 
    
         
            +
              jsval johnson = JSVAL_NULL;
         
     | 
| 
      
 568 
     | 
    
         
            +
              JCHECK(evaluate_js_property_expression(runtime, "Johnson", &johnson));
         
     | 
| 
      
 569 
     | 
    
         
            +
              JROOT(johnson);
         
     | 
| 
      
 570 
     | 
    
         
            +
             
     | 
| 
      
 571 
     | 
    
         
            +
              if (base_value)
         
     | 
| 
       565 
572 
     | 
    
         
             
              {
         
     | 
| 
       566 
     | 
    
         
            -
                 
     | 
| 
      
 573 
     | 
    
         
            +
                JCHECK(JS_CallFunctionName(context, johnson, "applyConversions", 1, &base_value, retval));
         
     | 
| 
      
 574 
     | 
    
         
            +
                JRETURN;
         
     | 
| 
       567 
575 
     | 
    
         
             
              }
         
     | 
| 
       568 
576 
     | 
    
         
             
              else
         
     | 
| 
       569 
577 
     | 
    
         
             
              {
         
     | 
| 
       570 
     | 
    
         
            -
                JSContext * context = johnson_get_current_context(runtime);
         
     | 
| 
       571 
     | 
    
         
            -
                PREPARE_JROOTS(context, 1);
         
     | 
| 
       572 
     | 
    
         
            -
             
     | 
| 
       573 
578 
     | 
    
         
             
                JSObject *jsobj;
         
     | 
| 
       574 
579 
     | 
    
         | 
| 
       575 
580 
     | 
    
         
             
                JSClass *klass = &JSLandProxyClass;
         
     | 
| 
         @@ -596,15 +601,20 @@ JSBool make_js_land_proxy(JohnsonRuntime* runtime, VALUE value, jsval* retval) 
     | 
|
| 
       596 
601 
     | 
    
         
             
                JCHECK(JS_DefineFunction(context, jsobj, "toArray", to_array, 0, 0));
         
     | 
| 
       597 
602 
     | 
    
         
             
                JCHECK(JS_DefineFunction(context, jsobj, "toString", to_string, 0, 0));
         
     | 
| 
       598 
603 
     | 
    
         | 
| 
       599 
     | 
    
         
            -
                 
     | 
| 
      
 604 
     | 
    
         
            +
                base_value = OBJECT_TO_JSVAL(jsobj);
         
     | 
| 
       600 
605 
     | 
    
         | 
| 
       601 
     | 
    
         
            -
                // put the proxy OID in the id map
         
     | 
| 
       602 
     | 
    
         
            -
                JCHECK(JS_HashTableAdd(runtime->rbids, (void *)value, (void *)(*retval)));
         
     | 
| 
       603 
     | 
    
         
            -
                
         
     | 
| 
       604 
606 
     | 
    
         
             
                // root the ruby value for GC
         
     | 
| 
       605 
607 
     | 
    
         
             
                VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(runtime->js);
         
     | 
| 
       606 
608 
     | 
    
         
             
                rb_funcall(ruby_runtime, rb_intern("add_gcthing"), 1, value);
         
     | 
| 
       607 
609 
     | 
    
         | 
| 
      
 610 
     | 
    
         
            +
                jsval wrapped_value = JSVAL_NULL;
         
     | 
| 
      
 611 
     | 
    
         
            +
                JCHECK(JS_CallFunctionName(context, johnson, "applyWrappers", 1, &base_value, &wrapped_value));
         
     | 
| 
      
 612 
     | 
    
         
            +
             
     | 
| 
      
 613 
     | 
    
         
            +
                // put the proxy OID in the id map
         
     | 
| 
      
 614 
     | 
    
         
            +
                JCHECK(JS_HashTableAdd(runtime->rbids, (void *)value, (void *)(wrapped_value)));
         
     | 
| 
      
 615 
     | 
    
         
            +
                
         
     | 
| 
      
 616 
     | 
    
         
            +
                JCHECK(JS_CallFunctionName(context, johnson, "applyConversions", 1, &wrapped_value, retval));
         
     | 
| 
      
 617 
     | 
    
         
            +
             
     | 
| 
       608 
618 
     | 
    
         
             
                JRETURN;
         
     | 
| 
       609 
619 
     | 
    
         
             
              }
         
     | 
| 
       610 
620 
     | 
    
         
             
            }
         
     | 
| 
         @@ -7,7 +7,16 @@ DEFINE_RUBY_WRAPPER(rb_call_super, rb_call_super, ARGLIST2(argc, argv)) 
     | 
|
| 
       7 
7 
     | 
    
         
             
            DECLARE_RUBY_WRAPPER(rb_yield, VALUE v)
         
     | 
| 
       8 
8 
     | 
    
         
             
            DEFINE_RUBY_WRAPPER(rb_yield, rb_yield, ARGLIST1(v))
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
      
 10 
     | 
    
         
            +
            DECLARE_RUBY_WRAPPER(rb_check_type, VALUE o; int t)
         
     | 
| 
      
 11 
     | 
    
         
            +
            DEFINE_VOID_RUBY_WRAPPER(rb_check_type, rb_check_type, ARGLIST2(o, t))
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            DEFINE_RUBY_WRAPPER(rb_string_value, rb_string_value, ARGLIST1(v))
         
     | 
| 
      
 14 
     | 
    
         
            +
            DEFINE_VOID_RUBY_WRAPPER(rb_string_value_cstr, rb_string_value_cstr, ARGLIST1(v))
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            DEFINE_RUBY_WRAPPER(make_ruby_land_proxy, make_ruby_land_proxy, ARGLIST3(runtime, value, root_name))
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
       10 
18 
     | 
    
         
             
            static VALUE proxy_class = Qnil;
         
     | 
| 
      
 19 
     | 
    
         
            +
            static VALUE script_class = Qnil;
         
     | 
| 
       11 
20 
     | 
    
         | 
| 
       12 
21 
     | 
    
         
             
            static inline JSBool get_jsval_for_proxy(RubyLandProxy* proxy, jsval* jv)
         
     | 
| 
       13 
22 
     | 
    
         
             
            {
         
     | 
| 
         @@ -45,7 +54,8 @@ static VALUE call_js_function_value(JohnsonRuntime* runtime, jsval target, jsval 
     | 
|
| 
       45 
54 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       46 
55 
     | 
    
         
             
             *   [](name)
         
     | 
| 
       47 
56 
     | 
    
         
             
             *
         
     | 
| 
       48 
     | 
    
         
            -
             *  
     | 
| 
      
 57 
     | 
    
         
            +
             * Retrieves the current value of the +name+ property of this JavaScript
         
     | 
| 
      
 58 
     | 
    
         
            +
             * object.
         
     | 
| 
       49 
59 
     | 
    
         
             
             */
         
     | 
| 
       50 
60 
     | 
    
         
             
            static VALUE
         
     | 
| 
       51 
61 
     | 
    
         
             
            get(VALUE self, VALUE name)
         
     | 
| 
         @@ -67,8 +77,10 @@ get(VALUE self, VALUE name) 
     | 
|
| 
       67 
77 
     | 
    
         
             
                  JCHECK(JS_GetElement(context,
         
     | 
| 
       68 
78 
     | 
    
         
             
                      JSVAL_TO_OBJECT(proxy_value), (jsint)(NUM2INT(name)), &js_value));
         
     | 
| 
       69 
79 
     | 
    
         
             
                  break;
         
     | 
| 
      
 80 
     | 
    
         
            +
                case T_SYMBOL:
         
     | 
| 
      
 81 
     | 
    
         
            +
                  name = RB_FUNCALL_0(name, RB_INTERN("to_s"));
         
     | 
| 
       70 
82 
     | 
    
         
             
                default:
         
     | 
| 
       71 
     | 
    
         
            -
                   
     | 
| 
      
 83 
     | 
    
         
            +
                  CALL_RUBY_WRAPPER(rb_string_value_cstr, &name);
         
     | 
| 
       72 
84 
     | 
    
         
             
                  JCHECK(JS_GetProperty(context,
         
     | 
| 
       73 
85 
     | 
    
         
             
                      JSVAL_TO_OBJECT(proxy_value), StringValueCStr(name), &js_value));
         
     | 
| 
       74 
86 
     | 
    
         
             
                  break;
         
     | 
| 
         @@ -79,9 +91,9 @@ get(VALUE self, VALUE name) 
     | 
|
| 
       79 
91 
     | 
    
         | 
| 
       80 
92 
     | 
    
         
             
            /*
         
     | 
| 
       81 
93 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       82 
     | 
    
         
            -
             *   []=(name,value)
         
     | 
| 
      
 94 
     | 
    
         
            +
             *   []=(name, value)
         
     | 
| 
       83 
95 
     | 
    
         
             
             *
         
     | 
| 
       84 
     | 
    
         
            -
             * Sets  
     | 
| 
      
 96 
     | 
    
         
            +
             * Sets this JavaScript object's +name+ property to +value+.
         
     | 
| 
       85 
97 
     | 
    
         
             
             */
         
     | 
| 
       86 
98 
     | 
    
         
             
            static VALUE
         
     | 
| 
       87 
99 
     | 
    
         
             
            set(VALUE self, VALUE name, VALUE value)
         
     | 
| 
         @@ -106,8 +118,10 @@ set(VALUE self, VALUE name, VALUE value) 
     | 
|
| 
       106 
118 
     | 
    
         
             
                  JCHECK(JS_SetElement(context,
         
     | 
| 
       107 
119 
     | 
    
         
             
                          JSVAL_TO_OBJECT(proxy_value), (jsint)(NUM2INT(name)), &js_value));
         
     | 
| 
       108 
120 
     | 
    
         
             
                  break;
         
     | 
| 
      
 121 
     | 
    
         
            +
                case T_SYMBOL:
         
     | 
| 
      
 122 
     | 
    
         
            +
                  name = RB_FUNCALL_0(name, RB_INTERN("to_s"));
         
     | 
| 
       109 
123 
     | 
    
         
             
                default:
         
     | 
| 
       110 
     | 
    
         
            -
                   
     | 
| 
      
 124 
     | 
    
         
            +
                  CALL_RUBY_WRAPPER(rb_string_value_cstr, &name);
         
     | 
| 
       111 
125 
     | 
    
         
             
                  JCHECK(JS_SetProperty(context,
         
     | 
| 
       112 
126 
     | 
    
         
             
                        JSVAL_TO_OBJECT(proxy_value), StringValueCStr(name), &js_value));
         
     | 
| 
       113 
127 
     | 
    
         
             
                  break;
         
     | 
| 
         @@ -118,9 +132,9 @@ set(VALUE self, VALUE name, VALUE value) 
     | 
|
| 
       118 
132 
     | 
    
         | 
| 
       119 
133 
     | 
    
         
             
            /*
         
     | 
| 
       120 
134 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       121 
     | 
    
         
            -
             *   function?
         
     | 
| 
      
 135 
     | 
    
         
            +
             *   function?()
         
     | 
| 
       122 
136 
     | 
    
         
             
             *
         
     | 
| 
       123 
     | 
    
         
            -
             * Returns <code>true</code> if this is a function.
         
     | 
| 
      
 137 
     | 
    
         
            +
             * Returns <code>true</code> if this JavaScript object is a function.
         
     | 
| 
       124 
138 
     | 
    
         
             
             */
         
     | 
| 
       125 
139 
     | 
    
         
             
            static VALUE
         
     | 
| 
       126 
140 
     | 
    
         
             
            function_p(VALUE self)
         
     | 
| 
         @@ -135,11 +149,18 @@ function_p(VALUE self) 
     | 
|
| 
       135 
149 
     | 
    
         
             
              JRETURN_RUBY(JS_TypeOfValue(context, proxy_value) == JSTYPE_FUNCTION ? Qtrue : Qfalse);
         
     | 
| 
       136 
150 
     | 
    
         
             
            }
         
     | 
| 
       137 
151 
     | 
    
         | 
| 
      
 152 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 153 
     | 
    
         
            +
            callable_test_p(VALUE self, VALUE proxy)
         
     | 
| 
      
 154 
     | 
    
         
            +
            {
         
     | 
| 
      
 155 
     | 
    
         
            +
              return function_p(proxy);
         
     | 
| 
      
 156 
     | 
    
         
            +
            }
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
       138 
158 
     | 
    
         
             
            /*
         
     | 
| 
       139 
159 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       140 
160 
     | 
    
         
             
             *   respond_to?(symbol)
         
     | 
| 
       141 
161 
     | 
    
         
             
             *
         
     | 
| 
       142 
     | 
    
         
            -
             * Returns <code>true</code> if  
     | 
| 
      
 162 
     | 
    
         
            +
             * Returns <code>true</code> if this JavaScript object responds to the
         
     | 
| 
      
 163 
     | 
    
         
            +
             * named method.
         
     | 
| 
       143 
164 
     | 
    
         
             
             */
         
     | 
| 
       144 
165 
     | 
    
         
             
            static VALUE
         
     | 
| 
       145 
166 
     | 
    
         
             
            respond_to_p(int argc, const VALUE* argv, VALUE self)
         
     | 
| 
         @@ -178,9 +199,10 @@ respond_to_p(int argc, const VALUE* argv, VALUE self) 
     | 
|
| 
       178 
199 
     | 
    
         | 
| 
       179 
200 
     | 
    
         
             
            /*
         
     | 
| 
       180 
201 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       181 
     | 
    
         
            -
             *   native_call( 
     | 
| 
      
 202 
     | 
    
         
            +
             *   native_call(this, *args)
         
     | 
| 
       182 
203 
     | 
    
         
             
             *
         
     | 
| 
       183 
     | 
    
         
            -
             * Call as a function with given + 
     | 
| 
      
 204 
     | 
    
         
            +
             * Call this Ruby Object as a function, with the given +this+ object and
         
     | 
| 
      
 205 
     | 
    
         
            +
             * arguments. Equivalent to the call method in JavaScript.
         
     | 
| 
       184 
206 
     | 
    
         
             
             */
         
     | 
| 
       185 
207 
     | 
    
         
             
            static VALUE
         
     | 
| 
       186 
208 
     | 
    
         
             
            native_call(int argc, VALUE* argv, VALUE self)
         
     | 
| 
         @@ -217,9 +239,12 @@ destroy_id_array(JSContext* context, void* data) 
     | 
|
| 
       217 
239 
     | 
    
         | 
| 
       218 
240 
     | 
    
         
             
            /*
         
     | 
| 
       219 
241 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       220 
     | 
    
         
            -
             *   each { | 
     | 
| 
      
 242 
     | 
    
         
            +
             *   each {| element | block }
         
     | 
| 
      
 243 
     | 
    
         
            +
             *   each {| name, value | block }
         
     | 
| 
       221 
244 
     | 
    
         
             
             *
         
     | 
| 
       222 
     | 
    
         
            -
             * Calls <em>block</em> with each item in  
     | 
| 
      
 245 
     | 
    
         
            +
             * Calls <em>block</em> with each item in this JavaScript array, or with
         
     | 
| 
      
 246 
     | 
    
         
            +
             * each +name+/+value+ pair (like a Hash) for any other JavaScript
         
     | 
| 
      
 247 
     | 
    
         
            +
             * object.
         
     | 
| 
       223 
248 
     | 
    
         
             
             */
         
     | 
| 
       224 
249 
     | 
    
         
             
            static VALUE
         
     | 
| 
       225 
250 
     | 
    
         
             
            each(VALUE self)
         
     | 
| 
         @@ -248,7 +273,7 @@ each(VALUE self) 
     | 
|
| 
       248 
273 
     | 
    
         
             
                {
         
     | 
| 
       249 
274 
     | 
    
         
             
                  jsval element;
         
     | 
| 
       250 
275 
     | 
    
         
             
                  JCHECK(JS_GetElement(context, value, (signed) i, &element));
         
     | 
| 
       251 
     | 
    
         
            -
                  CALL_RUBY_WRAPPER(rb_yield,  
     | 
| 
      
 276 
     | 
    
         
            +
                  CALL_RUBY_WRAPPER(rb_yield, CONVERT_TO_RUBY(proxy->runtime, element));
         
     | 
| 
       252 
277 
     | 
    
         
             
                }
         
     | 
| 
       253 
278 
     | 
    
         
             
              }
         
     | 
| 
       254 
279 
     | 
    
         
             
              else
         
     | 
| 
         @@ -296,9 +321,10 @@ each(VALUE self) 
     | 
|
| 
       296 
321 
     | 
    
         | 
| 
       297 
322 
     | 
    
         
             
            /*
         
     | 
| 
       298 
323 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       299 
     | 
    
         
            -
             *   length
         
     | 
| 
      
 324 
     | 
    
         
            +
             *   length()
         
     | 
| 
       300 
325 
     | 
    
         
             
             *
         
     | 
| 
       301 
     | 
    
         
            -
             * Returns the  
     | 
| 
      
 326 
     | 
    
         
            +
             * Returns the number of entries in the JavaScript array, or the number
         
     | 
| 
      
 327 
     | 
    
         
            +
             * of properties on the JavaScript object.
         
     | 
| 
       302 
328 
     | 
    
         
             
             */
         
     | 
| 
       303 
329 
     | 
    
         
             
            static VALUE
         
     | 
| 
       304 
330 
     | 
    
         
             
            length(VALUE self)
         
     | 
| 
         @@ -337,9 +363,10 @@ length(VALUE self) 
     | 
|
| 
       337 
363 
     | 
    
         | 
| 
       338 
364 
     | 
    
         
             
            /*
         
     | 
| 
       339 
365 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       340 
     | 
    
         
            -
             *   runtime
         
     | 
| 
      
 366 
     | 
    
         
            +
             *   runtime()
         
     | 
| 
       341 
367 
     | 
    
         
             
             *
         
     | 
| 
       342 
     | 
    
         
            -
             * Returns  
     | 
| 
      
 368 
     | 
    
         
            +
             * Returns the Johnson::SpiderMonkey::Runtime against which this object
         
     | 
| 
      
 369 
     | 
    
         
            +
             * is registered.
         
     | 
| 
       343 
370 
     | 
    
         
             
             */
         
     | 
| 
       344 
371 
     | 
    
         
             
            static VALUE
         
     | 
| 
       345 
372 
     | 
    
         
             
            runtime(VALUE self)
         
     | 
| 
         @@ -353,13 +380,17 @@ runtime(VALUE self) 
     | 
|
| 
       353 
380 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       354 
381 
     | 
    
         
             
             *   function_property?(name)
         
     | 
| 
       355 
382 
     | 
    
         
             
             *
         
     | 
| 
       356 
     | 
    
         
            -
             * Returns <code>true</code> if +name+  
     | 
| 
      
 383 
     | 
    
         
            +
             * Returns <code>true</code> if this JavaScript object's +name+ property
         
     | 
| 
      
 384 
     | 
    
         
            +
             * is a function.
         
     | 
| 
       357 
385 
     | 
    
         
             
             */
         
     | 
| 
       358 
386 
     | 
    
         
             
            static VALUE
         
     | 
| 
       359 
387 
     | 
    
         
             
            function_property_p(VALUE self, VALUE name)
         
     | 
| 
       360 
388 
     | 
    
         
             
            {
         
     | 
| 
       361 
     | 
    
         
            -
               
     | 
| 
       362 
     | 
    
         
            -
             
     | 
| 
      
 389 
     | 
    
         
            +
              if (TYPE(name) == T_SYMBOL)
         
     | 
| 
      
 390 
     | 
    
         
            +
                name = rb_funcall(name, rb_intern("to_s"), 0);
         
     | 
| 
      
 391 
     | 
    
         
            +
             
     | 
| 
      
 392 
     | 
    
         
            +
              rb_string_value_cstr(&name);
         
     | 
| 
      
 393 
     | 
    
         
            +
             
     | 
| 
       363 
394 
     | 
    
         
             
              RubyLandProxy* proxy;
         
     | 
| 
       364 
395 
     | 
    
         
             
              Data_Get_Struct(self, RubyLandProxy, proxy);
         
     | 
| 
       365 
396 
     | 
    
         
             
              JSContext * context = johnson_get_current_context(proxy->runtime);
         
     | 
| 
         @@ -386,7 +417,11 @@ function_property_p(VALUE self, VALUE name) 
     | 
|
| 
       386 
417 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       387 
418 
     | 
    
         
             
             *   call_function_property(name, arguments)
         
     | 
| 
       388 
419 
     | 
    
         
             
             *
         
     | 
| 
       389 
     | 
    
         
            -
             * Calls  
     | 
| 
      
 420 
     | 
    
         
            +
             * Calls this JavaScript object's +name+ method, passing the given
         
     | 
| 
      
 421 
     | 
    
         
            +
             * arguments.
         
     | 
| 
      
 422 
     | 
    
         
            +
             *
         
     | 
| 
      
 423 
     | 
    
         
            +
             * Equivalent to:
         
     | 
| 
      
 424 
     | 
    
         
            +
             *    proxy[name].native_call(proxy, *arguments)
         
     | 
| 
       390 
425 
     | 
    
         
             
             */
         
     | 
| 
       391 
426 
     | 
    
         
             
            static VALUE
         
     | 
| 
       392 
427 
     | 
    
         
             
            call_function_property(int argc, VALUE* argv, VALUE self)
         
     | 
| 
         @@ -405,26 +440,30 @@ call_function_property(int argc, VALUE* argv, VALUE self) 
     | 
|
| 
       405 
440 
     | 
    
         
             
              JROOT(proxy_value);
         
     | 
| 
       406 
441 
     | 
    
         | 
| 
       407 
442 
     | 
    
         
             
              jsval function;
         
     | 
| 
      
 443 
     | 
    
         
            +
             
     | 
| 
      
 444 
     | 
    
         
            +
              VALUE name = argv[0];
         
     | 
| 
      
 445 
     | 
    
         
            +
              CALL_RUBY_WRAPPER(rb_string_value_cstr, &name);
         
     | 
| 
       408 
446 
     | 
    
         | 
| 
       409 
447 
     | 
    
         
             
              JCHECK(JS_GetProperty(context,
         
     | 
| 
       410 
     | 
    
         
            -
                JSVAL_TO_OBJECT(proxy_value), StringValueCStr( 
     | 
| 
      
 448 
     | 
    
         
            +
                JSVAL_TO_OBJECT(proxy_value), StringValueCStr(name), &function));
         
     | 
| 
       411 
449 
     | 
    
         | 
| 
       412 
450 
     | 
    
         
             
              JROOT(function);
         
     | 
| 
       413 
451 
     | 
    
         | 
| 
       414 
     | 
    
         
            -
              JSType funtype = JS_TypeOfValue(context, function);
         
     | 
| 
       415 
     | 
    
         
            -
              
         
     | 
| 
       416 
452 
     | 
    
         
             
              // should never be anything but a function
         
     | 
| 
       417 
     | 
    
         
            -
              if ( 
     | 
| 
       418 
     | 
    
         
            -
                JERROR("Specified property \"%s\" isn't a function.", StringValueCStr( 
     | 
| 
      
 453 
     | 
    
         
            +
              if (!JS_ObjectIsFunction(context, function))
         
     | 
| 
      
 454 
     | 
    
         
            +
                JERROR("Specified property \"%s\" isn't a function.", StringValueCStr(name));
         
     | 
| 
      
 455 
     | 
    
         
            +
             
     | 
| 
      
 456 
     | 
    
         
            +
              REMOVE_JROOTS;
         
     | 
| 
       419 
457 
     | 
    
         | 
| 
       420 
     | 
    
         
            -
               
     | 
| 
      
 458 
     | 
    
         
            +
              return call_js_function_value(proxy->runtime, proxy_value, function, argc - 1, &(argv[1]));
         
     | 
| 
       421 
459 
     | 
    
         
             
            }
         
     | 
| 
       422 
460 
     | 
    
         | 
| 
       423 
461 
     | 
    
         
             
            /*
         
     | 
| 
       424 
462 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       425 
     | 
    
         
            -
             *   to_s
         
     | 
| 
      
 463 
     | 
    
         
            +
             *   to_s()
         
     | 
| 
       426 
464 
     | 
    
         
             
             *
         
     | 
| 
       427 
     | 
    
         
            -
             * Converts object to a string 
     | 
| 
      
 465 
     | 
    
         
            +
             * Converts the JavaScript object to a string, using its toString method
         
     | 
| 
      
 466 
     | 
    
         
            +
             * if available.
         
     | 
| 
       428 
467 
     | 
    
         
             
             */
         
     | 
| 
       429 
468 
     | 
    
         
             
            static VALUE to_s(VALUE self)
         
     | 
| 
       430 
469 
     | 
    
         
             
            {
         
     | 
| 
         @@ -439,7 +478,7 @@ static VALUE to_s(VALUE self) 
     | 
|
| 
       439 
478 
     | 
    
         
             
              JROOT(proxy_value);
         
     | 
| 
       440 
479 
     | 
    
         | 
| 
       441 
480 
     | 
    
         
             
              JSString* str = JS_ValueToString(context, proxy_value);
         
     | 
| 
       442 
     | 
    
         
            -
              JRETURN_RUBY( 
     | 
| 
      
 481 
     | 
    
         
            +
              JRETURN_RUBY(CONVERT_JS_STRING_TO_RUBY(proxy->runtime, str));
         
     | 
| 
       443 
482 
     | 
    
         
             
            }
         
     | 
| 
       444 
483 
     | 
    
         | 
| 
       445 
484 
     | 
    
         
             
            ///////////////////////////////////////////////////////////////////////////
         
     | 
| 
         @@ -468,7 +507,26 @@ static void finalize(RubyLandProxy* proxy) 
     | 
|
| 
       468 
507 
     | 
    
         | 
| 
       469 
508 
     | 
    
         
             
            bool ruby_value_is_proxy(VALUE maybe_proxy)
         
     | 
| 
       470 
509 
     | 
    
         
             
            {
         
     | 
| 
       471 
     | 
    
         
            -
              return  
     | 
| 
      
 510 
     | 
    
         
            +
              return rb_obj_is_kind_of(maybe_proxy, proxy_class);
         
     | 
| 
      
 511 
     | 
    
         
            +
            }
         
     | 
| 
      
 512 
     | 
    
         
            +
             
     | 
| 
      
 513 
     | 
    
         
            +
            bool ruby_value_is_script_proxy(VALUE maybe_proxy)
         
     | 
| 
      
 514 
     | 
    
         
            +
            {
         
     | 
| 
      
 515 
     | 
    
         
            +
              return rb_obj_is_kind_of(maybe_proxy, script_class);
         
     | 
| 
      
 516 
     | 
    
         
            +
            }
         
     | 
| 
      
 517 
     | 
    
         
            +
             
     | 
| 
      
 518 
     | 
    
         
            +
            VALUE apply_wrappers(VALUE proxy)
         
     | 
| 
      
 519 
     | 
    
         
            +
            {
         
     | 
| 
      
 520 
     | 
    
         
            +
              VALUE johnson = rb_const_get(rb_mKernel, rb_intern("Johnson"));
         
     | 
| 
      
 521 
     | 
    
         
            +
              VALUE johnson_proxy = rb_const_get(johnson, rb_intern("RubyLandProxy"));
         
     | 
| 
      
 522 
     | 
    
         
            +
              return rb_funcall(johnson_proxy, rb_intern("apply_wrappers"), 1, proxy);
         
     | 
| 
      
 523 
     | 
    
         
            +
            }
         
     | 
| 
      
 524 
     | 
    
         
            +
             
     | 
| 
      
 525 
     | 
    
         
            +
            VALUE apply_conversions(VALUE proxy)
         
     | 
| 
      
 526 
     | 
    
         
            +
            {
         
     | 
| 
      
 527 
     | 
    
         
            +
              VALUE johnson = rb_const_get(rb_mKernel, rb_intern("Johnson"));
         
     | 
| 
      
 528 
     | 
    
         
            +
              VALUE johnson_proxy = rb_const_get(johnson, rb_intern("RubyLandProxy"));
         
     | 
| 
      
 529 
     | 
    
         
            +
              return rb_funcall(johnson_proxy, rb_intern("apply_conversions"), 1, proxy);
         
     | 
| 
       472 
530 
     | 
    
         
             
            }
         
     | 
| 
       473 
531 
     | 
    
         | 
| 
       474 
532 
     | 
    
         
             
            JSBool unwrap_ruby_land_proxy(JohnsonRuntime* runtime, VALUE wrapped, jsval* retval)
         
     | 
| 
         @@ -487,34 +545,41 @@ JSBool unwrap_ruby_land_proxy(JohnsonRuntime* runtime, VALUE wrapped, jsval* ret 
     | 
|
| 
       487 
545 
     | 
    
         | 
| 
       488 
546 
     | 
    
         
             
            VALUE make_ruby_land_proxy(JohnsonRuntime* runtime, jsval value, const char const* root_name)
         
     | 
| 
       489 
547 
     | 
    
         
             
            {
         
     | 
| 
       490 
     | 
    
         
            -
               
     | 
| 
      
 548 
     | 
    
         
            +
              RubyLandProxy * our_proxy = (RubyLandProxy *)JS_HashTableLookup(runtime->jsids, (void *)value);
         
     | 
| 
       491 
549 
     | 
    
         | 
| 
       492 
     | 
    
         
            -
              if ( 
     | 
| 
      
 550 
     | 
    
         
            +
              if (our_proxy)
         
     | 
| 
       493 
551 
     | 
    
         
             
              {
         
     | 
| 
       494 
552 
     | 
    
         
             
                // if we already have a proxy, return it
         
     | 
| 
       495 
     | 
    
         
            -
                return  
     | 
| 
      
 553 
     | 
    
         
            +
                return apply_conversions(our_proxy->self);
         
     | 
| 
       496 
554 
     | 
    
         
             
              }
         
     | 
| 
       497 
555 
     | 
    
         
             
              else
         
     | 
| 
       498 
556 
     | 
    
         
             
              {    
         
     | 
| 
       499 
557 
     | 
    
         
             
                // otherwise make one and cache it
         
     | 
| 
       500 
     | 
    
         
            -
                RubyLandProxy 
     | 
| 
       501 
     | 
    
         
            -
                VALUE proxy = Data_Make_Struct(proxy_class, RubyLandProxy, 0, finalize, our_proxy);
         
     | 
| 
      
 558 
     | 
    
         
            +
                VALUE proxy = Data_Make_Struct((strncmp(root_name, "JSScriptProxy", strlen("JSScriptProxy")) ? proxy_class : script_class), RubyLandProxy, 0, finalize, our_proxy);
         
     | 
| 
       502 
559 
     | 
    
         | 
| 
       503 
560 
     | 
    
         
             
                JSContext * context = johnson_get_current_context(runtime);
         
     | 
| 
       504 
561 
     | 
    
         | 
| 
       505 
562 
     | 
    
         
             
                PREPARE_RUBY_JROOTS(context, 1);
         
     | 
| 
       506 
563 
     | 
    
         
             
                JROOT(value);
         
     | 
| 
       507 
564 
     | 
    
         | 
| 
      
 565 
     | 
    
         
            +
                VALUE rb_runtime = (VALUE)JS_GetRuntimePrivate(runtime->js);
         
     | 
| 
      
 566 
     | 
    
         
            +
                rb_iv_set(proxy, "@runtime", rb_runtime);
         
     | 
| 
      
 567 
     | 
    
         
            +
             
     | 
| 
       508 
568 
     | 
    
         
             
                our_proxy->runtime = runtime;
         
     | 
| 
       509 
569 
     | 
    
         
             
                our_proxy->key = (void *)value;
         
     | 
| 
      
 570 
     | 
    
         
            +
                our_proxy->self = proxy;
         
     | 
| 
       510 
571 
     | 
    
         | 
| 
       511 
572 
     | 
    
         
             
                // root the value for JS GC and lookups
         
     | 
| 
       512 
573 
     | 
    
         
             
                JCHECK(JS_AddNamedRootRT(runtime->js, &(our_proxy->key), root_name));
         
     | 
| 
       513 
574 
     | 
    
         | 
| 
       514 
575 
     | 
    
         
             
                // put the proxy OID in the id map
         
     | 
| 
       515 
     | 
    
         
            -
                JCHECK(JS_HashTableAdd(runtime->jsids, (void *)value, (void *) 
     | 
| 
       516 
     | 
    
         
            -
             
     | 
| 
       517 
     | 
    
         
            -
                 
     | 
| 
      
 576 
     | 
    
         
            +
                JCHECK(JS_HashTableAdd(runtime->jsids, (void *)value, (void *)our_proxy));
         
     | 
| 
      
 577 
     | 
    
         
            +
             
     | 
| 
      
 578 
     | 
    
         
            +
                VALUE final_proxy = JPROTECT(apply_wrappers, proxy);
         
     | 
| 
      
 579 
     | 
    
         
            +
             
     | 
| 
      
 580 
     | 
    
         
            +
                our_proxy->self = final_proxy;
         
     | 
| 
      
 581 
     | 
    
         
            +
             
     | 
| 
      
 582 
     | 
    
         
            +
                JRETURN_RUBY(JPROTECT(apply_conversions, final_proxy));
         
     | 
| 
       518 
583 
     | 
    
         
             
              }
         
     | 
| 
       519 
584 
     | 
    
         
             
            }
         
     | 
| 
       520 
585 
     | 
    
         | 
| 
         @@ -525,8 +590,11 @@ void init_Johnson_SpiderMonkey_Proxy(VALUE spidermonkey) 
     | 
|
| 
       525 
590 
     | 
    
         
             
              VALUE spidermonkey = rb_define_module_under(johnson, "SpiderMonkey");
         
     | 
| 
       526 
591 
     | 
    
         
             
              */
         
     | 
| 
       527 
592 
     | 
    
         | 
| 
      
 593 
     | 
    
         
            +
              VALUE johnson = rb_const_get(rb_mKernel, rb_intern("Johnson"));
         
     | 
| 
      
 594 
     | 
    
         
            +
              VALUE johnson_proxy = rb_const_get(johnson, rb_intern("RubyLandProxy"));
         
     | 
| 
      
 595 
     | 
    
         
            +
             
     | 
| 
       528 
596 
     | 
    
         
             
              /* RubyLandProxy class. */
         
     | 
| 
       529 
     | 
    
         
            -
              proxy_class = rb_define_class_under(spidermonkey, "RubyLandProxy",  
     | 
| 
      
 597 
     | 
    
         
            +
              proxy_class = rb_define_class_under(spidermonkey, "RubyLandProxy", johnson_proxy);
         
     | 
| 
       530 
598 
     | 
    
         | 
| 
       531 
599 
     | 
    
         
             
              rb_define_method(proxy_class, "[]", get, 1);
         
     | 
| 
       532 
600 
     | 
    
         
             
              rb_define_method(proxy_class, "[]=", set, 2);
         
     | 
| 
         @@ -536,8 +604,15 @@ void init_Johnson_SpiderMonkey_Proxy(VALUE spidermonkey) 
     | 
|
| 
       536 
604 
     | 
    
         
             
              rb_define_method(proxy_class, "length", length, 0);
         
     | 
| 
       537 
605 
     | 
    
         
             
              rb_define_method(proxy_class, "to_s", to_s, 0);
         
     | 
| 
       538 
606 
     | 
    
         | 
| 
       539 
     | 
    
         
            -
              rb_define_private_method(proxy_class, "native_call", native_call, -1);
         
     | 
| 
       540 
607 
     | 
    
         
             
              rb_define_private_method(proxy_class, "runtime", runtime, 0);
         
     | 
| 
       541 
608 
     | 
    
         
             
              rb_define_private_method(proxy_class, "function_property?", function_property_p, 1);
         
     | 
| 
       542 
609 
     | 
    
         
             
              rb_define_private_method(proxy_class, "call_function_property", call_function_property, -1);
         
     | 
| 
      
 610 
     | 
    
         
            +
             
     | 
| 
      
 611 
     | 
    
         
            +
              VALUE callable = rb_define_module_under(proxy_class, "Callable");
         
     | 
| 
      
 612 
     | 
    
         
            +
              rb_define_singleton_method(callable, "test?", callable_test_p, 1);
         
     | 
| 
      
 613 
     | 
    
         
            +
              rb_define_private_method(callable, "native_call", native_call, -1);
         
     | 
| 
      
 614 
     | 
    
         
            +
             
     | 
| 
      
 615 
     | 
    
         
            +
              rb_funcall(johnson_proxy, rb_intern("insert_wrapper"), 1, callable);
         
     | 
| 
      
 616 
     | 
    
         
            +
             
     | 
| 
      
 617 
     | 
    
         
            +
              script_class = rb_define_class_under(spidermonkey, "RubyLandScript", proxy_class);
         
     | 
| 
       543 
618 
     | 
    
         
             
            }
         
     | 
| 
         @@ -4,12 +4,33 @@ 
     | 
|
| 
       4 
4 
     | 
    
         
             
            #include "spidermonkey.h"
         
     | 
| 
       5 
5 
     | 
    
         
             
            #include "runtime.h"
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
      
 7 
     | 
    
         
            +
            #ifdef LEAK_ROOT_NAMES
         
     | 
| 
      
 8 
     | 
    
         
            +
            #define LEAKY_ROOT_NAME(static_string, dynamic_detail) \
         
     | 
| 
      
 9 
     | 
    
         
            +
              ({\
         
     | 
| 
      
 10 
     | 
    
         
            +
                const char * const _leaky_root__detail = (dynamic_detail);\
         
     | 
| 
      
 11 
     | 
    
         
            +
                char * _leaky_root__leaked = malloc(strlen(static_string) + strlen(_leaky_root__detail) + 2);\
         
     | 
| 
      
 12 
     | 
    
         
            +
                strcpy(_leaky_root__leaked, static_string);\
         
     | 
| 
      
 13 
     | 
    
         
            +
                _leaky_root__leaked[strlen(static_string)] = ':';\
         
     | 
| 
      
 14 
     | 
    
         
            +
                strcpy(_leaky_root__leaked + strlen(static_string) + 1, _leaky_root__detail);\
         
     | 
| 
      
 15 
     | 
    
         
            +
                _leaky_root__leaked;\
         
     | 
| 
      
 16 
     | 
    
         
            +
              })
         
     | 
| 
      
 17 
     | 
    
         
            +
            #else
         
     | 
| 
      
 18 
     | 
    
         
            +
            #define LEAKY_ROOT_NAME(static_string, dynamic_detail) (static_string)
         
     | 
| 
      
 19 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            DECLARE_RUBY_WRAPPER(make_ruby_land_proxy, JohnsonRuntime* runtime; jsval value; const char const* root_name)
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            DECLARE_RUBY_WRAPPER(rb_string_value, VALUE v)
         
     | 
| 
      
 24 
     | 
    
         
            +
            DECLARE_RUBY_WRAPPER(rb_string_value_cstr, VALUE v)
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
       7 
26 
     | 
    
         
             
            typedef struct {
         
     | 
| 
       8 
27 
     | 
    
         
             
              void* key;
         
     | 
| 
       9 
28 
     | 
    
         
             
              JohnsonRuntime* runtime;
         
     | 
| 
      
 29 
     | 
    
         
            +
              VALUE self;
         
     | 
| 
       10 
30 
     | 
    
         
             
            } RubyLandProxy;
         
     | 
| 
       11 
31 
     | 
    
         | 
| 
       12 
32 
     | 
    
         
             
            bool ruby_value_is_proxy(VALUE maybe_proxy);
         
     | 
| 
      
 33 
     | 
    
         
            +
            bool ruby_value_is_script_proxy(VALUE maybe_proxy);
         
     | 
| 
       13 
34 
     | 
    
         
             
            JSBool unwrap_ruby_land_proxy(JohnsonRuntime* runtime, VALUE proxy, jsval* retval);
         
     | 
| 
       14 
35 
     | 
    
         
             
            VALUE make_ruby_land_proxy(JohnsonRuntime* runtime, jsval value, const char const* root_name);
         
     | 
| 
       15 
36 
     | 
    
         
             
            void init_Johnson_SpiderMonkey_Proxy(VALUE spidermonkey);
         
     | 
    
        data/ext/spidermonkey/runtime.c
    CHANGED
    
    | 
         @@ -2,13 +2,13 @@ 
     | 
|
| 
       2 
2 
     | 
    
         
             
            #include "global.h"
         
     | 
| 
       3 
3 
     | 
    
         
             
            #include "idhash.h"
         
     | 
| 
       4 
4 
     | 
    
         
             
            #include "conversions.h"
         
     | 
| 
       5 
     | 
    
         
            -
            #include " 
     | 
| 
      
 5 
     | 
    
         
            +
            #include "debugger.h"
         
     | 
| 
       6 
6 
     | 
    
         
             
            #include "jroot.h"
         
     | 
| 
       7 
7 
     | 
    
         
             
            #include "ruby_land_proxy.h"
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
            /*
         
     | 
| 
       10 
10 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       11 
     | 
    
         
            -
             *   global
         
     | 
| 
      
 11 
     | 
    
         
            +
             *   global()
         
     | 
| 
       12 
12 
     | 
    
         
             
             *
         
     | 
| 
       13 
13 
     | 
    
         
             
             * Returns the global object used for this context.
         
     | 
| 
       14 
14 
     | 
    
         
             
             */
         
     | 
| 
         @@ -19,14 +19,15 @@ static VALUE global(VALUE self) 
     | 
|
| 
       19 
19 
     | 
    
         
             
              return convert_to_ruby(runtime, OBJECT_TO_JSVAL(runtime->global));
         
     | 
| 
       20 
20 
     | 
    
         
             
            }
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
            static JSTrapStatus trap_handler( JSContext * 
     | 
| 
      
 22 
     | 
    
         
            +
            static JSTrapStatus trap_handler( JSContext *context,
         
     | 
| 
       23 
23 
     | 
    
         
             
                                              JSScript *UNUSED(script),
         
     | 
| 
       24 
24 
     | 
    
         
             
                                              jsbytecode *UNUSED(pc),
         
     | 
| 
       25 
25 
     | 
    
         
             
                                              jsval *UNUSED(rval),
         
     | 
| 
       26 
26 
     | 
    
         
             
                                              void *block_closure )
         
     | 
| 
       27 
27 
     | 
    
         
             
            {
         
     | 
| 
      
 28 
     | 
    
         
            +
              PREPARE_JROOTS(context, 0);
         
     | 
| 
       28 
29 
     | 
    
         
             
              VALUE block = (VALUE)block_closure;
         
     | 
| 
       29 
     | 
    
         
            -
               
     | 
| 
      
 30 
     | 
    
         
            +
              RB_FUNCALL_0(block, rb_intern("call"));
         
     | 
| 
       30 
31 
     | 
    
         
             
              return JSTRAP_CONTINUE;
         
     | 
| 
       31 
32 
     | 
    
         
             
            }
         
     | 
| 
       32 
33 
     | 
    
         | 
| 
         @@ -34,7 +35,7 @@ static JSTrapStatus trap_handler( JSContext *UNUSED(context), 
     | 
|
| 
       34 
35 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       35 
36 
     | 
    
         
             
             *   clear_trap(script, line_num)
         
     | 
| 
       36 
37 
     | 
    
         
             
             *
         
     | 
| 
       37 
     | 
    
         
            -
             *  
     | 
| 
      
 38 
     | 
    
         
            +
             * Clear the trap previously set at +line_num+ of +script+.
         
     | 
| 
       38 
39 
     | 
    
         
             
             */
         
     | 
| 
       39 
40 
     | 
    
         
             
            static VALUE clear_trap(VALUE self, VALUE script, VALUE linenum)
         
     | 
| 
       40 
41 
     | 
    
         
             
            {
         
     | 
| 
         @@ -56,9 +57,10 @@ static VALUE clear_trap(VALUE self, VALUE script, VALUE linenum) 
     | 
|
| 
       56 
57 
     | 
    
         | 
| 
       57 
58 
     | 
    
         
             
            /*
         
     | 
| 
       58 
59 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       59 
     | 
    
         
            -
             *   set_trap(script,  
     | 
| 
      
 60 
     | 
    
         
            +
             *   set_trap(script, line_num, block)
         
     | 
| 
       60 
61 
     | 
    
         
             
             *
         
     | 
| 
       61 
     | 
    
         
            -
             * Set  
     | 
| 
      
 62 
     | 
    
         
            +
             * Set a trap to invoke +block+ when execution of +script+ reaches
         
     | 
| 
      
 63 
     | 
    
         
            +
             * +line_num+.
         
     | 
| 
       62 
64 
     | 
    
         
             
             */
         
     | 
| 
       63 
65 
     | 
    
         
             
            static VALUE set_trap(VALUE self, VALUE script, VALUE linenum, VALUE block)
         
     | 
| 
       64 
66 
     | 
    
         
             
            {
         
     | 
| 
         @@ -77,9 +79,10 @@ static VALUE set_trap(VALUE self, VALUE script, VALUE linenum, VALUE block) 
     | 
|
| 
       77 
79 
     | 
    
         | 
| 
       78 
80 
     | 
    
         
             
            /*
         
     | 
| 
       79 
81 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       80 
     | 
    
         
            -
             *   native_compile( 
     | 
| 
      
 82 
     | 
    
         
            +
             *   native_compile(script_string, filename, linenum)
         
     | 
| 
       81 
83 
     | 
    
         
             
             *
         
     | 
| 
       82 
     | 
    
         
            -
             * Compile  
     | 
| 
      
 84 
     | 
    
         
            +
             * Compile the JavaScript code in +script_string+, marked as originating
         
     | 
| 
      
 85 
     | 
    
         
            +
             * from +filename+ starting at +linenum+.
         
     | 
| 
       83 
86 
     | 
    
         
             
             */
         
     | 
| 
       84 
87 
     | 
    
         
             
            static VALUE native_compile(VALUE self, VALUE script, VALUE filename, VALUE linenum)
         
     | 
| 
       85 
88 
     | 
    
         
             
            {
         
     | 
| 
         @@ -113,20 +116,23 @@ static VALUE native_compile(VALUE self, VALUE script, VALUE filename, VALUE line 
     | 
|
| 
       113 
116 
     | 
    
         | 
| 
       114 
117 
     | 
    
         
             
              JSObject * script_object = JS_NewScriptObject(context, compiled_js);
         
     | 
| 
       115 
118 
     | 
    
         | 
| 
       116 
     | 
    
         
            -
               
     | 
| 
       117 
     | 
    
         
            -
              JROOT(script_object);
         
     | 
| 
       118 
     | 
    
         
            -
              JRETURN_RUBY(make_ruby_land_proxy(runtime, OBJECT_TO_JSVAL(script_object), "JSScriptProxy"));
         
     | 
| 
      
 119 
     | 
    
         
            +
              return make_ruby_land_proxy(runtime, OBJECT_TO_JSVAL(script_object), LEAKY_ROOT_NAME("JSScriptProxy", RTEST(filename) ? RSTRING(rb_inspect(filename))->ptr : "(?)"));
         
     | 
| 
       119 
120 
     | 
    
         
             
            }
         
     | 
| 
       120 
121 
     | 
    
         | 
| 
       121 
122 
     | 
    
         
             
            /*
         
     | 
| 
       122 
123 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       123 
     | 
    
         
            -
             *   evaluate_compiled_script( 
     | 
| 
      
 124 
     | 
    
         
            +
             *   evaluate_compiled_script(script_proxy)
         
     | 
| 
       124 
125 
     | 
    
         
             
             *
         
     | 
| 
       125 
     | 
    
         
            -
             * Evaluate + 
     | 
| 
      
 126 
     | 
    
         
            +
             * Evaluate previously compiled +script_proxy+, returning the final
         
     | 
| 
      
 127 
     | 
    
         
            +
             * result from that script.
         
     | 
| 
       126 
128 
     | 
    
         
             
             */
         
     | 
| 
       127 
129 
     | 
    
         
             
            static VALUE evaluate_compiled_script(VALUE self, VALUE compiled_script)
         
     | 
| 
       128 
130 
     | 
    
         
             
            {
         
     | 
| 
       129 
131 
     | 
    
         
             
              JohnsonRuntime* runtime;
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
              if (!ruby_value_is_script_proxy(compiled_script))
         
     | 
| 
      
 134 
     | 
    
         
            +
                rb_raise(rb_eArgError, "Compiled JS Script expected");
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
       130 
136 
     | 
    
         
             
              Data_Get_Struct(self, JohnsonRuntime, runtime);
         
     | 
| 
       131 
137 
     | 
    
         | 
| 
       132 
138 
     | 
    
         
             
              JSContext * context = johnson_get_current_context(runtime);
         
     | 
| 
         @@ -163,12 +169,16 @@ static VALUE evaluate_compiled_script(VALUE self, VALUE compiled_script) 
     | 
|
| 
       163 
169 
     | 
    
         
             
              return convert_to_ruby(runtime, js);
         
     | 
| 
       164 
170 
     | 
    
         
             
            }
         
     | 
| 
       165 
171 
     | 
    
         | 
| 
      
 172 
     | 
    
         
            +
            #ifdef JS_GC_ZEAL
         
     | 
| 
       166 
173 
     | 
    
         
             
            /*
         
     | 
| 
       167 
174 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       168 
175 
     | 
    
         
             
             *   gc_zeal=(level)
         
     | 
| 
       169 
176 
     | 
    
         
             
             *
         
     | 
| 
       170 
177 
     | 
    
         
             
             * Sets the GC zeal.
         
     | 
| 
       171 
     | 
    
         
            -
             * 
     | 
| 
      
 178 
     | 
    
         
            +
             *
         
     | 
| 
      
 179 
     | 
    
         
            +
             * 0:: Normal
         
     | 
| 
      
 180 
     | 
    
         
            +
             * 1:: Very Frequent
         
     | 
| 
      
 181 
     | 
    
         
            +
             * 2:: Extremely Frequent
         
     | 
| 
       172 
182 
     | 
    
         
             
             */
         
     | 
| 
       173 
183 
     | 
    
         
             
            static VALUE
         
     | 
| 
       174 
184 
     | 
    
         
             
            set_gc_zeal(VALUE self, VALUE zeal)
         
     | 
| 
         @@ -182,12 +192,33 @@ set_gc_zeal(VALUE self, VALUE zeal) 
     | 
|
| 
       182 
192 
     | 
    
         | 
| 
       183 
193 
     | 
    
         
             
              return zeal;
         
     | 
| 
       184 
194 
     | 
    
         
             
            }
         
     | 
| 
      
 195 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 196 
     | 
    
         
            +
             
     | 
| 
      
 197 
     | 
    
         
            +
            /*
         
     | 
| 
      
 198 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 199 
     | 
    
         
            +
             *   gc()
         
     | 
| 
      
 200 
     | 
    
         
            +
             *
         
     | 
| 
      
 201 
     | 
    
         
            +
             * Manually initiates a SpiderMonkey Garbage Collection run.
         
     | 
| 
      
 202 
     | 
    
         
            +
             */
         
     | 
| 
      
 203 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 204 
     | 
    
         
            +
            gc(VALUE self)
         
     | 
| 
      
 205 
     | 
    
         
            +
            {
         
     | 
| 
      
 206 
     | 
    
         
            +
              JohnsonRuntime* runtime;
         
     | 
| 
      
 207 
     | 
    
         
            +
              Data_Get_Struct(self, JohnsonRuntime, runtime);
         
     | 
| 
      
 208 
     | 
    
         
            +
             
     | 
| 
      
 209 
     | 
    
         
            +
              JSContext* context = johnson_get_current_context(runtime);
         
     | 
| 
      
 210 
     | 
    
         
            +
             
     | 
| 
      
 211 
     | 
    
         
            +
              JS_GC(context);
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
      
 213 
     | 
    
         
            +
              return Qnil;
         
     | 
| 
      
 214 
     | 
    
         
            +
            }
         
     | 
| 
       185 
215 
     | 
    
         | 
| 
       186 
216 
     | 
    
         
             
            /*
         
     | 
| 
       187 
217 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       188 
218 
     | 
    
         
             
             *   debugger=(debugger)
         
     | 
| 
       189 
219 
     | 
    
         
             
             *
         
     | 
| 
       190 
     | 
    
         
            -
             *  
     | 
| 
      
 220 
     | 
    
         
            +
             * Directs the runtime to install a full set of debug hooks, using the
         
     | 
| 
      
 221 
     | 
    
         
            +
             * given +debugger+, which must be a Johnson::SpiderMonkey::Debugger.
         
     | 
| 
       191 
222 
     | 
    
         
             
             */
         
     | 
| 
       192 
223 
     | 
    
         
             
            static VALUE
         
     | 
| 
       193 
224 
     | 
    
         
             
            set_debugger(VALUE self, VALUE debugger)
         
     | 
| 
         @@ -195,6 +226,9 @@ set_debugger(VALUE self, VALUE debugger) 
     | 
|
| 
       195 
226 
     | 
    
         
             
              JohnsonRuntime* runtime;
         
     | 
| 
       196 
227 
     | 
    
         
             
              JSDebugHooks* debug_hooks;
         
     | 
| 
       197 
228 
     | 
    
         | 
| 
      
 229 
     | 
    
         
            +
              if (!ruby_value_is_debugger(debugger))
         
     | 
| 
      
 230 
     | 
    
         
            +
                rb_raise(rb_eTypeError, "Expected Johnson::SpiderMonkey::Debugger instance");
         
     | 
| 
      
 231 
     | 
    
         
            +
             
     | 
| 
       198 
232 
     | 
    
         
             
              rb_iv_set(self, "@debugger", debugger);
         
     | 
| 
       199 
233 
     | 
    
         
             
              Data_Get_Struct(self, JohnsonRuntime, runtime);
         
     | 
| 
       200 
234 
     | 
    
         
             
              Data_Get_Struct(debugger, JSDebugHooks, debug_hooks);
         
     | 
| 
         @@ -247,6 +281,13 @@ JSBool gc_callback(JSContext *context, JSGCStatus status) 
     | 
|
| 
       247 
281 
     | 
    
         
             
              return JS_FALSE;
         
     | 
| 
       248 
282 
     | 
    
         
             
            }
         
     | 
| 
       249 
283 
     | 
    
         | 
| 
      
 284 
     | 
    
         
            +
            /**
         
     | 
| 
      
 285 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 286 
     | 
    
         
            +
             *   initialize_native(options)
         
     | 
| 
      
 287 
     | 
    
         
            +
             *
         
     | 
| 
      
 288 
     | 
    
         
            +
             * Create the underlying SpiderMonkey runtime. This must be called
         
     | 
| 
      
 289 
     | 
    
         
            +
             * first, and only once. Called by +initialize+ by default.
         
     | 
| 
      
 290 
     | 
    
         
            +
             */
         
     | 
| 
       250 
291 
     | 
    
         
             
            static VALUE
         
     | 
| 
       251 
292 
     | 
    
         
             
            initialize_native(VALUE self, VALUE UNUSED(options))
         
     | 
| 
       252 
293 
     | 
    
         
             
            {
         
     | 
| 
         @@ -262,7 +303,7 @@ initialize_native(VALUE self, VALUE UNUSED(options)) 
     | 
|
| 
       262 
303 
     | 
    
         | 
| 
       263 
304 
     | 
    
         
             
                JSContext* context = johnson_get_current_context(runtime);
         
     | 
| 
       264 
305 
     | 
    
         | 
| 
       265 
     | 
    
         
            -
                if (runtime->global = JS_GetGlobalObject(context))
         
     | 
| 
      
 306 
     | 
    
         
            +
                if ((runtime->global = JS_GetGlobalObject(context)))
         
     | 
| 
       266 
307 
     | 
    
         
             
                  return self;
         
     | 
| 
       267 
308 
     | 
    
         
             
              }
         
     | 
| 
       268 
309 
     | 
    
         | 
| 
         @@ -289,6 +330,16 @@ JSContext* johnson_get_current_context(JohnsonRuntime * runtime) 
     | 
|
| 
       289 
330 
     | 
    
         
             
              return context->js;
         
     | 
| 
       290 
331 
     | 
    
         
             
            }
         
     | 
| 
       291 
332 
     | 
    
         | 
| 
      
 333 
     | 
    
         
            +
            static int proxy_cleanup_enumerator(JSHashEntry *entry, int i, void* arg)
         
     | 
| 
      
 334 
     | 
    
         
            +
            {
         
     | 
| 
      
 335 
     | 
    
         
            +
              JohnsonRuntime *runtime = (JohnsonRuntime*)(arg);
         
     | 
| 
      
 336 
     | 
    
         
            +
              // entry->key is jsval; entry->value is RubyLandProxy*
         
     | 
| 
      
 337 
     | 
    
         
            +
              RubyLandProxy * proxy = (RubyLandProxy *)(entry->value);
         
     | 
| 
      
 338 
     | 
    
         
            +
              JS_RemoveRootRT(runtime->js, &(proxy->key));
         
     | 
| 
      
 339 
     | 
    
         
            +
              proxy->runtime = NULL;
         
     | 
| 
      
 340 
     | 
    
         
            +
              return 0;
         
     | 
| 
      
 341 
     | 
    
         
            +
            }
         
     | 
| 
      
 342 
     | 
    
         
            +
             
     | 
| 
       292 
343 
     | 
    
         
             
            static void deallocate(JohnsonRuntime* runtime)
         
     | 
| 
       293 
344 
     | 
    
         
             
            {
         
     | 
| 
       294 
345 
     | 
    
         
             
              // our gc callback can create ruby objects, so disable it
         
     | 
| 
         @@ -303,6 +354,10 @@ static void deallocate(JohnsonRuntime* runtime) 
     | 
|
| 
       303 
354 
     | 
    
         
             
                iterator = NULL;
         
     | 
| 
       304 
355 
     | 
    
         
             
              }
         
     | 
| 
       305 
356 
     | 
    
         | 
| 
      
 357 
     | 
    
         
            +
              JSContext* cleanup = JS_NewContext(runtime->js, 8192L);
         
     | 
| 
      
 358 
     | 
    
         
            +
              JS_HashTableEnumerateEntries(runtime->jsids, proxy_cleanup_enumerator, runtime);
         
     | 
| 
      
 359 
     | 
    
         
            +
              JS_DestroyContext(cleanup);
         
     | 
| 
      
 360 
     | 
    
         
            +
             
     | 
| 
       306 
361 
     | 
    
         
             
              JS_DestroyRuntime(runtime->js);
         
     | 
| 
       307 
362 
     | 
    
         
             
              free(runtime);
         
     | 
| 
       308 
363 
     | 
    
         
             
            }
         
     | 
| 
         @@ -315,16 +370,27 @@ static VALUE allocate(VALUE klass) 
     | 
|
| 
       315 
370 
     | 
    
         | 
| 
       316 
371 
     | 
    
         
             
            void init_Johnson_SpiderMonkey_Runtime(VALUE spidermonkey)
         
     | 
| 
       317 
372 
     | 
    
         
             
            {
         
     | 
| 
       318 
     | 
    
         
            -
               
     | 
| 
      
 373 
     | 
    
         
            +
              /* HACK:  These comments are *only* to make RDoc happy.
         
     | 
| 
      
 374 
     | 
    
         
            +
              VALUE johnson = rb_define_module("Johnson");
         
     | 
| 
      
 375 
     | 
    
         
            +
              VALUE spidermonkey = rb_define_module_under(johnson, "SpiderMonkey");
         
     | 
| 
      
 376 
     | 
    
         
            +
              */
         
     | 
| 
      
 377 
     | 
    
         
            +
             
     | 
| 
      
 378 
     | 
    
         
            +
              VALUE johnson = rb_const_get(rb_mKernel, rb_intern("Johnson"));
         
     | 
| 
      
 379 
     | 
    
         
            +
              VALUE johnson_runtime = rb_const_get(johnson, rb_intern("Runtime"));
         
     | 
| 
      
 380 
     | 
    
         
            +
             
     | 
| 
      
 381 
     | 
    
         
            +
              VALUE klass = rb_define_class_under(spidermonkey, "Runtime", johnson_runtime);
         
     | 
| 
       319 
382 
     | 
    
         | 
| 
       320 
383 
     | 
    
         
             
              rb_define_alloc_func(klass, allocate);
         
     | 
| 
       321 
384 
     | 
    
         
             
              rb_define_private_method(klass, "initialize_native", initialize_native, 1);
         
     | 
| 
       322 
385 
     | 
    
         | 
| 
       323 
386 
     | 
    
         
             
              rb_define_method(klass, "global", global, 0);
         
     | 
| 
       324 
387 
     | 
    
         
             
              rb_define_method(klass, "debugger=", set_debugger, 1);
         
     | 
| 
      
 388 
     | 
    
         
            +
              rb_define_method(klass, "gc", gc, 0);
         
     | 
| 
      
 389 
     | 
    
         
            +
            #ifdef JS_GC_ZEAL
         
     | 
| 
       325 
390 
     | 
    
         
             
              rb_define_method(klass, "gc_zeal=", set_gc_zeal, 1);
         
     | 
| 
      
 391 
     | 
    
         
            +
            #endif
         
     | 
| 
       326 
392 
     | 
    
         
             
              rb_define_method(klass, "evaluate_compiled_script", evaluate_compiled_script, 1);
         
     | 
| 
       327 
393 
     | 
    
         
             
              rb_define_private_method(klass, "native_compile", native_compile, 3);
         
     | 
| 
       328 
     | 
    
         
            -
               
     | 
| 
      
 394 
     | 
    
         
            +
              rb_define_method(klass, "set_trap", set_trap, 3);
         
     | 
| 
       329 
395 
     | 
    
         
             
              rb_define_private_method(klass, "clear_trap", clear_trap, 2);
         
     | 
| 
       330 
396 
     | 
    
         
             
            }
         
     |