Permalink
Browse files

Runtime is the new Context. One context per Ruby thread.

  • Loading branch information...
jbarnette committed May 31, 2008
1 parent 794e0ac commit ae3584f2d4e47d82c063c89631bcd8b23acfd9db
Showing with 770 additions and 718 deletions.
  1. +28 −159 ext/spidermonkey/context.c
  2. +1 −7 ext/spidermonkey/context.h
  3. +68 −55 ext/spidermonkey/conversions.c
  4. +8 −7 ext/spidermonkey/conversions.h
  5. +4 −4 ext/spidermonkey/debugger.c
  6. +4 −3 ext/spidermonkey/extensions.c
  7. +3 −1 ext/spidermonkey/extensions.h
  8. +1 −6 ext/spidermonkey/global.c
  9. +0 −2 ext/spidermonkey/global.h
  10. +22 −12 ext/spidermonkey/jroot.h
  11. +121 −84 ext/spidermonkey/js_land_proxy.c
  12. +4 −4 ext/spidermonkey/js_land_proxy.h
  13. +83 −68 ext/spidermonkey/ruby_land_proxy.c
  14. +4 −4 ext/spidermonkey/ruby_land_proxy.h
  15. +171 −44 ext/spidermonkey/runtime.c
  16. +4 −1 ext/spidermonkey/runtime.h
  17. +1 −1 js/johnson/prelude.js
  18. +4 −4 lib/johnson.rb
  19. +3 −3 lib/johnson/{context.rb → runtime.rb}
  20. +3 −30 lib/johnson/spidermonkey/context.rb
  21. +1 −1 lib/johnson/spidermonkey/ruby_land_proxy.rb
  22. +33 −0 lib/johnson/spidermonkey/runtime.rb
  23. +5 −5 test/helper.rb
  24. +4 −4 test/johnson/browser_test.rb
  25. +10 −10 test/johnson/conversions/array_test.rb
  26. +5 −5 test/johnson/conversions/boolean_test.rb
  27. +7 −7 test/johnson/conversions/callable_test.rb
  28. +4 −4 test/johnson/conversions/file_test.rb
  29. +5 −5 test/johnson/conversions/nil_test.rb
  30. +8 −8 test/johnson/conversions/number_test.rb
  31. +11 −11 test/johnson/conversions/regexp_test.rb
  32. +7 −7 test/johnson/conversions/string_test.rb
  33. +4 −4 test/johnson/conversions/struct_test.rb
  34. +6 −6 test/johnson/conversions/symbol_test.rb
  35. +13 −2 test/johnson/conversions/thread_test.rb
  36. +14 −14 test/johnson/extensions_test.rb
  37. +9 −9 test/johnson/prelude_test.rb
  38. +5 −5 test/johnson/{context_test.rb → runtime_test.rb}
  39. +6 −6 test/johnson/spidermonkey/context_test.rb
  40. +39 −39 test/johnson/spidermonkey/js_land_proxy_test.rb
  41. +33 −33 test/johnson/spidermonkey/ruby_land_proxy_test.rb
  42. +3 −1 test/johnson/spidermonkey/runtime_test.rb
  43. +1 −1 test/johnson_test.rb
  44. +0 −1 test/parser_test.rb
  45. 0 todo/.keep
  46. +0 −31 todo/threading_test.rb
