therubyracer-freebsd 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }