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.
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))