johnson 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/CHANGELOG.rdoc +12 -0
  2. data/Manifest.txt +6 -4
  3. data/README.rdoc +2 -8
  4. data/Rakefile +11 -11
  5. data/bin/johnson +1 -3
  6. data/ext/spidermonkey/context.c +3 -2
  7. data/ext/spidermonkey/conversions.c +61 -27
  8. data/ext/spidermonkey/conversions.h +13 -0
  9. data/ext/spidermonkey/debugger.c +13 -5
  10. data/ext/spidermonkey/debugger.h +1 -0
  11. data/ext/spidermonkey/extconf.rb +2 -3
  12. data/ext/spidermonkey/jroot.h +11 -1
  13. data/ext/spidermonkey/js_land_proxy.c +21 -11
  14. data/ext/spidermonkey/ruby_land_proxy.c +116 -41
  15. data/ext/spidermonkey/ruby_land_proxy.h +21 -0
  16. data/ext/spidermonkey/runtime.c +85 -19
  17. data/ext/spidermonkey/runtime.h +2 -0
  18. data/ext/spidermonkey/spidermonkey.c +3 -1
  19. data/lib/johnson.rb +19 -27
  20. data/lib/johnson/cli.rb +2 -1
  21. data/{js/johnson → lib/johnson/js}/cli.js +0 -0
  22. data/lib/johnson/js/core.js +34 -0
  23. data/lib/johnson/js/prelude.js +149 -0
  24. data/lib/johnson/ruby_land_proxy.rb +113 -0
  25. data/lib/johnson/runtime.rb +92 -33
  26. data/lib/johnson/spidermonkey.rb +12 -0
  27. data/lib/johnson/spidermonkey/js_land_proxy.rb +10 -8
  28. data/lib/johnson/spidermonkey/ruby_land_proxy.rb +10 -47
  29. data/lib/johnson/spidermonkey/runtime.rb +11 -31
  30. data/test/johnson/conversions/array_test.rb +41 -3
  31. data/test/johnson/conversions/string_test.rb +12 -0
  32. data/test/johnson/custom_conversions_test.rb +50 -0
  33. data/test/johnson/prelude_test.rb +23 -0
  34. data/test/johnson/runtime_test.rb +82 -2
  35. data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +17 -1
  36. data/test/johnson/spidermonkey/runtime_test.rb +24 -0
  37. data/vendor/spidermonkey/jsprf.c +2 -0
  38. metadata +22 -9
  39. data/js/johnson/prelude.js +0 -80
  40. data/lib/johnson/version.rb +0 -3
  41. data/lib/rails/init.rb +0 -37
@@ -1,3 +1,15 @@
1
+ === 1.2.0 / 2010-01-25
2
+
3
+ * Add an API for registering custom conversions.
4
+ * Subclass Runtime, don't delegate.
5
+ * Make builds a bit more robust, especially on Snow Leopard.
6
+ * Handle UTF-8 conversion better. Also, treat JS strings as UTF-16.
7
+ * Add small bits of API doco.
8
+ * Plug tons of root leaks.
9
+ * Make Function.prototype.apply handle Ruby arrays.
10
+ * Remove Rails EJS support, it was a joke to begin with.
11
+ * Whitespace, formatting, and organization cleanups.
12
+
1
13
  === 1.1.2 / 2009-07-29
2
14
 
3
15
  * Cleaned up building / packaging. Gem installs work again!
@@ -29,12 +29,13 @@ ext/spidermonkey/runtime.c
29
29
  ext/spidermonkey/runtime.h
30
30
  ext/spidermonkey/spidermonkey.c
31
31
  ext/spidermonkey/spidermonkey.h
32
- js/johnson/cli.js
33
- js/johnson/prelude.js
34
32
  lib/johnson.rb
35
33
  lib/johnson/cli.rb
36
34
  lib/johnson/cli/options.rb
37
35
  lib/johnson/error.rb
