therubyracer 0.9.0beta3 → 0.9.0beta4
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/bin/therubyracer +0 -2
- data/ext/v8/rr.cpp +7 -0
- data/ext/v8/rr.h +4 -0
- data/ext/v8/v8_weakref.cpp +14 -4
- data/ext/v8/v8_weakref.h +4 -1
- data/lib/v8/portal/proxies.rb +15 -0
- data/lib/v8/version.rb +1 -1
- data/specmem/object_memspec.rb +1 -3
- data/specmem/proxies_memspec.rb +14 -52
- data/therubyracer.gemspec +1 -0
- metadata +47 -11
data/bin/therubyracer
CHANGED
data/ext/v8/rr.cpp
CHANGED
@@ -40,6 +40,13 @@ VALUE rr_const_get(const char *name) {
|
|
40
40
|
return rb_const_get(V8_C, rb_intern(name));
|
41
41
|
}
|
42
42
|
|
43
|
+
VALUE rr_define_finalizer(VALUE object, void* finalizer, VALUE data) {
|
44
|
+
VALUE finalizer_proc = rb_proc_new((VALUE (*)(...))finalizer, data);
|
45
|
+
rb_iv_set(finalizer_proc, "data", data);
|
46
|
+
VALUE ospace = rb_const_get(rb_cObject, rb_intern("ObjectSpace"));
|
47
|
+
rb_funcall(ospace, rb_intern("define_finalizer"), 2, object, finalizer_proc);
|
48
|
+
}
|
49
|
+
|
43
50
|
VALUE rr_v82rb(Handle<Value> value) {
|
44
51
|
if (value.IsEmpty()) {
|
45
52
|
return rr_v8_value_empty();
|
data/ext/v8/rr.h
CHANGED
@@ -11,6 +11,10 @@ VALUE rr_define_class(const char *name, VALUE superclass = rb_cObject);
|
|
11
11
|
VALUE rr_define_module(const char *name);
|
12
12
|
VALUE rr_define_const(const char *name, VALUE value);
|
13
13
|
VALUE rr_const_get(const char *name);
|
14
|
+
VALUE rr_define_finalizer(VALUE object, void* finalizer, VALUE data);
|
15
|
+
|
16
|
+
extern "C" VALUE rb_proc_new(VALUE (*)(ANYARGS/* VALUE yieldarg[, VALUE procarg] */), VALUE);
|
17
|
+
|
14
18
|
|
15
19
|
VALUE rr_v82rb(v8::Handle<v8::Value> value);
|
16
20
|
VALUE rr_v82rb(v8::Handle<v8::Boolean> value);
|
data/ext/v8/v8_weakref.cpp
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
using namespace v8;
|
5
5
|
|
6
6
|
v8_weakref::v8_weakref(VALUE object) {
|
7
|
+
this->v8_active = true;
|
8
|
+
this->rb_active = true;
|
7
9
|
this->external = Persistent<External>::New(External::New((void *)this));
|
8
10
|
this->external.MakeWeak(this, v8_weakref_dispose);
|
9
11
|
this->set(object);
|
@@ -11,9 +13,9 @@ v8_weakref::v8_weakref(VALUE object) {
|
|
11
13
|
|
12
14
|
void v8_weakref::set(VALUE value) {
|
13
15
|
this->object_id = rb_obj_id(value);
|
16
|
+
this->rb_active = true;
|
14
17
|
VALUE data = Data_Wrap_Struct(rb_cObject, 0, 0, this);
|
15
|
-
|
16
|
-
rb_funcall(v8_weakref_objectspace(), rb_intern("define_finalizer"), 2, value, finalizer);
|
18
|
+
rr_define_finalizer(value,(void*)v8_weakref_finalize, data);
|
17
19
|
}
|
18
20
|
|
19
21
|
VALUE v8_weakref::get() {
|
@@ -28,13 +30,21 @@ VALUE v8_weakref_finalize(VALUE object_id, VALUE data) {
|
|
28
30
|
v8_weakref* weakref = 0;
|
29
31
|
Data_Get_Struct(data, struct v8_weakref, weakref);
|
30
32
|
weakref->object_id = Qnil;
|
33
|
+
weakref->rb_active = false;
|
34
|
+
if (!weakref->v8_active) {
|
35
|
+
delete weakref;
|
36
|
+
}
|
31
37
|
return Qnil;
|
32
38
|
}
|
33
39
|
|
34
|
-
void v8_weakref_dispose(Persistent<Value> value, void*
|
40
|
+
void v8_weakref_dispose(Persistent<Value> value, void* data) {
|
35
41
|
value.Dispose();
|
36
42
|
value.Clear();
|
37
|
-
|
43
|
+
v8_weakref* weakref = (v8_weakref*)data;
|
44
|
+
weakref->v8_active = false;
|
45
|
+
if (!weakref->rb_active) {
|
46
|
+
delete weakref;
|
47
|
+
}
|
38
48
|
}
|
39
49
|
|
40
50
|
VALUE v8_weakref_nil(VALUE nil, VALUE exception) {
|
data/ext/v8/v8_weakref.h
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
#include <v8.h>
|
5
5
|
#include "ruby.h"
|
6
|
+
#include "rr.h"
|
6
7
|
|
7
8
|
struct v8_weakref {
|
8
9
|
v8_weakref(VALUE object);
|
@@ -12,6 +13,8 @@ struct v8_weakref {
|
|
12
13
|
void release();
|
13
14
|
|
14
15
|
VALUE object_id;
|
16
|
+
bool v8_active;
|
17
|
+
bool rb_active;
|
15
18
|
v8::Persistent<v8::External> external;
|
16
19
|
};
|
17
20
|
|
@@ -21,6 +24,6 @@ VALUE v8_weakref_objectspace();
|
|
21
24
|
VALUE v8_weakref_nil(VALUE nil, VALUE exception);
|
22
25
|
VALUE v8_weakref_id2ref(VALUE id);
|
23
26
|
|
24
|
-
extern "C" VALUE rb_proc_new(VALUE (*)(ANYARGS/* VALUE yieldarg[, VALUE procarg] */), VALUE);
|
27
|
+
// extern "C" VALUE rb_proc_new(VALUE (*)(ANYARGS/* VALUE yieldarg[, VALUE procarg] */), VALUE);
|
25
28
|
|
26
29
|
#endif
|
data/lib/v8/portal/proxies.rb
CHANGED
@@ -43,6 +43,7 @@ module V8
|
|
43
43
|
@js_proxies_js2rb[proxy] = target
|
44
44
|
@js_proxies_rb2js[target] = proxy
|
45
45
|
proxy.MakeWeak(nil, @clear_js_proxy)
|
46
|
+
V8::C::V8::AdjustAmountOfExternalAllocatedMemory(16 * 1024)
|
46
47
|
end
|
47
48
|
|
48
49
|
def rb_object_2_js_proxy(object)
|
@@ -59,6 +60,7 @@ module V8
|
|
59
60
|
@rb_proxies_rb2js[proxy.object_id] = target
|
60
61
|
@rb_proxies_js2rb[target] = proxy.object_id
|
61
62
|
ObjectSpace.define_finalizer(proxy, @clear_rb_proxy)
|
63
|
+
V8::C::V8::AdjustAmountOfExternalAllocatedMemory(8 * 1024)
|
62
64
|
end
|
63
65
|
|
64
66
|
def js_object_2_rb_proxy(object)
|
@@ -71,6 +73,17 @@ module V8
|
|
71
73
|
@rb_proxies_rb2js[proxy.object_id]
|
72
74
|
end
|
73
75
|
|
76
|
+
def js_empty?
|
77
|
+
@js_proxies_rb2js.empty? && @js_proxies_js2rb.empty?
|
78
|
+
end
|
79
|
+
|
80
|
+
def rb_empty?
|
81
|
+
@rb_proxies_rb2js.empty? && @rb_proxies_js2rb.empty?
|
82
|
+
end
|
83
|
+
|
84
|
+
def empty?
|
85
|
+
js_empty? && rb_empty?
|
86
|
+
end
|
74
87
|
DoubleProxyError = Class.new(StandardError)
|
75
88
|
|
76
89
|
class ClearJSProxy
|
@@ -83,6 +96,7 @@ module V8
|
|
83
96
|
rb = @js2rb[proxy]
|
84
97
|
@js2rb.delete(proxy)
|
85
98
|
@rb2js.delete(rb)
|
99
|
+
V8::C::V8::AdjustAmountOfExternalAllocatedMemory(-16 * 1024)
|
86
100
|
end
|
87
101
|
end
|
88
102
|
|
@@ -95,6 +109,7 @@ module V8
|
|
95
109
|
js = @rb2js[proxy_id]
|
96
110
|
@rb2js.delete(proxy_id)
|
97
111
|
@js2rb.delete(js)
|
112
|
+
V8::C::V8::AdjustAmountOfExternalAllocatedMemory(-8 * 1024)
|
98
113
|
end
|
99
114
|
end
|
100
115
|
end
|
data/lib/v8/version.rb
CHANGED
data/specmem/object_memspec.rb
CHANGED
@@ -5,10 +5,8 @@ describe V8::C::Object do
|
|
5
5
|
include V8::MemSpec
|
6
6
|
it "will return a new peer and not barf if the old peer has been garbage collected" do
|
7
7
|
v8_eval('var o = {foo: "bar"}')
|
8
|
-
|
9
|
-
old_id = o.object_id
|
8
|
+
old_id = v8_eval('o').object_id
|
10
9
|
ruby_gc do
|
11
|
-
o = nil
|
12
10
|
v8_eval('o').Get(c::String::New("foo")).Utf8Value().should == "bar"
|
13
11
|
v8_eval('o').object_id.should_not be(old_id)
|
14
12
|
end
|
data/specmem/proxies_memspec.rb
CHANGED
@@ -5,82 +5,44 @@ describe V8::Portal::Proxies do
|
|
5
5
|
|
6
6
|
context "A Ruby object embedded into JavaScript" do
|
7
7
|
it "holds a hard reference to any ruby object which is linked to a javascript proxy" do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
subject.register_javascript_proxy c::Object::New(), :for => Object.new
|
9
|
+
ruby_gc do
|
10
|
+
subject.should_not be_empty
|
11
|
+
end
|
12
12
|
end
|
13
13
|
|
14
14
|
it "releases the hard reference if its corresponding javascript object has been garbage collected" do
|
15
15
|
rb_object = Object.new
|
16
16
|
js_proxy = c::Object::New()
|
17
|
-
check_finalized(rb_object)
|
18
17
|
subject.register_javascript_proxy js_proxy, :for => rb_object
|
19
18
|
rb_object = nil
|
20
19
|
ruby_gc do
|
20
|
+
subject.should_not be_empty
|
21
21
|
v8_gc()
|
22
22
|
end
|
23
|
+
subject.should be_empty
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
26
27
|
context "A JavaScript object embedded into Ruby" do
|
27
28
|
it "holds a hard reference to any JavaScript object which is linked to a Ruby proxy" do
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
proxy = Object.new
|
30
|
+
subject.register_ruby_proxy proxy, :for => c::Object::New()
|
31
|
+
ruby_gc do
|
32
|
+
subject.should_not be_empty
|
33
|
+
end
|
32
34
|
end
|
33
35
|
|
34
36
|
it "clears any strong references to the JavaScript object when it's Ruby proxy is garbage collected" do
|
35
|
-
|
36
|
-
|
37
|
-
subject.register_ruby_proxy rb_proxy, :for => js_object
|
38
|
-
check_finalized(js_object)
|
39
|
-
js_object = rb_proxy = nil
|
37
|
+
subject.register_ruby_proxy Object.new, :for => c::Object::New()
|
38
|
+
subject.should_not be_empty
|
40
39
|
ruby_gc do
|
41
40
|
v8_gc
|
42
41
|
GC.start
|
43
42
|
v8_gc
|
44
43
|
end
|
45
|
-
|
46
|
-
end
|
47
|
-
private
|
48
|
-
|
49
|
-
def finalize(object_id)
|
50
|
-
@finalized ||= {}
|
51
|
-
@finalized[object_id] = true
|
52
|
-
end
|
53
|
-
|
54
|
-
def check_finalized(object)
|
55
|
-
@finalized ||= {}
|
56
|
-
ObjectSpace.define_finalizer(object, method(:finalize))
|
57
|
-
id_to_check = object.object_id
|
58
|
-
object = nil
|
59
|
-
afterwards do
|
60
|
-
@finalized[id_to_check].should be_true
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def check_not_finalized(object)
|
65
|
-
@finalized ||= {}
|
66
|
-
ObjectSpace.define_finalizer(object, method(:finalize))
|
67
|
-
id_to_check = object.object_id
|
68
|
-
object = nil
|
69
|
-
afterwards do
|
70
|
-
@finalized[id_to_check].should be_false
|
44
|
+
subject.should be_empty
|
71
45
|
end
|
72
46
|
end
|
73
47
|
|
74
|
-
def afterwards(&block)
|
75
|
-
@after ||= []
|
76
|
-
@after << block if block_given?
|
77
|
-
end
|
78
|
-
|
79
|
-
after do
|
80
|
-
ruby_gc do
|
81
|
-
@after.each do |proc|
|
82
|
-
proc.call
|
83
|
-
end if @after
|
84
|
-
end
|
85
|
-
end
|
86
48
|
end
|
data/therubyracer.gemspec
CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
|
|
24
24
|
s.extensions = ["ext/v8/extconf.rb"]
|
25
25
|
s.require_paths = ["lib", "ext"]
|
26
26
|
|
27
|
+
s.add_development_dependency "rake", "~> 0.8.7"
|
27
28
|
s.add_development_dependency "rspec", ">= 2.0.0"
|
28
29
|
s.add_development_dependency "rake-compiler"
|
29
30
|
end
|
metadata
CHANGED
@@ -1,8 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: therubyracer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 62196283
|
4
5
|
prerelease: 5
|
5
|
-
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 9
|
9
|
+
- 0
|
10
|
+
- beta
|
11
|
+
- 4
|
12
|
+
version: 0.9.0beta4
|
6
13
|
platform: ruby
|
7
14
|
authors:
|
8
15
|
- Charles Lowell
|
@@ -11,31 +18,55 @@ autorequire:
|
|
11
18
|
bindir: bin
|
12
19
|
cert_chain: []
|
13
20
|
|
14
|
-
date: 2011-05-
|
21
|
+
date: 2011-05-25 00:00:00 -05:00
|
15
22
|
default_executable:
|
16
23
|
dependencies:
|
17
24
|
- !ruby/object:Gem::Dependency
|
18
|
-
name:
|
25
|
+
name: rake
|
26
|
+
prerelease: false
|
27
|
+
type: :development
|
19
28
|
requirement: &id001 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
hash: 49
|
34
|
+
segments:
|
35
|
+
- 0
|
36
|
+
- 8
|
37
|
+
- 7
|
38
|
+
version: 0.8.7
|
39
|
+
version_requirements: *id001
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: rspec
|
42
|
+
prerelease: false
|
43
|
+
type: :development
|
44
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
20
45
|
none: false
|
21
46
|
requirements:
|
22
47
|
- - ">="
|
23
48
|
- !ruby/object:Gem::Version
|
49
|
+
hash: 15
|
50
|
+
segments:
|
51
|
+
- 2
|
52
|
+
- 0
|
53
|
+
- 0
|
24
54
|
version: 2.0.0
|
25
|
-
|
26
|
-
prerelease: false
|
27
|
-
version_requirements: *id001
|
55
|
+
version_requirements: *id002
|
28
56
|
- !ruby/object:Gem::Dependency
|
29
57
|
name: rake-compiler
|
30
|
-
|
58
|
+
prerelease: false
|
59
|
+
type: :development
|
60
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
31
61
|
none: false
|
32
62
|
requirements:
|
33
63
|
- - ">="
|
34
64
|
- !ruby/object:Gem::Version
|
65
|
+
hash: 3
|
66
|
+
segments:
|
67
|
+
- 0
|
35
68
|
version: "0"
|
36
|
-
|
37
|
-
prerelease: false
|
38
|
-
version_requirements: *id002
|
69
|
+
version_requirements: *id003
|
39
70
|
description: Call javascript code and manipulate javascript objects from ruby. Call ruby code and manipulate ruby objects from javascript.
|
40
71
|
email: cowboyd@thefrontside.net
|
41
72
|
executables:
|
@@ -909,7 +940,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
909
940
|
requirements:
|
910
941
|
- - ">="
|
911
942
|
- !ruby/object:Gem::Version
|
912
|
-
hash:
|
943
|
+
hash: 3
|
913
944
|
segments:
|
914
945
|
- 0
|
915
946
|
version: "0"
|
@@ -918,6 +949,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
918
949
|
requirements:
|
919
950
|
- - ">"
|
920
951
|
- !ruby/object:Gem::Version
|
952
|
+
hash: 25
|
953
|
+
segments:
|
954
|
+
- 1
|
955
|
+
- 3
|
956
|
+
- 1
|
921
957
|
version: 1.3.1
|
922
958
|
requirements: []
|
923
959
|
|