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

Commit 19438dd

Browse files
committed
Namespace the PropertyCallbackInfo classes
1 parent 45ddb40 commit 19438dd

5 files changed

Lines changed: 167 additions & 135 deletions

File tree

ext/v8/class_builder.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ namespace rr {
1111
return klass;
1212
}
1313

14+
VALUE ClassBuilder::defineClassUnder(const char* name, VALUE module, VALUE superclass) {
15+
VALUE klass = rb_define_class_under(module, name, superclass);
16+
rb_funcall(klass, rb_intern("private_class_method"), 1, rb_str_new2("new"));
17+
return klass;
18+
}
19+
1420
VALUE ClassBuilder::defineModule(const char *name) {
1521
VALUE V8 = rb_define_module("V8");
1622
VALUE V8_C = rb_define_module_under(V8, "C");
@@ -21,6 +27,10 @@ namespace rr {
2127
this->value = ClassBuilder::defineClass(name, superclass);
2228
}
2329

30+
ClassBuilder::ClassBuilder(const char* name, VALUE module, VALUE superclass) {
31+
this->value = ClassBuilder::defineClassUnder(name, module, superclass);
32+
}
33+
2434
ClassBuilder::ClassBuilder(const char* name, const char* supername) {
2535
VALUE superclass = ClassBuilder::defineClass(supername);
2636
this->value = ClassBuilder::defineClass(name, superclass);

ext/v8/class_builder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ namespace rr {
77
class ClassBuilder {
88
public:
99
static VALUE defineClass(const char *name, VALUE superclass = rb_cObject);
10+
static VALUE defineClassUnder(const char *name, VALUE module, VALUE superclass = rb_cObject);
1011
static VALUE defineModule(const char *name);
1112

1213
ClassBuilder() {};
1314
ClassBuilder(const char* name, VALUE superclass = rb_cObject);
15+
ClassBuilder(const char* name, VALUE module, VALUE superclass);
1416
ClassBuilder(const char* name, const char* supername);
1517

1618
ClassBuilder& defineConst(const char* name, VALUE value);

ext/v8/init.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ extern "C" {
66

77
using namespace rr;
88

9+
VALUE PropertyCallbackInfo::Class;
10+
911
extern "C" {
1012
void Init_init() {
1113
V8::Init();
@@ -27,8 +29,7 @@ extern "C" {
2729
Symbol::Init();
2830
Function::Init();
2931
FunctionCallbackInfo::Init();
30-
PropertyCallbackInfoValue::Init();
31-
PropertyCallbackInfoVoid::Init();
32+
PropertyCallbackInfo::Init();
3233
ReturnValue::Init();
3334
Script::Init();
3435
ScriptOrigin::Init();

ext/v8/object.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ namespace rr {
9090
return Bool::Maybe(object->SetAccessor(
9191
context,
9292
Name(name),
93-
&PropertyCallbackInfoValue::invoke,
94-
RTEST(setter) ? &PropertyCallbackInfoVoid::invoke : 0,
95-
v8::MaybeLocal<v8::Value>(PropertyCallbackInfo<v8::Value>::wrapData(isolate, getter, setter, data)),
93+
&PropertyCallbackInfo::Value::invoke,
94+
RTEST(setter) ? &PropertyCallbackInfo::Void::invoke : 0,
95+
v8::MaybeLocal<v8::Value>(PropertyCallbackInfo::Base<v8::Value>::wrapData(isolate, getter, setter, data)),
9696
Enum<v8::AccessControl>(settings, v8::DEFAULT),
9797
Enum<v8::PropertyAttribute>(attribute, v8::None)
9898
));

ext/v8/property-callback.h

Lines changed: 149 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -4,160 +4,179 @@
44

55
namespace rr {
66

7-
template <class T>
8-
class PropertyCallbackInfo : public Wrapper<v8::PropertyCallbackInfo<T>> {
7+
class PropertyCallbackInfo {
98
public:
109

11-
inline PropertyCallbackInfo(v8::PropertyCallbackInfo<T> info) :
12-
Wrapper<v8::PropertyCallbackInfo<T>>(info) {}
13-
14-
inline PropertyCallbackInfo(VALUE self) : Wrapper<v8::PropertyCallbackInfo<T>>(self) {}
15-
16-
/**
17-
* Package up the callback data for this object so that it can
18-
* invoke Ruby callables.
19-
*
20-
* Each accessor can have one `v8::Value` associated with it
21-
* that is passed to the `SetAccessor` method. To support this
22-
* same API from ruby, we take the passed data constructor *and*
23-
* the callbacks and store them *both* in a single `v8::Object`
24-
* which we use for the C++ level callback data.
25-
*/
26-
static v8::Local<v8::Value> wrapData(v8::Isolate* isolate, VALUE r_getter, VALUE r_setter, VALUE r_data) {
27-
v8::Local<v8::Object> holder = v8::Object::New(isolate);
28-
29-
v8::Local<v8::String> getter_key = v8::String::NewFromUtf8(isolate, "rr::getter");
30-
v8::Local<v8::String> setter_key = v8::String::NewFromUtf8(isolate, "rr::setter");
31-
v8::Local<v8::String> data_key = v8::String::NewFromUtf8(isolate, "rr::data");
32-
33-
holder->SetHiddenValue(getter_key, External::wrap(isolate, r_getter));
34-
holder->SetHiddenValue(setter_key, External::wrap(isolate, r_setter));
35-
holder->SetHiddenValue(data_key, Value(r_data));
36-
37-
return holder;
38-
}
10+
template <class T>
11+
class Base : public Wrapper<v8::PropertyCallbackInfo<T>> {
12+
public:
13+
14+
inline Base(v8::PropertyCallbackInfo<T> info) :
15+
Wrapper<v8::PropertyCallbackInfo<T>>(info) {}
16+
17+
inline Base(VALUE self) : Wrapper<v8::PropertyCallbackInfo<T>>(self) {}
18+
19+
/**
20+
* Package up the callback data for this object so that it can
21+
* invoke Ruby callables.
22+
*
23+
* Each accessor can have one `v8::Value` associated with it
24+
* that is passed to the `SetAccessor` method. To support this
25+
* same API from ruby, we take the passed data constructor *and*
26+
* the callbacks and store them *both* in a single `v8::Object`
27+
* which we use for the C++ level callback data.
28+
*/
29+
static v8::Local<v8::Value> wrapData(v8::Isolate* isolate, VALUE r_getter, VALUE r_setter, VALUE r_data) {
30+
v8::Local<v8::Object> holder = v8::Object::New(isolate);
31+
32+
v8::Local<v8::String> getter_key = v8::String::NewFromUtf8(isolate, "rr::getter");
33+
v8::Local<v8::String> setter_key = v8::String::NewFromUtf8(isolate, "rr::setter");
34+
v8::Local<v8::String> data_key = v8::String::NewFromUtf8(isolate, "rr::data");
35+
36+
holder->SetHiddenValue(getter_key, External::wrap(isolate, r_getter));
37+
holder->SetHiddenValue(setter_key, External::wrap(isolate, r_setter));
38+
holder->SetHiddenValue(data_key, rr::Value(r_data));
39+
40+
return holder;
41+
}
3942

40-
static VALUE This(VALUE self) {
41-
PropertyCallbackInfo<T> info(self);
42-
Locker lock(info->GetIsolate());
43-
return Object(info->GetIsolate(), info->This());
44-
}
43+
static VALUE This(VALUE self) {
44+
Base<T> info(self);
45+
Locker lock(info->GetIsolate());
46+
return Object(info->GetIsolate(), info->This());
47+
}
4548

46-
static VALUE Data(VALUE self) {
47-
PropertyCallbackInfo<T> info(self);
48-
Isolate isolate(info->GetIsolate());
49-
Locker lock(isolate);
49+
static VALUE Data(VALUE self) {
50+
Base<T> info(self);
51+
Isolate isolate(info->GetIsolate());
52+
Locker lock(isolate);
5053

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::Value> data(holder->GetHiddenValue(data_key));
54+
v8::Local<v8::Object> holder = v8::Local<v8::Object>::Cast<v8::Value>(info->Data());
55+
v8::Local<v8::String> data_key = v8::String::NewFromUtf8(isolate, "rr::data");
56+
v8::Local<v8::Value> data(holder->GetHiddenValue(data_key));
5457

55-
return Value::handleToRubyObject(info->GetIsolate(), data);
56-
}
58+
return rr::Value::handleToRubyObject(info->GetIsolate(), data);
59+
}
5760

58-
static VALUE GetIsolate(VALUE self) {
59-
PropertyCallbackInfo<T> info(self);
60-
return Isolate(info->GetIsolate());
61-
}
62-
};
61+
static VALUE GetIsolate(VALUE self) {
62+
Base<T> info(self);
63+
return Isolate(info->GetIsolate());
64+
}
6365

64-
class PropertyCallbackInfoValue : public PropertyCallbackInfo<v8::Value> {
65-
public:
66+
};
6667

67-
inline PropertyCallbackInfoValue(v8::PropertyCallbackInfo<v8::Value> info) :
68-
PropertyCallbackInfo<v8::Value>(info) {}
69-
70-
inline PropertyCallbackInfoValue(VALUE self) : PropertyCallbackInfo<v8::Value>(self) {}
71-
72-
/**
73-
* Call the Ruby code associated with this callback.
74-
*
75-
* Unpack the Ruby code, and the callback data from the C++
76-
* callback data, and then invoke that code.
77-
*
78-
* Note: This function implements the `v8::AccessorNameGetterCallback` API.
79-
*/
80-
static void invoke(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) {
81-
v8::Isolate* isolate = info.GetIsolate();
82-
v8::Local<v8::Object> holder = v8::Local<v8::Object>::Cast<v8::Value>(info.Data());
83-
v8::Local<v8::String> callback_key = v8::String::NewFromUtf8(isolate, "rr::getter");
84-
85-
VALUE code(External::unwrap(holder->GetHiddenValue(callback_key)));
86-
87-
VALUE rb_property;
88-
if (property->IsSymbol()) {
89-
rb_property = Symbol(isolate, v8::Local<v8::Symbol>::Cast(property));
90-
} else {
91-
rb_property = String(isolate, property->ToString());
92-
}
68+
class Value : public Base<v8::Value> {
69+
public:
9370

94-
Unlocker unlock(info.GetIsolate());
95-
rb_funcall(code, rb_intern("call"), 2, rb_property, (VALUE)PropertyCallbackInfo(info));
96-
}
71+
inline Value(v8::PropertyCallbackInfo<v8::Value> info) :
72+
Base<v8::Value>(info) {}
9773

98-
static VALUE GetReturnValue(VALUE self) {
99-
PropertyCallbackInfoValue info(self);
100-
Locker lock(info->GetIsolate());
101-
return ReturnValue(info->GetReturnValue());
102-
}
74+
inline Value(VALUE self) : Base<v8::Value>(self) {}
10375

104-
static inline void Init() {
105-
ClassBuilder("PropertyCallbackInfoValue").
106-
defineMethod("This", &This).
107-
defineMethod("Data", &Data).
108-
defineMethod("GetIsolate", &GetIsolate).
109-
defineMethod("GetReturnValue", &GetReturnValue).
110-
store(&Class);
111-
}
112-
};
76+
/**
77+
* Call the Ruby code associated with this callback.
78+
*
79+
* Unpack the Ruby code, and the callback data from the C++
80+
* callback data, and then invoke that code.
81+
*
82+
* Note: This function implements the `v8::AccessorNameGetterCallback` API.
83+
*/
84+
static void invoke(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) {
85+
v8::Isolate* isolate = info.GetIsolate();
86+
v8::Local<v8::Object> holder = v8::Local<v8::Object>::Cast<v8::Value>(info.Data());
87+
v8::Local<v8::String> callback_key = v8::String::NewFromUtf8(isolate, "rr::getter");
11388

114-
class PropertyCallbackInfoVoid : public PropertyCallbackInfo<void> {
115-
public:
89+
VALUE code(External::unwrap(holder->GetHiddenValue(callback_key)));
11690

117-
inline PropertyCallbackInfoVoid(v8::PropertyCallbackInfo<void> info) :
118-
PropertyCallbackInfo<void>(info) {}
91+
VALUE rb_property;
92+
if (property->IsSymbol()) {
93+
rb_property = Symbol(isolate, v8::Local<v8::Symbol>::Cast(property));
94+
} else {
95+
rb_property = String(isolate, property->ToString());
96+
}
11997

120-
inline PropertyCallbackInfoVoid(VALUE self) : PropertyCallbackInfo<void>(self) {}
98+
Unlocker unlock(info.GetIsolate());
99+
rb_funcall(code, rb_intern("call"), 2, rb_property, (VALUE)Value(info));
100+
}
121101

122-
/**
123-
* Call the Ruby code associated with this callback.
124-
*
125-
* Unpack the Ruby code, and the callback data from the C++
126-
* callback data, and then invoke that code.
127-
*
128-
* Note: This function implements the `v8::AccessorNameSetterCallback` API.
129-
*/
130-
static void invoke(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info) {
131-
v8::Isolate* isolate = info.GetIsolate();
102+
static VALUE GetReturnValue(VALUE self) {
103+
Value info(self);
104+
Locker lock(info->GetIsolate());
105+
return ReturnValue(info->GetReturnValue());
106+
}
132107

133-
v8::Local<v8::Object> holder = v8::Local<v8::Object>::Cast<v8::Value>(info.Data());
134-
v8::Local<v8::String> callback_key = v8::String::NewFromUtf8(isolate, "rr::setter");
108+
static inline void Init() {
109+
ClassBuilder("Value", PropertyCallbackInfo::Class, PropertyCallbackInfo::Class).
110+
defineMethod("This", &This).
111+
defineMethod("Data", &Data).
112+
defineMethod("GetIsolate", &GetIsolate).
113+
defineMethod("GetReturnValue", &GetReturnValue).
114+
store(&Class);
115+
}
135116

136-
VALUE code(External::unwrap(holder->GetHiddenValue(callback_key)));
117+
};
118+
119+
class Void : public Base<void> {
120+
public:
121+
122+
inline Void(v8::PropertyCallbackInfo<void> info) :
123+
Base<void>(info) {}
124+
125+
inline Void(VALUE self) : Base<void>(self) {}
126+
127+
/**
128+
* Call the Ruby code associated with this callback.
129+
*
130+
* Unpack the Ruby code, and the callback data from the C++
131+
* callback data, and then invoke that code.
132+
*
133+
* Note: This function implements the `v8::AccessorNameSetterCallback` API.
134+
*/
135+
static void invoke(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info) {
136+
v8::Isolate* isolate = info.GetIsolate();
137+
138+
v8::Local<v8::Object> holder = v8::Local<v8::Object>::Cast<v8::Value>(info.Data());
139+
v8::Local<v8::String> callback_key = v8::String::NewFromUtf8(isolate, "rr::setter");
140+
141+
VALUE code(External::unwrap(holder->GetHiddenValue(callback_key)));
142+
143+
VALUE rb_property;
144+
if (property->IsSymbol()) {
145+
rb_property = Symbol(isolate, v8::Local<v8::Symbol>::Cast(property));
146+
} else {
147+
rb_property = String(isolate, property->ToString());
148+
}
149+
150+
Unlocker unlock(info.GetIsolate());
151+
rb_funcall(
152+
code, rb_intern("call"), 3,
153+
rb_property,
154+
(VALUE)rr::Value::handleToRubyObject(isolate, value),
155+
(VALUE)Void(info)
156+
);
157+
}
137158

138-
VALUE rb_property;
139-
if (property->IsSymbol()) {
140-
rb_property = Symbol(isolate, v8::Local<v8::Symbol>::Cast(property));
141-
} else {
142-
rb_property = String(isolate, property->ToString());
159+
static inline void Init() {
160+
ClassBuilder("Void", PropertyCallbackInfo::Class, PropertyCallbackInfo::Class).
161+
defineMethod("This", &This).
162+
defineMethod("Data", &Data).
163+
defineMethod("GetIsolate", &GetIsolate).
164+
// defineMethod("GetReturnValue", &GetReturnValue).
165+
store(&Class);
143166
}
144167

145-
Unlocker unlock(info.GetIsolate());
146-
rb_funcall(
147-
code, rb_intern("call"), 3,
148-
rb_property,
149-
(VALUE)Value::handleToRubyObject(isolate, value),
150-
(VALUE)PropertyCallbackInfoVoid(info)
151-
);
152-
}
168+
};
153169

154-
static inline void Init() {
155-
ClassBuilder("PropertyCallbackInfoVoid").
156-
defineMethod("This", &This).
157-
defineMethod("Data", &Data).
158-
defineMethod("GetIsolate", &GetIsolate).
170+
static VALUE Class;
171+
172+
static void Init() {
173+
ClassBuilder("PropertyCallbackInfo").
159174
store(&Class);
175+
176+
Value::Init();
177+
Void::Init();
160178
}
179+
161180
};
162181

163182
}

0 commit comments

Comments
 (0)