36
+ lib/johnson/js/cli.js
37
+ lib/johnson/js/core.js
38
+ lib/johnson/js/prelude.js
38
39
  lib/johnson/nodes.rb
39
40
  lib/johnson/nodes/binary_node.rb
40
41
  lib/johnson/nodes/for.rb
@@ -45,7 +46,9 @@ lib/johnson/nodes/node.rb
45
46
  lib/johnson/nodes/ternary_node.rb
46
47
  lib/johnson/parser.rb
47
48
  lib/johnson/parser/syntax_error.rb
49
+ lib/johnson/ruby_land_proxy.rb
48
50
  lib/johnson/runtime.rb
51
+ lib/johnson/spidermonkey.rb
49
52
  lib/johnson/spidermonkey/context.rb
50
53
  lib/johnson/spidermonkey/debugger.rb
51
54
  lib/johnson/spidermonkey/immutable_node.rb
@@ -53,7 +56,6 @@ lib/johnson/spidermonkey/js_land_proxy.rb
53
56
  lib/johnson/spidermonkey/mutable_tree_visitor.rb
54
57
  lib/johnson/spidermonkey/ruby_land_proxy.rb
55
58
  lib/johnson/spidermonkey/runtime.rb
56
- lib/johnson/version.rb
57
59
  lib/johnson/visitable.rb
58
60
  lib/johnson/visitors.rb
59
61
  lib/johnson/visitors/dot_visitor.rb
@@ -61,7 +63,6 @@ lib/johnson/visitors/ecma_visitor.rb
61
63
  lib/johnson/visitors/enumerating_visitor.rb
62
64
  lib/johnson/visitors/sexp_visitor.rb
63
65
  lib/johnson/visitors/visitor.rb
64
- lib/rails/init.rb
65
66
  test/helper.rb
66
67
  test/johnson/browser_test.rb
67
68
  test/johnson/conversions/array_test.rb
@@ -75,6 +76,7 @@ test/johnson/conversions/string_test.rb
75
76
  test/johnson/conversions/struct_test.rb
76
77
  test/johnson/conversions/symbol_test.rb
77
78
  test/johnson/conversions/thread_test.rb
79
+ test/johnson/custom_conversions_test.rb
78
80
  test/johnson/error_test.rb
79
81
  test/johnson/extensions_test.rb
80
82
  test/johnson/nodes/array_literal_test.rb
@@ -1,7 +1,6 @@
1
1
  = Johnson
2
2
 
3
3
  * http://github.com/jbarnette/johnson
4
- * http://johnson.lighthouseapp.com
5
4
  * http://groups.google.com/group/johnson-talk
6
5
 
7
6
  == Description
@@ -11,7 +10,7 @@ Mozilla SpiderMonkey JavaScript runtime as a C extension.
11
10
 
12
11
  == Examples
13
12
 
14
- # FIXME: write some decent examples
13
+ # FIX: write some decent examples
15
14
  require "johnson"
16
15
 
17
16
  Johnson.evaluate("4 + 4") # => 8
@@ -21,14 +20,9 @@ Mozilla SpiderMonkey JavaScript runtime as a C extension.
21
20
 
22
21
  $ gem install johnson
23
22
 
24
- === TODO
25
-
26
- * Support more than just Mac OS X / Ruby 1.8.6.
27
- * Stop freaking segfaulting.
28
-
29
23
  == License
30
24
 
31
- Copyright 2008-2009 John Barnette,
25
+ Copyright 2008-2010 John Barnette,
32
26
  Aaron Patterson,
33
27
  Yehuda Katz,
34
28
  Matthew Draper
data/Rakefile CHANGED
@@ -1,12 +1,13 @@
1
1
  require "rubygems"
2
2
 
3
- gem "hoe", ">= 2.3"
3
+ gem "hoe", "~> 2.3"
4
4
  require "hoe"
5
5
 