View
@@ -6,103 +6,15 @@
#include "idhash.h"
#include "jsdbgapi.h"
-/*
- * call-seq:
- * global
- *
- * Returns the global object used for this context.
- */
-static VALUE global(VALUE self)
-{
- OurContext* context;
- Data_Get_Struct(self, OurContext, context);
- return convert_to_ruby(context, OBJECT_TO_JSVAL(context->global));
-}
-
-/*
- * call-seq:
- * evaluate(script, filename=nil, linenum=nil)
- *
- * Evaluate +script+ with +filename+ using +linenum+
- */
-static VALUE evaluate(int argc, VALUE* argv, VALUE self)
-{
- VALUE script, filename, linenum;
-
- OurContext* context;
- Data_Get_Struct(self, OurContext, context);
-
- rb_scan_args( argc, argv, "12", &script, &filename, &linenum );
-
- // clean things up first
- context->ex = 0;
- memset(context->msg, 0, MAX_EXCEPTION_MESSAGE_SIZE);
-
- const char* filenamez = RTEST(filename) ? StringValueCStr(filename) : "none";
- int linenumi = RTEST(linenum) ? NUM2INT(linenum) : 1;
-
- jsval js;
-
- // FIXME: should be able to pass in the 'file' name
- JSBool ok = JS_EvaluateScript(context->js, context->global,
- StringValuePtr(script), (unsigned)StringValueLen(script), filenamez, (unsigned)linenumi, &js);
-
- if (!ok)
- {
- if (JS_IsExceptionPending(context->js))
- {
- // If there's an exception pending here, it's a syntax error.
- JS_GetPendingException(context->js, &context->ex);
- JS_ClearPendingException(context->js);
- }
-
- if (context->ex)
- {
- return rb_funcall(self, rb_intern("handle_js_exception"),
- 1, convert_to_ruby(context, context->ex));
-
- // VALUE message, file, line, stack;
- //
- // jsval js_message;
- // assert(JS_GetProperty(context->js, JSVAL_TO_OBJECT(context->ex), "message", &js_message));
- // message = convert_to_ruby(context, js_message);
- //
- // jsval js_file;
- // assert(JS_GetProperty(context->js, JSVAL_TO_OBJECT(context->ex), "fileName", &js_file));
- // file = convert_to_ruby(context, js_file);
- //
- // jsval js_line;
- // assert(JS_GetProperty(context->js, JSVAL_TO_OBJECT(context->ex), "lineNumber", &js_line));
- // line = convert_to_ruby(context, js_line);
- //
- // jsval js_stack;
- // assert(JS_GetProperty(context->js, JSVAL_TO_OBJECT(context->ex), "stack", &js_stack));
- // stack = convert_to_ruby(context, js_stack);
- //
- // return rb_funcall(self, rb_intern("handle_js_exception"),
- // 4, message, file, line, stack);
- }
-
- char* msg = context->msg;
-
- // toString() whatever the exception object is (if we have one)
- if (context->ex) msg = JS_GetStringBytes(JS_ValueToString(context->js, context->ex));
-
- return Johnson_Error_raise(msg);
- }
-
- return convert_to_ruby(context, js);
-}
-
// callback for JS_SetErrorReporter
static void report_js_error(JSContext* js, const char* message, JSErrorReport* UNUSED(report))
{
// first we find ourselves
VALUE self = (VALUE)JS_GetContextPrivate(js);
// then we find our bridge
- OurContext* context;
- Data_Get_Struct(self, OurContext, context);
+ JohnsonContext* context;
+ Data_Get_Struct(self, JohnsonContext, context);
// NOTE: SpiderMonkey REALLY doesn't like being interrupted. If we
// jump over to Ruby and raise here, segfaults and such ensue.
@@ -124,80 +36,52 @@ static JSBool branch_callback(JSContext* js, JSScript* UNUSED(script))
/*
* call-seq:
- * debugger=(debugger)
+ * native_initialize(options={})
*
- * Sets a debugger object
+ * Initializes the native spidermonkey values.
*/
static VALUE
-set_debugger(VALUE self, VALUE debugger)
+initialize_native(VALUE self, VALUE rb_runtime, VALUE UNUSED(options))
{
- OurContext* context;
- JSDebugHooks* debug_hooks;
+ JohnsonContext* context;
+ JohnsonRuntime* runtime;
- Data_Get_Struct(self, OurContext, context);
- Data_Get_Struct(debugger, JSDebugHooks, debug_hooks);
+ Data_Get_Struct(self, JohnsonContext, context);
+ Data_Get_Struct(rb_runtime, JohnsonRuntime, runtime);
- JS_SetContextDebugHooks(context->js, debug_hooks);
+ if ((context->js = JS_NewContext(runtime->js, 8192)))
+ {
+ // See if the runtime already has a shared global object.
+ JSObject* global = runtime->global;
- return debugger;
-}
+ // If it does, use it. If not,
+ if (!global)
+ // create one of our global objects.
+ global = johnson_create_global_object(context->js);
-/*
- * call-seq:
- * native_initialize(options={})
- *
- * Initializes the native spidermonkey values.
- */
-static VALUE
-initialize_native(VALUE self, VALUE UNUSED(options))
-{
- OurContext* context;
- bool gthings_rooted_p = false;
-
- Data_Get_Struct(self, OurContext, context);
-
- if ((context->runtime = JS_NewRuntime(0x100000))
- && (context->js = JS_NewContext(context->runtime, 8192))
- && (context->jsids = create_id_hash())
- && (context->rbids = create_id_hash())
- && (context->gcthings = JS_NewObject(context->js, NULL, 0, 0))
- && (gthings_rooted_p = JS_AddNamedRoot(context->js, &(context->gcthings), "context->gcthings"))
- && (context->global = create_global_object(context))
- && (JS_AddNamedRoot(context->js, &(context->global), "context->global")))
- {
+ // Manually set the context's global object.
+ JS_SetGlobalObject(context->js, global);
JS_SetErrorReporter(context->js, report_js_error);
JS_SetBranchCallback(context->js, branch_callback);
JS_SetContextPrivate(context->js, (void *)self);
JS_SetOptions(context->js, JS_GetOptions(context->js)
#ifdef JSOPTION_DONT_REPORT_UNCAUGHT
- | JSOPTION_DONT_REPORT_UNCAUGHT
+ | JSOPTION_DONT_REPORT_UNCAUGHT
#endif
#ifdef JSOPTION_VAROBJFIX
- | JSOPTION_VAROBJFIX
+ | JSOPTION_VAROBJFIX
#endif
#ifdef JSOPTION_XML
- | JSOPTION_XML
+ | JSOPTION_XML
#endif
- );
+ );
+ // Success.
return init_spidermonkey_extensions(context, self);
}
- if (gthings_rooted_p)
- JS_RemoveRoot(context->js, &(context->gcthings));
-
- if (context->rbids)
- JS_HashTableDestroy(context->rbids);
-
- if (context->jsids)
- JS_HashTableDestroy(context->jsids);
-
- if (context->js)
- JS_DestroyContext(context->js);
-
- if (context->runtime)
- JS_DestroyRuntime(context->runtime);
+ if (context->js) JS_DestroyContext(context->js);
rb_raise(rb_eRuntimeError, "Failed to initialize SpiderMonkey context");
}
@@ -206,27 +90,16 @@ initialize_native(VALUE self, VALUE UNUSED(options))
//// INFRASTRUCTURE BELOW HERE ////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
-static void deallocate(OurContext* context)
+static void deallocate(JohnsonContext* context)
{
JS_SetContextPrivate(context->js, 0);
-
- JS_RemoveRoot(context->js, &(context->global));
- JS_RemoveRoot(context->js, &(context->gcthings));
- JS_HashTableDestroy(context->rbids);
- JS_HashTableDestroy(context->jsids);
-
- context->jsids = 0;
- context->rbids = 0;
-
JS_DestroyContext(context->js);
- JS_DestroyRuntime(context->runtime);
-
free(context);
}
static VALUE allocate(VALUE klass)
{
- OurContext* context = calloc(1, sizeof(OurContext));
+ JohnsonContext* context = calloc(1, sizeof(JohnsonContext));
return Data_Wrap_Struct(klass, 0, deallocate, context);
}
@@ -241,11 +114,7 @@ void init_Johnson_SpiderMonkey_Context(VALUE spidermonkey)
VALUE context = rb_define_class_under(spidermonkey, "Context", rb_cObject);
rb_define_alloc_func(context, allocate);
- rb_define_private_method(context, "initialize_native", initialize_native, 1);
-
- rb_define_method(context, "global", global, 0);
- rb_define_method(context, "evaluate", evaluate, -1);
- rb_define_method(context, "debugger=", set_debugger, 1);
+ rb_define_private_method(context, "initialize_native", initialize_native, 2);
}
VALUE Johnson_SpiderMonkey_JSLandProxy()
@@ -7,17 +7,11 @@
typedef struct {
JSContext *js;
- JSObject *global;
- JSRuntime *runtime;
-
- JSHashTable *jsids; // jsid -> rbid
- JSHashTable *rbids; // rbid -> jsid
- JSObject *gcthings;
jsval ex; // an exception value
char msg[MAX_EXCEPTION_MESSAGE_SIZE]; // the 'backup' message
-} OurContext;
+} JohnsonContext;
void init_Johnson_SpiderMonkey_Context(VALUE spidermonkey);
VALUE Johnson_SpiderMonkey_JSLandProxy();
Oops, something went wrong.

0 comments on commit ae3584f

Please sign in to comment.