therubyracer 0.9.0beta7 → 0.9.0
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/Changelog.md +3 -1
- data/ext/v8/v8_string.cpp +4 -2
- data/lib/v8/portal/caller.rb +2 -0
- data/lib/v8/portal/proxies.rb +42 -4
- data/lib/v8/version.rb +1 -1
- data/spec/ext/string_spec.rb +11 -0
- data/specmem/proxies_memspec.rb +5 -4
- metadata +10 -6
data/Changelog.md
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
##
|
3
|
+
## 0.9.0 - 2011/06/10
|
4
4
|
|
5
|
+
* extract libv8 into installable binary for most platforms
|
6
|
+
* fix numerous memory leaks
|
5
7
|
* expose the V8 debugger via V8::C::Debug::EnableAgent()
|
6
8
|
* force UTf-8 encoding on strings returned from javascript in ruby 1.9
|
7
9
|
* remove deprecated evaluate() methods
|
data/ext/v8/v8_string.cpp
CHANGED
@@ -24,7 +24,8 @@ namespace {
|
|
24
24
|
}
|
25
25
|
VALUE Utf8Value(VALUE self) {
|
26
26
|
HandleScope handles;
|
27
|
-
|
27
|
+
Handle<String> str = unwrap(self);
|
28
|
+
return rb_str_new(*String::Utf8Value(str), str->Utf8Length());
|
28
29
|
}
|
29
30
|
VALUE Utf16Value(VALUE self) {
|
30
31
|
//How are UTF16 strings represented in ruby 1.8, 1.9
|
@@ -32,7 +33,8 @@ namespace {
|
|
32
33
|
}
|
33
34
|
VALUE AsciiValue(VALUE self) {
|
34
35
|
HandleScope handles;
|
35
|
-
|
36
|
+
Handle<String> str = unwrap(self);
|
37
|
+
return rb_str_new(*String::AsciiValue(str), str->Length());
|
36
38
|
}
|
37
39
|
}
|
38
40
|
|
data/lib/v8/portal/caller.rb
CHANGED
@@ -16,6 +16,8 @@ module V8
|
|
16
16
|
raise e
|
17
17
|
else
|
18
18
|
error = V8::C::Exception::Error(V8::C::String::New(e.message))
|
19
|
+
#TODO: This is almost certainly a crash here.
|
20
|
+
#we need to hold onto `error` while it bubbles up the javascript stack.
|
19
21
|
error.SetHiddenValue("TheRubyRacer::Cause", C::External::New(e))
|
20
22
|
V8::C::ThrowException(error)
|
21
23
|
end
|
data/lib/v8/portal/proxies.rb
CHANGED
@@ -46,10 +46,16 @@ module V8
|
|
46
46
|
V8::C::V8::AdjustAmountOfExternalAllocatedMemory(16 * 1024)
|
47
47
|
end
|
48
48
|
|
49
|
+
# Lookup the JavaScript proxy for a natively Ruby object
|
50
|
+
# @param [Object] object the Ruby object
|
51
|
+
# @return [V8::C::Handle] the JavaScript proxy representing `object`
|
49
52
|
def rb_object_2_js_proxy(object)
|
50
53
|
@js_proxies_rb2js[object]
|
51
54
|
end
|
52
55
|
|
56
|
+
# Look up a natively Ruby object given its JavaScript proxy
|
57
|
+
# @param [V8::C::Handle] proxy the JavaScript proxy
|
58
|
+
# @return [Object] the Ruby object represented by `proxy`
|
53
59
|
def js_proxy_2_rb_object(proxy)
|
54
60
|
@js_proxies_js2rb[proxy]
|
55
61
|
end
|
@@ -63,12 +69,25 @@ module V8
|
|
63
69
|
V8::C::V8::AdjustAmountOfExternalAllocatedMemory(8 * 1024)
|
64
70
|
end
|
65
71
|
|
72
|
+
# Looks up the Ruby proxy for an object that is natively JavaScript
|
73
|
+
# @param [V8::C::Handle] object the JavaScript whose proxy we want
|
74
|
+
# @return [Object] the Ruby proxy for `object`
|
66
75
|
def js_object_2_rb_proxy(object)
|
67
76
|
if id = @rb_proxies_js2rb[object]
|
68
77
|
ObjectSpace._id2ref id
|
69
78
|
end
|
79
|
+
rescue RangeError => e
|
80
|
+
# sometimes, the Ruby proxy has been garbage collected, but
|
81
|
+
# the finalizer which runs has not been called. That's OK
|
82
|
+
# we just clear out the entry, and return nil so that a new
|
83
|
+
# proxy can be created.
|
84
|
+
@clear_rb_proxy.call(id)
|
85
|
+
return nil
|
70
86
|
end
|
71
87
|
|
88
|
+
# Looks up a native JavaScript object by its Ruby proxy
|
89
|
+
# @param [Object] proxy the Ruby proxy
|
90
|
+
# @return [V8::C::Handle] the native JavaScript object
|
72
91
|
def rb_proxy_2_js_object(proxy)
|
73
92
|
@rb_proxies_rb2js[proxy.object_id]
|
74
93
|
end
|
@@ -100,16 +119,35 @@ module V8
|
|
100
119
|
end
|
101
120
|
end
|
102
121
|
|
122
|
+
# @Private
|
123
|
+
# Remove the linkage between a Ruby proxy and a native
|
124
|
+
# JavaScript object. In general, this object is registered
|
125
|
+
# as a finalizer on the Ruby proxy itself, so that when it is
|
126
|
+
# garbage collected, it releases the back reference to the
|
127
|
+
# native JavaScript object.
|
128
|
+
#
|
129
|
+
# It is important to do this as soon as is reasonably possible
|
130
|
+
# so that the native JavaScript object can itself be garbage
|
131
|
+
# collected (provided there are no other references to it)
|
103
132
|
class ClearRubyProxy
|
104
133
|
def initialize(rb2js, js2rb)
|
105
134
|
@rb2js, @js2rb = rb2js, js2rb
|
106
135
|
end
|
107
136
|
|
137
|
+
# takes the object id of a Ruby proxy that has been garbage collected
|
138
|
+
# and releases the reference to the native JavaScript object that
|
139
|
+
# it was bound to.
|
140
|
+
# @param[Fixnum] proxy_id the proxy id of the garbage collected Ruby proxy
|
108
141
|
def call(proxy_id)
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
142
|
+
# TODO: this if-check should be synchronized, so that if called manually
|
143
|
+
# it will not conflict with the finalization thread. It's not so heinous
|
144
|
+
# if the refererence gets cleared twice, but we definiteily dont't want
|
145
|
+
# to double-decrement the v8 GC hint.
|
146
|
+
if js = @rb2js[proxy_id]
|
147
|
+
@rb2js.delete(proxy_id)
|
148
|
+
@js2rb.delete(js)
|
149
|
+
V8::C::V8::AdjustAmountOfExternalAllocatedMemory(-8 * 1024)
|
150
|
+
end
|
113
151
|
end
|
114
152
|
end
|
115
153
|
end
|
data/lib/v8/version.rb
CHANGED
data/specmem/proxies_memspec.rb
CHANGED
@@ -12,11 +12,12 @@ describe V8::Portal::Proxies do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it "releases the hard reference if its corresponding javascript object has been garbage collected" do
|
15
|
-
rb_object = Object.new
|
16
|
-
js_proxy = c::Object::New()
|
17
|
-
subject.register_javascript_proxy js_proxy, :for => rb_object
|
18
|
-
rb_object = nil
|
19
15
|
ruby_gc do
|
16
|
+
rb_object = Object.new
|
17
|
+
js_proxy = c::Object::New()
|
18
|
+
subject.should be_empty
|
19
|
+
subject.register_javascript_proxy js_proxy, :for => rb_object
|
20
|
+
rb_object = nil
|
20
21
|
subject.should_not be_empty
|
21
22
|
v8_gc()
|
22
23
|
end
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: therubyracer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
version: 0.9.
|
4
|
+
prerelease:
|
5
|
+
version: 0.9.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Charles Lowell
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2011-06-
|
14
|
+
date: 2011-06-10 00:00:00 -05:00
|
15
15
|
default_executable:
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
@@ -140,6 +140,7 @@ files:
|
|
140
140
|
- spec/ext/ext_spec_helper.rb
|
141
141
|
- spec/ext/func_spec.rb
|
142
142
|
- spec/ext/object_spec.rb
|
143
|
+
- spec/ext/string_spec.rb
|
143
144
|
- spec/ext/try_catch_spec.rb
|
144
145
|
- spec/redjs_helper.rb
|
145
146
|
- spec/spec_helper.rb
|
@@ -169,16 +170,19 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
169
170
|
requirements:
|
170
171
|
- - ">="
|
171
172
|
- !ruby/object:Gem::Version
|
172
|
-
hash: -
|
173
|
+
hash: -3759778087038355586
|
173
174
|
segments:
|
174
175
|
- 0
|
175
176
|
version: "0"
|
176
177
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
177
178
|
none: false
|
178
179
|
requirements:
|
179
|
-
- - "
|
180
|
+
- - ">="
|
180
181
|
- !ruby/object:Gem::Version
|
181
|
-
|
182
|
+
hash: -3759778087038355586
|
183
|
+
segments:
|
184
|
+
- 0
|
185
|
+
version: "0"
|
182
186
|
requirements: []
|
183
187
|
|
184
188
|
rubyforge_project: therubyracer
|