therubyracer 0.8.2 → 0.9.0beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of therubyracer might be problematic. Click here for more details.
- data/Changelog.md +1 -1
- data/ext/v8/rr.cpp +14 -7
- data/ext/v8/rr.h +1 -0
- data/ext/v8/v8.cpp +27 -25
- data/ext/v8/v8_array.cpp +7 -9
- data/ext/v8/v8_callbacks.cpp +1 -1
- data/ext/v8/{v8_cxt.cpp → v8_context.cpp} +11 -11
- data/ext/v8/{v8_cxt.h → v8_context.h} +1 -1
- data/ext/v8/v8_date.cpp +6 -6
- data/ext/v8/v8_exception.cpp +10 -11
- data/ext/v8/v8_external.cpp +7 -24
- data/ext/v8/v8_external.h +0 -1
- data/ext/v8/{v8_func.cpp → v8_function.cpp} +14 -14
- data/ext/v8/{v8_func.h → v8_function.h} +1 -2
- data/ext/v8/v8_handle.cpp +119 -0
- data/ext/v8/v8_handle.h +27 -0
- data/ext/v8/{v8_msg.cpp → v8_message.cpp} +8 -9
- data/ext/v8/{v8_msg.h → v8_message.h} +1 -1
- data/ext/v8/{v8_obj.cpp → v8_object.cpp} +51 -29
- data/ext/v8/{v8_obj.h → v8_object.h} +3 -4
- data/ext/v8/v8_script.cpp +5 -5
- data/ext/v8/{v8_str.cpp → v8_string.cpp} +9 -11
- data/ext/v8/{v8_str.h → v8_string.h} +1 -1
- data/ext/v8/v8_template.cpp +113 -98
- data/ext/v8/v8_try_catch.cpp +1 -1
- data/ext/v8/v8_v8.cpp +7 -0
- data/ext/v8/v8_value.cpp +44 -36
- data/ext/v8/v8_value.h +2 -2
- data/ext/v8/v8_weakref.cpp +51 -0
- data/ext/v8/v8_weakref.h +30 -0
- data/lib/v8.rb +6 -1
- data/lib/v8/context.rb +13 -3
- data/lib/v8/error.rb +1 -1
- data/lib/v8/portal.rb +26 -277
- data/lib/v8/portal/caller.rb +36 -0
- data/lib/v8/portal/constructor.rb +98 -0
- data/lib/v8/portal/function.rb +48 -0
- data/lib/v8/portal/interceptors.rb +153 -0
- data/lib/v8/portal/proxies.rb +102 -0
- data/lib/v8/portal/templates.rb +73 -0
- data/lib/v8/version.rb +1 -1
- data/spec/ext/array_spec.rb +15 -0
- data/spec/ext/cxt_spec.rb +4 -4
- data/spec/ext/ext_spec_helper.rb +43 -0
- data/spec/ext/mem_spec.rb +42 -0
- data/spec/ext/object_spec.rb +22 -0
- data/spec/redjs/jsapi_spec.rb +4 -4
- data/spec/spec_helper.rb +1 -1
- data/spec/v8/portal/proxies_spec.rb +189 -0
- metadata +38 -42
- data/ext/v8/v8_ref.cpp +0 -37
- data/ext/v8/v8_ref.h +0 -28
- data/lib/v8/portal/functions.rb +0 -45
@@ -0,0 +1,119 @@
|
|
1
|
+
|
2
|
+
#include "rr.h"
|
3
|
+
#include "v8_handle.h"
|
4
|
+
|
5
|
+
using namespace v8;
|
6
|
+
|
7
|
+
v8_handle::v8_handle(Handle<void> handle) : handle(Persistent<void>::New(handle)) {
|
8
|
+
this->weakref_callback = Qnil;
|
9
|
+
this->weakref_callback_parameters = Qnil;
|
10
|
+
this->dead = false;
|
11
|
+
}
|
12
|
+
|
13
|
+
v8_handle::~v8_handle() {
|
14
|
+
handle.Dispose();
|
15
|
+
handle.Clear();
|
16
|
+
dead = true;
|
17
|
+
}
|
18
|
+
|
19
|
+
namespace {
|
20
|
+
void v8_handle_mark(v8_handle* handle) {
|
21
|
+
rb_gc_mark(handle->weakref_callback);
|
22
|
+
rb_gc_mark(handle->weakref_callback_parameters);
|
23
|
+
}
|
24
|
+
|
25
|
+
void v8_handle_free(v8_handle* handle) {
|
26
|
+
delete handle;
|
27
|
+
}
|
28
|
+
|
29
|
+
VALUE New(VALUE self, VALUE handle) {
|
30
|
+
if (RTEST(handle)) {
|
31
|
+
Persistent<void> that = rr_v8_handle<void>(handle);
|
32
|
+
return rr_v8_handle_new(self, that);
|
33
|
+
} else {
|
34
|
+
return rr_v8_handle_new(self, Handle<void>());
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
VALUE IsEmpty(VALUE self) {
|
39
|
+
return rr_v82rb(rr_v8_handle<void>(self).IsEmpty());
|
40
|
+
}
|
41
|
+
|
42
|
+
VALUE Clear(VALUE self) {
|
43
|
+
rr_v8_handle<void>(self).Clear();
|
44
|
+
return Qnil;
|
45
|
+
}
|
46
|
+
|
47
|
+
VALUE Dispose(VALUE self) {
|
48
|
+
rr_v8_handle<void>(self).Dispose();
|
49
|
+
return Qnil;
|
50
|
+
}
|
51
|
+
|
52
|
+
void RubyWeakReferenceCallback(Persistent<Value> value, void* parameter) {
|
53
|
+
VALUE self = (VALUE)parameter;
|
54
|
+
v8_handle* handle = rr_v8_handle_raw(self);
|
55
|
+
VALUE callback = handle->weakref_callback;
|
56
|
+
VALUE parameters = handle->weakref_callback_parameters;
|
57
|
+
if (RTEST(callback)) {
|
58
|
+
rb_funcall(callback, rb_intern("call"), 2, self, parameters);
|
59
|
+
}
|
60
|
+
value.Dispose();
|
61
|
+
handle->handle.Dispose();
|
62
|
+
handle->handle.Clear();
|
63
|
+
handle->dead = true;
|
64
|
+
|
65
|
+
}
|
66
|
+
|
67
|
+
VALUE MakeWeak(VALUE self, VALUE parameters, VALUE callback) {
|
68
|
+
v8_handle* handle = rr_v8_handle_raw(self);
|
69
|
+
handle->weakref_callback = callback;
|
70
|
+
handle->weakref_callback_parameters = parameters;
|
71
|
+
rr_v8_handle<void>(self).MakeWeak((void*)self, RubyWeakReferenceCallback);
|
72
|
+
return Qnil;
|
73
|
+
}
|
74
|
+
|
75
|
+
VALUE ClearWeak(VALUE self) {
|
76
|
+
rr_v8_handle<void>(self).ClearWeak();
|
77
|
+
return Qnil;
|
78
|
+
}
|
79
|
+
|
80
|
+
VALUE IsNearDeath(VALUE self) {
|
81
|
+
return rr_v82rb(rr_v8_handle<void>(self).IsNearDeath());
|
82
|
+
}
|
83
|
+
|
84
|
+
VALUE IsWeak(VALUE self) {
|
85
|
+
return rr_v82rb(rr_v8_handle<void>(self).IsWeak());
|
86
|
+
}
|
87
|
+
|
88
|
+
VALUE dead_p(VALUE self) {
|
89
|
+
return rr_v8_handle_raw(self)->dead ? Qtrue : Qfalse;
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
void rr_init_handle() {
|
94
|
+
VALUE HandleClass = rr_define_class("Handle");
|
95
|
+
rr_define_method(HandleClass, "dead?", dead_p, 0);
|
96
|
+
rr_define_singleton_method(HandleClass, "New", New, 1);
|
97
|
+
rr_define_method(HandleClass, "IsEmpty", IsEmpty, 0);
|
98
|
+
rr_define_method(HandleClass, "Clear", Clear, 0);
|
99
|
+
rr_define_method(HandleClass, "Dispose", Dispose, 0);
|
100
|
+
rr_define_method(HandleClass, "MakeWeak", MakeWeak, 2);
|
101
|
+
rr_define_method(HandleClass, "ClearWeak", ClearWeak, 0);
|
102
|
+
rr_define_method(HandleClass, "IsNearDeath", IsNearDeath, 0);
|
103
|
+
rr_define_method(HandleClass, "IsWeak", IsWeak, 0);
|
104
|
+
}
|
105
|
+
|
106
|
+
VALUE rr_v8_handle_new(VALUE klass, v8::Handle<void> handle) {
|
107
|
+
v8_handle* new_handle = new v8_handle(handle);
|
108
|
+
return Data_Wrap_Struct(klass, v8_handle_mark, v8_handle_free, new_handle);
|
109
|
+
}
|
110
|
+
|
111
|
+
VALUE rr_v8_handle_class() {
|
112
|
+
return rr_define_class("Handle");
|
113
|
+
}
|
114
|
+
|
115
|
+
v8_handle* rr_v8_handle_raw(VALUE value) {
|
116
|
+
v8_handle* handle = 0;
|
117
|
+
Data_Get_Struct(value, struct v8_handle, handle);
|
118
|
+
return handle;
|
119
|
+
}
|
data/ext/v8/v8_handle.h
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#ifndef _RR_V8_HANDLE_
|
2
|
+
#define _RR_V8_HANDLE_
|
3
|
+
|
4
|
+
#include <v8.h>
|
5
|
+
#include "ruby.h"
|
6
|
+
|
7
|
+
struct v8_handle {
|
8
|
+
v8_handle(v8::Handle<void> object);
|
9
|
+
virtual ~v8_handle();
|
10
|
+
|
11
|
+
v8::Persistent<void> handle;
|
12
|
+
bool dead;
|
13
|
+
VALUE weakref_callback;
|
14
|
+
VALUE weakref_callback_parameters;
|
15
|
+
};
|
16
|
+
|
17
|
+
void rr_init_handle();
|
18
|
+
|
19
|
+
v8_handle* rr_v8_handle_raw(VALUE value);
|
20
|
+
|
21
|
+
template <class T> v8::Persistent<T>& rr_v8_handle(VALUE value) {
|
22
|
+
return (v8::Persistent<T>&)(rr_v8_handle_raw(value)->handle);
|
23
|
+
}
|
24
|
+
VALUE rr_v8_handle_new(VALUE rbclass, v8::Handle<void> handle);
|
25
|
+
VALUE rr_v8_handle_class();
|
26
|
+
|
27
|
+
#endif
|
@@ -1,18 +1,17 @@
|
|
1
|
-
#include "
|
2
|
-
#include "
|
1
|
+
#include "v8_message.h"
|
2
|
+
#include "v8_handle.h"
|
3
3
|
|
4
4
|
using namespace v8;
|
5
5
|
|
6
6
|
namespace {
|
7
7
|
VALUE MessageClass;
|
8
8
|
|
9
|
-
|
10
|
-
return
|
9
|
+
Persistent<Message>& unwrap(VALUE self) {
|
10
|
+
return rr_v8_handle<Message>(self);
|
11
11
|
}
|
12
12
|
|
13
13
|
VALUE Get(VALUE self) {
|
14
|
-
|
15
|
-
return rr_v82rb(message->Get());
|
14
|
+
return rr_v82rb(unwrap(self)->Get());
|
16
15
|
}
|
17
16
|
|
18
17
|
VALUE GetSourceLine(VALUE self) {
|
@@ -49,8 +48,8 @@ namespace {
|
|
49
48
|
}
|
50
49
|
}
|
51
50
|
|
52
|
-
void
|
53
|
-
MessageClass = rr_define_class("Message");
|
51
|
+
void rr_init_message() {
|
52
|
+
MessageClass = rr_define_class("Message", rr_v8_handle_class());
|
54
53
|
rr_define_method(MessageClass, "Get", Get, 0);
|
55
54
|
rr_define_method(MessageClass, "GetSourceLine", GetSourceLine, 0);
|
56
55
|
rr_define_method(MessageClass, "GetScriptResourceName", GetScriptResourceName, 0);
|
@@ -63,6 +62,6 @@ void rr_init_msg() {
|
|
63
62
|
}
|
64
63
|
|
65
64
|
VALUE rr_reflect_v8_message(Handle<Message> value) {
|
66
|
-
return
|
65
|
+
return rr_v8_handle_new(MessageClass, value);
|
67
66
|
}
|
68
67
|
|
@@ -1,5 +1,6 @@
|
|
1
|
-
#include "
|
2
|
-
#include "
|
1
|
+
#include "v8_handle.h"
|
2
|
+
#include "v8_weakref.h"
|
3
|
+
#include "v8_object.h"
|
3
4
|
#include "v8_value.h"
|
4
5
|
#include "v8_template.h"
|
5
6
|
#include "v8_external.h"
|
@@ -8,36 +9,36 @@ using namespace v8;
|
|
8
9
|
|
9
10
|
#include <cstdio>
|
10
11
|
|
11
|
-
VALUE rr_cV8_C_Object;
|
12
|
-
|
13
12
|
namespace {
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
|
14
|
+
VALUE ObjectClass;
|
15
|
+
|
16
|
+
Persistent<Object>& unwrap(VALUE object) {
|
17
|
+
return rr_v8_handle<Object>(object);
|
17
18
|
}
|
18
|
-
|
19
|
+
|
19
20
|
VALUE Get(VALUE self, VALUE key) {
|
20
21
|
HandleScope handles;
|
21
|
-
|
22
|
+
Persistent<Object> obj(unwrap(self));
|
22
23
|
if (rb_obj_is_kind_of(key, rb_cNumeric)) {
|
23
24
|
return rr_v82rb(obj->Get(NUM2UINT(key)));
|
24
25
|
} else {
|
25
26
|
return rr_v82rb(obj->Get(rr_rb2v8(key)->ToString()));
|
26
27
|
}
|
27
28
|
}
|
28
|
-
|
29
|
+
|
29
30
|
VALUE New(VALUE rbclass) {
|
30
31
|
HandleScope handles;
|
31
32
|
if (!Context::InContext()) {
|
32
33
|
rb_raise(rb_eScriptError, "Object::New() called without an entered Context");
|
33
34
|
return Qnil;
|
34
35
|
}
|
35
|
-
return
|
36
|
+
return rr_v8_handle_new(rbclass, Object::New());
|
36
37
|
}
|
37
|
-
|
38
|
+
|
38
39
|
VALUE Set(VALUE self, VALUE key, VALUE value) {
|
39
40
|
HandleScope handles;
|
40
|
-
|
41
|
+
Persistent<Object> obj = unwrap(self);
|
41
42
|
if (rb_obj_is_kind_of(key, rb_cNumeric)) {
|
42
43
|
return rr_v82rb(obj->Set(NUM2UINT(key), rr_rb2v8(value)));
|
43
44
|
} else {
|
@@ -47,7 +48,7 @@ namespace {
|
|
47
48
|
|
48
49
|
VALUE GetPropertyNames(VALUE self) {
|
49
50
|
HandleScope handles;
|
50
|
-
|
51
|
+
Persistent<Object> object = unwrap(self);
|
51
52
|
Local<Value> names = object->GetPropertyNames();
|
52
53
|
return rr_v82rb(names);
|
53
54
|
}
|
@@ -70,27 +71,48 @@ namespace {
|
|
70
71
|
}
|
71
72
|
VALUE SetPrototype(VALUE self, VALUE prototype) {
|
72
73
|
HandleScope scope;
|
73
|
-
Handle<Value> proto
|
74
|
-
Local<Object> me = unwrap(self);
|
74
|
+
Handle<Value> proto(rr_rb2v8(prototype));
|
75
75
|
return rr_v82rb(unwrap(self)->SetPrototype(rr_rb2v8(prototype)));
|
76
76
|
}
|
77
77
|
}
|
78
78
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
rr_define_method(
|
87
|
-
rr_define_method(
|
88
|
-
rr_define_method(
|
79
|
+
VALUE rr_v8_object_class() {
|
80
|
+
return ObjectClass;
|
81
|
+
}
|
82
|
+
|
83
|
+
void rr_init_object() {
|
84
|
+
ObjectClass = rr_define_class("Object", rr_v8_value_class());
|
85
|
+
rr_define_singleton_method(ObjectClass, "New", New, 0);
|
86
|
+
rr_define_method(ObjectClass, "Get", Get, 1);
|
87
|
+
rr_define_method(ObjectClass, "Set", Set, 2);
|
88
|
+
rr_define_method(ObjectClass, "GetPropertyNames", GetPropertyNames, 0);
|
89
|
+
rr_define_method(ObjectClass, "GetHiddenValue", GetHiddenValue, 1);
|
90
|
+
rr_define_method(ObjectClass, "SetHiddenValue", SetHiddenValue, 2);
|
91
|
+
rr_define_method(ObjectClass, "GetPrototype", GetPrototype, 0);
|
92
|
+
rr_define_method(ObjectClass, "SetPrototype", SetPrototype, 1);
|
93
|
+
}
|
94
|
+
|
95
|
+
VALUE rr_reflect_v8_object_as(Handle<Value> value, VALUE ruby_class) {
|
96
|
+
Handle<Object> object = Handle<Object>::Cast(value);
|
97
|
+
VALUE handle;
|
98
|
+
v8_weakref* backref;
|
99
|
+
Local<Value> holder = object->GetHiddenValue(String::NewSymbol("TheRubyRacer::Backref"));
|
100
|
+
if (holder.IsEmpty()) {
|
101
|
+
handle = rr_v8_handle_new(ruby_class, object);
|
102
|
+
backref = new v8_weakref(handle);
|
103
|
+
object->SetHiddenValue(String::NewSymbol("TheRubyRacer::Backref"), backref->external);
|
104
|
+
} else {
|
105
|
+
backref = (v8_weakref*)External::Unwrap(holder);
|
106
|
+
handle = backref->get();
|
107
|
+
if (!RTEST(handle)) {
|
108
|
+
handle = rr_v8_handle_new(ruby_class, object);
|
109
|
+
backref->set(handle);
|
110
|
+
}
|
111
|
+
}
|
112
|
+
return handle;
|
89
113
|
}
|
90
114
|
|
91
115
|
VALUE rr_reflect_v8_object(Handle<Value> value) {
|
92
|
-
|
93
|
-
Local<Value> peer = object->GetHiddenValue(String::NewSymbol("TheRubyRacer::RubyObject"));
|
94
|
-
return peer.IsEmpty() ? rr_v8_ref_create(rr_cV8_C_Object, object) : (VALUE)External::Unwrap(peer);
|
116
|
+
return rr_reflect_v8_object_as(value, ObjectClass);
|
95
117
|
}
|
96
118
|
|
@@ -3,9 +3,8 @@
|
|
3
3
|
|
4
4
|
#include "rr.h"
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
void rr_init_obj();
|
6
|
+
void rr_init_object();
|
7
|
+
VALUE rr_v8_object_class();
|
9
8
|
VALUE rr_reflect_v8_object(v8::Handle<v8::Value> value);
|
10
|
-
|
9
|
+
VALUE rr_reflect_v8_object_as(v8::Handle<v8::Value> object, VALUE ruby_class);
|
11
10
|
#endif
|
data/ext/v8/v8_script.cpp
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#include "v8.h"
|
2
|
-
#include "
|
2
|
+
#include "v8_handle.h"
|
3
3
|
#include "v8_script.h"
|
4
4
|
|
5
5
|
using namespace v8;
|
@@ -10,26 +10,26 @@ namespace {
|
|
10
10
|
HandleScope scope;
|
11
11
|
Local<String> src(rr_rb2v8(source)->ToString());
|
12
12
|
Local<String> src_name(rr_rb2v8(source_name)->ToString());
|
13
|
-
return
|
13
|
+
return rr_v8_handle_new(self, Script::Compile(src, src_name));
|
14
14
|
}
|
15
15
|
|
16
16
|
VALUE Compile(VALUE self, VALUE source, VALUE source_name) {
|
17
17
|
HandleScope scope;
|
18
18
|
Local<String> src(rr_rb2v8(source)->ToString());
|
19
19
|
Local<String> src_name(rr_rb2v8(source_name)->ToString());
|
20
|
-
return
|
20
|
+
return rr_v8_handle_new(self, Script::Compile(src, src_name));
|
21
21
|
}
|
22
22
|
|
23
23
|
VALUE Run(VALUE self) {
|
24
24
|
HandleScope scope;
|
25
|
-
|
25
|
+
Persistent<Script> script(rr_v8_handle<Script>(self));
|
26
26
|
Local<Value> result(script->Run());
|
27
27
|
return result.IsEmpty() ? Qnil : rr_v82rb(result);
|
28
28
|
}
|
29
29
|
}
|
30
30
|
|
31
31
|
void rr_init_script() {
|
32
|
-
VALUE ScriptClass = rr_define_class("Script");
|
32
|
+
VALUE ScriptClass = rr_define_class("Script", rr_v8_handle_class());
|
33
33
|
rr_define_singleton_method(ScriptClass, "New", New, 2);
|
34
34
|
rr_define_singleton_method(ScriptClass, "Compile", Compile, 2);
|
35
35
|
rr_define_method(ScriptClass, "Run", Run, 0);
|
@@ -1,26 +1,26 @@
|
|
1
1
|
|
2
|
-
#include "v8_str.h"
|
3
2
|
#include "v8.h"
|
4
|
-
#include "
|
3
|
+
#include "v8_handle.h"
|
5
4
|
#include "v8_value.h"
|
5
|
+
#include "v8_string.h"
|
6
6
|
|
7
7
|
using namespace v8;
|
8
8
|
|
9
9
|
namespace {
|
10
10
|
VALUE StringClass;
|
11
11
|
|
12
|
-
|
13
|
-
return
|
12
|
+
Persistent<String>& unwrap(VALUE value) {
|
13
|
+
return rr_v8_handle<String>(value);
|
14
14
|
}
|
15
15
|
VALUE New(VALUE string_class, VALUE data) {
|
16
16
|
HandleScope handles;
|
17
17
|
VALUE str = rb_funcall(data, rb_intern("to_s"), 0);
|
18
|
-
return
|
18
|
+
return rr_v8_handle_new(string_class, String::New(RSTRING_PTR(str), RSTRING_LEN(str)));
|
19
19
|
}
|
20
20
|
VALUE NewSymbol(VALUE string_class, VALUE data) {
|
21
21
|
HandleScope scope;
|
22
22
|
VALUE str = rb_funcall(data, rb_intern("to_s"), 0);
|
23
|
-
return
|
23
|
+
return rr_v8_handle_new(string_class, String::NewSymbol(RSTRING_PTR(str), RSTRING_LEN(str)));
|
24
24
|
}
|
25
25
|
VALUE Utf8Value(VALUE self) {
|
26
26
|
HandleScope handles;
|
@@ -37,13 +37,11 @@ namespace {
|
|
37
37
|
}
|
38
38
|
|
39
39
|
VALUE rr_reflect_v8_string(Handle<Value> value) {
|
40
|
-
|
41
|
-
Local<String> string = String::Cast(*value);
|
42
|
-
return rr_v8_ref_create(StringClass, string);
|
40
|
+
return rr_v8_handle_new(StringClass, Handle<String>::Cast(value));
|
43
41
|
}
|
44
42
|
|
45
|
-
void
|
46
|
-
StringClass = rr_define_class("String",
|
43
|
+
void rr_init_string() {
|
44
|
+
StringClass = rr_define_class("String", rr_v8_value_class());
|
47
45
|
rr_define_singleton_method(StringClass, "New", New, 1);
|
48
46
|
rr_define_singleton_method(StringClass, "NewSymbol", NewSymbol, 1);
|
49
47
|
rr_define_method(StringClass, "Utf8Value", Utf8Value, 0);
|