Skip to content
This repository has been archived by the owner on Aug 18, 2018. It is now read-only.

Commit

Permalink
An initial, incomplete JohnsonRuntime.
Browse files Browse the repository at this point in the history
  • Loading branch information
jbarnette committed May 30, 2008
1 parent 9f0bede commit 54a6d97
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 1 deletion.
4 changes: 4 additions & 0 deletions Manifest.txt
Expand Up @@ -28,6 +28,8 @@ ext/spidermonkey/js_land_proxy.c
ext/spidermonkey/js_land_proxy.h
ext/spidermonkey/ruby_land_proxy.c
ext/spidermonkey/ruby_land_proxy.h
ext/spidermonkey/runtime.c
ext/spidermonkey/runtime.h
ext/spidermonkey/spidermonkey.c
ext/spidermonkey/spidermonkey.h
js/johnson/browser.js
Expand Down Expand Up @@ -55,6 +57,7 @@ lib/johnson/spidermonkey/immutable_node.rb
lib/johnson/spidermonkey/js_land_proxy.rb
lib/johnson/spidermonkey/mutable_tree_visitor.rb
lib/johnson/spidermonkey/ruby_land_proxy.rb
lib/johnson/spidermonkey/runtime.rb
lib/johnson/version.rb
lib/johnson/visitable.rb
lib/johnson/visitors.rb
Expand Down Expand Up @@ -108,6 +111,7 @@ test/johnson/spidermonkey/context_test.rb
test/johnson/spidermonkey/immutable_node_test.rb
test/johnson/spidermonkey/js_land_proxy_test.rb
test/johnson/spidermonkey/ruby_land_proxy_test.rb
test/johnson/spidermonkey/runtime_test.rb
test/johnson/version_test.rb
test/johnson/visitors/dot_visitor_test.rb
test/johnson_test.rb
Expand Down
5 changes: 5 additions & 0 deletions ext/spidermonkey/global.c
Expand Up @@ -38,3 +38,8 @@ JSObject* create_global_object(OurContext* context)
{
return JS_NewObject(context->js, &OurGlobalClass, NULL, NULL);
}

JSObject* johnson_create_global_object(JSContext* context)
{
return JS_NewObject(context, &OurGlobalClass, NULL, NULL);
}
6 changes: 5 additions & 1 deletion ext/spidermonkey/global.h
Expand Up @@ -3,7 +3,11 @@

#include "spidermonkey.h"
#include "context.h"
#include "runtime.h"

JSObject* create_global_object(OurContext* context);
JSObject* create_global_object(OurContext* context); // FIXME: remove or rename

// NOTE: one of the FEW places a context should be passed around
JSObject* johnson_create_global_object(JSContext* context);

#endif
102 changes: 102 additions & 0 deletions ext/spidermonkey/runtime.c
@@ -0,0 +1,102 @@
#include "runtime.h"
#include "error.h"
#include "global.h"
#include "idhash.h"

JSContext* johnson_get_current_context(JohnsonRuntime* runtime)
{
// First, see if we already have a context for the current thread.
JSContext* context = (JSContext*)JS_HashTableLookup(runtime->contexts, (void*)rb_thread_current());

// If not,
if (!context)
{
// try and create one.
if ((context = JS_NewContext(runtime->js, 8192)))
{
// See if the runtime already has a shared global object.
JSObject* global = runtime->global;

// If it does, use it. If not,
if (!global)
// create one of our global objects.
global = johnson_create_global_object(context);

// Manually set the context's global object.
JS_SetGlobalObject(context, global);

// Register this context (thread -> context) for lookup next time.
JS_HashTableAdd(runtime->contexts, (void*)rb_thread_current(), (void*) context);

// Success.
return context;
}

// Something went wrong! If a context was created,
if (context)
// destroy it safely.
JS_DestroyContext(context);

// Scream for help.
Johnson_Error_raise("Unable to create Johnson::SpiderMonkey::Runtime!");
}

// Success. Already had a context for the current thread.
return context;
}