6
- gem "rake-compiler", ">= 0.6.0"
6
+ gem "rake-compiler", "~> 0.6"
7
7
  require "rake/extensiontask"
8
8
 
9
9
  Hoe.plugin :debugging, :doofus, :git
10
+ Hoe.plugins.delete :rubyforge
10
11
 
11
12
  Hoe.spec "johnson" do
12
13
  developer "John Barnette", "jbarnette@rubyforge.org"
@@ -14,24 +15,23 @@ Hoe.spec "johnson" do
14
15
  developer "Yehuda Katz", "wycats@gmail.com"
15
16
  developer "Matthew Draper", "matthew@trebex.net"
16
17
 
17
- self.extra_rdoc_files = FileList["*.rdoc"]
18
- self.history_file = "CHANGELOG.rdoc"
19
- self.readme_file = "README.rdoc"
20
- self.test_globs = %w(test/**/*_test.rb)
18
+ self.extra_rdoc_files = FileList["*.rdoc"]
19
+ self.history_file = "CHANGELOG.rdoc"
20
+ self.readme_file = "README.rdoc"
21
+ self.test_globs = %w(test/**/*_test.rb)
22
+ self.spec_extras[:extensions] = %w(ext/spidermonkey/extconf.rb)
21
23
 
22
- self.spec_extras = { :extensions => %w(ext/spidermonkey/extconf.rb) }
23
-
24
- extra_dev_deps << ["rake-compiler", ">= 0.6.0"]
24
+ extra_dev_deps << ["rake-compiler", "~> 0.6"]
25
25
 
26
26
  clean_globs << "ext/**/Makefile"
27
27
  clean_globs << "ext/**/*.{o,so,bundle,a,log}"
28
28
  clean_globs << "ext/spidermonkey/immutable_node.c"
29
- clean_globs << "lib/johnson/spidermonkey.bundle"
29
+ clean_globs << "lib/johnson/**/*.{bundle,so}"
30
30
  clean_globs << "tmp"
31
31
  clean_globs << "vendor/spidermonkey/**/*.OBJ"
32
32
 
33
33
  Rake::ExtensionTask.new "spidermonkey", spec do |ext|
34
- ext.lib_dir = "lib/johnson"
34
+ ext.lib_dir = "lib/johnson/spidermonkey"
35
35
  end
36
36
  end
37
37
 
@@ -1,9 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")))
4
-
5
3
  require "readline"
6
- require "johnson"
4
+ require "johnson/cli"
7
5
 
8
6
  RUNTIME = js = Johnson::Runtime.new
9
7
  RUNTIME.evaluate(Johnson::CLI::JS)
@@ -35,9 +35,10 @@ static JSBool branch_callback(JSContext* js, JSScript* UNUSED(script))
35
35
 
36
36
  /*
37
37
  * call-seq:
38
- * native_initialize(options={})
38
+ * native_initialize(runtime, options)
39
39
  *
40
- * Initializes the native spidermonkey values.
40
+ * Create the underlying SpiderMonkey context. This must be called
41
+ * first, and only once. Called by +initialize+ by default.
41
42
  */
42
43
  static VALUE
43
44
  initialize_native(VALUE self, VALUE rb_runtime, VALUE UNUSED(options))
@@ -4,12 +4,21 @@
4
4
 
5
5
  DEFINE_RUBY_WRAPPER(convert_to_ruby, convert_to_ruby, ARGLIST2(runtime, js_value))
6
6
 
7
- DECLARE_RUBY_WRAPPER(rb_funcall_0, VALUE obj; ID sym; int argc)
8
- DEFINE_RUBY_WRAPPER(rb_funcall_0, rb_funcall, ARGLIST3(obj, sym, argc))
7
+ DEFINE_RUBY_WRAPPER(convert_js_string_to_ruby, convert_js_string_to_ruby, ARGLIST2(runtime, str))
8
+
9
+ static VALUE convert_regexp_to_ruby(JohnsonRuntime* runtime, jsval regexp);
10
+ DECLARE_RUBY_WRAPPER(convert_regexp_to_ruby, JohnsonRuntime* runtime; jsval regexp)
11
+ DEFINE_RUBY_WRAPPER(convert_regexp_to_ruby, convert_regexp_to_ruby, ARGLIST2(runtime, regexp))
9
12
 
