therubyracer-freebsd 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/.gitignore +13 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +8 -0
  4. data/.yardopts +1 -0
  5. data/Changelog.md +231 -0
  6. data/Gemfile +3 -0
  7. data/README.md +167 -0
  8. data/Rakefile +26 -0
  9. data/bin/therubyracer +11 -0
  10. data/ext/v8/extconf.rb +26 -0
  11. data/ext/v8/rr.cpp +189 -0
  12. data/ext/v8/rr.h +41 -0
  13. data/ext/v8/v8.cpp +48 -0
  14. data/ext/v8/v8_array.cpp +48 -0
  15. data/ext/v8/v8_array.h +8 -0
  16. data/ext/v8/v8_callbacks.cpp +81 -0
  17. data/ext/v8/v8_callbacks.h +8 -0
  18. data/ext/v8/v8_context.cpp +92 -0
  19. data/ext/v8/v8_context.h +6 -0
  20. data/ext/v8/v8_date.cpp +40 -0
  21. data/ext/v8/v8_date.h +6 -0
  22. data/ext/v8/v8_debug.cpp +17 -0
  23. data/ext/v8/v8_debug.h +6 -0
  24. data/ext/v8/v8_exception.cpp +133 -0
  25. data/ext/v8/v8_exception.h +11 -0
  26. data/ext/v8/v8_external.cpp +70 -0
  27. data/ext/v8/v8_external.h +8 -0
  28. data/ext/v8/v8_function.cpp +69 -0
  29. data/ext/v8/v8_function.h +11 -0
  30. data/ext/v8/v8_handle.cpp +186 -0
  31. data/ext/v8/v8_handle.h +48 -0
  32. data/ext/v8/v8_locker.cpp +139 -0
  33. data/ext/v8/v8_locker.h +6 -0
  34. data/ext/v8/v8_message.cpp +67 -0
  35. data/ext/v8/v8_message.h +10 -0
  36. data/ext/v8/v8_object.cpp +122 -0
  37. data/ext/v8/v8_object.h +10 -0
  38. data/ext/v8/v8_script.cpp +36 -0
  39. data/ext/v8/v8_script.h +8 -0
  40. data/ext/v8/v8_string.cpp +52 -0
  41. data/ext/v8/v8_string.h +9 -0
  42. data/ext/v8/v8_template.cpp +344 -0
  43. data/ext/v8/v8_template.h +8 -0
  44. data/ext/v8/v8_try_catch.cpp +70 -0
  45. data/ext/v8/v8_try_catch.h +5 -0
  46. data/ext/v8/v8_v8.cpp +34 -0
  47. data/ext/v8/v8_v8.h +6 -0
  48. data/ext/v8/v8_value.cpp +175 -0
  49. data/ext/v8/v8_value.h +10 -0
  50. data/ext/v8/v8_weakref.cpp +61 -0
  51. data/ext/v8/v8_weakref.h +29 -0
  52. data/lib/v8.rb +23 -0
  53. data/lib/v8/access.rb +92 -0
  54. data/lib/v8/array.rb +17 -0
  55. data/lib/v8/c/locker.rb +18 -0
  56. data/lib/v8/cli.rb +133 -0
  57. data/lib/v8/context.rb +111 -0
  58. data/lib/v8/error.rb +130 -0
  59. data/lib/v8/function.rb +44 -0
  60. data/lib/v8/object.rb +69 -0
  61. data/lib/v8/portal.rb +86 -0
  62. data/lib/v8/portal/caller.rb +37 -0
  63. data/lib/v8/portal/constructor.rb +98 -0
  64. data/lib/v8/portal/function.rb +63 -0
  65. data/lib/v8/portal/interceptors.rb +152 -0
  66. data/lib/v8/portal/proxies.rb +151 -0
  67. data/lib/v8/portal/templates.rb +73 -0
  68. data/lib/v8/stack.rb +66 -0
  69. data/lib/v8/tap.rb +9 -0
  70. data/lib/v8/version.rb +3 -0
  71. data/spec/ext/array_spec.rb +15 -0
  72. data/spec/ext/cxt_spec.rb +57 -0
  73. data/spec/ext/ext_spec_helper.rb +27 -0
  74. data/spec/ext/func_spec.rb +64 -0
  75. data/spec/ext/object_spec.rb +10 -0
  76. data/spec/ext/string_spec.rb +11 -0
  77. data/spec/ext/try_catch_spec.rb +60 -0
  78. data/spec/redjs_spec.rb +9 -0
  79. data/spec/spec_helper.rb +9 -0
  80. data/spec/v8/error_spec.rb +131 -0
  81. data/spec/v8/portal/proxies_spec.rb +106 -0
  82. data/specmem/handle_memspec.rb +41 -0
  83. data/specmem/object_memspec.rb +14 -0
  84. data/specmem/proxies_memspec.rb +49 -0
  85. data/specmem/spec_helper.rb +24 -0
  86. data/specthread/spec_helper.rb +2 -0
  87. data/specthread/threading_spec.rb +13 -0
  88. data/thefrontside.png +0 -0
  89. data/therubyracer.gemspec +27 -0
  90. metadata +183 -0
