therubyracer 0.10.2 → 0.11.0beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of therubyracer might be problematic. Click here for more details.

Files changed (159) hide show
  1. data/.gitignore +21 -11
  2. data/.travis.yml +2 -1
  3. data/Changelog.md +46 -0
  4. data/Gemfile +16 -1
  5. data/README.md +31 -13
  6. data/Rakefile +42 -23
  7. data/benchmarks.rb +217 -0
  8. data/ext/v8/accessor.cc +181 -0
  9. data/ext/v8/array.cc +26 -0
  10. data/ext/v8/backref.cc +56 -0
  11. data/ext/v8/build.rb +51 -0
  12. data/ext/v8/constants.cc +34 -0
  13. data/ext/v8/constraints.cc +52 -0
  14. data/ext/v8/context.cc +130 -0
  15. data/ext/v8/date.cc +18 -0
  16. data/ext/v8/exception.cc +38 -0
  17. data/ext/v8/extconf.rb +14 -18
  18. data/ext/v8/external.cc +43 -0
  19. data/ext/v8/function.cc +58 -0
  20. data/ext/v8/gc.cc +43 -0
  21. data/ext/v8/handles.cc +34 -0
  22. data/ext/v8/heap.cc +31 -0
  23. data/ext/v8/init.cc +39 -0
  24. data/ext/v8/invocation.cc +86 -0
  25. data/ext/v8/locker.cc +77 -0
  26. data/ext/v8/message.cc +51 -0
  27. data/ext/v8/object.cc +334 -0
  28. data/ext/v8/primitive.cc +8 -0
  29. data/ext/v8/rr.cc +83 -0
  30. data/ext/v8/rr.h +878 -36
  31. data/ext/v8/script.cc +80 -0
  32. data/ext/v8/signature.cc +18 -0
  33. data/ext/v8/stack.cc +75 -0
  34. data/ext/v8/string.cc +47 -0
  35. data/ext/v8/template.cc +175 -0
  36. data/ext/v8/trycatch.cc +86 -0
  37. data/ext/v8/v8.cc +87 -0
  38. data/ext/v8/value.cc +239 -0
  39. data/lib/v8.rb +30 -22
  40. data/lib/v8/access.rb +5 -87
  41. data/lib/v8/access/indices.rb +40 -0
  42. data/lib/v8/access/invocation.rb +47 -0
  43. data/lib/v8/access/names.rb +65 -0
  44. data/lib/v8/array.rb +19 -10
  45. data/lib/v8/context.rb +85 -78
  46. data/lib/v8/conversion.rb +35 -0
  47. data/lib/v8/conversion/array.rb +11 -0
  48. data/lib/v8/conversion/class.rb +120 -0
  49. data/lib/v8/conversion/code.rb +38 -0
  50. data/lib/v8/conversion/fundamental.rb +11 -0
  51. data/lib/v8/conversion/hash.rb +11 -0
  52. data/lib/v8/conversion/indentity.rb +31 -0
  53. data/lib/v8/conversion/method.rb +26 -0
  54. data/lib/v8/conversion/object.rb +28 -0
  55. data/lib/v8/conversion/primitive.rb +7 -0
  56. data/lib/v8/conversion/proc.rb +5 -0
  57. data/lib/v8/conversion/reference.rb +16 -0
  58. data/lib/v8/conversion/string.rb +12 -0
  59. data/lib/v8/conversion/symbol.rb +7 -0
  60. data/lib/v8/conversion/time.rb +13 -0
  61. data/lib/v8/error.rb +18 -123
  62. data/lib/v8/error/protect.rb +20 -0
  63. data/lib/v8/error/try.rb +15 -0
  64. data/lib/v8/function.rb +18 -34
  65. data/lib/v8/object.rb +48 -52
  66. data/lib/v8/util/weakcell.rb +29 -0
  67. data/lib/v8/version.rb +2 -2
  68. data/spec/c/array_spec.rb +17 -0
  69. data/spec/c/constants_spec.rb +20 -0
  70. data/spec/c/exception_spec.rb +26 -0
  71. data/spec/c/external_spec.rb +9 -0
  72. data/spec/c/function_spec.rb +46 -0
  73. data/spec/c/handles_spec.rb +35 -0
  74. data/spec/c/locker_spec.rb +38 -0
  75. data/spec/c/object_spec.rb +46 -0
  76. data/spec/c/script_spec.rb +28 -0
  77. data/spec/c/string_spec.rb +16 -0
  78. data/spec/c/template_spec.rb +30 -0
  79. data/spec/c/trycatch_spec.rb +51 -0
  80. data/spec/mem/blunt_spec.rb +42 -0
  81. data/spec/redjs_spec.rb +10 -0
  82. data/spec/spec_helper.rb +40 -4
  83. data/spec/threading_spec.rb +52 -0
  84. data/spec/v8/context_spec.rb +19 -0
  85. data/spec/v8/conversion_spec.rb +9 -0
  86. data/spec/v8/error_spec.rb +15 -125
  87. data/spec/v8/function_spec.rb +9 -0
  88. data/therubyracer.gemspec +15 -24
  89. metadata +102 -135
  90. data/.gitmodules +0 -3
  91. data/.rspec +0 -1
  92. data/.yardopts +0 -1
  93. data/bin/therubyracer +0 -11
  94. data/ext/v8/rr.cpp +0 -189
  95. data/ext/v8/v8.cpp +0 -48
  96. data/ext/v8/v8_array.cpp +0 -48
  97. data/ext/v8/v8_array.h +0 -8
  98. data/ext/v8/v8_callbacks.cpp +0 -81
  99. data/ext/v8/v8_callbacks.h +0 -8
  100. data/ext/v8/v8_context.cpp +0 -92
  101. data/ext/v8/v8_context.h +0 -6
  102. data/ext/v8/v8_date.cpp +0 -34
  103. data/ext/v8/v8_date.h +0 -6
  104. data/ext/v8/v8_debug.cpp +0 -17
  105. data/ext/v8/v8_debug.h +0 -6
  106. data/ext/v8/v8_exception.cpp +0 -133
  107. data/ext/v8/v8_exception.h +0 -11
  108. data/ext/v8/v8_external.cpp +0 -70
  109. data/ext/v8/v8_external.h +0 -8
  110. data/ext/v8/v8_function.cpp +0 -69
  111. data/ext/v8/v8_function.h +0 -11
  112. data/ext/v8/v8_handle.cpp +0 -186
  113. data/ext/v8/v8_handle.h +0 -48
  114. data/ext/v8/v8_locker.cpp +0 -139
  115. data/ext/v8/v8_locker.h +0 -6
  116. data/ext/v8/v8_message.cpp +0 -67
  117. data/ext/v8/v8_message.h +0 -10
  118. data/ext/v8/v8_object.cpp +0 -122
  119. data/ext/v8/v8_object.h +0 -10
  120. data/ext/v8/v8_script.cpp +0 -36
  121. data/ext/v8/v8_script.h +0 -8
  122. data/ext/v8/v8_string.cpp +0 -52
  123. data/ext/v8/v8_string.h +0 -9
  124. data/ext/v8/v8_template.cpp +0 -344
  125. data/ext/v8/v8_template.h +0 -8
  126. data/ext/v8/v8_try_catch.cpp +0 -70
  127. data/ext/v8/v8_try_catch.h +0 -5
  128. data/ext/v8/v8_v8.cpp +0 -35
  129. data/ext/v8/v8_v8.h +0 -6
  130. data/ext/v8/v8_value.cpp +0 -175
  131. data/ext/v8/v8_value.h +0 -10
  132. data/ext/v8/v8_weakref.cpp +0 -61
  133. data/ext/v8/v8_weakref.h +0 -29
  134. data/lib/v8/c/locker.rb +0 -18
  135. data/lib/v8/cli.rb +0 -133
  136. data/lib/v8/portal.rb +0 -86
  137. data/lib/v8/portal/caller.rb +0 -37
  138. data/lib/v8/portal/constructor.rb +0 -98
  139. data/lib/v8/portal/function.rb +0 -63
  140. data/lib/v8/portal/interceptors.rb +0 -152
  141. data/lib/v8/portal/proxies.rb +0 -151
  142. data/lib/v8/portal/templates.rb +0 -73
  143. data/lib/v8/stack.rb +0 -66
  144. data/lib/v8/tap.rb +0 -9
  145. data/spec/ext/array_spec.rb +0 -15
  146. data/spec/ext/cxt_spec.rb +0 -57
  147. data/spec/ext/ext_spec_helper.rb +0 -27
  148. data/spec/ext/func_spec.rb +0 -64
  149. data/spec/ext/object_spec.rb +0 -10
  150. data/spec/ext/string_spec.rb +0 -11
  151. data/spec/ext/try_catch_spec.rb +0 -60
  152. data/spec/redjs_helper.rb +0 -3
  153. data/spec/v8/portal/proxies_spec.rb +0 -106
  154. data/specmem/handle_memspec.rb +0 -41
  155. data/specmem/object_memspec.rb +0 -14
  156. data/specmem/proxies_memspec.rb +0 -49
  157. data/specmem/spec_helper.rb +0 -24
  158. data/specthread/spec_helper.rb +0 -2
  159. data/specthread/threading_spec.rb +0 -13
