public
Description: Johnson wraps JavaScript in a loving Ruby embrace.
Homepage: http://github.com/jbarnette/johnson/wikis
Clone URL: git://github.com/jbarnette/johnson.git
making more shit work
tenderlove (author)
Fri May 30 16:47:33 -0700 2008
commit  dc2a8331070fe0cb318d359ee5d439859d957604
tree    1938dd6db795c18a80d1a8b4b590f359df742b17
parent  40f5721b35e94fe0630cb2372d246b62664c9439
...
343
344
345
346
 
347
348
 
349
350
351
 
352
353
354
355
356
 
357
358
359
...
547
548
549
550
 
551
552
553
...
343
344
345
 
346
347
 
348
349
350
 
351
352
353
354
 
 
355
356
357
358
...
546
547
548
 
549
550
551
552
0
@@ -343,17 +343,16 @@ length(VALUE self)
0
 
0
 /*
0
  * call-seq:
0
- *   context
0
+ *   runtime
0
  *
0
- * Returns context.
0
+ * Returns runtime.
0
  */
0
 static VALUE
0
-context(VALUE self)
0
+runtime(VALUE self)
0
 {
0
   RubyLandProxy* proxy;
0
   Data_Get_Struct(self, RubyLandProxy, proxy);
0
-  JSContext * context = johnson_get_current_context(proxy->runtime);
0
-  return (VALUE)JS_GetContextPrivate(context);
0
+  return (VALUE)JS_GetRuntimePrivate(proxy->runtime->js);
0
 }
0
 