@@ -0,0 +1,10 @@
1
+ #ifndef _RUBY_V8_MESSAGE_
2
+ #define _RUBY_V8_MESSAGE_
3
+
4
+ #include "v8.h"
5
+ #include "rr.h"
6
+
7
+ void rr_init_message();
8
+ VALUE rr_reflect_v8_message(v8::Handle<v8::Message> value);
9
+
10
+ #endif
@@ -0,0 +1,122 @@
1
+ #include "v8_handle.h"
2
+ #include "v8_weakref.h"
3
+ #include "v8_object.h"
4
+ #include "v8_value.h"
5
+ #include "v8_template.h"
6
+ #include "v8_external.h"
7
+
8
+ using namespace v8;
9
+
10
+ #include <cstdio>
11
+
12
+ namespace {
13
+
14
+ VALUE ObjectClass;
15
+
16
+ Persistent<Object>& unwrap(VALUE object) {
17
+ return rr_v8_handle<Object>(object);
18
+ }
19
+
20
+ VALUE Get(VALUE self, VALUE key) {
21
+ HandleScope handles;
22
+ Persistent<Object> obj(unwrap(self));
23
+ if (rb_obj_is_kind_of(key, rb_cNumeric)) {
24
+ return rr_v82rb(obj->Get(NUM2UINT(key)));
25
+ } else {
26
+ return rr_v82rb(obj->Get(rr_rb2v8(key)->ToString()));
27
+ }
28
+ }
29
+
30
+ VALUE New(VALUE rbclass) {
31
+ HandleScope handles;
32
+ if (!Context::InContext()) {
33
+ rb_raise(rb_eScriptError, "Object::New() called without an entered Context");
34
+ return Qnil;
35
+ }
36
+ return rr_v8_handle_new(rbclass, Object::New());
37
+ }
38
+
39
+ VALUE Set(VALUE self, VALUE key, VALUE value) {
40
+ HandleScope handles;
41
+ Persistent<Object> obj = unwrap(self);
42
+ if (rb_obj_is_kind_of(key, rb_cNumeric)) {
43
+ return rr_v82rb(obj->Set(NUM2UINT(key), rr_rb2v8(value)));
44
+ } else {
45
+ return rr_v82rb(obj->Set(rr_rb2v8(key), rr_rb2v8(value)));
46
+ }
47
+ }
48
+
49
+ VALUE GetPropertyNames(VALUE self) {
50
+ HandleScope handles;
51
+ Persistent<Object> object = unwrap(self);
52
+ Local<Value> names = object->GetPropertyNames();
53
+ return rr_v82rb(names);
54
+ }
55
+ VALUE GetIdentityHash(VALUE self) {
56
+ return rr_v82rb(unwrap(self)->GetIdentityHash());
57
+ }
58
+ VALUE SetHiddenValue(VALUE self, VALUE key, VALUE value) {
59
+ HandleScope scope;
60
+ if (Context::InContext()) {
61
+ unwrap(self)->SetHiddenValue(rr_rb2v8(key)->ToString(), rr_rb2v8(value));
62
+ } else {
63
+ rb_raise(rb_eScriptError, "Object::SetHiddenValue() called without an entered Context");
64
+ }
65
+ return Qnil;
66
+ }
67
+ VALUE GetHiddenValue(VALUE self, VALUE key) {
68
+ HandleScope scope;
69
+ return rr_v82rb(unwrap(self)->GetHiddenValue(rr_rb2v8(key)->ToString()));
70
+ }
71
+ VALUE GetPrototype(VALUE self) {
72
+ HandleScope scope;
73
+ return rr_v82rb(unwrap(self)->GetPrototype());
74
+ }
75
+ VALUE SetPrototype(VALUE self, VALUE prototype) {
76
+ HandleScope scope;
77
+ Handle<Value> proto(rr_rb2v8(prototype));
78
+ return rr_v82rb(unwrap(self)->SetPrototype(rr_rb2v8(prototype)));
79
+ }
80
+ }
81
+
82
+ VALUE rr_v8_object_class() {
83
+ return ObjectClass;
84
+ }
85
+
86
+ void rr_init_object() {
87
+ ObjectClass = rr_define_class("Object", rr_v8_value_class());
88
+ rr_define_singleton_method(ObjectClass, "New", New, 0);
89
+ rr_define_method(ObjectClass, "Get", Get, 1);
90
+ rr_define_method(ObjectClass, "Set", Set, 2);
91
+ rr_define_method(ObjectClass, "GetPropertyNames", GetPropertyNames, 0);
92
+ rr_define_method(ObjectClass, "GetIdentityHash", GetIdentityHash, 0);
93
+ rr_define_method(ObjectClass, "GetHiddenValue", GetHiddenValue, 1);
94
+ rr_define_method(ObjectClass, "SetHiddenValue", SetHiddenValue, 2);
95
+ rr_define_method(ObjectClass, "GetPrototype", GetPrototype, 0);
96
+ rr_define_method(ObjectClass, "SetPrototype", SetPrototype, 1);
97
+ }
98
+
99
+ VALUE rr_reflect_v8_object_as(Handle<Value> value, VALUE ruby_class) {
100
+ Handle<Object> object = Handle<Object>::Cast(value);
101
+ VALUE handle;
102
+ v8_weakref* backref;
103
+ Local<Value> holder = object->GetHiddenValue(String::NewSymbol("TheRubyRacer::Backref"));
104
+ if (holder.IsEmpty()) {
105
+ handle = rr_v8_handle_new(ruby_class, object);
106
+ backref = new v8_weakref(handle);
107
+ object->SetHiddenValue(String::NewSymbol("TheRubyRacer::Backref"), backref->external);
108
+ } else {
109
+ backref = (v8_weakref*)External::Unwrap(holder);
110
+ handle = backref->get();
111
+ if (!RTEST(handle)) {
112
+ handle = rr_v8_handle_new(ruby_class, object);
113
+ backref->set(handle);
114
+ }
115
+ }
116
+ return handle;
117
+ }
118
+
119
+ VALUE rr_reflect_v8_object(Handle<Value> value) {
120
+ return rr_reflect_v8_object_as(value, ObjectClass);
121
+ }
122
+
@@ -0,0 +1,10 @@
1
+ #ifndef _RUBY_V8_OBJECT_
2
+ #define _RUBY_V8_OBJECT_
3
+
4
+ #include "rr.h"
5
+
6
+ void rr_init_object();
7
+ VALUE rr_v8_object_class();
8
+ VALUE rr_reflect_v8_object(v8::Handle<v8::Value> value);
9
+ VALUE rr_reflect_v8_object_as(v8::Handle<v8::Value> object, VALUE ruby_class);
10
+ #endif
@@ -0,0 +1,36 @@
1
+ #include "v8.h"
2
+ #include "v8_handle.h"
3
+ #include "v8_script.h"
4
+
5
+ using namespace v8;
6
+
7
+ namespace {
8
+
9
+ VALUE New(VALUE self, VALUE source, VALUE source_name) {
10
+ HandleScope scope;
11
+ Local<String> src(rr_rb2v8(source)->ToString());
12
+ Local<String> src_name(rr_rb2v8(source_name)->ToString());
13
+ return rr_v8_handle_new(self, Script::Compile(src, src_name));
14
+ }
15
+
16
+ VALUE Compile(VALUE self, VALUE source, VALUE source_name) {
17
+ HandleScope scope;
18
+ Local<String> src(rr_rb2v8(source)->ToString());
19
+ Local<String> src_name(rr_rb2v8(source_name)->ToString());
20
+ return rr_v8_handle_new(self, Script::Compile(src, src_name));
21
+ }
22
+
23
+ VALUE Run(VALUE self) {
24
+ HandleScope scope;
25
+ Persistent<Script> script(rr_v8_handle<Script>(self));
26
+ Local<Value> result(script->Run());
27
+ return result.IsEmpty() ? Qnil : rr_v82rb(result);
28
+ }
29
+ }
30
+
31
+ void rr_init_script() {
32
+ VALUE ScriptClass = rr_define_class("Script", rr_v8_handle_class());
33
+ rr_define_singleton_method(ScriptClass, "New", New, 2);
34
+ rr_define_singleton_method(ScriptClass, "Compile", Compile, 2);
35
+ rr_define_method(ScriptClass, "Run", Run, 0);
36
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef _RUBY_V8_SCRIPT_
2
+ #define _RUBY_V8_SCRIPT_
3
+
4
+ #include "rr.h"
5
+
6
+ void rr_init_script();
7
+
8
+ #endif
@@ -0,0 +1,52 @@
1
+
2
+ #include "v8.h"
3
+ #include "v8_handle.h"
4
+ #include "v8_value.h"
5
+ #include "v8_string.h"
6
+
7
+ using namespace v8;
8
+
9
+ namespace {
10
+ VALUE StringClass;
11
+
12
+ Persistent<String>& unwrap(VALUE value) {
13
+ return rr_v8_handle<String>(value);
14
+ }
15
+ VALUE New(VALUE string_class, VALUE data) {
16
+ HandleScope handles;
17
+ VALUE str = rb_funcall(data, rb_intern("to_s"), 0);
18
+ return rr_v8_handle_new(string_class, String::New(RSTRING_PTR(str), RSTRING_LEN(str)));
19
+ }
20
+ VALUE NewSymbol(VALUE string_class, VALUE data) {
21
+ HandleScope scope;
22
+ VALUE str = rb_funcall(data, rb_intern("to_s"), 0);
23
+ return rr_v8_handle_new(string_class, String::NewSymbol(RSTRING_PTR(str), RSTRING_LEN(str)));
24
+ }
25
+ VALUE Utf8Value(VALUE self) {
26
+ HandleScope handles;
27
+ Handle<String> str = unwrap(self);
28
+ return rb_str_new(*String::Utf8Value(str), str->Utf8Length());
29
+ }
30
+ VALUE Utf16Value(VALUE self) {
31
+ //How are UTF16 strings represented in ruby 1.8, 1.9
32
+ return Qnil;
33
+ }
34
+ VALUE AsciiValue(VALUE self) {
35
+ HandleScope handles;
36
+ Handle<String> str = unwrap(self);
37
+ return rb_str_new(*String::AsciiValue(str), str->Length());
38
+ }
39
+ }
40
+
41
+ VALUE rr_reflect_v8_string(Handle<Value> value) {
42
+ return rr_v8_handle_new(StringClass, Handle<String>::Cast(value));
43
+ }
44
+
45
+ void rr_init_string() {
46
+ StringClass = rr_define_class("String", rr_v8_value_class());
47
+ rr_define_singleton_method(StringClass, "New", New, 1);
48
+ rr_define_singleton_method(StringClass, "NewSymbol", NewSymbol, 1);
49
+ rr_define_method(StringClass, "Utf8Value", Utf8Value, 0);
50
+ rr_define_method(StringClass, "Utf16Value", Utf16Value, 0);
51
+ rr_define_method(StringClass, "AsciiValue", AsciiValue, 0);
52
+ }
@@ -0,0 +1,9 @@
1
+ #ifndef _RUBY_V8_STR_
2
+ #define _RUBY_V8_STR_
3
+
4
+ #include "rr.h"
5
+
6
+ void rr_init_string();
7
+
8
+ VALUE rr_reflect_v8_string(v8::Handle<v8::Value> value);
9
+ #endif
@@ -0,0 +1,344 @@
1
+ #include "rr.h"
2
+ #include "v8_handle.h"
3
+ #include "v8_function.h"
4
+ #include "v8_template.h"
5
+ #include "v8_external.h"
6
+ #include "v8_callbacks.h"
7
+
8
+ using namespace v8;
9
+
10
+ namespace {
11
+
12
+ VALUE ObjectTemplateClass;
13
+ VALUE FunctionTemplateClass;
14
+
15
+ struct v8_callback_data {
16
+ VALUE handler;
17
+ VALUE getter;
18
+ VALUE setter;
19
+ VALUE query;
20
+ VALUE deleter;
21
+ VALUE enumerator;
22
+ VALUE data;
23
+ };
24
+
25
+ void delete_v8_data(Persistent<Value> value, void* parameter) {
26
+ value.Dispose();
27
+ delete (v8_callback_data*)parameter;
28
+ }
29
+
30
+ Local<External> make_v8_data(int argc, VALUE *argv, const char* argf) {
31
+ VALUE handler; VALUE data;
32
+ rb_scan_args(argc, argv, argf, &handler, &data);
33
+ v8_callback_data* v8_data = new v8_callback_data();
34
+ v8_data->handler = handler;
35
+ v8_data->data = data;
36
+ Local<External> external = External::New((void*)v8_data);
37
+ Persistent<External>::New(external).MakeWeak((void*)v8_data, delete_v8_data);
38
+ return external;
39
+ }
40
+
41
+ Persistent<Template> tmpl(VALUE self) {
42
+ return rr_v8_handle<Template>(self);
43
+ }
44
+ Persistent<ObjectTemplate> obj(VALUE self) {
45
+ return rr_v8_handle<ObjectTemplate>(self);
46
+ }
47
+ Persistent<FunctionTemplate> func(VALUE self) {
48
+ return rr_v8_handle<FunctionTemplate>(self);
49
+ }
50
+
51
+ VALUE Set(VALUE self, VALUE name, VALUE value) {
52
+ HandleScope handles;
53
+ Local<String> key = rr_rb2v8(name)->ToString();
54
+ Persistent<Data> data = rr_v8_handle<Data>(value);
55
+ tmpl(self)->Set(key, data);
56
+ return Qnil;
57
+ }
58
+
59
+ Handle<Value> RubyInvocationCallback(const Arguments& args) {
60
+ Handle<External> v8_data_wrapper = Handle<External>::Cast(args.Data());
61
+ v8_callback_data* v8_data = (v8_callback_data*)v8_data_wrapper->Value();
62
+ if (RTEST(v8_data->handler)) {
63
+ VALUE rb_args = rr_v82rb(args);
64
+ rb_iv_set(rb_args, "data", v8_data->data);
65
+ VALUE result = rb_funcall(v8_data->handler, rb_intern("call"), 1, rb_args);
66
+ return rr_rb2v8(result);
67
+ } else {
68
+ return Handle<Value>();
69
+ }
70
+ }
71
+
72
+ namespace Obj {
73
+
74
+
75
+ v8_callback_data* accessor_info_data(const AccessorInfo& info) {
76
+ Handle<External> v8_data_wrapper = Handle<External>::Cast(info.Data());
77
+ return (v8_callback_data*)v8_data_wrapper->Value();
78
+ }
79
+
80
+ VALUE accessor_info_rb(const AccessorInfo& info) {
81
+ VALUE rb_data = accessor_info_data(info)->data;
82
+ VALUE rb_info = rr_v82rb(info);
83
+ rb_iv_set(rb_info, "data", rb_data);
84
+ return rb_info;
85
+ }
86
+
87
+ Local<External> accessor_info_data(VALUE getter, VALUE setter, VALUE query, VALUE deleter, VALUE enumerator, VALUE data) {
88
+ v8_callback_data* v8_data = new v8_callback_data();
89
+ v8_data->getter = getter;
90
+ v8_data->setter = setter;
91
+ v8_data->query = query;
92
+ v8_data->deleter = deleter;
93
+ v8_data->enumerator = enumerator;
94
+ v8_data->data = data;
95
+ Local<External> external = External::New((void*)v8_data);
96
+ Persistent<External>::New(external).MakeWeak((void*)v8_data, delete_v8_data);
97
+ return external;
98
+ }
99
+
100
+ /**
101
+ * NamedProperty[Getter|Setter] are used as interceptors on object.
102
+ * See ObjectTemplate::SetNamedPropertyHandler.
103
+ */
104
+ Handle<Value> RubyNamedPropertyGetter(Local<String> property, const AccessorInfo& info) {
105
+ VALUE getter = accessor_info_data(info)->getter;
106
+ return rr_rb2v8(rb_funcall(getter, rb_intern("call"), 2, rr_v82rb(property), accessor_info_rb(info)));
107
+ }
108
+
109
+ /**
110
+ * Returns the value if the setter intercepts the request.
111
+ * Otherwise, returns an empty handle.
112
+ */
113
+ Handle<Value> RubyNamedPropertySetter(Local<String> property, Local<Value> value, const AccessorInfo& info) {
114
+ VALUE setter = accessor_info_data(info)->setter;
115
+ VALUE result = rb_funcall(setter, rb_intern("call"), 3, rr_v82rb(property), rr_v82rb(value), accessor_info_rb(info));
116
+ return rr_rb2v8(result);
117
+ }
118
+
119
+
120
+ /**
121
+ * Returns a non-empty handle if the interceptor intercepts the request.
122
+ * The result is true if the property exists and false otherwise.
123
+ */
124
+ Handle<Integer> RubyNamedPropertyQuery(Local<String> property, const AccessorInfo& info) {
125
+ VALUE query = accessor_info_data(info)->query;
126
+ VALUE result = rb_funcall(query, rb_intern("call"), 2, rr_v82rb(property), accessor_info_rb(info));
127
+ Handle<Value> intercepts = rr_rb2v8(result);
128
+ return intercepts.IsEmpty() ? Handle<Integer>() : Integer::New(None);
129
+ }
130
+
131
+ /**
132
+ * Returns a non-empty handle if the deleter intercepts the request.
133
+ * The return value is true if the property could be deleted and false
134
+ * otherwise.
135
+ */
136
+ Handle<Boolean> RubyNamedPropertyDeleter(Local<String> property, const AccessorInfo& info) {
137
+ VALUE deleter = accessor_info_data(info)->deleter;
138
+ VALUE result = rb_funcall(deleter, rb_intern("call"), 2, rr_v82rb(property), accessor_info_rb(info));
139
+ Handle<Value> intercepts = rr_rb2v8(result);
140
+ return intercepts.IsEmpty() ? Handle<Boolean>() : intercepts->ToBoolean();
141
+ }
142
+
143
+ /**
144
+ * Returns an array containing the names of the properties the named
145
+ * property getter intercepts.
146
+ */
147
+ Handle<Array> RubyNamedPropertyEnumerator(const AccessorInfo& info) {
148
+ VALUE enumerator = accessor_info_data(info)->enumerator;
149
+ VALUE result = rb_funcall(enumerator, rb_intern("call"), 1, accessor_info_rb(info));
150
+ Handle<Value> v(rr_rb2v8(result));
151
+ if (v.IsEmpty()) {
152
+ return Array::New();
153
+ } else if (!v->IsArray()) {
154
+ Local<Array> a = Array::New();
155
+ a->Set(Integer::New(0), v->ToString());
156
+ return a;
157
+ } else {
158
+ return (Handle<Array>)Array::Cast(*v);
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Returns the value of the property if the getter intercepts the
164
+ * request. Otherwise, returns an empty handle.
165
+ */
166
+ Handle<Value> RubyIndexedPropertyGetter(uint32_t index, const AccessorInfo& info) {
167
+ VALUE getter = accessor_info_data(info)->getter;
168
+ VALUE result = rb_funcall(getter, rb_intern("call"), 2, UINT2NUM(index), accessor_info_rb(info));
169
+ return rr_rb2v8(result);
170
+ }
171
+
172
+ /**
173
+ * Returns the value if the setter intercepts the request.
174
+ * Otherwise, returns an empty handle.
175
+ */
176
+ Handle<Value> RubyIndexedPropertySetter(uint32_t index, Local<Value> value, const AccessorInfo& info) {
177
+ VALUE setter = accessor_info_data(info)->setter;
178
+ VALUE result = rb_funcall(setter, rb_intern("call"), 3, UINT2NUM(index), rr_v82rb(value), accessor_info_rb(info));
179
+ return rr_rb2v8(result);
180
+ }
181
+
182
+ /**
183
+ * Returns a non-empty handle if the interceptor intercepts the request.
184
+ * The result is true if the property exists and false otherwise.
185
+ */
186
+ Handle<Integer> RubyIndexedPropertyQuery(uint32_t index, const AccessorInfo& info) {
187
+ VALUE query = accessor_info_data(info)->query;
188
+ VALUE result = rb_funcall(query, rb_intern("call"), 2, UINT2NUM(index), accessor_info_rb(info));
189
+ Handle<Value> intercepts = rr_rb2v8(result);
190
+ return intercepts.IsEmpty() ? Handle<Integer>() : Integer::New(None);
191
+ }
192
+
193
+ /**
194
+ * Returns a non-empty handle if the deleter intercepts the request.
195
+ * The return value is true if the property could be deleted and false
196
+ * otherwise.
197
+ */
198
+ Handle<Boolean> RubyIndexedPropertyDeleter(uint32_t index, const AccessorInfo& info) {
199
+ VALUE deleter = accessor_info_data(info)->deleter;
200
+ VALUE result = rb_funcall(deleter, rb_intern("call"), 2, UINT2NUM(index), accessor_info_rb(info));
201
+ Handle<Value> intercepts = rr_rb2v8(result);
202
+ return intercepts.IsEmpty() ? Handle<Boolean>() : intercepts->ToBoolean();
203
+ }
204
+
205
+ /**
206
+ * Returns an array containing the indices of the properties the
207
+ * indexed property getter intercepts.
208
+ */
209
+ Handle<Array> RubyIndexedPropertyEnumerator(const AccessorInfo& info) {
210
+ VALUE enumerator = accessor_info_data(info)->enumerator;
211
+ VALUE result = rb_funcall(enumerator, rb_intern("call"), 1, accessor_info_rb(info));
212
+ Handle<Value> v(rr_rb2v8(result));
213
+ if (v.IsEmpty()) {
214
+ return Array::New();
215
+ } else if (!v->IsArray()) {
216
+ Local<Array> a = Array::New();
217
+ a->Set(Integer::New(0), v->ToString());
218
+ return a;
219
+ } else {
220
+ return (Handle<Array>)Array::Cast(*v);
221
+ }
222
+ }
223
+
224
+ VALUE New(VALUE rbclass) {
225
+ HandleScope handles;
226
+ return rr_v8_handle_new(rbclass, ObjectTemplate::New());
227
+ }
228
+ VALUE NewInstance(VALUE self) {
229
+ HandleScope scope;
230
+ if (!Context::InContext()) {
231
+ rb_raise(rb_eScriptError, "ObjectTemplate::NewInstance() called without an entered Context");
232
+ return Qnil;
233
+ }
234
+ Local<Object> object(obj(self)->NewInstance());
235
+ if (object.IsEmpty()) {
236
+ rb_raise(rb_eFatal, "V8 returned empty handle on call to ObjectTemplate::NewInstance()");
237
+ return Qnil;
238
+ }
239
+ return rr_v82rb(object);
240
+ }
241
+ VALUE SetNamedPropertyHandler(VALUE self, VALUE getter, VALUE setter, VALUE query, VALUE deleter, VALUE enumerator, VALUE data) {
242
+ HandleScope handles;
243
+ if (!RTEST(getter)) {
244
+ rb_raise(rb_eArgError, "you must supply at least a getter to V8::C::ObjectTemplate#SetNamedPropertyHandler()");
245
+ return Qnil;
246
+ }
247
+ obj(self)->SetNamedPropertyHandler(
248
+ RubyNamedPropertyGetter,
249
+ RTEST(setter) ? RubyNamedPropertySetter : 0,
250
+ RTEST(query) ? RubyNamedPropertyQuery : 0,
251
+ RTEST(deleter) ? RubyNamedPropertyDeleter : 0,
252
+ RTEST(enumerator) ? RubyNamedPropertyEnumerator : 0,
253
+ accessor_info_data(getter, setter, query, deleter, enumerator, data)
254
+ );
255
+ return Qnil;
256
+ }
257
+
258
+ VALUE SetIndexedPropertyHandler(VALUE self, VALUE getter, VALUE setter, VALUE query, VALUE deleter, VALUE enumerator, VALUE data) {
259
+ HandleScope scope;
260
+ if (!RTEST(getter)) {
261
+ rb_raise(rb_eArgError, "you must supply at least a getter to V8::C::ObjectTemplate#SetNamedPropertyHandler()");
262
+ return Qnil;
263
+ }
264
+ obj(self)->SetIndexedPropertyHandler(
265
+ RubyIndexedPropertyGetter,
266
+ RTEST(setter) ? RubyIndexedPropertySetter : 0,
267
+ RTEST(query) ? RubyIndexedPropertyQuery : 0,
268
+ RTEST(deleter) ? RubyIndexedPropertyDeleter : 0,
269
+ RTEST(enumerator) ? RubyIndexedPropertyEnumerator : 0,
270
+ accessor_info_data(getter, setter, query, deleter, enumerator, data)
271
+ );
272
+ return Qnil;
273
+ }
274
+ VALUE SetCallAsFunctionHandler(int argc, VALUE *argv, VALUE self) {
275
+ Handle<Value> v8_data = make_v8_data(argc, argv, "11");
276
+ obj(self)->SetCallAsFunctionHandler(RubyInvocationCallback, v8_data);
277
+ return Qnil;
278
+ }
279
+ }
280
+
281
+ namespace Func {
282
+
283
+ VALUE New(int argc, VALUE *argv, VALUE self) {
284
+ HandleScope h;
285
+ Handle<External> v8_data = make_v8_data(argc, argv, "02");
286
+ Local<FunctionTemplate> t = FunctionTemplate::New(RubyInvocationCallback, v8_data);
287
+ VALUE handle = rr_v8_handle_new(self,t);
288
+ return handle;
289
+ }
290
+ VALUE SetCallHandler(int argc, VALUE *argv, VALUE self) {
291
+ HandleScope h;
292
+ Handle<Value> v8_data = make_v8_data(argc, argv, "11");
293
+ func(self)->SetCallHandler(RubyInvocationCallback, v8_data);
294
+ return Qnil;
295
+ }
296
+ VALUE PrototypeTemplate(VALUE self) {
297
+ HandleScope scope;
298
+ return rr_v8_handle_new(ObjectTemplateClass, func(self)->PrototypeTemplate());
299
+ }
300
+ VALUE InstanceTemplate(VALUE self) {
301
+ HandleScope scope;
302
+ return rr_v8_handle_new(ObjectTemplateClass, func(self)->InstanceTemplate());
303
+ }
304
+ VALUE Inherit(VALUE self, VALUE function_template) {
305
+ HandleScope scope;
306
+ func(self)->Inherit(func(function_template));
307
+ return Qnil;
308
+ }
309
+ VALUE SetClassName(VALUE self, VALUE name) {
310
+ HandleScope scope;
311
+ func(self)->SetClassName(rr_rb2v8(name)->ToString());
312
+ return Qnil;
313
+ }
314
+ VALUE GetFunction(VALUE self) {
315
+ HandleScope handles;
316
+ if (!Context::InContext()) {
317
+ rb_raise(rb_eScriptError, "calls to FunctionTemplate::GetFunction() require a Context to be entered");
318
+ return Qnil;
319
+ }
320
+ return rr_v82rb(func(self)->GetFunction());
321
+ }
322
+ }
323
+ }
324
+
325
+ void rr_init_template() {
326
+ VALUE Template = rr_define_class("Template", rr_v8_handle_class());
327
+ rr_define_method(Template, "Set", Set, 2);
328
+
329
+ ObjectTemplateClass = rr_define_class("ObjectTemplate", Template);
330
+ rr_define_singleton_method(ObjectTemplateClass, "New", Obj::New, 0);
331
+ rr_define_method(ObjectTemplateClass, "NewInstance", Obj::NewInstance, 0);
332
+ rr_define_method(ObjectTemplateClass, "SetNamedPropertyHandler", Obj::SetNamedPropertyHandler, 6);
333
+ rr_define_method(ObjectTemplateClass, "SetIndexedPropertyHandler", Obj::SetIndexedPropertyHandler, 6);
334
+ rr_define_method(ObjectTemplateClass, "SetCallAsFunctionHandler", Obj::SetCallAsFunctionHandler, -1);
335
+
336
+ FunctionTemplateClass = rr_define_class("FunctionTemplate", Template);
337
+ rr_define_singleton_method(FunctionTemplateClass, "New", Func::New, -1);
338
+ rr_define_method(FunctionTemplateClass, "SetCallHandler", Func::SetCallHandler, -1);
339
+ rr_define_method(FunctionTemplateClass, "PrototypeTemplate", Func::PrototypeTemplate, 0);
340
+ rr_define_method(FunctionTemplateClass, "InstanceTemplate", Func::InstanceTemplate, 0);
341
+ rr_define_method(FunctionTemplateClass, "Inherit", Func::Inherit, 1);
342
+ rr_define_method(FunctionTemplateClass, "SetClassName", Func::SetClassName, 1);
343
+ rr_define_method(FunctionTemplateClass, "GetFunction", Func::GetFunction, 0);
344
+ }