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.
- data/.gitignore +13 -0
- data/.rspec +1 -0
- data/.travis.yml +8 -0
- data/.yardopts +1 -0
- data/Changelog.md +231 -0
- data/Gemfile +3 -0
- data/README.md +167 -0
- data/Rakefile +26 -0
- data/bin/therubyracer +11 -0
- data/ext/v8/extconf.rb +26 -0
- data/ext/v8/rr.cpp +189 -0
- data/ext/v8/rr.h +41 -0
- data/ext/v8/v8.cpp +48 -0
- data/ext/v8/v8_array.cpp +48 -0
- data/ext/v8/v8_array.h +8 -0
- data/ext/v8/v8_callbacks.cpp +81 -0
- data/ext/v8/v8_callbacks.h +8 -0
- data/ext/v8/v8_context.cpp +92 -0
- data/ext/v8/v8_context.h +6 -0
- data/ext/v8/v8_date.cpp +40 -0
- data/ext/v8/v8_date.h +6 -0
- data/ext/v8/v8_debug.cpp +17 -0
- data/ext/v8/v8_debug.h +6 -0
- data/ext/v8/v8_exception.cpp +133 -0
- data/ext/v8/v8_exception.h +11 -0
- data/ext/v8/v8_external.cpp +70 -0
- data/ext/v8/v8_external.h +8 -0
- data/ext/v8/v8_function.cpp +69 -0
- data/ext/v8/v8_function.h +11 -0
- data/ext/v8/v8_handle.cpp +186 -0
- data/ext/v8/v8_handle.h +48 -0
- data/ext/v8/v8_locker.cpp +139 -0
- data/ext/v8/v8_locker.h +6 -0
- data/ext/v8/v8_message.cpp +67 -0
- data/ext/v8/v8_message.h +10 -0
- data/ext/v8/v8_object.cpp +122 -0
- data/ext/v8/v8_object.h +10 -0
- data/ext/v8/v8_script.cpp +36 -0
- data/ext/v8/v8_script.h +8 -0
- data/ext/v8/v8_string.cpp +52 -0
- data/ext/v8/v8_string.h +9 -0
- data/ext/v8/v8_template.cpp +344 -0
- data/ext/v8/v8_template.h +8 -0
- data/ext/v8/v8_try_catch.cpp +70 -0
- data/ext/v8/v8_try_catch.h +5 -0
- data/ext/v8/v8_v8.cpp +34 -0
- data/ext/v8/v8_v8.h +6 -0
- data/ext/v8/v8_value.cpp +175 -0
- data/ext/v8/v8_value.h +10 -0
- data/ext/v8/v8_weakref.cpp +61 -0
- data/ext/v8/v8_weakref.h +29 -0
- data/lib/v8.rb +23 -0
- data/lib/v8/access.rb +92 -0
- data/lib/v8/array.rb +17 -0
- data/lib/v8/c/locker.rb +18 -0
- data/lib/v8/cli.rb +133 -0
- data/lib/v8/context.rb +111 -0
- data/lib/v8/error.rb +130 -0
- data/lib/v8/function.rb +44 -0
- data/lib/v8/object.rb +69 -0
- data/lib/v8/portal.rb +86 -0
- data/lib/v8/portal/caller.rb +37 -0
- data/lib/v8/portal/constructor.rb +98 -0
- data/lib/v8/portal/function.rb +63 -0
- data/lib/v8/portal/interceptors.rb +152 -0
- data/lib/v8/portal/proxies.rb +151 -0
- data/lib/v8/portal/templates.rb +73 -0
- data/lib/v8/stack.rb +66 -0
- data/lib/v8/tap.rb +9 -0
- data/lib/v8/version.rb +3 -0
- data/spec/ext/array_spec.rb +15 -0
- data/spec/ext/cxt_spec.rb +57 -0
- data/spec/ext/ext_spec_helper.rb +27 -0
- data/spec/ext/func_spec.rb +64 -0
- data/spec/ext/object_spec.rb +10 -0
- data/spec/ext/string_spec.rb +11 -0
- data/spec/ext/try_catch_spec.rb +60 -0
- data/spec/redjs_spec.rb +9 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/v8/error_spec.rb +131 -0
- data/spec/v8/portal/proxies_spec.rb +106 -0
- data/specmem/handle_memspec.rb +41 -0
- data/specmem/object_memspec.rb +14 -0
- data/specmem/proxies_memspec.rb +49 -0
- data/specmem/spec_helper.rb +24 -0
- data/specthread/spec_helper.rb +2 -0
- data/specthread/threading_spec.rb +13 -0
- data/thefrontside.png +0 -0
- data/therubyracer.gemspec +27 -0
- metadata +183 -0
@@ -0,0 +1,186 @@
|
|
1
|
+
|
2
|
+
#include "rr.h"
|
3
|
+
#include "v8_handle.h"
|
4
|
+
|
5
|
+
using namespace v8;
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Creates a new Persistent storage cell for `handle`
|
9
|
+
* so that we can reference it from Ruby. Ruby metadat
|
10
|
+
* is contained on the handle object, and then the actual
|
11
|
+
* v8 references are contain in an instance of `Payload`
|
12
|
+
*/
|
13
|
+
v8_handle::v8_handle(Handle<void> object) {
|
14
|
+
this->weakref_callback = Qnil;
|
15
|
+
this->weakref_callback_parameters = Qnil;
|
16
|
+
this->dead = false;
|
17
|
+
this->payload = new Payload(object);
|
18
|
+
}
|
19
|
+
|
20
|
+
v8_handle::~v8_handle() {}
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Construct a new handle payload.
|
24
|
+
*
|
25
|
+
* Each payload contains a Ruby object wrapper so that it
|
26
|
+
* can be enqueued for V8 GC (the GC queue is a ruby Array)
|
27
|
+
* the wrapper is pre-allocated at payload creation time
|
28
|
+
* so that no Ruby objects are allocated during Ruby GC.
|
29
|
+
*/
|
30
|
+
v8_handle::Payload::Payload(Handle<void> object) {
|
31
|
+
rb_gc_register_address(&wrapper);
|
32
|
+
handle = Persistent<void>::New(object);
|
33
|
+
wrapper = Data_Wrap_Struct(rb_cObject, 0, destroy, this);
|
34
|
+
}
|
35
|
+
|
36
|
+
v8_handle::Payload::~Payload() {
|
37
|
+
rb_gc_unregister_address(&wrapper);
|
38
|
+
}
|
39
|
+
|
40
|
+
void v8_handle::Payload::release() {
|
41
|
+
handle.Dispose();
|
42
|
+
handle.Clear();
|
43
|
+
}
|
44
|
+
|
45
|
+
void v8_handle::Payload::destroy(v8_handle::Payload* payload) {
|
46
|
+
delete payload;
|
47
|
+
}
|
48
|
+
|
49
|
+
namespace {
|
50
|
+
/**
|
51
|
+
* Holds dead references, that are no longer being held in Ruby, so that they can be garbage collected
|
52
|
+
* inside of V8
|
53
|
+
*/
|
54
|
+
VALUE handle_queue;
|
55
|
+
|
56
|
+
/**
|
57
|
+
* Invoked by the Ruby garbage collector whenever it determines that this handle is
|
58
|
+
* still reachable. We in turn, mark our weak callback parameters, so that it knows
|
59
|
+
* they are reachable too.
|
60
|
+
*/
|
61
|
+
void v8_handle_mark(v8_handle* handle) {
|
62
|
+
rb_gc_mark(handle->weakref_callback);
|
63
|
+
rb_gc_mark(handle->weakref_callback_parameters);
|
64
|
+
}
|
65
|
+
|
66
|
+
/**
|
67
|
+
* Whenver a V8::C::Handle becomes garbage collected, we do not free it immediately.
|
68
|
+
* instead, we put them into a "zombie" queue, where its corresponding V8 storage cell
|
69
|
+
* can be released safely while the V8 engine is running. A zombie Ruby object is
|
70
|
+
* created to wrap it so that it can be stored in the queue.
|
71
|
+
*/
|
72
|
+
void v8_handle_enqueue(v8_handle* handle) {
|
73
|
+
handle->dead = true;
|
74
|
+
rb_ary_unshift(handle_queue, handle->payload->wrapper);
|
75
|
+
}
|
76
|
+
|
77
|
+
/**
|
78
|
+
* Drains the dead handle queue, and releases them from V8
|
79
|
+
*
|
80
|
+
* This implements the V8 `GCPrologueCallback` and is registered to run before
|
81
|
+
* each invocation of the V8 garbage collector. It empties the queue of dead handles
|
82
|
+
* and disposes of them. It is important to do this operations inside V8 so that
|
83
|
+
* Ruby garbage collection is never locked, and never touches V8.
|
84
|
+
*/
|
85
|
+
void v8_handle_dequeue(GCType type, GCCallbackFlags flags) {
|
86
|
+
for (VALUE handle = rb_ary_pop(handle_queue); RTEST(handle); handle = rb_ary_pop(handle_queue)) {
|
87
|
+
v8_handle::Payload* payload = NULL;
|
88
|
+
Data_Get_Struct(handle, struct v8_handle::Payload, payload);
|
89
|
+
payload->release();
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
VALUE New(VALUE self, VALUE handle) {
|
94
|
+
if (RTEST(handle)) {
|
95
|
+
Persistent<void> that = rr_v8_handle<void>(handle);
|
96
|
+
return rr_v8_handle_new(self, that);
|
97
|
+
} else {
|
98
|
+
return rr_v8_handle_new(self, Handle<void>());
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
VALUE IsEmpty(VALUE self) {
|
103
|
+
return rr_v82rb(rr_v8_handle<void>(self).IsEmpty());
|
104
|
+
}
|
105
|
+
|
106
|
+
VALUE Clear(VALUE self) {
|
107
|
+
rr_v8_handle<void>(self).Clear();
|
108
|
+
return Qnil;
|
109
|
+
}
|
110
|
+
|
111
|
+
VALUE Dispose(VALUE self) {
|
112
|
+
rr_v8_handle<void>(self).Dispose();
|
113
|
+
return Qnil;
|
114
|
+
}
|
115
|
+
|
116
|
+
void RubyWeakReferenceCallback(Persistent<Value> value, void* parameter) {
|
117
|
+
VALUE self = (VALUE)parameter;
|
118
|
+
v8_handle* handle = rr_v8_handle_raw(self);
|
119
|
+
VALUE callback = handle->weakref_callback;
|
120
|
+
VALUE parameters = handle->weakref_callback_parameters;
|
121
|
+
if (RTEST(callback)) {
|
122
|
+
rb_funcall(callback, rb_intern("call"), 2, self, parameters);
|
123
|
+
}
|
124
|
+
value.Dispose();
|
125
|
+
handle->payload->release();
|
126
|
+
handle->dead = true;
|
127
|
+
|
128
|
+
}
|
129
|
+
|
130
|
+
VALUE MakeWeak(VALUE self, VALUE parameters, VALUE callback) {
|
131
|
+
v8_handle* handle = rr_v8_handle_raw(self);
|
132
|
+
handle->weakref_callback = callback;
|
133
|
+
handle->weakref_callback_parameters = parameters;
|
134
|
+
rr_v8_handle<void>(self).MakeWeak((void*)self, RubyWeakReferenceCallback);
|
135
|
+
return Qnil;
|
136
|
+
}
|
137
|
+
|
138
|
+
VALUE ClearWeak(VALUE self) {
|
139
|
+
rr_v8_handle<void>(self).ClearWeak();
|
140
|
+
return Qnil;
|
141
|
+
}
|
142
|
+
|
143
|
+
VALUE IsNearDeath(VALUE self) {
|
144
|
+
return rr_v82rb(rr_v8_handle<void>(self).IsNearDeath());
|
145
|
+
}
|
146
|
+
|
147
|
+
VALUE IsWeak(VALUE self) {
|
148
|
+
return rr_v82rb(rr_v8_handle<void>(self).IsWeak());
|
149
|
+
}
|
150
|
+
|
151
|
+
VALUE dead_p(VALUE self) {
|
152
|
+
return rr_v8_handle_raw(self)->dead ? Qtrue : Qfalse;
|
153
|
+
}
|
154
|
+
}
|
155
|
+
|
156
|
+
void rr_init_handle() {
|
157
|
+
VALUE HandleClass = rr_define_class("Handle");
|
158
|
+
rr_define_method(HandleClass, "dead?", dead_p, 0);
|
159
|
+
rr_define_singleton_method(HandleClass, "New", New, 1);
|
160
|
+
rr_define_method(HandleClass, "IsEmpty", IsEmpty, 0);
|
161
|
+
rr_define_method(HandleClass, "Clear", Clear, 0);
|
162
|
+
rr_define_method(HandleClass, "Dispose", Dispose, 0);
|
163
|
+
rr_define_method(HandleClass, "MakeWeak", MakeWeak, 2);
|
164
|
+
rr_define_method(HandleClass, "ClearWeak", ClearWeak, 0);
|
165
|
+
rr_define_method(HandleClass, "IsNearDeath", IsNearDeath, 0);
|
166
|
+
rr_define_method(HandleClass, "IsWeak", IsWeak, 0);
|
167
|
+
|
168
|
+
rb_gc_register_address(&handle_queue);
|
169
|
+
handle_queue = rb_ary_new();
|
170
|
+
V8::AddGCPrologueCallback(v8_handle_dequeue);
|
171
|
+
}
|
172
|
+
|
173
|
+
VALUE rr_v8_handle_new(VALUE klass, v8::Handle<void> handle) {
|
174
|
+
v8_handle* new_handle = new v8_handle(handle);
|
175
|
+
return Data_Wrap_Struct(klass, v8_handle_mark, v8_handle_enqueue, new_handle);
|
176
|
+
}
|
177
|
+
|
178
|
+
VALUE rr_v8_handle_class() {
|
179
|
+
return rr_define_class("Handle");
|
180
|
+
}
|
181
|
+
|
182
|
+
v8_handle* rr_v8_handle_raw(VALUE value) {
|
183
|
+
v8_handle* handle = 0;
|
184
|
+
Data_Get_Struct(value, struct v8_handle, handle);
|
185
|
+
return handle;
|
186
|
+
}
|
data/ext/v8/v8_handle.h
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
#ifndef _RR_V8_HANDLE_
|
2
|
+
#define _RR_V8_HANDLE_
|
3
|
+
|
4
|
+
#include <v8.h>
|
5
|
+
#include "ruby.h"
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Holds a reference to a V8 heap object. This serves as the base
|
9
|
+
* class for all of the low-level proxies that reference into V8.
|
10
|
+
*/
|
11
|
+
struct v8_handle {
|
12
|
+
|
13
|
+
/**
|
14
|
+
* Contains the *actual* V8 references. This object is kept
|
15
|
+
* separate so that it can be "detached" from the handle when
|
16
|
+
* it is garbage collected, and enqueued separately and
|
17
|
+
* collected in the context of a V8 thread.
|
18
|
+
*/
|
19
|
+
|
20
|
+
struct Payload {
|
21
|
+
Payload(v8::Handle<void> object);
|
22
|
+
virtual ~Payload();
|
23
|
+
void release();
|
24
|
+
static void destroy(v8_handle::Payload* payload);
|
25
|
+
v8::Persistent<void> handle;
|
26
|
+
VALUE wrapper;
|
27
|
+
};
|
28
|
+
|
29
|
+
v8_handle(v8::Handle<void> object);
|
30
|
+
virtual ~v8_handle();
|
31
|
+
|
32
|
+
Payload* payload;
|
33
|
+
bool dead;
|
34
|
+
VALUE weakref_callback;
|
35
|
+
VALUE weakref_callback_parameters;
|
36
|
+
};
|
37
|
+
|
38
|
+
void rr_init_handle();
|
39
|
+
|
40
|
+
v8_handle* rr_v8_handle_raw(VALUE value);
|
41
|
+
|
42
|
+
template <class T> v8::Persistent<T>& rr_v8_handle(VALUE value) {
|
43
|
+
return (v8::Persistent<T>&)(rr_v8_handle_raw(value)->payload->handle);
|
44
|
+
}
|
45
|
+
VALUE rr_v8_handle_new(VALUE rbclass, v8::Handle<void> handle);
|
46
|
+
VALUE rr_v8_handle_class();
|
47
|
+
|
48
|
+
#endif
|
@@ -0,0 +1,139 @@
|
|
1
|
+
#include "rr.h"
|
2
|
+
#include "v8_locker.h"
|
3
|
+
|
4
|
+
using namespace v8;
|
5
|
+
|
6
|
+
namespace {
|
7
|
+
namespace Lock {
|
8
|
+
|
9
|
+
/**
|
10
|
+
* Document-method: V8::C::Locker#new
|
11
|
+
*
|
12
|
+
* Allocates and returns a new `v8::Locker` object. The thread that instantiated
|
13
|
+
* this object will hold the V8 interpreter lock until it is released with a
|
14
|
+
* corresponding call to {#delete}.
|
15
|
+
*
|
16
|
+
* It critical that you call {#delete} to deallocate it, preferably within the same method.
|
17
|
+
* If you don't, two bad things will happen:
|
18
|
+
*
|
19
|
+
* 1. You'll leak the underlying C++ object
|
20
|
+
* 1. Worse, you'll leave the V8 vm locked to this thread forever
|
21
|
+
*
|
22
|
+
* It's dangerous! Be sure to `ensure`.
|
23
|
+
*
|
24
|
+
* for detailed semantics see the locking {API http://izs.me/v8-docs/classv8_1_1Unlocker.html}
|
25
|
+
*
|
26
|
+
* @return [V8::C::Locker] the new locker
|
27
|
+
*/
|
28
|
+
|
29
|
+
VALUE New(VALUE LockerClass) {
|
30
|
+
Locker* locker = new Locker();
|
31
|
+
return Data_Wrap_Struct(LockerClass, 0, 0, (void*)locker);
|
32
|
+
}
|
33
|
+
|
34
|
+
/**
|
35
|
+
* Document-method: V8::C::Locker#delete
|
36
|
+
*
|
37
|
+
* Pop this lock off the stack for this thread. For a full run down of V8 locking
|
38
|
+
* semantics see the locking {API http://izs.me/v8-docs/classv8_1_1Unlocker.html}
|
39
|
+
* @return nil
|
40
|
+
*/
|
41
|
+
VALUE Delete(VALUE self) {
|
42
|
+
Locker* locker = 0;
|
43
|
+
Data_Get_Struct(self, class Locker, locker);
|
44
|
+
delete locker;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
namespace Unlock {
|
49
|
+
/**
|
50
|
+
* Document-method: V8::C::Unlocker#new
|
51
|
+
*
|
52
|
+
* Allocates and returns a new `v8::UnLocker` object, temporarily releasing any locks that
|
53
|
+
* this thread is holding. It will reaquire all of the locksto {#delete}.
|
54
|
+
*
|
55
|
+
* This is a great thing to do when you want to call out to some code that might do some
|
56
|
+
* waiting, sleeping, and you want to politely let other threads use this VM.
|
57
|
+
*
|
58
|
+
* It critical that you call {#delete} to deallocate it, preferably within the same method.
|
59
|
+
* If you don't, two bad things will happen:
|
60
|
+
*
|
61
|
+
* 1. You'll leak the underlying C++ object
|
62
|
+
* 1. You won't restore the locks to your current thread, and will mess things up horribly
|
63
|
+
*
|
64
|
+
* It's dangerous! Be sure to `ensure`.
|
65
|
+
*
|
66
|
+
* For details on V8 locking semantics, see the locking {API http://izs.me/v8-docs/classv8_1_1Unlocker.html}
|
67
|
+
* @return [V8::C::Unocker] the new locker
|
68
|
+
*/
|
69
|
+
VALUE New(VALUE UnlockerClass) {
|
70
|
+
Unlocker* unlocker = new Unlocker();
|
71
|
+
return Data_Wrap_Struct(UnlockerClass, 0, 0, (void*)unlocker);
|
72
|
+
}
|
73
|
+
|
74
|
+
/**
|
75
|
+
* Document-method: V8::C::Unlocker#delete
|
76
|
+
*
|
77
|
+
* Restore any locks to the stack that were temporarily removed by this `Unlocker`.
|
78
|
+
* For a full run down, see semantics see the locking {API http://izs.me/v8-docs/classv8_1_1Unlocker.html}
|
79
|
+
* @return nil
|
80
|
+
*/
|
81
|
+
VALUE Delete(VALUE self) {
|
82
|
+
Unlocker* unlocker;
|
83
|
+
Data_Get_Struct(self, class Unlocker, unlocker);
|
84
|
+
delete unlocker;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
/**
|
89
|
+
* Document-method: V8::C::Locker#StartPreemption
|
90
|
+
* Start preemption.
|
91
|
+
* When preemption is started, a timer is fired every n milli seconds that will switch between
|
92
|
+
* multiple threads that are in contention for the V8 lock.
|
93
|
+
*
|
94
|
+
* @param [Integer] every_n_ms
|
95
|
+
* @return nil
|
96
|
+
*/
|
97
|
+
VALUE StartPreemption(VALUE self, VALUE every_n_ms) {
|
98
|
+
Locker::StartPreemption(NUM2INT(rb_to_int(every_n_ms)));
|
99
|
+
return Qnil;
|
100
|
+
}
|
101
|
+
|
102
|
+
/**
|
103
|
+
* Document-method: V8::C::Locker#StartPreemption
|
104
|
+
* Stop preemption
|
105
|
+
*/
|
106
|
+
VALUE StopPreemption(VALUE self) {
|
107
|
+
Locker::StopPreemption();
|
108
|
+
return Qnil;
|
109
|
+
}
|
110
|
+
|
111
|
+
/**
|
112
|
+
* Document-method: V8::C::Locker#IsLocked
|
113
|
+
* Returns whether or not the locker is locked by the current thread.
|
114
|
+
*/
|
115
|
+
VALUE IsLocked(VALUE self) {
|
116
|
+
return rr_v82rb(Locker::IsLocked());
|
117
|
+
}
|
118
|
+
|
119
|
+
/**
|
120
|
+
* Document-method: V8::C::Locker#IsActive
|
121
|
+
* Returns whether v8::Locker is being used by this V8 instance.
|
122
|
+
*/
|
123
|
+
VALUE IsActive(VALUE self) {
|
124
|
+
return rr_v82rb(Locker::IsActive());
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
void rr_init_v8_locker() {
|
129
|
+
VALUE LockerClass = rr_define_class("Locker");
|
130
|
+
VALUE UnlockerClass = rr_define_class("Unlocker");
|
131
|
+
rr_define_singleton_method(LockerClass, "new", Lock::New, 0);
|
132
|
+
rr_define_method(LockerClass, "delete", Lock::Delete, 0);
|
133
|
+
rr_define_singleton_method(UnlockerClass, "new", Unlock::New, 0);
|
134
|
+
rr_define_method(UnlockerClass, "delete", Unlock::Delete, 0);
|
135
|
+
rr_define_singleton_method(LockerClass, "StartPreemption", StartPreemption, 1);
|
136
|
+
rr_define_singleton_method(LockerClass, "StopPreemption", StopPreemption, 0);
|
137
|
+
rr_define_singleton_method(LockerClass, "IsLocked", IsLocked, 0);
|
138
|
+
rr_define_singleton_method(LockerClass, "IsActive", IsActive, 0);
|
139
|
+
}
|
data/ext/v8/v8_locker.h
ADDED
@@ -0,0 +1,67 @@
|
|
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
|
+
|