Skip to content
This repository was archived by the owner on Dec 4, 2023. It is now read-only.

Commit 288ae8c

Browse files
committed
Merge branch 'upgrade-to-v8-4.5' of github.com:cowboyd/therubyracer into 4.5/referential-integrity
2 parents 213c619 + 3727570 commit 288ae8c

17 files changed

Lines changed: 321 additions & 52 deletions

ext/v8/function-callback.h

Lines changed: 63 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,55 +9,15 @@ namespace rr {
99
class FunctionCallbackInfo : public FunctionCallbackInfoWrapper {
1010
public:
1111

12-
inline FunctionCallbackInfo(v8::FunctionCallbackInfo<v8::Value> info, v8::Local<v8::Value> data_) :
13-
FunctionCallbackInfoWrapper(info), data(data_) {}
12+
inline FunctionCallbackInfo(v8::FunctionCallbackInfo<v8::Value> info) :
13+
FunctionCallbackInfoWrapper(info) {}
1414

1515
inline FunctionCallbackInfo(VALUE self) : FunctionCallbackInfoWrapper(self) {}
1616

1717
inline v8::Local<v8::Value> operator [](int i) {
1818
return this->container->content[i];
1919
}
2020

21-
/**
22-
* Package up the callback data for this function so that it can
23-
* invoke a Ruby callable.
24-
*
25-
* Each `v8::Function` can have one `v8::Value` associated with it
26-
* that is passed to its `v8::FunctionCallback`. To support this
27-
* same API from ruby, we take the `Value` passed into the
28-
* Function constructor *and* the callback and store them *both*
29-
* in a single `v8::Object` which we use for the C++ level
30-
* callback data.
31-
*/
32-
static v8::Local<v8::Value> wrapData(v8::Isolate* isolate, VALUE r_callback, VALUE r_data) {
33-
v8::Local<v8::Object> holder = v8::Object::New(isolate);
34-
v8::Local<v8::String> callback_key = v8::String::NewFromUtf8(isolate, "rr::callback");
35-
v8::Local<v8::String> data_key = v8::String::NewFromUtf8(isolate, "rr::data");
36-
holder->SetHiddenValue(callback_key, External::wrap(isolate, r_callback));
37-
holder->SetHiddenValue(data_key, Value(r_data));
38-
return holder;
39-
}
40-
41-
/**
42-
* Call the Ruby code associated with this callback.
43-
*
44-
* Unpack the Ruby code, and the callback data from the C++
45-
* callback data, and then invoke that code.
46-
*
47-
* Note: This function implements the `v8::FunctionCallback` API.
48-
*/
49-
static void invoke(const v8::FunctionCallbackInfo<v8::Value>& info) {
50-
v8::Isolate* isolate = info.GetIsolate();
51-
v8::Local<v8::Object> holder = v8::Local<v8::Object>::Cast<v8::Value>(info.Data());
52-
v8::Local<v8::String> data_key = v8::String::NewFromUtf8(isolate, "rr::data");
53-
v8::Local<v8::String> callback_key = v8::String::NewFromUtf8(isolate, "rr::callback");
54-
v8::Local<v8::Value> data(holder->GetHiddenValue(data_key));
55-
56-
VALUE code(External::unwrap(holder->GetHiddenValue(callback_key)));
57-
Unlocker unlock(info.GetIsolate());
58-
rb_funcall(code, rb_intern("call"), 1, (VALUE)FunctionCallbackInfo(info, data));
59-
}
60-
6121
static VALUE Length(VALUE self) {
6222
FunctionCallbackInfo info(self);
6323
Locker lock(info->GetIsolate());
@@ -90,8 +50,14 @@ namespace rr {
9050

9151
static VALUE Data(VALUE self) {
9252
FunctionCallbackInfo info(self);
53+
Isolate isolate(info->GetIsolate());
9354
Locker lock(info->GetIsolate());
94-
return Value(info->GetIsolate(), info.data);
55+
56+
v8::Local<v8::Object> holder = v8::Local<v8::Object>::Cast<v8::Value>(info->Data());
57+
v8::Local<v8::String> data_key = v8::String::NewFromUtf8(isolate, "rr::data");
58+
v8::Local<v8::Value> data(holder->GetHiddenValue(data_key));
59+
60+
return Value(info->GetIsolate(), data);
9561
}
9662

9763
static VALUE GetIsolate(VALUE self) {
@@ -117,8 +83,61 @@ namespace rr {
11783
defineMethod("GetReturnValue", &GetReturnValue).
11884
store(&Class);
11985
}
86+
};
87+
88+
class FunctionCallback {
89+
public:
90+
FunctionCallback(v8::Isolate* i, VALUE c, VALUE d) : isolate(i), code(c), data(d) {}
91+
92+
/**
93+
* Package up the callback data for this function so that it can
94+
* invoke a Ruby callable.
95+
*
96+
* Each `v8::Function` can have one `v8::Value` associated with it
97+
* that is passed to its `v8::FunctionCallback`. To support this
98+
* same API from ruby, we take the `Value` passed into the
99+
* Function constructor *and* the callback and store them *both*
100+
* in a single `v8::Object` which we use for the C++ level
101+
* callback data.
102+
*/
103+
inline operator v8::Local<v8::Value>() {
104+
v8::Local<v8::Object> holder = v8::Object::New(isolate);
105+
v8::Local<v8::String> callback_key = v8::String::NewFromUtf8(isolate, "rr::callback");
106+
v8::Local<v8::String> data_key = v8::String::NewFromUtf8(isolate, "rr::data");
107+
holder->SetHiddenValue(callback_key, External::wrap(isolate, code));
108+
holder->SetHiddenValue(data_key, Value(data));
109+
return holder;
110+
}
111+
112+
/**
113+
* Call the Ruby code associated with this callback.
114+
*
115+
* Unpack the Ruby code, and the callback data from the C++
116+
* callback data, and then invoke that code.
117+
*
118+
* Note: This function implements the `v8::FunctionCallback` API.
119+
*/
120+
static void invoke(const v8::FunctionCallbackInfo<v8::Value>& info) {
121+
v8::Isolate* isolate = info.GetIsolate();
122+
v8::Local<v8::Object> holder = v8::Local<v8::Object>::Cast<v8::Value>(info.Data());
123+
v8::Local<v8::String> callback_key = v8::String::NewFromUtf8(isolate, "rr::callback");
124+
125+
VALUE code(External::unwrap(holder->GetHiddenValue(callback_key)));
126+
Unlocker unlock(info.GetIsolate());
127+
rb_funcall(code, rb_intern("call"), 1, (VALUE)FunctionCallbackInfo(info));
128+
}
129+
130+
inline operator v8::FunctionCallback() {
131+
if (RTEST(code)) {
132+
return &invoke;
133+
} else {
134+
return 0;
135+
}
136+
}
120137

121-
v8::Local<v8::Value> data;
138+
v8::Isolate* isolate;
139+
VALUE code;
140+
VALUE data;
122141
};
123142
}
124143

ext/v8/function-template.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// -*- mode: c++ -*-
2+
3+
#ifndef RR_FUNCTION_TEMPLATE_H
4+
#define RR_FUNCTION_TEMPLATE_H
5+
6+
namespace rr {
7+
8+
9+
class FunctionTemplate : public Ref<v8::FunctionTemplate> {
10+
public:
11+
FunctionTemplate(VALUE self) : Ref<v8::FunctionTemplate>(self) {}
12+
FunctionTemplate(v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> t) :
13+
Ref<v8::FunctionTemplate>(isolate, t) {}
14+
static inline void Init() {
15+
ClassBuilder("FunctionTemplate", Template::Class).
16+
defineSingletonMethod("New", &New).
17+
defineMethod("GetFunction", &GetFunction).
18+
store(&Class);
19+
}
20+
21+
static VALUE New(int argc, VALUE argv[], VALUE self) {
22+
VALUE r_isolate, r_callback, r_data, r_signature, r_length;
23+
rb_scan_args(argc, argv, "14", &r_isolate, &r_callback, &r_data, &r_signature, &r_length);
24+
Isolate isolate(r_isolate);
25+
Locker lock(isolate);
26+
27+
FunctionCallback callback(isolate, r_callback, r_data);
28+
Signature signature(r_signature);
29+
int length(RTEST(r_length) ? NUM2INT(r_length) : 0);
30+
31+
return FunctionTemplate(isolate, v8::FunctionTemplate::New(isolate, callback, callback, v8::Local<v8::Signature>(), length));
32+
}
33+
34+
static VALUE GetFunction(VALUE self, VALUE context) {
35+
FunctionTemplate t(self);
36+
Isolate isolate(t.getIsolate());
37+
Locker lock(isolate);
38+
39+
return Function::Maybe(isolate, t->GetFunction(Context(context)));
40+
}
41+
};
42+
}
43+
44+
#endif /* RR_FUNCTION_TEMPLATE_H */

ext/v8/function.cc

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,13 @@ namespace rr {
2626
Isolate isolate(r_isolate);
2727
Locker lock(isolate);
2828

29-
// package up the function's callback data to have bot the code and the data
29+
// package up the function's callback data to have both the code and the data
3030
// parameter.
31-
v8::Local<v8::Value> data(FunctionCallbackInfo::wrapData(isolate, r_callback, r_data));
31+
FunctionCallback callback(isolate, r_callback, r_data);
3232

3333
int length = RTEST(r_length) ? NUM2INT(r_length) : 0;
3434

35-
v8::FunctionCallback callback = &FunctionCallbackInfo::invoke;
36-
37-
return Function(isolate, v8::Function::New(isolate, callback, data, length));
35+
return Function(isolate, v8::Function::New(isolate, callback, callback, length));
3836
}
3937

4038
VALUE Function::NewInstance(int argc, VALUE argv[], VALUE self) {

ext/v8/function.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ namespace rr {
2424

2525
inline Function(VALUE value) : Ref<v8::Function>(value) {}
2626
inline Function(v8::Isolate* isolate, v8::Handle<v8::Function> function) : Ref<v8::Function>(isolate, function) {}
27+
typedef MaybeLocal<Function, v8::Function> Maybe;
2728
};
2829
}
2930

ext/v8/init.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ VALUE ReturnValue::Class;
1111

1212
extern "C" {
1313
void Init_init() {
14+
rb_eval_string("require 'v8/c'");
15+
1416
V8::Init();
1517
DefineEnums();
1618
Isolate::Init();
@@ -37,6 +39,10 @@ extern "C" {
3739
ScriptOrigin::Init();
3840
Array::Init();
3941
External::Init();
42+
Template::Init();
43+
ObjectTemplate::Init();
44+
FunctionTemplate::Init();
45+
Signature::Init();
4046

4147
// Invocation::Init();
4248
// Signature::Init();

ext/v8/object-template.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// -*- mode: c++ -*-
2+
#ifndef RR_OBJECT_TEMPLATE_H
3+
#define RR_OBJECT_TEMPLATE_H
4+
5+
namespace rr {
6+
class ObjectTemplate : Ref<v8::ObjectTemplate> {
7+
public:
8+
ObjectTemplate(VALUE self) : Ref<v8::ObjectTemplate>(self) {}
9+
ObjectTemplate(v8::Isolate* isolate, v8::Handle<v8::ObjectTemplate> tmpl) :
10+
Ref<v8::ObjectTemplate>(isolate, tmpl) {}
11+
inline static void Init() {
12+
ClassBuilder("ObjectTemplate", Template::Class).
13+
defineSingletonMethod("New", &New).
14+
defineMethod("NewInstance", &NewInstance).
15+
store(&Class);
16+
}
17+
18+
static VALUE New(int argc, VALUE argv[], VALUE self) {
19+
VALUE r_isolate, r_constructor;
20+
rb_scan_args(argc, argv, "11", &r_isolate, &r_constructor);
21+
Isolate isolate(r_isolate);
22+
Locker lock(isolate);
23+
return ObjectTemplate(isolate, v8::ObjectTemplate::New(isolate));
24+
}
25+
26+
static VALUE NewInstance(VALUE self , VALUE r_context) {
27+
ObjectTemplate t(self);
28+
Context context(r_context);
29+
Isolate isolate(context.getIsolate());
30+
Locker lock(isolate);
31+
v8::MaybeLocal<v8::Object> object(t->NewInstance());
32+
return Object::Maybe(isolate, ObjectTemplate(self)->NewInstance(context));
33+
}
34+
};
35+
}
36+
37+
38+
#endif /* RR_OBJECT_TEMPLATE_H */

ext/v8/object.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ namespace rr {
1717

1818
inline Object(VALUE value) : Ref<v8::Object>(value) {}
1919
inline Object(v8::Isolate* isolate, v8::Handle<v8::Object> object) : Ref<v8::Object>(isolate, object) {}
20+
21+
typedef MaybeLocal<Object, v8::Object> Maybe;
22+
2023
operator VALUE();
2124
};
2225

ext/v8/rr.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,9 @@ inline VALUE not_implemented(const char* message) {
6262
#include "script-origin.h"
6363
#include "function-callback.h"
6464

65+
#include "template.h"
66+
#include "signature.h"
67+
#include "function-template.h"
68+
#include "object-template.h"
69+
6570
#endif

ext/v8/signature.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include "rr.h"
2+
3+
namespace rr {
4+
VALUE Signature::New(int argc, VALUE argv[], VALUE self) {
5+
VALUE r_isolate;
6+
VALUE r_receiver;
7+
rb_scan_args(argc, argv, "11", &r_isolate, &r_receiver);
8+
9+
Isolate isolate(r_isolate);
10+
Locker lock(isolate);
11+
return Signature(isolate, v8::Signature::New(isolate, FunctionTemplate(r_receiver)));
12+
}
13+
}

ext/v8/signature.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// -*- mode: c++ -*-
2+
#ifndef RR_SIGNATURE_H
3+
#define RR_SIGNATURE_H
4+
5+
namespace rr {
6+
class Signature : public Ref<v8::Signature> {
7+
public:
8+
Signature(VALUE self) : Ref<v8::Signature>(self) {}
9+
Signature(v8::Isolate* i, v8::Local<v8::Signature> s) :
10+
Ref<v8::Signature>(i, s) {}
11+
12+
static void Init() {
13+
ClassBuilder("Signature").
14+
defineSingletonMethod("New", &New).
15+
store(&Class);
16+
}
17+
18+
static VALUE New(int argc, VALUE argv[], VALUE self);
19+
};
20+
}
21+
22+
#endif /* RR_SIGNATURE_H */

0 commit comments

Comments
 (0)