static VALUE
initialize_native(VALUE self, VALUE UNUSED(options))
{
JohnsonRuntime* runtime;
Data_Get_Struct(self, JohnsonRuntime, runtime);

if ((runtime->js = JS_NewRuntime(0x100000))
&& (runtime->contexts = create_id_hash()))
{
JSContext* context = johnson_get_current_context(runtime);
runtime->global = JS_GetGlobalObject(context);
JS_AddNamedRoot(context, &(runtime->global), "runtime->global");

return self;
}

if (runtime->contexts)
JS_HashTableDestroy(runtime->contexts);

if (runtime->js)
JS_DestroyRuntime(runtime->js);

return Johnson_Error_raise("Couldn't initialize the runtime!");
}

static void deallocate(JohnsonRuntime* runtime)
{
JS_RemoveRoot(johnson_get_current_context(runtime), &(runtime->global));

JS_HashTableDestroy(runtime->contexts);
runtime->contexts = 0;

JSContext *context;
JSContext *iterator = NULL;

while ((context = JS_ContextIterator(runtime->js, &iterator)) != NULL)
JS_DestroyContext(context);

JS_DestroyRuntime(runtime->js);
free(runtime);
}

static VALUE allocate(VALUE klass)
{
JohnsonRuntime* runtime = calloc(1, sizeof(JohnsonRuntime));
return Data_Wrap_Struct(klass, 0, deallocate, runtime);
}

void init_Johnson_SpiderMonkey_Runtime(VALUE spidermonkey)
{
VALUE klass = rb_define_class_under(spidermonkey, "Runtime", rb_cObject);

rb_define_alloc_func(klass, allocate);
rb_define_private_method(klass, "initialize_native", initialize_native, 1);
}
15 changes: 15 additions & 0 deletions ext/spidermonkey/runtime.h
@@ -0,0 +1,15 @@
#ifndef JOHNSON_SPIDERMONKEY_RUNTIME_H
#define JOHNSON_SPIDERMONKEY_RUNTIME_H

#include "spidermonkey.h"

typedef struct {
JSHashTable* contexts;
JSObject* global;
JSRuntime* js;
} JohnsonRuntime;

JSContext* johnson_get_current_context(JohnsonRuntime* runtime);
void init_Johnson_SpiderMonkey_Runtime(VALUE spidermonkey);

#endif
1 change: 1 addition & 0 deletions ext/spidermonkey/spidermonkey.c
Expand Up @@ -15,6 +15,7 @@ void Init_spidermonkey()
init_Johnson_SpiderMonkey_Proxy(spidermonkey);
init_Johnson_SpiderMonkey_Debugger(spidermonkey);
init_Johnson_SpiderMonkey_Immutable_Node(spidermonkey);
init_Johnson_SpiderMonkey_Runtime(spidermonkey);

rb_define_const(spidermonkey, "VERSION",
rb_obj_freeze(rb_str_new2(JS_GetImplementationVersion())));
Expand Down
1 change: 1 addition & 0 deletions lib/johnson.rb
Expand Up @@ -15,6 +15,7 @@
require "johnson/nodes"

# the SpiderMonkey bits written in Ruby
require "johnson/spidermonkey/runtime"
require "johnson/spidermonkey/context"
require "johnson/spidermonkey/js_land_proxy"
require "johnson/spidermonkey/ruby_land_proxy"
Expand Down
9 changes: 9 additions & 0 deletions lib/johnson/spidermonkey/runtime.rb
@@ -0,0 +1,9 @@
module Johnson #:nodoc:
module SpiderMonkey #:nodoc:
class Runtime # native
def initialize(options={})
initialize_native(options)
end
end
end
end
15 changes: 15 additions & 0 deletions test/johnson/spidermonkey/runtime_test.rb
@@ -0,0 +1,15 @@
require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))

module Johnson
module SpiderMonkey
class RuntimeTest < Johnson::TestCase
def setup
@runtime = Johnson::SpiderMonkey::Runtime.new
end

def test_can_create_more_than_one_without_barfing
Johnson::SpiderMonkey::Runtime.new
end
end
end
end

0 comments on commit 54a6d97

Please sign in to comment.