therubyracer 0.11.0beta8-x86-freebsd-9
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.
- data/.gitignore +23 -0
- data/.travis.yml +10 -0
- data/Changelog.md +242 -0
- data/Gemfile +16 -0
- data/README.md +185 -0
- data/Rakefile +42 -0
- data/benchmarks.rb +218 -0
- data/ext/v8/accessor.cc +181 -0
- data/ext/v8/array.cc +26 -0
- data/ext/v8/backref.cc +45 -0
- data/ext/v8/build.rb +52 -0
- data/ext/v8/constants.cc +34 -0
- data/ext/v8/constraints.cc +52 -0
- data/ext/v8/context.cc +130 -0
- data/ext/v8/date.cc +18 -0
- data/ext/v8/exception.cc +38 -0
- data/ext/v8/extconf.rb +25 -0
- data/ext/v8/external.cc +43 -0
- data/ext/v8/function.cc +58 -0
- data/ext/v8/gc.cc +43 -0
- data/ext/v8/handles.cc +34 -0
- data/ext/v8/heap.cc +31 -0
- data/ext/v8/init.cc +39 -0
- data/ext/v8/init.so +0 -0
- data/ext/v8/invocation.cc +86 -0
- data/ext/v8/locker.cc +77 -0
- data/ext/v8/message.cc +51 -0
- data/ext/v8/object.cc +334 -0
- data/ext/v8/primitive.cc +8 -0
- data/ext/v8/rr.cc +83 -0
- data/ext/v8/rr.h +932 -0
- data/ext/v8/script.cc +80 -0
- data/ext/v8/signature.cc +18 -0
- data/ext/v8/stack.cc +76 -0
- data/ext/v8/string.cc +47 -0
- data/ext/v8/template.cc +175 -0
- data/ext/v8/trycatch.cc +87 -0
- data/ext/v8/v8.cc +87 -0
- data/ext/v8/value.cc +239 -0
- data/lib/v8.rb +30 -0
- data/lib/v8/access.rb +5 -0
- data/lib/v8/access/indices.rb +40 -0
- data/lib/v8/access/invocation.rb +47 -0
- data/lib/v8/access/names.rb +65 -0
- data/lib/v8/array.rb +26 -0
- data/lib/v8/context.rb +245 -0
- data/lib/v8/conversion.rb +36 -0
- data/lib/v8/conversion/array.rb +11 -0
- data/lib/v8/conversion/class.rb +119 -0
- data/lib/v8/conversion/code.rb +38 -0
- data/lib/v8/conversion/fixnum.rb +11 -0
- data/lib/v8/conversion/fundamental.rb +11 -0
- data/lib/v8/conversion/hash.rb +11 -0
- data/lib/v8/conversion/indentity.rb +31 -0
- data/lib/v8/conversion/method.rb +26 -0
- data/lib/v8/conversion/object.rb +28 -0
- data/lib/v8/conversion/primitive.rb +7 -0
- data/lib/v8/conversion/proc.rb +5 -0
- data/lib/v8/conversion/reference.rb +16 -0
- data/lib/v8/conversion/string.rb +12 -0
- data/lib/v8/conversion/symbol.rb +7 -0
- data/lib/v8/conversion/time.rb +13 -0
- data/lib/v8/error.rb +166 -0
- data/lib/v8/function.rb +28 -0
- data/lib/v8/object.rb +79 -0
- data/lib/v8/stack.rb +85 -0
- data/lib/v8/version.rb +3 -0
- data/lib/v8/weak.rb +70 -0
- data/spec/c/array_spec.rb +17 -0
- data/spec/c/constants_spec.rb +20 -0
- data/spec/c/exception_spec.rb +26 -0
- data/spec/c/external_spec.rb +9 -0
- data/spec/c/function_spec.rb +46 -0
- data/spec/c/handles_spec.rb +35 -0
- data/spec/c/locker_spec.rb +38 -0
- data/spec/c/object_spec.rb +46 -0
- data/spec/c/script_spec.rb +28 -0
- data/spec/c/string_spec.rb +16 -0
- data/spec/c/template_spec.rb +30 -0
- data/spec/c/trycatch_spec.rb +51 -0
- data/spec/mem/blunt_spec.rb +42 -0
- data/spec/redjs_spec.rb +10 -0
- data/spec/spec_helper.rb +45 -0
- data/spec/threading_spec.rb +52 -0
- data/spec/v8/context_spec.rb +19 -0
- data/spec/v8/conversion_spec.rb +52 -0
- data/spec/v8/error_spec.rb +165 -0
- data/spec/v8/function_spec.rb +9 -0
- data/spec/v8/object_spec.rb +15 -0
- data/thefrontside.png +0 -0
- data/therubyracer.gemspec +20 -0
- metadata +164 -0
data/ext/v8/v8.cc
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
#include "rr.h"
|
2
|
+
|
3
|
+
namespace rr {
|
4
|
+
|
5
|
+
void V8::Init() {
|
6
|
+
ClassBuilder("V8").
|
7
|
+
defineSingletonMethod("IdleNotification", &IdleNotification).
|
8
|
+
defineSingletonMethod("SetFlagsFromString", &SetFlagsFromString).
|
9
|
+
defineSingletonMethod("SetFlagsFromCommandLine", &SetFlagsFromCommandLine).
|
10
|
+
defineSingletonMethod("PauseProfiler", &PauseProfiler).
|
11
|
+
defineSingletonMethod("ResumeProfiler", &ResumeProfiler).
|
12
|
+
defineSingletonMethod("IsProfilerPaused", &IsProfilerPaused).
|
13
|
+
defineSingletonMethod("GetCurrentThreadId", &GetCurrentThreadId).
|
14
|
+
defineSingletonMethod("TerminateExecution", &TerminateExecution).
|
15
|
+
defineSingletonMethod("IsExecutionTerminating", &IsExecutionTerminating).
|
16
|
+
defineSingletonMethod("Dispose", &Dispose).
|
17
|
+
defineSingletonMethod("LowMemoryNotification", &LowMemoryNotification).
|
18
|
+
defineSingletonMethod("AdjustAmountOfExternalAllocatedMemory", &AdjustAmountOfExternalAllocatedMemory).
|
19
|
+
defineSingletonMethod("ContextDisposedNotification", &ContextDisposedNotification).
|
20
|
+
defineSingletonMethod("SetCaptureStackTraceForUncaughtExceptions", &SetCaptureStackTraceForUncaughtExceptions).
|
21
|
+
defineSingletonMethod("GetHeapStatistics", &GetHeapStatistics).
|
22
|
+
defineSingletonMethod("GetVersion", &GetVersion);
|
23
|
+
}
|
24
|
+
|
25
|
+
VALUE V8::IdleNotification(int argc, VALUE argv[], VALUE self) {
|
26
|
+
VALUE hint;
|
27
|
+
rb_scan_args(argc, argv, "01", &hint);
|
28
|
+
if (RTEST(hint)) {
|
29
|
+
return Bool(v8::V8::IdleNotification(NUM2INT(hint)));
|
30
|
+
} else {
|
31
|
+
return Bool(v8::V8::IdleNotification());
|
32
|
+
}
|
33
|
+
}
|
34
|
+
VALUE V8::SetFlagsFromString(VALUE self, VALUE string) {
|
35
|
+
Void(v8::V8::SetFlagsFromString(RSTRING_PTR(string), (int)RSTRING_LEN(string)));
|
36
|
+
}
|
37
|
+
VALUE V8::SetFlagsFromCommandLine(VALUE self, VALUE args, VALUE remove_flags) {
|
38
|
+
int argc = RARRAY_LENINT(args);
|
39
|
+
char* argv[argc];
|
40
|
+
for(int i = 0; i < argc; i++) {
|
41
|
+
argv[i] = RSTRING_PTR(rb_ary_entry(args, i));
|
42
|
+
}
|
43
|
+
Void(v8::V8::SetFlagsFromCommandLine(&argc, argv, Bool(remove_flags)));
|
44
|
+
}
|
45
|
+
VALUE V8::AdjustAmountOfExternalAllocatedMemory(VALUE self, VALUE change_in_bytes) {
|
46
|
+
return SIZET2NUM(v8::V8::AdjustAmountOfExternalAllocatedMemory(NUM2SIZET(change_in_bytes)));
|
47
|
+
}
|
48
|
+
VALUE V8::PauseProfiler(VALUE self) {
|
49
|
+
Void(v8::V8::PauseProfiler());
|
50
|
+
}
|
51
|
+
VALUE V8::ResumeProfiler(VALUE self) {
|
52
|
+
Void(v8::V8::ResumeProfiler());
|
53
|
+
}
|
54
|
+
VALUE V8::IsProfilerPaused(VALUE self) {
|
55
|
+
return Bool(v8::V8::IsProfilerPaused());
|
56
|
+
}
|
57
|
+
VALUE V8::GetCurrentThreadId(VALUE self) {
|
58
|
+
return INT2FIX(v8::V8::GetCurrentThreadId());
|
59
|
+
}
|
60
|
+
VALUE V8::TerminateExecution(VALUE self, VALUE thread_id) {
|
61
|
+
Void(v8::V8::TerminateExecution(NUM2INT(thread_id)));
|
62
|
+
}
|
63
|
+
VALUE V8::IsExecutionTerminating(VALUE self) {
|
64
|
+
return Bool(v8::V8::IsExecutionTerminating());
|
65
|
+
}
|
66
|
+
VALUE V8::Dispose(VALUE self) {
|
67
|
+
Void(v8::V8::Dispose());
|
68
|
+
}
|
69
|
+
VALUE V8::LowMemoryNotification(VALUE self) {
|
70
|
+
Void(v8::V8::LowMemoryNotification());
|
71
|
+
}
|
72
|
+
VALUE V8::ContextDisposedNotification(VALUE self) {
|
73
|
+
return INT2FIX(v8::V8::ContextDisposedNotification());
|
74
|
+
}
|
75
|
+
VALUE V8::SetCaptureStackTraceForUncaughtExceptions(int argc, VALUE argv[], VALUE self) {
|
76
|
+
VALUE should_capture; VALUE frame_limit; VALUE options;
|
77
|
+
rb_scan_args(argc, argv, "12", &should_capture, &frame_limit, &options);
|
78
|
+
int limit = RTEST(frame_limit) ? NUM2INT(frame_limit) : 10;
|
79
|
+
Void(v8::V8::SetCaptureStackTraceForUncaughtExceptions(Bool(should_capture), limit, Stack::Trace::StackTraceOptions(options)));
|
80
|
+
}
|
81
|
+
VALUE V8::GetHeapStatistics(VALUE self, VALUE statistics_ptr) {
|
82
|
+
Void(v8::V8::GetHeapStatistics(HeapStatistics(statistics_ptr)));
|
83
|
+
}
|
84
|
+
VALUE V8::GetVersion(VALUE self) {
|
85
|
+
return rb_str_new2(v8::V8::GetVersion());
|
86
|
+
}
|
87
|
+
}
|
data/ext/v8/value.cc
ADDED
@@ -0,0 +1,239 @@
|
|
1
|
+
#include "rr.h"
|
2
|
+
|
3
|
+
namespace rr {
|
4
|
+
|
5
|
+
VALUE Value::Empty;
|
6
|
+
|
7
|
+
void Value::Init() {
|
8
|
+
Empty = rb_eval_string("Object.new");
|
9
|
+
ClassBuilder("Value").
|
10
|
+
defineConst("Empty", Empty).
|
11
|
+
defineMethod("IsUndefined", &IsUndefined).
|
12
|
+
defineMethod("IsNull", &IsNull).
|
13
|
+
defineMethod("IsTrue", &IsTrue).
|
14
|
+
defineMethod("IsFalse", &IsFalse).
|
15
|
+
defineMethod("IsString", &IsString).
|
16
|
+
defineMethod("IsFunction", &IsFunction).
|
17
|
+
defineMethod("IsArray", &IsArray).
|
18
|
+
defineMethod("IsObject", &IsObject).
|
19
|
+
defineMethod("IsBoolean", &IsBoolean).
|
20
|
+
defineMethod("IsNumber", &IsNumber).
|
21
|
+
defineMethod("IsExternal", &IsExternal).
|
22
|
+
defineMethod("IsInt32", &IsInt32).
|
23
|
+
defineMethod("IsUint32", &IsUint32).
|
24
|
+
defineMethod("IsDate", &IsDate).
|
25
|
+
defineMethod("IsBooleanObject", &IsBooleanObject).
|
26
|
+
defineMethod("IsNumberObject", &IsNumberObject).
|
27
|
+
defineMethod("IsStringObject", &IsStringObject).
|
28
|
+
defineMethod("IsNativeError", &IsNativeError).
|
29
|
+
defineMethod("IsRegExp", &IsRegExp).
|
30
|
+
defineMethod("ToString", &ToString).
|
31
|
+
defineMethod("ToDetailString", &ToDetailString).
|
32
|
+
defineMethod("ToObject", &ToObject).
|
33
|
+
defineMethod("BooleanValue", &BooleanValue).
|
34
|
+
defineMethod("NumberValue", &NumberValue).
|
35
|
+
defineMethod("IntegerValue", &IntegerValue).
|
36
|
+
defineMethod("Uint32Value", &Uint32Value).
|
37
|
+
defineMethod("IntegerValue", &IntegerValue).
|
38
|
+
defineMethod("Equals", &Equals).
|
39
|
+
defineMethod("StrictEquals", &StrictEquals)
|
40
|
+
.store(&Class);
|
41
|
+
rb_gc_register_address(&Empty);
|
42
|
+
}
|
43
|
+
|
44
|
+
VALUE Value::IsUndefined(VALUE self) {
|
45
|
+
return Bool(Value(self)->IsUndefined());
|
46
|
+
}
|
47
|
+
VALUE Value::IsNull(VALUE self) {
|
48
|
+
return Bool(Value(self)->IsNull());
|
49
|
+
}
|
50
|
+
VALUE Value::IsTrue(VALUE self) {
|
51
|
+
return Bool(Value(self)->IsTrue());
|
52
|
+
}
|
53
|
+
VALUE Value::IsFalse(VALUE self) {
|
54
|
+
return Bool(Value(self)->IsFalse());
|
55
|
+
}
|
56
|
+
VALUE Value::IsString(VALUE self) {
|
57
|
+
return Bool(Value(self)->IsString());
|
58
|
+
}
|
59
|
+
VALUE Value::IsFunction(VALUE self) {
|
60
|
+
return Bool(Value(self)->IsFunction());
|
61
|
+
}
|
62
|
+
VALUE Value::IsArray(VALUE self) {
|
63
|
+
return Bool(Value(self)->IsArray());
|
64
|
+
}
|
65
|
+
VALUE Value::IsObject(VALUE self) {
|
66
|
+
return Bool(Value(self)->IsObject());
|
67
|
+
}
|
68
|
+
VALUE Value::IsBoolean(VALUE self) {
|
69
|
+
return Bool(Value(self)->IsBoolean());
|
70
|
+
}
|
71
|
+
VALUE Value::IsNumber(VALUE self) {
|
72
|
+
return Bool(Value(self)->IsNumber());
|
73
|
+
}
|
74
|
+
VALUE Value::IsExternal(VALUE self) {
|
75
|
+
return Bool(Value(self)->IsExternal());
|
76
|
+
}
|
77
|
+
VALUE Value::IsInt32(VALUE self) {
|
78
|
+
return Bool(Value(self)->IsInt32());
|
79
|
+
}
|
80
|
+
VALUE Value::IsUint32(VALUE self) {
|
81
|
+
return Bool(Value(self)->IsUint32());
|
82
|
+
}
|
83
|
+
VALUE Value::IsDate(VALUE self) {
|
84
|
+
return Bool(Value(self)->IsDate());
|
85
|
+
}
|
86
|
+
VALUE Value::IsBooleanObject(VALUE self) {
|
87
|
+
return Bool(Value(self)->IsBooleanObject());
|
88
|
+
}
|
89
|
+
VALUE Value::IsNumberObject(VALUE self) {
|
90
|
+
return Bool(Value(self)->IsNumberObject());
|
91
|
+
}
|
92
|
+
VALUE Value::IsStringObject(VALUE self) {
|
93
|
+
return Bool(Value(self)->IsStringObject());
|
94
|
+
}
|
95
|
+
VALUE Value::IsNativeError(VALUE self) {
|
96
|
+
return Bool(Value(self)->IsNativeError());
|
97
|
+
}
|
98
|
+
VALUE Value::IsRegExp(VALUE self) {
|
99
|
+
return Bool(Value(self)->IsRegExp());
|
100
|
+
}
|
101
|
+
|
102
|
+
// VALUE Value::ToBoolean(VALUE self) {
|
103
|
+
// return Boolean(Value(self)->ToBoolean());
|
104
|
+
// }
|
105
|
+
|
106
|
+
// VALUE Value::ToNumber(VALUE self) {
|
107
|
+
// return Number(Value(self)->ToNumber());
|
108
|
+
// }
|
109
|
+
VALUE Value::ToString(VALUE self) {
|
110
|
+
return String(Value(self)->ToString());
|
111
|
+
}
|
112
|
+
|
113
|
+
VALUE Value::ToDetailString(VALUE self) {
|
114
|
+
return String(Value(self)->ToDetailString());
|
115
|
+
}
|
116
|
+
|
117
|
+
VALUE Value::ToObject(VALUE self) {
|
118
|
+
return Object(Value(self)->ToObject());
|
119
|
+
}
|
120
|
+
|
121
|
+
// VALUE Value::ToInteger(VALUE self) {
|
122
|
+
// return Integer(Value(self)->ToInteger());
|
123
|
+
// }
|
124
|
+
|
125
|
+
// VALUE Value::ToUint32(VALUE self) {
|
126
|
+
// return Uint32(Value(self)->ToUint32());
|
127
|
+
// }
|
128
|
+
|
129
|
+
// VALUE Value::ToInt32(VALUE self) {
|
130
|
+
// return Int32(Value(self)->ToInt32());
|
131
|
+
// }
|
132
|
+
|
133
|
+
|
134
|
+
// VALUE Value::ToArrayIndex(VALUE self) {
|
135
|
+
// return Uint32(Value(self)->ToArrayIndex());
|
136
|
+
// }
|
137
|
+
|
138
|
+
VALUE Value::BooleanValue(VALUE self) {
|
139
|
+
return Bool(Value(self)->BooleanValue());
|
140
|
+
}
|
141
|
+
VALUE Value::NumberValue(VALUE self) {
|
142
|
+
return rb_float_new(Value(self)->NumberValue());
|
143
|
+
}
|
144
|
+
VALUE Value::IntegerValue(VALUE self) {
|
145
|
+
return INT2NUM(Value(self)->IntegerValue());
|
146
|
+
}
|
147
|
+
VALUE Value::Uint32Value(VALUE self) {
|
148
|
+
return UINT2NUM(Value(self)->Uint32Value());
|
149
|
+
}
|
150
|
+
VALUE Value::Int32Value(VALUE self) {
|
151
|
+
return INT2FIX(Value(self)->Int32Value());
|
152
|
+
}
|
153
|
+
|
154
|
+
VALUE Value::Equals(VALUE self, VALUE other) {
|
155
|
+
return Bool(Value(self)->Equals(Value(other)));
|
156
|
+
}
|
157
|
+
|
158
|
+
VALUE Value::StrictEquals(VALUE self, VALUE other) {
|
159
|
+
return Bool(Value(self)->StrictEquals(Value(other)));
|
160
|
+
}
|
161
|
+
|
162
|
+
Value::operator VALUE() {
|
163
|
+
if (handle.IsEmpty() || handle->IsUndefined() || handle->IsNull()) {
|
164
|
+
return Qnil;
|
165
|
+
}
|
166
|
+
if (handle->IsTrue()) {
|
167
|
+
return Qtrue;
|
168
|
+
}
|
169
|
+
if (handle->IsFalse()) {
|
170
|
+
return Qfalse;
|
171
|
+
}
|
172
|
+
if (handle->IsExternal()) {
|
173
|
+
return External((v8::Handle<v8::External>)v8::External::Cast(*handle));
|
174
|
+
}
|
175
|
+
if (handle->IsUint32()) {
|
176
|
+
return UInt32(handle->Uint32Value());
|
177
|
+
}
|
178
|
+
if (handle->IsInt32()) {
|
179
|
+
return INT2FIX(handle->Int32Value());
|
180
|
+
}
|
181
|
+
if (handle->IsBoolean()) {
|
182
|
+
return handle->BooleanValue() ? Qtrue : Qfalse;
|
183
|
+
}
|
184
|
+
if (handle->IsNumber()) {
|
185
|
+
return rb_float_new(handle->NumberValue());
|
186
|
+
}
|
187
|
+
if (handle->IsString()) {
|
188
|
+
return String(handle->ToString());
|
189
|
+
}
|
190
|
+
if (handle->IsDate()) {
|
191
|
+
return Date((v8::Handle<v8::Date>)v8::Date::Cast(*handle));
|
192
|
+
}
|
193
|
+
if (handle->IsObject()) {
|
194
|
+
return Object(handle->ToObject());
|
195
|
+
}
|
196
|
+
return Ref<v8::Value>::operator VALUE();
|
197
|
+
}
|
198
|
+
|
199
|
+
Value::operator v8::Handle<v8::Value>() const {
|
200
|
+
if (rb_equal(value,Empty)) {
|
201
|
+
return v8::Handle<v8::Value>();
|
202
|
+
}
|
203
|
+
switch (TYPE(value)) {
|
204
|
+
case T_FIXNUM:
|
205
|
+
return v8::Integer::New(NUM2INT(value));
|
206
|
+
case T_FLOAT:
|
207
|
+
return v8::Number::New(NUM2DBL(value));
|
208
|
+
case T_STRING:
|
209
|
+
return v8::String::New(RSTRING_PTR(value), (int)RSTRING_LEN(value));
|
210
|
+
case T_NIL:
|
211
|
+
return v8::Null();
|
212
|
+
case T_TRUE:
|
213
|
+
return v8::True();
|
214
|
+
case T_FALSE:
|
215
|
+
return v8::False();
|
216
|
+
case T_DATA:
|
217
|
+
return Ref<v8::Value>::operator v8::Handle<v8::Value>();
|
218
|
+
case T_OBJECT:
|
219
|
+
case T_CLASS:
|
220
|
+
case T_ICLASS:
|
221
|
+
case T_MODULE:
|
222
|
+
case T_REGEXP:
|
223
|
+
case T_MATCH:
|
224
|
+
case T_ARRAY:
|
225
|
+
case T_HASH:
|
226
|
+
case T_STRUCT:
|
227
|
+
case T_BIGNUM:
|
228
|
+
case T_FILE:
|
229
|
+
case T_SYMBOL:
|
230
|
+
case T_UNDEF:
|
231
|
+
case T_NODE:
|
232
|
+
default:
|
233
|
+
rb_warn("unknown conversion to V8 for: %s", RSTRING_PTR(rb_inspect(value)));
|
234
|
+
return v8::String::New("Undefined Conversion");
|
235
|
+
}
|
236
|
+
|
237
|
+
return v8::Undefined();
|
238
|
+
}
|
239
|
+
}
|
data/lib/v8.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "v8/version"
|
2
|
+
|
3
|
+
require 'v8/weak'
|
4
|
+
require 'v8/init'
|
5
|
+
require 'v8/error'
|
6
|
+
require 'v8/stack'
|
7
|
+
require 'v8/conversion/fundamental'
|
8
|
+
require 'v8/conversion/indentity'
|
9
|
+
require 'v8/conversion/reference'
|
10
|
+
require 'v8/conversion/primitive'
|
11
|
+
require 'v8/conversion/code'
|
12
|
+
require 'v8/conversion/class'
|
13
|
+
require 'v8/conversion/object'
|
14
|
+
require 'v8/conversion/time'
|
15
|
+
require 'v8/conversion/hash'
|
16
|
+
require 'v8/conversion/array'
|
17
|
+
require 'v8/conversion/proc'
|
18
|
+
require 'v8/conversion/method'
|
19
|
+
require 'v8/conversion/symbol'
|
20
|
+
require 'v8/conversion/string'
|
21
|
+
require 'v8/conversion/fixnum'
|
22
|
+
require 'v8/conversion'
|
23
|
+
require 'v8/access/names'
|
24
|
+
require 'v8/access/indices'
|
25
|
+
require 'v8/access/invocation'
|
26
|
+
require 'v8/access'
|
27
|
+
require 'v8/context'
|
28
|
+
require 'v8/object'
|
29
|
+
require 'v8/array'
|
30
|
+
require 'v8/function'
|
data/lib/v8/access.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
class V8::Access
|
2
|
+
module Indices
|
3
|
+
|
4
|
+
def indices(obj)
|
5
|
+
obj.respond_to?(:length) ? (0..obj.length).to_a : []
|
6
|
+
end
|
7
|
+
|
8
|
+
def iget(obj, index, &dontintercept)
|
9
|
+
if obj.respond_to?(:[])
|
10
|
+
obj.send(:[], index, &dontintercept)
|
11
|
+
else
|
12
|
+
yield
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def iset(obj, index, value, &dontintercept)
|
17
|
+
if obj.respond_to?(:[]=)
|
18
|
+
obj.send(:[]=, index, value, &dontintercept)
|
19
|
+
else
|
20
|
+
yield
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def iquery(obj, index, attributes, &dontintercept)
|
25
|
+
if obj.respond_to?(:[])
|
26
|
+
attributes.dont_delete
|
27
|
+
unless obj.respond_to?(:[]=)
|
28
|
+
attributes.read_only
|
29
|
+
end
|
30
|
+
else
|
31
|
+
yield
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def idelete(obj, index, &dontintercept)
|
36
|
+
yield
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class V8::Access
|
2
|
+
module Invocation
|
3
|
+
def methodcall(code, this, args)
|
4
|
+
code.methodcall this, args
|
5
|
+
end
|
6
|
+
|
7
|
+
module Aritize
|
8
|
+
def aritize(args)
|
9
|
+
arity < 0 ? args : Array.new(arity).to_enum(:each_with_index).map {|item, i| args[i]}
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module Proc
|
14
|
+
include Aritize
|
15
|
+
def methodcall(this, args)
|
16
|
+
call *aritize([this].concat(args))
|
17
|
+
end
|
18
|
+
::Proc.send :include, self
|
19
|
+
end
|
20
|
+
|
21
|
+
module Method
|
22
|
+
include Aritize
|
23
|
+
def methodcall(this, args)
|
24
|
+
context = V8::Context.current
|
25
|
+
access = context.access
|
26
|
+
if this.equal? self.receiver
|
27
|
+
call *aritize(args)
|
28
|
+
elsif this.class <= self.receiver.class
|
29
|
+
access.methodcall(unbind, this, args)
|
30
|
+
elsif this.equal? context.scope
|
31
|
+
call *aritize(args)
|
32
|
+
else
|
33
|
+
fail TypeError, "cannot invoke #{self} on #{this}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
::Method.send :include, self
|
37
|
+
end
|
38
|
+
|
39
|
+
module UnboundMethod
|
40
|
+
def methodcall(this, args)
|
41
|
+
access = V8::Context.current.access
|
42
|
+
access.methodcall bind(this), this, args
|
43
|
+
end
|
44
|
+
::UnboundMethod.send :include, self
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|