data/ext/v8/v8_locker.h DELETED
@@ -1,6 +0,0 @@
1
- #ifndef _RUBY_V8_LOCKER
2
- #define _RUBY_V8_LOCKER
3
-
4
- void rr_init_v8_locker();
5
-
6
- #endif
@@ -1,67 +0,0 @@
1
- #include "v8_message.h"
2
- #include "v8_handle.h"
3
-
4
- using namespace v8;
5
-
6
- namespace {
7
- VALUE MessageClass;
8
-
9
- Persistent<Message>& unwrap(VALUE self) {
10
- return rr_v8_handle<Message>(self);
11
- }
12
-
13
- VALUE Get(VALUE self) {
14
- return rr_v82rb(unwrap(self)->Get());
15
- }
16
-
17
- VALUE GetSourceLine(VALUE self) {
18
- return rr_v82rb(unwrap(self)->GetSourceLine());
19
- }
20
-
21
- VALUE GetScriptResourceName(VALUE self) {
22
- return rr_v82rb(unwrap(self)->GetScriptResourceName());
23
- }
24
-
25
- VALUE GetStackTrace(VALUE self) {
26
- Handle<StackTrace> trace = unwrap(self)->GetStackTrace();
27
- return trace.IsEmpty() ? Qnil : rr_v82rb(trace);
28
- }
29
-
30
- VALUE GetLineNumber(VALUE self) {
31
- return rr_v82rb(unwrap(self)->GetLineNumber());
32
- }
33
-
34
- VALUE GetStartPosition(VALUE self) {
35
- return rr_v82rb(unwrap(self)->GetStartPosition());
36
- }
37
-
38
- VALUE GetEndPosition(VALUE self) {
39
- return rr_v82rb(unwrap(self)->GetEndPosition());
40
- }
41
-
42
- VALUE GetStartColumn(VALUE self) {
43
- return rr_v82rb(unwrap(self)->GetStartColumn());
44
- }
45
-
46
- VALUE GetEndColumn(VALUE self) {
47
- return rr_v82rb(unwrap(self)->GetEndColumn());
48
- }
49
- }
50
-
51
- void rr_init_message() {
52
- MessageClass = rr_define_class("Message", rr_v8_handle_class());
53
- rr_define_method(MessageClass, "Get", Get, 0);
54
- rr_define_method(MessageClass, "GetSourceLine", GetSourceLine, 0);
55
- rr_define_method(MessageClass, "GetScriptResourceName", GetScriptResourceName, 0);
56
- rr_define_method(MessageClass, "GetStackTrace", GetStackTrace, 0);
57
- rr_define_method(MessageClass, "GetLineNumber", GetLineNumber, 0);
58
- rr_define_method(MessageClass, "GetStartPosition", GetStartPosition, 0);
59
- rr_define_method(MessageClass, "GetEndPosition", GetEndPosition, 0);
60
- rr_define_method(MessageClass, "GetStartColumn", GetStartColumn, 0);
61
- rr_define_method(MessageClass, "GetEndColumn", GetEndColumn, 0);
62
- }
63
-
64
- VALUE rr_reflect_v8_message(Handle<Message> value) {
65
- return rr_v8_handle_new(MessageClass, value);
66
- }
67
-
data/ext/v8/v8_message.h DELETED
@@ -1,10 +0,0 @@
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
data/ext/v8/v8_object.cpp DELETED
@@ -1,122 +0,0 @@
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
-
data/ext/v8/v8_object.h DELETED
@@ -1,10 +0,0 @@
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
data/ext/v8/v8_script.cpp DELETED
@@ -1,36 +0,0 @@
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
- }
data/ext/v8/v8_script.h DELETED
@@ -1,8 +0,0 @@
1
- #ifndef _RUBY_V8_SCRIPT_
2
- #define _RUBY_V8_SCRIPT_
3
-
4
- #include "rr.h"
5
-
6
- void rr_init_script();
7
-
8
- #endif
data/ext/v8/v8_string.cpp DELETED
@@ -1,52 +0,0 @@
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
- }
data/ext/v8/v8_string.h DELETED
@@ -1,9 +0,0 @@
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
@@ -1,344 +0,0 @@
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
- }