10
- DECLARE_RUBY_WRAPPER(rb_funcall_2, VALUE obj; ID sym; int argc; VALUE a; VALUE b)
13
+ DEFINE_RUBY_WRAPPER(rb_funcall_0, rb_funcall, ARGLIST3(obj, sym, argc))
14
+ DEFINE_RUBY_WRAPPER(rb_funcall_1, rb_funcall, ARGLIST4(obj, sym, argc, a))
11
15
  DEFINE_RUBY_WRAPPER(rb_funcall_2, rb_funcall, ARGLIST5(obj, sym, argc, a, b))
12
16
 
17
+ DECLARE_RUBY_WRAPPER(rb_float_new, double v)
18
+ DEFINE_RUBY_WRAPPER(rb_float_new, rb_float_new, ARGLIST1(v))
19
+
20
+ DEFINE_RUBY_WRAPPER(rb_intern, rb_intern, ARGLIST1(name))
21
+
13
22
  static JSBool convert_float_or_bignum_to_js(JohnsonRuntime* runtime, VALUE float_or_bignum, jsval* retval)
14
23
  {
15
24
  JSContext * context = johnson_get_current_context(runtime);
@@ -21,7 +30,8 @@ static JSBool convert_symbol_to_js(JohnsonRuntime* runtime, VALUE symbol, jsval*
21
30
  JSContext * context = johnson_get_current_context(runtime);
22
31
  PREPARE_JROOTS(context, 2);
23
32
 
24
- VALUE to_s = CALL_RUBY_WRAPPER(rb_funcall_0, symbol, rb_intern("to_s"), 0);
33
+ VALUE to_s = CALL_RUBY_WRAPPER(rb_funcall_0, symbol, RB_INTERN("to_s"), 0);
34
+ CALL_RUBY_WRAPPER(rb_string_value, &to_s);
25
35
  jsval name = STRING_TO_JSVAL(JS_NewStringCopyN(context, StringValuePtr(to_s), (size_t) StringValueLen(to_s)));
26
36
 
27
37
  JROOT(name);
@@ -41,8 +51,9 @@ static JSBool convert_regexp_to_js(JohnsonRuntime* runtime, VALUE regexp, jsval*
41
51
  {
42
52
  JSContext * context = johnson_get_current_context(runtime);
43
53
  PREPARE_JROOTS(context, 0);
44
- VALUE source = rb_funcall(regexp, rb_intern("source"), 0);
45
- jsint options = (jsint)(NUM2INT(rb_funcall(regexp, rb_intern("options"), 0)));
54
+ VALUE source = rb_funcall(regexp, RB_INTERN("source"), 0);
55
+ CALL_RUBY_WRAPPER(rb_string_value, &source);
56
+ jsint options = (jsint)(NUM2INT(rb_funcall(regexp, RB_INTERN("options"), 0)));
46
57
 
47
58
  JSObject* obj = JS_NewRegExpObject(context,
48
59
  StringValuePtr(source),
@@ -102,7 +113,15 @@ JSBool convert_to_js(JohnsonRuntime* runtime, VALUE ruby, jsval* retval)
102
113
 
103
114
  case T_STRING:
104
115
  {
105
- JSString* str = JS_NewStringCopyN(context, StringValuePtr(ruby), (size_t) StringValueLen(ruby));
116
+ CALL_RUBY_WRAPPER(rb_string_value, &ruby);
117
+ const char * src = StringValuePtr(ruby);
118
+ const size_t srclen = StringValueLen(ruby);
119
+ size_t dstlen = 0;
120
+ JCHECK(JS_DecodeBytes(context, src, srclen, NULL, &dstlen));
121
+ jschar* dstchars = JS_malloc(context, sizeof(jschar) * (1 + dstlen));
122
+ JCHECK(dstchars);
123
+ JCHECK(JS_DecodeBytes(context, src, srclen, dstchars, &dstlen));
124
+ JSString* str = JS_NewUCString(context, dstchars, dstlen);
106
125
  JCHECK(str);
107
126
  *retval = STRING_TO_JSVAL(str);
108
127
  JRETURN;
@@ -141,7 +160,7 @@ JSBool convert_to_js(JohnsonRuntime* runtime, VALUE ruby, jsval* retval)
141
160
  JCHECK(convert_regexp_to_js(runtime, ruby, retval));
142
161
  JRETURN;
143
162
 
144
- case T_DATA: // HEY! keep T_DATA last for fall-through
163
+ case T_DATA:
145
164
  if (ruby_value_is_proxy(ruby))
146
165
  JCHECK(unwrap_ruby_land_proxy(runtime, ruby, retval));
147
166
  else // If we can't identify the object, just wrap it
@@ -161,9 +180,18 @@ VALUE convert_js_string_to_ruby(JohnsonRuntime* runtime, JSString* str)
161
180
  JSContext * context = johnson_get_current_context(runtime);
162
181
  PREPARE_RUBY_JROOTS(context, 1);
163
182
  JROOT(str);
164
- char* bytes = JS_GetStringBytes(str);
165
- JCHECK(bytes);
166
- JRETURN_RUBY(rb_str_new(bytes, (signed long)JS_GetStringLength(str)));
183
+ jschar* src = JS_GetStringChars(str);
184
+ JCHECK(src);
185
+ size_t srclen = JS_GetStringLength(str);
186
+ size_t dstlen = 0;
187
+ JCHECK(JS_EncodeCharacters(context, src, srclen, NULL, &dstlen));
188
+ char* dst = JS_malloc(context, sizeof(char) * (1 + dstlen));
189
+ JCHECK(dst);
190
+ JCHECK(JS_EncodeCharacters(context, src, srclen, dst, &dstlen));
191
+ // This will leak dst if rb_str_new raises
192
+ VALUE ruby_str = rb_str_new(dst, dstlen);
193
+ JS_free(context, dst);
194
+ JRETURN_RUBY(ruby_str);
167
195
  }
168
196
 
169
197
  static VALUE convert_regexp_to_ruby(JohnsonRuntime* runtime, jsval regexp)
@@ -173,26 +201,27 @@ static VALUE convert_regexp_to_ruby(JohnsonRuntime* runtime, jsval regexp)
173
201
  JROOT(regexp);
174
202
  JSRegExp* re = (JSRegExp*)JS_GetPrivate(context, JSVAL_TO_OBJECT(regexp));
175
203
 
176
- JRETURN_RUBY(CALL_RUBY_WRAPPER(rb_funcall_2, rb_cRegexp, rb_intern("new"), 2,
177
- convert_js_string_to_ruby(runtime, re->source),
204
+ JRETURN_RUBY(RB_FUNCALL_2(rb_cRegexp, RB_INTERN("new"),
205
+ CONVERT_JS_STRING_TO_RUBY(runtime, re->source),
178
206
  INT2NUM((long)re->flags)));
179
207
  }
180
208
 
181
- static bool js_value_is_regexp(JohnsonRuntime* runtime, jsval maybe_regexp)
209
+ static JSBool js_value_is_regexp(JohnsonRuntime* runtime, jsval maybe_regexp, bool* is_regexp)
182
210
  {
183
211
  JSContext * context = johnson_get_current_context(runtime);
184
- PREPARE_RUBY_JROOTS(context, 1);
212
+ PREPARE_JROOTS(context, 1);
185
213
  JROOT(maybe_regexp);
186
214
  JSBool result = JS_InstanceOf(context, JSVAL_TO_OBJECT(maybe_regexp), &js_RegExpClass, NULL);
187
- JRETURN_RUBY(result ? true : false);
215
+ *is_regexp = (result ? true : false);
216
+ JRETURN;
188
217
  }
189
218
 
190
- static bool js_value_is_symbol(JohnsonRuntime* runtime, jsval maybe_symbol)
219
+ static JSBool js_value_is_symbol(JohnsonRuntime* runtime, jsval maybe_symbol, bool* is_symbol)
191
220
  {
192
221
  jsval nsJohnson, cSymbol;
193
222
  JSContext * context = johnson_get_current_context(runtime);
194
223
 
195
- PREPARE_RUBY_JROOTS(context, 3);
224
+ PREPARE_JROOTS(context, 3);
196
225
  JROOT(maybe_symbol);
197
226
 
198
227
  JCHECK(JS_GetProperty(context, runtime->global, "Johnson", &nsJohnson));
@@ -208,7 +237,8 @@ static bool js_value_is_symbol(JohnsonRuntime* runtime, jsval maybe_symbol)
208
237
  JSBool is_a_symbol;
209
238
  JCHECK(JS_HasInstance(context, JSVAL_TO_OBJECT(cSymbol), maybe_symbol, &is_a_symbol));
210
239
 
211
- JRETURN_RUBY(is_a_symbol != JS_FALSE);
240
+ *is_symbol = (is_a_symbol != JS_FALSE);
241
+ JRETURN;
212
242
  }
213
243
 
214
244
  VALUE convert_to_ruby(JohnsonRuntime* runtime, jsval js)
@@ -229,29 +259,33 @@ VALUE convert_to_ruby(JohnsonRuntime* runtime, jsval js)
229
259
  case JSTYPE_OBJECT:
230
260
  if (OBJECT_TO_JSVAL(runtime->global) == js)
231
261
  // global gets special treatment, since the Prelude might not be loaded
232
- JRETURN_RUBY(make_ruby_land_proxy(runtime, js, "GlobalProxy"));
262
+ JRETURN_RUBY(CALL_RUBY_WRAPPER(make_ruby_land_proxy, runtime, js, "GlobalProxy"));
233
263
 
234
264
  // this conditional requires the Prelude
235
- if (js_value_is_symbol(runtime, js))
236
- JRETURN_RUBY(ID2SYM(rb_intern(JS_GetStringBytes(JS_ValueToString(context, js)))));
265
+ bool is_symbol = false;
266
+ JCHECK(js_value_is_symbol(runtime, js, &is_symbol));
267
+ if (is_symbol)
268
+ JRETURN_RUBY(ID2SYM(RB_INTERN(JS_GetStringBytes(JS_ValueToString(context, js)))));
237
269
 
238
270
  if (js_value_is_proxy(runtime, js))
239
271
  JRETURN_RUBY(unwrap_js_land_proxy(runtime, js));
240
272
 
241
- if (js_value_is_regexp(runtime, js))
242
- JRETURN_RUBY(convert_regexp_to_ruby(runtime, js));
273
+ bool is_regexp = false;
274
+ JCHECK(js_value_is_regexp(runtime, js, &is_regexp));
275
+ if (is_regexp)
276
+ JRETURN_RUBY(CALL_RUBY_WRAPPER(convert_regexp_to_ruby, runtime, js));
243
277
 
244
- JRETURN_RUBY(make_ruby_land_proxy(runtime, js, "RubyLandProxy"));
278
+ JRETURN_RUBY(CALL_RUBY_WRAPPER(make_ruby_land_proxy, runtime, js, LEAKY_ROOT_NAME("RubyLandProxy", JS_GetStringBytes(JS_ValueToString(context, js)))));
245
279
 
246
280
  case JSTYPE_BOOLEAN:
247
281
  JRETURN_RUBY(JSVAL_TRUE == js ? Qtrue : Qfalse);
248
282
 
249
283
  case JSTYPE_STRING:
250
- JRETURN_RUBY(convert_js_string_to_ruby(runtime, JSVAL_TO_STRING(js)));
284
+ JRETURN_RUBY(CONVERT_JS_STRING_TO_RUBY(runtime, JSVAL_TO_STRING(js)));
251
285
 
252
286
  case JSTYPE_NUMBER:
253
287
  if (JSVAL_IS_INT(js)) JRETURN_RUBY(INT2FIX(JSVAL_TO_INT(js)));
254
- else JRETURN_RUBY(rb_float_new(*JSVAL_TO_DOUBLE(js)));
288
+ else JRETURN_RUBY(CALL_RUBY_WRAPPER(rb_float_new, *JSVAL_TO_DOUBLE(js)));
255
289
 
256
290
  default:
257
291
  JERROR("unknown js type in switch");
@@ -8,6 +8,19 @@
8
8
  DECLARE_RUBY_WRAPPER(convert_to_ruby, JohnsonRuntime* runtime; jsval js_value)
9
9
  #define CONVERT_TO_RUBY(runtime, js) CALL_RUBY_WRAPPER(convert_to_ruby, runtime, js)
10
10
 
11
+ DECLARE_RUBY_WRAPPER(convert_js_string_to_ruby, JohnsonRuntime* runtime; JSString* str)
12
+ #define CONVERT_JS_STRING_TO_RUBY(runtime, js) CALL_RUBY_WRAPPER(convert_js_string_to_ruby, runtime, js)
13
+
14
+ DECLARE_RUBY_WRAPPER(rb_funcall_0, VALUE obj; ID sym; int argc)
15
+ #define RB_FUNCALL_0(obj, sym) CALL_RUBY_WRAPPER(rb_funcall_0, obj, sym, 0)
16
+ DECLARE_RUBY_WRAPPER(rb_funcall_1, VALUE obj; ID sym; int argc; VALUE a)
17
+ #define RB_FUNCALL_1(obj, sym, a) CALL_RUBY_WRAPPER(rb_funcall_1, obj, sym, 1, a)
18
+ DECLARE_RUBY_WRAPPER(rb_funcall_2, VALUE obj; ID sym; int argc; VALUE a; VALUE b)
19
+ #define RB_FUNCALL_2(obj, sym, a, b) CALL_RUBY_WRAPPER(rb_funcall_2, obj, sym, 2, a, b)
20
+
21
+ DECLARE_RUBY_WRAPPER(rb_intern, const char* name)
22
+ #define RB_INTERN(name) CALL_RUBY_WRAPPER(rb_intern, name)
23
+
11
24
  JSBool convert_to_js(JohnsonRuntime* runtime, VALUE ruby, jsval* retval);
12
25
  VALUE convert_to_ruby(JohnsonRuntime* runtime, jsval js);
13
26
  VALUE convert_js_string_to_ruby(JohnsonRuntime* runtime, JSString* str);
@@ -3,6 +3,14 @@
3
3
  #include "conversions.h"
4
4
  #include "immutable_node.h"
5
5
 
6
+ static VALUE debugger_class = Qnil;
7
+
8
+ bool ruby_value_is_debugger(VALUE maybe_debugger)
9
+ {
10
+ VALUE klass = CLASS_OF(maybe_debugger);
11
+ return (klass == debugger_class);
12
+ }
13
+
6
14
  /*
7
15
  * call-seq:
8
16
  * frame_pc(context, frame)
@@ -217,10 +225,10 @@ void init_Johnson_SpiderMonkey_Debugger(VALUE spidermonkey)
217
225
  */
218
226
 
219
227
  /* This is the debugging hooks used with SpiderMonkey. */
220
- VALUE debugger = rb_define_class_under(spidermonkey, "Debugger", rb_cObject);
221
- rb_define_private_method(debugger, "frame_pc", frame_pc, 2);
222
- rb_define_private_method(debugger, "line_number", line_number, 3);
223
- rb_define_private_method(debugger, "file_name", file_name, 2);
228
+ debugger_class = rb_define_class_under(spidermonkey, "Debugger", rb_cObject);
229
+ rb_define_private_method(debugger_class, "frame_pc", frame_pc, 2);
230
+ rb_define_private_method(debugger_class, "line_number", line_number, 3);
231
+ rb_define_private_method(debugger_class, "file_name", file_name, 2);
224
232
 
225
- rb_define_alloc_func(debugger, allocate);
233
+ rb_define_alloc_func(debugger_class, allocate);
226
234
  }
@@ -5,5 +5,6 @@
5
5
  #include "jsdbgapi.h"
6
6
 
7
7
  void init_Johnson_SpiderMonkey_Debugger(VALUE spidermonkey);
8
+ bool ruby_value_is_debugger(VALUE maybe_debugger);
8
9
 
9
10
  #endif
@@ -1,5 +1,4 @@
1
- # this needs to happen before mkmf is required
2
- ENV["ARCHFLAGS"] = "-arch #{`uname -p` =~ /powerpc/ ? 'ppc' : 'i386'}"
1
+ ENV["RC_ARCHS"] = "" if RUBY_PLATFORM =~ /darwin/
3
2
 
4
3
  require "find"
5
4
  require "mkmf"
@@ -30,4 +29,4 @@ dir_config "johnson/spidermonkey"
30
29
  find_header "jsautocfg.h", File.dirname(libjs)
31
30
  find_header "jsapi.h", spidermonkey_dir
32
31
 
33
- create_makefile "johnson/spidermonkey"
32
+ create_makefile "johnson/spidermonkey/spidermonkey"
@@ -148,15 +148,18 @@
148
148
  #define JERROR(format, args...) \
149
149
  do \
150
150
  { \
151
- REMOVE_JROOTS; \
152
151
  char _jroot_msg[_JROOT_ERRSIZE]; \
153
152
  snprintf(_jroot_msg, _JROOT_ERRSIZE, (format) , ## args); \
154
153
  if (_jroot_ruby) \
154
+ { \
155
+ REMOVE_JROOTS; \
155
156
  rb_raise(rb_eRuntimeError, _jroot_msg); \
157
+ } \
156
158
  else \
157
159
  { \
158
160
  JSString* _jroot_err_str = JS_NewStringCopyZ(_jroot_context, _jroot_msg); \
159
161
  if (_jroot_err_str) JS_SetPendingException(_jroot_context, STRING_TO_JSVAL(_jroot_err_str)); \
162
+ REMOVE_JROOTS; \
160
163
  return JS_FALSE; \
161
164
  } \
162
165
  } while(0)
@@ -179,6 +182,13 @@
179
182
  name ## _args * _data = (name ## _args *)(FIX2LONG(magic) << 2); \
180
183
  return func(arglist); \
181
184
  }
185
+ #define DEFINE_VOID_RUBY_WRAPPER(name, func, arglist) \
186
+ VALUE name ## _invoke(VALUE magic) \
187
+ { \
188
+ name ## _args * _data = (name ## _args *)(FIX2LONG(magic) << 2); \
189
+ func(arglist); \
190
+ return Qnil; \
191
+ }
182
192
  #define RUBY_WRAPPER_ARG(name, args...) ({ name ## _args _x = { args }; LONG2FIX((long)(&_x) >> 2); })
183
193
  #define RUBY_WRAPPER(name) name ## _invoke
184
194
  #define CALL_RUBY_WRAPPER(name, args...) JPROTECT(RUBY_WRAPPER(name), RUBY_WRAPPER_ARG(name, args))