therubyracer-freebsd 0.10.1 → 0.11.1p2
Sign up to get free protection for your applications and to get access to all the features.
- metadata +37 -109
- data/.gitignore +0 -13
- data/.rspec +0 -1
- data/.travis.yml +0 -8
- data/.yardopts +0 -1
- data/Changelog.md +0 -231
- data/Gemfile +0 -3
- data/README.md +0 -167
- data/Rakefile +0 -26
- data/bin/therubyracer +0 -11
- data/ext/v8/extconf.rb +0 -26
- data/ext/v8/rr.cpp +0 -189
- data/ext/v8/rr.h +0 -41
- data/ext/v8/v8.cpp +0 -48
- data/ext/v8/v8_array.cpp +0 -48
- data/ext/v8/v8_array.h +0 -8
- data/ext/v8/v8_callbacks.cpp +0 -81
- data/ext/v8/v8_callbacks.h +0 -8
- data/ext/v8/v8_context.cpp +0 -92
- data/ext/v8/v8_context.h +0 -6
- data/ext/v8/v8_date.cpp +0 -40
- data/ext/v8/v8_date.h +0 -6
- data/ext/v8/v8_debug.cpp +0 -17
- data/ext/v8/v8_debug.h +0 -6
- data/ext/v8/v8_exception.cpp +0 -133
- data/ext/v8/v8_exception.h +0 -11
- data/ext/v8/v8_external.cpp +0 -70
- data/ext/v8/v8_external.h +0 -8
- data/ext/v8/v8_function.cpp +0 -69
- data/ext/v8/v8_function.h +0 -11
- data/ext/v8/v8_handle.cpp +0 -186
- data/ext/v8/v8_handle.h +0 -48
- data/ext/v8/v8_locker.cpp +0 -139
- data/ext/v8/v8_locker.h +0 -6
- data/ext/v8/v8_message.cpp +0 -67
- data/ext/v8/v8_message.h +0 -10
- data/ext/v8/v8_object.cpp +0 -122
- data/ext/v8/v8_object.h +0 -10
- data/ext/v8/v8_script.cpp +0 -36
- data/ext/v8/v8_script.h +0 -8
- data/ext/v8/v8_string.cpp +0 -52
- data/ext/v8/v8_string.h +0 -9
- data/ext/v8/v8_template.cpp +0 -344
- data/ext/v8/v8_template.h +0 -8
- data/ext/v8/v8_try_catch.cpp +0 -70
- data/ext/v8/v8_try_catch.h +0 -5
- data/ext/v8/v8_v8.cpp +0 -34
- data/ext/v8/v8_v8.h +0 -6
- data/ext/v8/v8_value.cpp +0 -175
- data/ext/v8/v8_value.h +0 -10
- data/ext/v8/v8_weakref.cpp +0 -61
- data/ext/v8/v8_weakref.h +0 -29
- data/lib/v8/access.rb +0 -92
- data/lib/v8/array.rb +0 -17
- data/lib/v8/c/locker.rb +0 -18
- data/lib/v8/cli.rb +0 -133
- data/lib/v8/context.rb +0 -111
- data/lib/v8/error.rb +0 -130
- data/lib/v8/function.rb +0 -44
- data/lib/v8/object.rb +0 -69
- data/lib/v8/portal/caller.rb +0 -37
- data/lib/v8/portal/constructor.rb +0 -98
- data/lib/v8/portal/function.rb +0 -63
- data/lib/v8/portal/interceptors.rb +0 -152
- data/lib/v8/portal/proxies.rb +0 -151
- data/lib/v8/portal/templates.rb +0 -73
- data/lib/v8/portal.rb +0 -86
- data/lib/v8/stack.rb +0 -66
- data/lib/v8/tap.rb +0 -9
- data/lib/v8/version.rb +0 -3
- data/lib/v8.rb +0 -23
- data/spec/ext/array_spec.rb +0 -15
- data/spec/ext/cxt_spec.rb +0 -57
- data/spec/ext/ext_spec_helper.rb +0 -27
- data/spec/ext/func_spec.rb +0 -64
- data/spec/ext/object_spec.rb +0 -10
- data/spec/ext/string_spec.rb +0 -11
- data/spec/ext/try_catch_spec.rb +0 -60
- data/spec/redjs_spec.rb +0 -9
- data/spec/spec_helper.rb +0 -9
- data/spec/v8/error_spec.rb +0 -131
- data/spec/v8/portal/proxies_spec.rb +0 -106
- data/specmem/handle_memspec.rb +0 -41
- data/specmem/object_memspec.rb +0 -14
- data/specmem/proxies_memspec.rb +0 -49
- data/specmem/spec_helper.rb +0 -24
- data/specthread/spec_helper.rb +0 -2
- data/specthread/threading_spec.rb +0 -13
- data/thefrontside.png +0 -0
- data/therubyracer.gemspec +0 -27
data/ext/v8/v8_exception.cpp
DELETED
@@ -1,133 +0,0 @@
|
|
1
|
-
#include "v8_exception.h"
|
2
|
-
#include "rr.h"
|
3
|
-
#include "v8_handle.h"
|
4
|
-
// #include "execinfo.h"
|
5
|
-
// #include "signal.h"
|
6
|
-
|
7
|
-
using namespace v8;
|
8
|
-
namespace {
|
9
|
-
|
10
|
-
static void* stack[20];
|
11
|
-
|
12
|
-
void fatal(const char* location, const char* message) {
|
13
|
-
rb_raise(rb_eFatal, "%s: %s", location, message);
|
14
|
-
}
|
15
|
-
// void segfault(int sig) {
|
16
|
-
// fprintf(stderr, "segfault: game over.\n");
|
17
|
-
// int size = backtrace(stack, 20);
|
18
|
-
// backtrace_symbols_fd(stack, size, 2);
|
19
|
-
// exit(1);
|
20
|
-
// }
|
21
|
-
VALUE _ThrowException(VALUE rbmod, VALUE value) {
|
22
|
-
HandleScope scope;
|
23
|
-
Handle<Value> err = rr_rb2v8(value);
|
24
|
-
return rr_v82rb(ThrowException(err));
|
25
|
-
}
|
26
|
-
VALUE RangeError(VALUE rbclass, VALUE value) {
|
27
|
-
HandleScope scope;
|
28
|
-
return rr_v82rb(Exception::RangeError(rr_rb2v8(value)->ToString()));
|
29
|
-
}
|
30
|
-
VALUE ReferenceError(VALUE rbclass, VALUE value) {
|
31
|
-
HandleScope scope;
|
32
|
-
return rr_v82rb(Exception::ReferenceError(rr_rb2v8(value)->ToString()));
|
33
|
-
}
|
34
|
-
VALUE SyntaxError(VALUE rbclass, VALUE value) {
|
35
|
-
HandleScope scope;
|
36
|
-
return rr_v82rb(Exception::SyntaxError(rr_rb2v8(value)->ToString()));
|
37
|
-
}
|
38
|
-
VALUE Error(VALUE rbclass, VALUE value) {
|
39
|
-
HandleScope scope;
|
40
|
-
return rr_v82rb(Exception::Error(rr_rb2v8(value)->ToString()));
|
41
|
-
}
|
42
|
-
|
43
|
-
VALUE StackTraceClass;
|
44
|
-
VALUE StackFrameClass;
|
45
|
-
namespace Trace {
|
46
|
-
|
47
|
-
Persistent<StackTrace>& trace(VALUE value) {
|
48
|
-
return rr_v8_handle<StackTrace>(value);
|
49
|
-
}
|
50
|
-
VALUE GetFrame(VALUE self, VALUE index) {
|
51
|
-
HandleScope scope;
|
52
|
-
return rr_v82rb(trace(self)->GetFrame(NUM2UINT(index)));
|
53
|
-
}
|
54
|
-
VALUE GetFrameCount(VALUE self) {
|
55
|
-
HandleScope scope;
|
56
|
-
return rr_v82rb(trace(self)->GetFrameCount());
|
57
|
-
}
|
58
|
-
VALUE AsArray(VALUE self) {
|
59
|
-
return rr_v82rb(trace(self)->AsArray());
|
60
|
-
}
|
61
|
-
VALUE CurrentStackTrace(VALUE self, VALUE frame_limit) {
|
62
|
-
return rr_v82rb(StackTrace::CurrentStackTrace(NUM2INT(frame_limit)));
|
63
|
-
}
|
64
|
-
}
|
65
|
-
|
66
|
-
namespace Frame {
|
67
|
-
Persistent<StackFrame>& frame(VALUE value) {
|
68
|
-
return rr_v8_handle<StackFrame>(value);
|
69
|
-
}
|
70
|
-
VALUE GetLineNumber(VALUE self) {
|
71
|
-
HandleScope scope;
|
72
|
-
return rr_v82rb(frame(self)->GetLineNumber());
|
73
|
-
}
|
74
|
-
VALUE GetColumn(VALUE self) {
|
75
|
-
HandleScope scope;
|
76
|
-
return rr_v82rb(frame(self)->GetColumn());
|
77
|
-
}
|
78
|
-
VALUE GetScriptName(VALUE self) {
|
79
|
-
HandleScope scope;
|
80
|
-
return rr_v82rb(frame(self)->GetScriptName());
|
81
|
-
}
|
82
|
-
VALUE GetFunctionName(VALUE self) {
|
83
|
-
HandleScope scope;
|
84
|
-
return rr_v82rb(frame(self)->GetFunctionName());
|
85
|
-
}
|
86
|
-
VALUE IsEval(VALUE self) {
|
87
|
-
HandleScope scope;
|
88
|
-
return rr_v82rb(frame(self)->IsEval());
|
89
|
-
}
|
90
|
-
VALUE IsConstructor(VALUE self) {
|
91
|
-
HandleScope scope;
|
92
|
-
return rr_v82rb(frame(self)->IsConstructor());
|
93
|
-
}
|
94
|
-
}
|
95
|
-
|
96
|
-
}
|
97
|
-
|
98
|
-
void rr_init_v8_exception() {
|
99
|
-
VALUE V8 = rb_define_module("V8");
|
100
|
-
VALUE V8_C = rb_define_module_under(V8, "C");
|
101
|
-
rr_define_singleton_method(V8_C, "ThrowException", _ThrowException, 1);
|
102
|
-
|
103
|
-
VALUE ExceptionClass = rr_define_class("Exception");
|
104
|
-
rr_define_singleton_method(ExceptionClass, "RangeError", RangeError, 1);
|
105
|
-
rr_define_singleton_method(ExceptionClass, "ReferenceError", ReferenceError, 1);
|
106
|
-
rr_define_singleton_method(ExceptionClass, "SyntaxError", SyntaxError, 1);
|
107
|
-
rr_define_singleton_method(ExceptionClass, "Error", Error, 1);
|
108
|
-
|
109
|
-
StackTraceClass = rr_define_class("StackTrace", rr_v8_handle_class());
|
110
|
-
rr_define_singleton_method(StackTraceClass, "CurrentStackTrace", Trace::CurrentStackTrace, 1);
|
111
|
-
rr_define_method(StackTraceClass, "GetFrame", Trace::GetFrame, 1);
|
112
|
-
rr_define_method(StackTraceClass, "GetFrameCount", Trace::GetFrameCount, 0);
|
113
|
-
rr_define_method(StackTraceClass, "AsArray", Trace::AsArray, 0);
|
114
|
-
|
115
|
-
StackFrameClass = rr_define_class("StackFrame", rr_v8_handle_class());
|
116
|
-
rr_define_method(StackFrameClass, "GetLineNumber", Frame::GetLineNumber, 0);
|
117
|
-
rr_define_method(StackFrameClass, "GetColumn", Frame::GetColumn, 0);
|
118
|
-
rr_define_method(StackFrameClass, "GetScriptName", Frame::GetScriptName, 0);
|
119
|
-
rr_define_method(StackFrameClass, "GetFunctionName", Frame::GetFunctionName, 0);
|
120
|
-
rr_define_method(StackFrameClass, "IsEval", Frame::IsEval, 0);
|
121
|
-
rr_define_method(StackFrameClass, "IsConstructor", Frame::IsConstructor, 0);
|
122
|
-
|
123
|
-
v8::V8::SetFatalErrorHandler(fatal);
|
124
|
-
//comment this in for debugging.
|
125
|
-
// signal(SIGSEGV, segfault);
|
126
|
-
}
|
127
|
-
|
128
|
-
VALUE rr_reflect_v8_stacktrace(Handle<StackTrace> value) {
|
129
|
-
return rr_v8_handle_new(StackTraceClass, value);
|
130
|
-
}
|
131
|
-
VALUE rr_reflect_v8_stackframe(Handle<StackFrame> value) {
|
132
|
-
return rr_v8_handle_new(StackFrameClass, value);
|
133
|
-
}
|
data/ext/v8/v8_exception.h
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
#ifndef _RR_V8_EXCEPTION_
|
2
|
-
#define _RR_V8_EXCEPTION_
|
3
|
-
|
4
|
-
#include "v8.h"
|
5
|
-
#include "ruby.h"
|
6
|
-
|
7
|
-
void rr_init_v8_exception();
|
8
|
-
VALUE rr_reflect_v8_stacktrace(v8::Handle<v8::StackTrace> value);
|
9
|
-
VALUE rr_reflect_v8_stackframe(v8::Handle<v8::StackFrame> value);
|
10
|
-
|
11
|
-
#endif
|
data/ext/v8/v8_external.cpp
DELETED
@@ -1,70 +0,0 @@
|
|
1
|
-
#include "rr.h"
|
2
|
-
#include "v8_external.h"
|
3
|
-
|
4
|
-
#include "v8_handle.h"
|
5
|
-
#include "v8_value.h"
|
6
|
-
using namespace v8;
|
7
|
-
|
8
|
-
namespace {
|
9
|
-
VALUE ExternalClass;
|
10
|
-
VALUE references;
|
11
|
-
|
12
|
-
struct Weaklink {
|
13
|
-
bool finalized_from_rb;
|
14
|
-
bool finalized_from_v8;
|
15
|
-
VALUE target;
|
16
|
-
};
|
17
|
-
|
18
|
-
VALUE Weaklink_finalized_from_ruby(VALUE object_id, VALUE data) {
|
19
|
-
Weaklink* link = 0;
|
20
|
-
Data_Get_Struct(data, struct Weaklink, link);
|
21
|
-
link->finalized_from_rb = true;
|
22
|
-
if (link->finalized_from_v8) {
|
23
|
-
delete link;
|
24
|
-
}
|
25
|
-
return Qnil;
|
26
|
-
}
|
27
|
-
void Weaklink_finalized_from_v8(Persistent<Value> value, void* data) {
|
28
|
-
Weaklink* link = (Weaklink*)data;
|
29
|
-
link->finalized_from_v8 = true;
|
30
|
-
if (link->finalized_from_rb) {
|
31
|
-
delete link;
|
32
|
-
}
|
33
|
-
value.Dispose();
|
34
|
-
}
|
35
|
-
|
36
|
-
VALUE New(VALUE self, VALUE value) {
|
37
|
-
HandleScope scope;
|
38
|
-
Weaklink* link = new Weaklink();
|
39
|
-
link->finalized_from_v8 = false;
|
40
|
-
link->finalized_from_rb = false;
|
41
|
-
link->target = value;
|
42
|
-
Persistent<External> external = Persistent<External>::New(External::New((void*)link));
|
43
|
-
external.MakeWeak(link,Weaklink_finalized_from_v8);
|
44
|
-
VALUE finalizer_data = Data_Wrap_Struct(rb_cObject, 0, 0, link);
|
45
|
-
rr_define_finalizer(value, (void*)Weaklink_finalized_from_ruby, finalizer_data);
|
46
|
-
return rr_v8_handle_new(self, external);
|
47
|
-
}
|
48
|
-
|
49
|
-
VALUE _Value(VALUE self) {
|
50
|
-
HandleScope scope;
|
51
|
-
Weaklink* link = (Weaklink*)rr_v8_handle<External>(self)->Value();
|
52
|
-
if (link->finalized_from_rb) {
|
53
|
-
rb_warn("an active v8::External wraps a VALUE that has already been finalized! This is not good.\n");
|
54
|
-
return Qnil;
|
55
|
-
} else {
|
56
|
-
return link->target;
|
57
|
-
}
|
58
|
-
return (VALUE)rr_v8_handle<External>(self)->Value();
|
59
|
-
}
|
60
|
-
}
|
61
|
-
|
62
|
-
void rr_init_v8_external() {
|
63
|
-
ExternalClass = rr_define_class("External", rr_v8_value_class());
|
64
|
-
rr_define_singleton_method(ExternalClass, "New", New, 1);
|
65
|
-
rr_define_method(ExternalClass, "Value", _Value, 0);
|
66
|
-
}
|
67
|
-
|
68
|
-
VALUE rr_reflect_v8_external(Handle<Value> external) {
|
69
|
-
return rr_v8_handle_new(ExternalClass, external);
|
70
|
-
}
|
data/ext/v8/v8_external.h
DELETED
data/ext/v8/v8_function.cpp
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
|
2
|
-
#include <vector>
|
3
|
-
#include "v8_function.h"
|
4
|
-
#include "v8_object.h"
|
5
|
-
#include "v8_handle.h"
|
6
|
-
|
7
|
-
using namespace v8;
|
8
|
-
|
9
|
-
namespace {
|
10
|
-
VALUE FunctionClass;
|
11
|
-
|
12
|
-
Persistent<Function>& unwrap(VALUE value) {
|
13
|
-
return rr_v8_handle<Function>(value);
|
14
|
-
}
|
15
|
-
VALUE Call(VALUE self, VALUE recv, VALUE arguments) {
|
16
|
-
HandleScope handles;
|
17
|
-
if (!Context::InContext()) {
|
18
|
-
rb_raise(rb_eScriptError, "no open V8 Context in V8::C::Function::Call()");
|
19
|
-
return Qnil;
|
20
|
-
}
|
21
|
-
Handle<Function> function = unwrap(self);
|
22
|
-
Local<Object> thisObj = rr_rb2v8(recv)->ToObject();
|
23
|
-
Handle<Array> args = rr_v8_handle<Array>(arguments);
|
24
|
-
int argc = args->Length();
|
25
|
-
std::vector< Handle<Value> > argv (argc);
|
26
|
-
for (int i = 0; i < argc; i++) {
|
27
|
-
argv[i] = args->Get(i);
|
28
|
-
}
|
29
|
-
return rr_v82rb(function->Call(thisObj, argc, &argv[0]));
|
30
|
-
}
|
31
|
-
|
32
|
-
VALUE NewInstance(VALUE self, VALUE arguments) {
|
33
|
-
HandleScope scope;
|
34
|
-
Handle<Function> function = unwrap(self);
|
35
|
-
Handle<Array> args = rr_v8_handle<Array>(arguments);
|
36
|
-
int argc = args->Length();
|
37
|
-
std::vector< Handle<Value> > argv (argc);
|
38
|
-
for (int i = 0; i < argc; i++) {
|
39
|
-
argv[i] = args->Get(i);
|
40
|
-
}
|
41
|
-
return rr_v82rb(function->NewInstance(argc, &argv[0]));
|
42
|
-
}
|
43
|
-
VALUE GetName(VALUE self) {
|
44
|
-
HandleScope scope;
|
45
|
-
return rr_v82rb(unwrap(self)->GetName());
|
46
|
-
}
|
47
|
-
VALUE SetName(VALUE self, VALUE name) {
|
48
|
-
HandleScope scope;
|
49
|
-
Handle<String> str = rr_v8_handle<String>(name);
|
50
|
-
unwrap(self)->SetName(str);
|
51
|
-
return Qnil;
|
52
|
-
}
|
53
|
-
// VALUE GetScriptOrigin(VALUE self) {
|
54
|
-
// return rr_v82rb(unwrap(self)->GetScriptOrigin());
|
55
|
-
// }
|
56
|
-
}
|
57
|
-
|
58
|
-
void rr_init_function() {
|
59
|
-
FunctionClass = rr_define_class("Function", rr_v8_object_class());
|
60
|
-
rr_define_method(FunctionClass, "Call", Call, 2);
|
61
|
-
rr_define_method(FunctionClass, "NewInstance", NewInstance, 1);
|
62
|
-
rr_define_method(FunctionClass, "GetName", GetName, 0);
|
63
|
-
rr_define_method(FunctionClass, "SetName", SetName, 1);
|
64
|
-
// rr_define_method(FunctionClass, "GetScriptOrigin", GetScriptOrigin, 0);
|
65
|
-
}
|
66
|
-
|
67
|
-
VALUE rr_reflect_v8_function(Handle<Value> value) {
|
68
|
-
return rr_reflect_v8_object_as(value, FunctionClass);
|
69
|
-
}
|
data/ext/v8/v8_function.h
DELETED
data/ext/v8/v8_handle.cpp
DELETED
@@ -1,186 +0,0 @@
|
|
1
|
-
|
2
|
-
#include "rr.h"
|
3
|
-
#include "v8_handle.h"
|
4
|
-
|
5
|
-
using namespace v8;
|
6
|
-
|
7
|
-
/**
|
8
|
-
* Creates a new Persistent storage cell for `handle`
|
9
|
-
* so that we can reference it from Ruby. Ruby metadat
|
10
|
-
* is contained on the handle object, and then the actual
|
11
|
-
* v8 references are contain in an instance of `Payload`
|
12
|
-
*/
|
13
|
-
v8_handle::v8_handle(Handle<void> object) {
|
14
|
-
this->weakref_callback = Qnil;
|
15
|
-
this->weakref_callback_parameters = Qnil;
|
16
|
-
this->dead = false;
|
17
|
-
this->payload = new Payload(object);
|
18
|
-
}
|
19
|
-
|
20
|
-
v8_handle::~v8_handle() {}
|
21
|
-
|
22
|
-
/**
|
23
|
-
* Construct a new handle payload.
|
24
|
-
*
|
25
|
-
* Each payload contains a Ruby object wrapper so that it
|
26
|
-
* can be enqueued for V8 GC (the GC queue is a ruby Array)
|
27
|
-
* the wrapper is pre-allocated at payload creation time
|
28
|
-
* so that no Ruby objects are allocated during Ruby GC.
|
29
|
-
*/
|
30
|
-
v8_handle::Payload::Payload(Handle<void> object) {
|
31
|
-
rb_gc_register_address(&wrapper);
|
32
|
-
handle = Persistent<void>::New(object);
|
33
|
-
wrapper = Data_Wrap_Struct(rb_cObject, 0, destroy, this);
|
34
|
-
}
|
35
|
-
|
36
|
-
v8_handle::Payload::~Payload() {
|
37
|
-
rb_gc_unregister_address(&wrapper);
|
38
|
-
}
|
39
|
-
|
40
|
-
void v8_handle::Payload::release() {
|
41
|
-
handle.Dispose();
|
42
|
-
handle.Clear();
|
43
|
-
}
|
44
|
-
|
45
|
-
void v8_handle::Payload::destroy(v8_handle::Payload* payload) {
|
46
|
-
delete payload;
|
47
|
-
}
|
48
|
-
|
49
|
-
namespace {
|
50
|
-
/**
|
51
|
-
* Holds dead references, that are no longer being held in Ruby, so that they can be garbage collected
|
52
|
-
* inside of V8
|
53
|
-
*/
|
54
|
-
VALUE handle_queue;
|
55
|
-
|
56
|
-
/**
|
57
|
-
* Invoked by the Ruby garbage collector whenever it determines that this handle is
|
58
|
-
* still reachable. We in turn, mark our weak callback parameters, so that it knows
|
59
|
-
* they are reachable too.
|
60
|
-
*/
|
61
|
-
void v8_handle_mark(v8_handle* handle) {
|
62
|
-
rb_gc_mark(handle->weakref_callback);
|
63
|
-
rb_gc_mark(handle->weakref_callback_parameters);
|
64
|
-
}
|
65
|
-
|
66
|
-
/**
|
67
|
-
* Whenver a V8::C::Handle becomes garbage collected, we do not free it immediately.
|
68
|
-
* instead, we put them into a "zombie" queue, where its corresponding V8 storage cell
|
69
|
-
* can be released safely while the V8 engine is running. A zombie Ruby object is
|
70
|
-
* created to wrap it so that it can be stored in the queue.
|
71
|
-
*/
|
72
|
-
void v8_handle_enqueue(v8_handle* handle) {
|
73
|
-
handle->dead = true;
|
74
|
-
rb_ary_unshift(handle_queue, handle->payload->wrapper);
|
75
|
-
}
|
76
|
-
|
77
|
-
/**
|
78
|
-
* Drains the dead handle queue, and releases them from V8
|
79
|
-
*
|
80
|
-
* This implements the V8 `GCPrologueCallback` and is registered to run before
|
81
|
-
* each invocation of the V8 garbage collector. It empties the queue of dead handles
|
82
|
-
* and disposes of them. It is important to do this operations inside V8 so that
|
83
|
-
* Ruby garbage collection is never locked, and never touches V8.
|
84
|
-
*/
|
85
|
-
void v8_handle_dequeue(GCType type, GCCallbackFlags flags) {
|
86
|
-
for (VALUE handle = rb_ary_pop(handle_queue); RTEST(handle); handle = rb_ary_pop(handle_queue)) {
|
87
|
-
v8_handle::Payload* payload = NULL;
|
88
|
-
Data_Get_Struct(handle, struct v8_handle::Payload, payload);
|
89
|
-
payload->release();
|
90
|
-
}
|
91
|
-
}
|
92
|
-
|
93
|
-
VALUE New(VALUE self, VALUE handle) {
|
94
|
-
if (RTEST(handle)) {
|
95
|
-
Persistent<void> that = rr_v8_handle<void>(handle);
|
96
|
-
return rr_v8_handle_new(self, that);
|
97
|
-
} else {
|
98
|
-
return rr_v8_handle_new(self, Handle<void>());
|
99
|
-
}
|
100
|
-
}
|
101
|
-
|
102
|
-
VALUE IsEmpty(VALUE self) {
|
103
|
-
return rr_v82rb(rr_v8_handle<void>(self).IsEmpty());
|
104
|
-
}
|
105
|
-
|
106
|
-
VALUE Clear(VALUE self) {
|
107
|
-
rr_v8_handle<void>(self).Clear();
|
108
|
-
return Qnil;
|
109
|
-
}
|
110
|
-
|
111
|
-
VALUE Dispose(VALUE self) {
|
112
|
-
rr_v8_handle<void>(self).Dispose();
|
113
|
-
return Qnil;
|
114
|
-
}
|
115
|
-
|
116
|
-
void RubyWeakReferenceCallback(Persistent<Value> value, void* parameter) {
|
117
|
-
VALUE self = (VALUE)parameter;
|
118
|
-
v8_handle* handle = rr_v8_handle_raw(self);
|
119
|
-
VALUE callback = handle->weakref_callback;
|
120
|
-
VALUE parameters = handle->weakref_callback_parameters;
|
121
|
-
if (RTEST(callback)) {
|
122
|
-
rb_funcall(callback, rb_intern("call"), 2, self, parameters);
|
123
|
-
}
|
124
|
-
value.Dispose();
|
125
|
-
handle->payload->release();
|
126
|
-
handle->dead = true;
|
127
|
-
|
128
|
-
}
|
129
|
-
|
130
|
-
VALUE MakeWeak(VALUE self, VALUE parameters, VALUE callback) {
|
131
|
-
v8_handle* handle = rr_v8_handle_raw(self);
|
132
|
-
handle->weakref_callback = callback;
|
133
|
-
handle->weakref_callback_parameters = parameters;
|
134
|
-
rr_v8_handle<void>(self).MakeWeak((void*)self, RubyWeakReferenceCallback);
|
135
|
-
return Qnil;
|
136
|
-
}
|
137
|
-
|
138
|
-
VALUE ClearWeak(VALUE self) {
|
139
|
-
rr_v8_handle<void>(self).ClearWeak();
|
140
|
-
return Qnil;
|
141
|
-
}
|
142
|
-
|
143
|
-
VALUE IsNearDeath(VALUE self) {
|
144
|
-
return rr_v82rb(rr_v8_handle<void>(self).IsNearDeath());
|
145
|
-
}
|
146
|
-
|
147
|
-
VALUE IsWeak(VALUE self) {
|
148
|
-
return rr_v82rb(rr_v8_handle<void>(self).IsWeak());
|
149
|
-
}
|
150
|
-
|
151
|
-
VALUE dead_p(VALUE self) {
|
152
|
-
return rr_v8_handle_raw(self)->dead ? Qtrue : Qfalse;
|
153
|
-
}
|
154
|
-
}
|
155
|
-
|
156
|
-
void rr_init_handle() {
|
157
|
-
VALUE HandleClass = rr_define_class("Handle");
|
158
|
-
rr_define_method(HandleClass, "dead?", dead_p, 0);
|
159
|
-
rr_define_singleton_method(HandleClass, "New", New, 1);
|
160
|
-
rr_define_method(HandleClass, "IsEmpty", IsEmpty, 0);
|
161
|
-
rr_define_method(HandleClass, "Clear", Clear, 0);
|
162
|
-
rr_define_method(HandleClass, "Dispose", Dispose, 0);
|
163
|
-
rr_define_method(HandleClass, "MakeWeak", MakeWeak, 2);
|
164
|
-
rr_define_method(HandleClass, "ClearWeak", ClearWeak, 0);
|
165
|
-
rr_define_method(HandleClass, "IsNearDeath", IsNearDeath, 0);
|
166
|
-
rr_define_method(HandleClass, "IsWeak", IsWeak, 0);
|
167
|
-
|
168
|
-
rb_gc_register_address(&handle_queue);
|
169
|
-
handle_queue = rb_ary_new();
|
170
|
-
V8::AddGCPrologueCallback(v8_handle_dequeue);
|
171
|
-
}
|
172
|
-
|
173
|
-
VALUE rr_v8_handle_new(VALUE klass, v8::Handle<void> handle) {
|
174
|
-
v8_handle* new_handle = new v8_handle(handle);
|
175
|
-
return Data_Wrap_Struct(klass, v8_handle_mark, v8_handle_enqueue, new_handle);
|
176
|
-
}
|
177
|
-
|
178
|
-
VALUE rr_v8_handle_class() {
|
179
|
-
return rr_define_class("Handle");
|
180
|
-
}
|
181
|
-
|
182
|
-
v8_handle* rr_v8_handle_raw(VALUE value) {
|
183
|
-
v8_handle* handle = 0;
|
184
|
-
Data_Get_Struct(value, struct v8_handle, handle);
|
185
|
-
return handle;
|
186
|
-
}
|
data/ext/v8/v8_handle.h
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
#ifndef _RR_V8_HANDLE_
|
2
|
-
#define _RR_V8_HANDLE_
|
3
|
-
|
4
|
-
#include <v8.h>
|
5
|
-
#include "ruby.h"
|
6
|
-
|
7
|
-
/**
|
8
|
-
* Holds a reference to a V8 heap object. This serves as the base
|
9
|
-
* class for all of the low-level proxies that reference into V8.
|
10
|
-
*/
|
11
|
-
struct v8_handle {
|
12
|
-
|
13
|
-
/**
|
14
|
-
* Contains the *actual* V8 references. This object is kept
|
15
|
-
* separate so that it can be "detached" from the handle when
|
16
|
-
* it is garbage collected, and enqueued separately and
|
17
|
-
* collected in the context of a V8 thread.
|
18
|
-
*/
|
19
|
-
|
20
|
-
struct Payload {
|
21
|
-
Payload(v8::Handle<void> object);
|
22
|
-
virtual ~Payload();
|
23
|
-
void release();
|
24
|
-
static void destroy(v8_handle::Payload* payload);
|
25
|
-
v8::Persistent<void> handle;
|
26
|
-
VALUE wrapper;
|
27
|
-
};
|
28
|
-
|
29
|
-
v8_handle(v8::Handle<void> object);
|
30
|
-
virtual ~v8_handle();
|
31
|
-
|
32
|
-
Payload* payload;
|
33
|
-
bool dead;
|
34
|
-
VALUE weakref_callback;
|
35
|
-
VALUE weakref_callback_parameters;
|
36
|
-
};
|
37
|
-
|
38
|
-
void rr_init_handle();
|
39
|
-
|
40
|
-
v8_handle* rr_v8_handle_raw(VALUE value);
|
41
|
-
|
42
|
-
template <class T> v8::Persistent<T>& rr_v8_handle(VALUE value) {
|
43
|
-
return (v8::Persistent<T>&)(rr_v8_handle_raw(value)->payload->handle);
|
44
|
-
}
|
45
|
-
VALUE rr_v8_handle_new(VALUE rbclass, v8::Handle<void> handle);
|
46
|
-
VALUE rr_v8_handle_class();
|
47
|
-
|
48
|
-
#endif
|
data/ext/v8/v8_locker.cpp
DELETED
@@ -1,139 +0,0 @@
|
|
1
|
-
#include "rr.h"
|
2
|
-
#include "v8_locker.h"
|
3
|
-
|
4
|
-
using namespace v8;
|
5
|
-
|
6
|
-
namespace {
|
7
|
-
namespace Lock {
|
8
|
-
|
9
|
-
/**
|
10
|
-
* Document-method: V8::C::Locker#new
|
11
|
-
*
|
12
|
-
* Allocates and returns a new `v8::Locker` object. The thread that instantiated
|
13
|
-
* this object will hold the V8 interpreter lock until it is released with a
|
14
|
-
* corresponding call to {#delete}.
|
15
|
-
*
|
16
|
-
* It critical that you call {#delete} to deallocate it, preferably within the same method.
|
17
|
-
* If you don't, two bad things will happen:
|
18
|
-
*
|
19
|
-
* 1. You'll leak the underlying C++ object
|
20
|
-
* 1. Worse, you'll leave the V8 vm locked to this thread forever
|
21
|
-
*
|
22
|
-
* It's dangerous! Be sure to `ensure`.
|
23
|
-
*
|
24
|
-
* for detailed semantics see the locking {API http://izs.me/v8-docs/classv8_1_1Unlocker.html}
|
25
|
-
*
|
26
|
-
* @return [V8::C::Locker] the new locker
|
27
|
-
*/
|
28
|
-
|
29
|
-
VALUE New(VALUE LockerClass) {
|
30
|
-
Locker* locker = new Locker();
|
31
|
-
return Data_Wrap_Struct(LockerClass, 0, 0, (void*)locker);
|
32
|
-
}
|
33
|
-
|
34
|
-
/**
|
35
|
-
* Document-method: V8::C::Locker#delete
|
36
|
-
*
|
37
|
-
* Pop this lock off the stack for this thread. For a full run down of V8 locking
|
38
|
-
* semantics see the locking {API http://izs.me/v8-docs/classv8_1_1Unlocker.html}
|
39
|
-
* @return nil
|
40
|
-
*/
|
41
|
-
VALUE Delete(VALUE self) {
|
42
|
-
Locker* locker = 0;
|
43
|
-
Data_Get_Struct(self, class Locker, locker);
|
44
|
-
delete locker;
|
45
|
-
}
|
46
|
-
}
|
47
|
-
|
48
|
-
namespace Unlock {
|
49
|
-
/**
|
50
|
-
* Document-method: V8::C::Unlocker#new
|
51
|
-
*
|
52
|
-
* Allocates and returns a new `v8::UnLocker` object, temporarily releasing any locks that
|
53
|
-
* this thread is holding. It will reaquire all of the locksto {#delete}.
|
54
|
-
*
|
55
|
-
* This is a great thing to do when you want to call out to some code that might do some
|
56
|
-
* waiting, sleeping, and you want to politely let other threads use this VM.
|
57
|
-
*
|
58
|
-
* It critical that you call {#delete} to deallocate it, preferably within the same method.
|
59
|
-
* If you don't, two bad things will happen:
|
60
|
-
*
|
61
|
-
* 1. You'll leak the underlying C++ object
|
62
|
-
* 1. You won't restore the locks to your current thread, and will mess things up horribly
|
63
|
-
*
|
64
|
-
* It's dangerous! Be sure to `ensure`.
|
65
|
-
*
|
66
|
-
* For details on V8 locking semantics, see the locking {API http://izs.me/v8-docs/classv8_1_1Unlocker.html}
|
67
|
-
* @return [V8::C::Unocker] the new locker
|
68
|
-
*/
|
69
|
-
VALUE New(VALUE UnlockerClass) {
|
70
|
-
Unlocker* unlocker = new Unlocker();
|
71
|
-
return Data_Wrap_Struct(UnlockerClass, 0, 0, (void*)unlocker);
|
72
|
-
}
|
73
|
-
|
74
|
-
/**
|
75
|
-
* Document-method: V8::C::Unlocker#delete
|
76
|
-
*
|
77
|
-
* Restore any locks to the stack that were temporarily removed by this `Unlocker`.
|
78
|
-
* For a full run down, see semantics see the locking {API http://izs.me/v8-docs/classv8_1_1Unlocker.html}
|
79
|
-
* @return nil
|
80
|
-
*/
|
81
|
-
VALUE Delete(VALUE self) {
|
82
|
-
Unlocker* unlocker;
|
83
|
-
Data_Get_Struct(self, class Unlocker, unlocker);
|
84
|
-
delete unlocker;
|
85
|
-
}
|
86
|
-
}
|
87
|
-
|
88
|
-
/**
|
89
|
-
* Document-method: V8::C::Locker#StartPreemption
|
90
|
-
* Start preemption.
|
91
|
-
* When preemption is started, a timer is fired every n milli seconds that will switch between
|
92
|
-
* multiple threads that are in contention for the V8 lock.
|
93
|
-
*
|
94
|
-
* @param [Integer] every_n_ms
|
95
|
-
* @return nil
|
96
|
-
*/
|
97
|
-
VALUE StartPreemption(VALUE self, VALUE every_n_ms) {
|
98
|
-
Locker::StartPreemption(NUM2INT(rb_to_int(every_n_ms)));
|
99
|
-
return Qnil;
|
100
|
-
}
|
101
|
-
|
102
|
-
/**
|
103
|
-
* Document-method: V8::C::Locker#StartPreemption
|
104
|
-
* Stop preemption
|
105
|
-
*/
|
106
|
-
VALUE StopPreemption(VALUE self) {
|
107
|
-
Locker::StopPreemption();
|
108
|
-
return Qnil;
|
109
|
-
}
|
110
|
-
|
111
|
-
/**
|
112
|
-
* Document-method: V8::C::Locker#IsLocked
|
113
|
-
* Returns whether or not the locker is locked by the current thread.
|
114
|
-
*/
|
115
|
-
VALUE IsLocked(VALUE self) {
|
116
|
-
return rr_v82rb(Locker::IsLocked());
|
117
|
-
}
|
118
|
-
|
119
|
-
/**
|
120
|
-
* Document-method: V8::C::Locker#IsActive
|
121
|
-
* Returns whether v8::Locker is being used by this V8 instance.
|
122
|
-
*/
|
123
|
-
VALUE IsActive(VALUE self) {
|
124
|
-
return rr_v82rb(Locker::IsActive());
|
125
|
-
}
|
126
|
-
}
|
127
|
-
|
128
|
-
void rr_init_v8_locker() {
|
129
|
-
VALUE LockerClass = rr_define_class("Locker");
|
130
|
-
VALUE UnlockerClass = rr_define_class("Unlocker");
|
131
|
-
rr_define_singleton_method(LockerClass, "new", Lock::New, 0);
|
132
|
-
rr_define_method(LockerClass, "delete", Lock::Delete, 0);
|
133
|
-
rr_define_singleton_method(UnlockerClass, "new", Unlock::New, 0);
|
134
|
-
rr_define_method(UnlockerClass, "delete", Unlock::Delete, 0);
|
135
|
-
rr_define_singleton_method(LockerClass, "StartPreemption", StartPreemption, 1);
|
136
|
-
rr_define_singleton_method(LockerClass, "StopPreemption", StopPreemption, 0);
|
137
|
-
rr_define_singleton_method(LockerClass, "IsLocked", IsLocked, 0);
|
138
|
-
rr_define_singleton_method(LockerClass, "IsActive", IsActive, 0);
|
139
|
-
}
|