0
 /*
0
@@ -547,7 +546,7 @@ void init_Johnson_SpiderMonkey_Proxy(VALUE spidermonkey)
0
   rb_define_method(proxy_class, "to_s", to_s, 0);
0
 
0
   rb_define_private_method(proxy_class, "native_call", native_call, -1);
0
-  rb_define_private_method(proxy_class, "context", context, 0);
0
+  rb_define_private_method(proxy_class, "runtime", runtime, 0);
0
   rb_define_private_method(proxy_class, "function_property?", function_property_p, 1);
0
   rb_define_private_method(proxy_class, "call_function_property", call_function_property, -1);
0
 }
...
33
34
35
36
37
 
 
38
39
 
40
41
42
...
33
34
35
 
 
36
37
38
 
39
40
41
42
0
@@ -33,10 +33,10 @@ module Johnson
0
   PRELUDE = IO.read(File.dirname(__FILE__) + "/../js/johnson/prelude.js")
0
   
0
   def self.evaluate(expression, vars={})
0
-    context = Johnson::Context.new
0
-    vars.each { |key, value| context[key] = value }
0
+    runtime = Johnson::Runtime.new
0
+    vars.each { |key, value| runtime[key] = value }
0
     
0
-    context.evaluate(expression)
0
+    runtime.evaluate(expression)
0
   end
0
   
0
   def self.parse(js, *args)
...
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
...
7
8
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
11
12
0
@@ -7,25 +7,6 @@ module Johnson #:nodoc:
0
         @gcthings = {}
0
       end
0
       
0
-      protected
0
-      
0
-      def handle_js_exception(jsex)
0
-        raise jsex if Exception === jsex
0
-        raise Johnson::Error.new(jsex.to_s) unless Johnson::SpiderMonkey::RubyLandProxy === jsex
0
-        
0
-        # FIXME: sanitize stack traces
0
-        stack = jsex.stack rescue nil
0
-        
0
-        ex = Johnson::Error.new(jsex)
0
-        if stack
0
-          ex.set_backtrace(stack.split("\n") + caller)
0
-        else
0
-          ex.set_backtrace(caller)
0
-        end
0
-        
0
-        raise ex
0
-      end
0
-      
0
       # called from js_land_proxy.c:make_js_land_proxy
0
       def add_gcthing(thing)
0
         @gcthings[thing.object_id] = thing
...
16
17
18
19
 
20
21
22
...
16
17
18
 
19
20
21
22
0
@@ -16,7 +16,7 @@ module Johnson #:nodoc:
0
       end
0
 
0
       def call(*args)
0
-        call_using(context.global, *args)
0
+        call_using(runtime.global, *args)
0
       end
0
 
0
       def call_using(this, *args)
...
7
8
9
10
 
 
11
12
13
...
17
18
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
21
22
...
7
8
9
 
10
11
12
13
14
...
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
0
@@ -7,7 +7,8 @@ module Johnson #:nodoc:
0
       end
0
 
0
       def current_context
0
-        Thread.current[:johson_context] ||= Context.new(self)
0
+        contexts = (Thread.current[:johson_context_map] ||= {})
0
+        contexts[self.object_id] ||= Context.new(self)
0
       end
0
 
0
       def [](key)
0
@@ -17,6 +18,25 @@ module Johnson #:nodoc:
0
       def []=(key, value)
0
         global[key] = value
0
       end
0
+
0
+      protected
0
+      
0
+      def handle_js_exception(jsex)
0
+        raise jsex if Exception === jsex
0
+        raise Johnson::Error.new(jsex.to_s) unless Johnson::SpiderMonkey::RubyLandProxy === jsex
0
+        
0
+        # FIXME: sanitize stack traces
0
+        stack = jsex.stack rescue nil
0
+        
0
+        ex = Johnson::Error.new(jsex)
0
+        if stack
0
+          ex.set_backtrace(stack.split("\n") + caller)
0
+        else
0
+          ex.set_backtrace(caller)
0
+        end
0
+        
0
+        raise ex
0
+      end
0
     end
0
   end
0
 end
...
21
22
23
24
25
 
 
26
27
28
29
30
31
 
 
 
32
33
34
...
21
22
23
 
 
24
25
26
27
28
 
 
 
29
30
31
32
33
34
0
@@ -21,14 +21,14 @@ module Johnson
0
     undef :default_test
0
     
0
     def assert_js(expression, options={})
0
-      context = options[:context] || @context
0
-      assert(context.evaluate(expression), "Expected JS expression [#{expression}] to be true.")
0
+      runtime = options[:runtime] || @runtime
0
+      assert(runtime.evaluate(expression), "Expected JS expression [#{expression}] to be true.")
0
     end
0
     
0
     def assert_js_equal(expected, expression, options={})
0
-      context = options.delete(:context) || @context
0
-      options.each { |k, v| context[k.to_s] = v }
0
-      assert_equal(expected, context.evaluate(expression))
0
+      runtime = options.delete(:runtime) || @runtime
0
+      options.each { |k, v| runtime[k.to_s] = v }
0
+      assert_equal(expected, runtime.evaluate(expression))
0
     end
0
   end
0
 
...
4
5
6
7
 
8
9
10
...
12
13
14
15
16
 
 
17
18
19
20
21
22
 
 
 
23
24
25
26
 
27
28
29
...
32
33
34
35
 
36
37
38
...
41
42
43
44
 
45
46
47
48
49
50
 
51
52
53
54
 
55
56
57
58
59
60
 
61
62
63
64
 
65
66
67
68
69
 
70
71
72
73
74
 
75
76
77
78
79
80
81
 
82
83
84
85
86
 
87
88
89
...
97
98
99
100
 
101
102
103
104
105
106
 
107
108
109
110
111
112
 
113
114
115
116
117
 
118
119
120
121
122
 
123
124
125
...
127
128
129
130
 
131
132
133
134
135
 
136
137
138
139
140
 
141
142
143
144
145
 
146
147
148
...
150
151
152
153
 
154
155
156
...
158
159
160
161
 
162
163
164
...
171
172
173
174
 
175
176
177
178
179
180
181
 
182
183
184
185
186
 
187
188
189
190
191
 
192
193
194
195
196
 
197
198
199
...
4
5
6
 
7
8
9
10
...
12
13
14
 
 
15
16
17
18
19
 
 
 
20
21
22
23
24
25
 
26
27
28
29
...
32
33
34
 
35
36
37
38
...
41
42
43
 
44
45
46
47
48
49
 
50
51
52
53
 
54
55
56
57
58
59
 
60
61
62
63
 
64
65
66
67
68
 
69
70
71
72
73
 
74
75
76
77
78
79
80
 
81
82
83
84
85
 
86
87
88
89
...
97
98
99
 
100
101
102
103
104
105
 
106
107
108
109
110
111
 
112
113
114
115
116
 
117
118
119
120
121
 
122
123
124
125
...
127
128
129
 
130
131
132
133
134
 
135
136
137
138
139
 
140
141
142
143
144
 
145
146
147
148
...
150
151
152
 
153
154
155
156
...
158
159
160
 
161
162
163
164
...
171
172
173
 
174
175
176
177
178
179
180
 
181
182
183
184
185
 
186
187
188
189
190
 
191
192
193
194
195
 
196
197
198
199
0
@@ -4,7 +4,7 @@ module Johnson
0
   module SpiderMonkey
0
     class RubyLandProxyTest < Johnson::TestCase
0
       def setup
0
-        @context = Johnson::Context.new(Johnson::SpiderMonkey::Context)
0
+        @runtime = Johnson::Runtime.new(Johnson::SpiderMonkey::Runtime)
0
       end
0
       
0
       def test_constructing_a_proxy_directly_asplodes
0
@@ -12,18 +12,18 @@ module Johnson
0
       end
0
       
0
       def test_objects_get_wrapped_as_proxies
0
-        assert_kind_of(Johnson::SpiderMonkey::RubyLandProxy, @context.evaluate("x = {}"))
0
-        assert_kind_of(Johnson::SpiderMonkey::RubyLandProxy, @context.evaluate("new Object()"))
0
+        assert_kind_of(Johnson::SpiderMonkey::RubyLandProxy, @runtime.evaluate("x = {}"))
0
+        assert_kind_of(Johnson::SpiderMonkey::RubyLandProxy, @runtime.evaluate("new Object()"))
0
       end
0
       
0
       def test_proxies_get_unwrapped_when_roundtripping
0
-        proxy = @context.evaluate("x = {}")
0
-        @context["y"] = proxy
0
-        assert(@context.evaluate("x === y"))
0
+        proxy = @runtime.evaluate("x = {}")
0
+        @runtime["y"] = proxy
0
+        assert(@runtime.evaluate("x === y"))
0
       end
0
       
0
       def test_array_indexable
0
-        proxy = @context.evaluate("var x = [1,2,3]; x")
0
+        proxy = @runtime.evaluate("var x = [1,2,3]; x")
0
         assert_equal(1, proxy[0])
0
         assert_equal(1, proxy['0'])
0
 
0
@@ -32,7 +32,7 @@ module Johnson
0
       end
0
       
0
       def test_hash_indexable
0
-        proxy = @context.evaluate("var x = { 0: 1, 1: 2, 2: 3 }; x")
0
+        proxy = @runtime.evaluate("var x = { 0: 1, 1: 2, 2: 3 }; x")
0
         assert_equal(1, proxy[0])
0
         assert_equal(1, proxy['0'])
0
 
0
@@ -41,49 +41,49 @@ module Johnson
0
       end
0
 
0
       def test_functions_get_wrapped_as_proxies
0
-        f = @context.evaluate("function() {}")
0
+        f = @runtime.evaluate("function() {}")
0
         assert_kind_of(Johnson::SpiderMonkey::RubyLandProxy, f)
0
         assert(f.function?)
0
       end
0
 
0
       def test_function?
0
-        f = @context.evaluate("function() {}")
0
+        f = @runtime.evaluate("function() {}")
0
         assert_kind_of(Johnson::SpiderMonkey::RubyLandProxy, f)
0
         assert(f.function?)
0
 
0
-        f = @context.evaluate("new Object()")
0
+        f = @runtime.evaluate("new Object()")
0
         assert_kind_of(Johnson::SpiderMonkey::RubyLandProxy, f)
0
         assert(!f.function?)
0
       end
0
       
0
       def test_calling_non_functions_complains
0
-        assert_raise(Johnson::Error) { @context.evaluate("new Object()").call }
0
+        assert_raise(Johnson::Error) { @runtime.evaluate("new Object()").call }
0
       end
0
       
0
       def test_functions_can_be_called
0
-        f = @context.evaluate("function() { return 42; }")
0
+        f = @runtime.evaluate("function() { return 42; }")
0
         assert_equal(42, f.call)
0
       end
0
       
0
       def test_functions_can_be_called_with_args
0
-        f = @context.evaluate("function(x) { return x * 2; }")
0
+        f = @runtime.evaluate("function(x) { return x * 2; }")
0
         assert_equal(84, f.call(42))
0
       end
0
       
0
       def test_functions_can_be_used_as_procs
0
-        f = @context.evaluate("function(x) { return x * 2; }")
0
+        f = @runtime.evaluate("function(x) { return x * 2; }")
0
         a = [1, 2, 3]
0
         
0
         assert_equal([2, 4, 6], a.collect(&f))
0
       end
0
       
0
       def test_function_proxies_are_called_with_a_global_this
0
-        f = @context.evaluate("x = 42; function() { return this.x; }")
0
+        f = @runtime.evaluate("x = 42; function() { return this.x; }")
0
         assert_equal(42, f.call)
0
       end
0
       
0
       def test_can_be_indexed_by_string
0
-        proxy = @context.evaluate("x = { foo: 42 }")
0
+        proxy = @runtime.evaluate("x = { foo: 42 }")
0
         assert_kind_of(Johnson::SpiderMonkey::RubyLandProxy, proxy)
0
         
0
         assert_equal(42, proxy["foo"])
0
@@ -97,29 +97,29 @@ module Johnson
0
       end
0
       
0
       def test_multilevel_indexing_works
0
-        proxy = @context.evaluate("x = { foo: { bar: 42 , baz: function() { return 42 } } }")
0
+        proxy = @runtime.evaluate("x = { foo: { bar: 42 , baz: function() { return 42 } } }")
0
         assert_equal(42, proxy["foo"]["bar"])
0
         assert_equal(42, proxy["foo"]["baz"].call)
0
       end
0
       
0
       def test_respond_to_works
0
-        proxy = @context.evaluate("x = { foo: 42 }")
0
+        proxy = @runtime.evaluate("x = { foo: 42 }")
0
         assert(!proxy.respond_to?(:bar))
0
         assert(proxy.respond_to?(:foo))
0
       end
0
       
0
       def test_respond_to_always_returns_true_for_assignment
0
-        proxy = @context.evaluate("x = {}")
0
+        proxy = @runtime.evaluate("x = {}")
0
         assert(proxy.respond_to?(:bar=))
0
       end
0
       
0
       def test_accessor
0
-        proxy = @context.evaluate("x = { foo: 42 }")
0
+        proxy = @runtime.evaluate("x = { foo: 42 }")
0
         assert_equal(42, proxy.foo)
0
       end
0
       
0
       def test_mutator
0
-        proxy = @context.evaluate("x = {}")
0
+        proxy = @runtime.evaluate("x = {}")
0
         proxy.foo = 42
0
         
0
         assert_js_equal(42, "x.foo")
0
@@ -127,22 +127,22 @@ module Johnson
0
       end
0
       
0
       def test_method_with_no_arguments
0
-        proxy = @context.evaluate("x = { foo: function() { return 42 } }")
0
+        proxy = @runtime.evaluate("x = { foo: function() { return 42 } }")
0
         assert_equal(42, proxy.foo)
0
       end
0
       
0
       def test_method_with_one_argument
0
-        proxy = @context.evaluate("f = { f: function(x) { return x * 2 } }")
0
+        proxy = @runtime.evaluate("f = { f: function(x) { return x * 2 } }")
0
         assert_equal(84, proxy.f(42))
0
       end
0
       
0
       def test_method_with_multiple_arguments
0
-        proxy = @context.evaluate("x = { add: function(x, y) { return x + y } }")
0
+        proxy = @runtime.evaluate("x = { add: function(x, y) { return x + y } }")
0
         assert_equal(42, proxy.add(40, 2))
0
       end
0
       
0
       def test_supports_each_on_arrays
0
-        proxy = @context.evaluate("[1, 2, 3]")
0
+        proxy = @runtime.evaluate("[1, 2, 3]")
0
         values = []
0
         
0
         proxy.each { |n| values << n }
0
@@ -150,7 +150,7 @@ module Johnson
0
       end
0
       
0
       def test_supports_each_on_things_that_arent_arrays
0
-        proxy = @context.evaluate("x = { foo: 'fooval', bar: 'barval' }; x[0] = 42; x")
0
+        proxy = @runtime.evaluate("x = { foo: 'fooval', bar: 'barval' }; x[0] = 42; x")
0
         values = {}
0
         
0
         proxy.each { |k, v| values[k] = v }
0
@@ -158,7 +158,7 @@ module Johnson
0
       end
0
       
0
       def test_each_passes_an_exception
0
-        proxy = @context.evaluate("x = { foo: 'fooval', bar: 'barval' }; x[0] = 42; x")
0
+        proxy = @runtime.evaluate("x = { foo: 'fooval', bar: 'barval' }; x[0] = 42; x")
0
         values = {}
0
         
0
         assert_raise(RuntimeError) do
0
@@ -171,29 +171,29 @@ module Johnson
0
       end
0
       
0
       def test_is_enumerable
0
-        proxy = @context.evaluate("[1, 2, 3]")
0
+        proxy = @runtime.evaluate("[1, 2, 3]")
0
         assert_kind_of(Enumerable, proxy)
0
         
0
         assert_equal([2, 4, 6], proxy.collect { |n| n * 2 })
0
       end
0
       
0
       def test_has_a_length
0
-        proxy = @context.evaluate("[1, 2, 3]")
0
+        proxy = @runtime.evaluate("[1, 2, 3]")
0
         assert_equal(3, proxy.length)
0
       end
0
       
0
       def test_length_is_aliased_as_size
0
-        proxy = @context.evaluate("[1, 2, 3]")
0
+        proxy = @runtime.evaluate("[1, 2, 3]")
0
         assert_equal(3, proxy.size)
0
       end
0
       
0
       def test_length_for_arrays_ignores_non_numeric_properties
0
-        proxy = @context.evaluate("x = [1, 2, 3]; x['foo'] = 'bar'; x")
0
+        proxy = @runtime.evaluate("x = [1, 2, 3]; x['foo'] = 'bar'; x")
0
         assert_equal(3, proxy.length)
0
       end
0
       
0
       def test_length_for_objects_includes_all_properties
0
-        proxy = @context.evaluate("x = { foo: 'foo', bar: 'bar', 0: 42 }")
0
+        proxy = @runtime.evaluate("x = { foo: 'foo', bar: 'bar', 0: 42 }")
0
         assert_equal(3, proxy.length)
0
       end
0
 
...
9
10
11
12
 
13
14
15
...
9
10
11
 
12
13
14
15
0
@@ -9,7 +9,7 @@ class JohnsonTest < Test::Unit::TestCase
0
     assert_equal(4, Johnson.evaluate("2 + foo", :foo => 2))
0
   end
0
   
0
-  def test_evaluate_uses_a_new_context_each_time
0
+  def test_evaluate_uses_a_new_runtime_each_time
0
     assert_equal(4, Johnson.evaluate("foo", :foo => 4))
0
     assert_raise(Johnson::Error) { Johnson.evaluate("foo") }
0
   end

Comments