therubyracer-freebsd 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/.gitignore +13 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +8 -0
  4. data/.yardopts +1 -0
  5. data/Changelog.md +231 -0
  6. data/Gemfile +3 -0
  7. data/README.md +167 -0
  8. data/Rakefile +26 -0
  9. data/bin/therubyracer +11 -0
  10. data/ext/v8/extconf.rb +26 -0
  11. data/ext/v8/rr.cpp +189 -0
  12. data/ext/v8/rr.h +41 -0
  13. data/ext/v8/v8.cpp +48 -0
  14. data/ext/v8/v8_array.cpp +48 -0
  15. data/ext/v8/v8_array.h +8 -0
  16. data/ext/v8/v8_callbacks.cpp +81 -0
  17. data/ext/v8/v8_callbacks.h +8 -0
  18. data/ext/v8/v8_context.cpp +92 -0
  19. data/ext/v8/v8_context.h +6 -0
  20. data/ext/v8/v8_date.cpp +40 -0
  21. data/ext/v8/v8_date.h +6 -0
  22. data/ext/v8/v8_debug.cpp +17 -0
  23. data/ext/v8/v8_debug.h +6 -0
  24. data/ext/v8/v8_exception.cpp +133 -0
  25. data/ext/v8/v8_exception.h +11 -0
  26. data/ext/v8/v8_external.cpp +70 -0
  27. data/ext/v8/v8_external.h +8 -0
  28. data/ext/v8/v8_function.cpp +69 -0
  29. data/ext/v8/v8_function.h +11 -0
  30. data/ext/v8/v8_handle.cpp +186 -0
  31. data/ext/v8/v8_handle.h +48 -0
  32. data/ext/v8/v8_locker.cpp +139 -0
  33. data/ext/v8/v8_locker.h +6 -0
  34. data/ext/v8/v8_message.cpp +67 -0
  35. data/ext/v8/v8_message.h +10 -0
  36. data/ext/v8/v8_object.cpp +122 -0
  37. data/ext/v8/v8_object.h +10 -0
  38. data/ext/v8/v8_script.cpp +36 -0
  39. data/ext/v8/v8_script.h +8 -0
  40. data/ext/v8/v8_string.cpp +52 -0
  41. data/ext/v8/v8_string.h +9 -0
  42. data/ext/v8/v8_template.cpp +344 -0
  43. data/ext/v8/v8_template.h +8 -0
  44. data/ext/v8/v8_try_catch.cpp +70 -0
  45. data/ext/v8/v8_try_catch.h +5 -0
  46. data/ext/v8/v8_v8.cpp +34 -0
  47. data/ext/v8/v8_v8.h +6 -0
  48. data/ext/v8/v8_value.cpp +175 -0
  49. data/ext/v8/v8_value.h +10 -0
  50. data/ext/v8/v8_weakref.cpp +61 -0
  51. data/ext/v8/v8_weakref.h +29 -0
  52. data/lib/v8.rb +23 -0
  53. data/lib/v8/access.rb +92 -0
  54. data/lib/v8/array.rb +17 -0
  55. data/lib/v8/c/locker.rb +18 -0
  56. data/lib/v8/cli.rb +133 -0
  57. data/lib/v8/context.rb +111 -0
  58. data/lib/v8/error.rb +130 -0
  59. data/lib/v8/function.rb +44 -0
  60. data/lib/v8/object.rb +69 -0
  61. data/lib/v8/portal.rb +86 -0
  62. data/lib/v8/portal/caller.rb +37 -0
  63. data/lib/v8/portal/constructor.rb +98 -0
  64. data/lib/v8/portal/function.rb +63 -0
  65. data/lib/v8/portal/interceptors.rb +152 -0
  66. data/lib/v8/portal/proxies.rb +151 -0
  67. data/lib/v8/portal/templates.rb +73 -0
  68. data/lib/v8/stack.rb +66 -0
  69. data/lib/v8/tap.rb +9 -0
  70. data/lib/v8/version.rb +3 -0
  71. data/spec/ext/array_spec.rb +15 -0
  72. data/spec/ext/cxt_spec.rb +57 -0
  73. data/spec/ext/ext_spec_helper.rb +27 -0
  74. data/spec/ext/func_spec.rb +64 -0
  75. data/spec/ext/object_spec.rb +10 -0
  76. data/spec/ext/string_spec.rb +11 -0
  77. data/spec/ext/try_catch_spec.rb +60 -0
  78. data/spec/redjs_spec.rb +9 -0
  79. data/spec/spec_helper.rb +9 -0
  80. data/spec/v8/error_spec.rb +131 -0
  81. data/spec/v8/portal/proxies_spec.rb +106 -0
  82. data/specmem/handle_memspec.rb +41 -0
  83. data/specmem/object_memspec.rb +14 -0
  84. data/specmem/proxies_memspec.rb +49 -0
  85. data/specmem/spec_helper.rb +24 -0
  86. data/specthread/spec_helper.rb +2 -0
  87. data/specthread/threading_spec.rb +13 -0
  88. data/thefrontside.png +0 -0
  89. data/therubyracer.gemspec +27 -0
  90. metadata +183 -0
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C::Object do
4
+ include V8::ExtSpec
5
+
6
+ it "always returns a copy of the same object if it is the same object" do
7
+ v8_eval('var o = new Object()')
8
+ v8_eval('o').should be(v8_eval('o'))
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+
2
+ require 'spec_helper'
3
+
4
+ describe V8::C::String do
5
+ include V8::ExtSpec
6
+
7
+ describe "a string with null bytes" do
8
+ subject {c::String::New("foo\0bar")}
9
+ its(:Utf8Value) {should eql "foo\0bar"}
10
+ end
11
+ end
@@ -0,0 +1,60 @@
1
+ require "#{File.dirname(__FILE__)}/../spec_helper.rb"
2
+
3
+ include V8
4
+
5
+ describe C::TryCatch do
6
+
7
+ before {@lock = C::Locker.new;@cxt = C::Context::New();}
8
+ after {@cxt.Dispose(); @lock.delete}
9
+
10
+ it "does not allow instance creation by default" do
11
+ lambda {
12
+ C::TryCatch.new
13
+ }.should raise_error
14
+ end
15
+
16
+ it "will do nothing if not passed a block" do
17
+ C::TryCatch.try.should == nil
18
+ end
19
+
20
+ it "executes a block in the context of a C++ stack frame" do
21
+ C::TryCatch.try do |catch|
22
+ catch.HasCaught().should be(false)
23
+ end
24
+ end
25
+
26
+ it "raises an erro if you try to access it outside of its scope" do
27
+ tc = C::TryCatch.try do |catch|
28
+ catch.tap {}
29
+ end
30
+ lambda {
31
+ tc.HasCaught()
32
+ }.should raise_error(ScriptError)
33
+ end
34
+
35
+ it "doesn't segfault when an error is raised in a javascript function on a native prototype" do
36
+ constructor = Class.new
37
+ constructor.class_eval do
38
+ def detonate(*a)
39
+ raise "BOOM!"
40
+ end
41
+ end
42
+ V8::Context.new do |cxt|
43
+ cxt['Boom'] = constructor
44
+ cxt['puts'] = method(:puts)
45
+ danger = <<-JS
46
+ Boom.prototype.boom = function() {
47
+ this.detonate()
48
+ }
49
+ var go = new(Boom)()
50
+ try {
51
+ go.boom()
52
+ } catch (e) {
53
+ }
54
+ go.boom()
55
+ JS
56
+ expect {cxt.eval(danger, 'danger.js')}.should raise_error(V8::JSError)
57
+ end
58
+ end
59
+
60
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+ require 'redjs/load_specs'
3
+ module RedJS
4
+ Context = V8::Context
5
+ Error = V8::JSError
6
+ end
7
+ describe V8::Context do
8
+ it_behaves_like 'RedJS::Context'
9
+ end
@@ -0,0 +1,9 @@
1
+
2
+ require 'v8'
3
+ require 'erb'
4
+ require Pathname(__FILE__).dirname.join('ext/ext_spec_helper')
5
+ require Pathname(__FILE__).dirname.join('../specmem/spec_helper')
6
+ def rputs(msg)
7
+ puts "<pre>#{ERB::Util.h(msg)}</pre>"
8
+ $stdout.flush
9
+ end
@@ -0,0 +1,131 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe V8::JSError do
4
+
5
+ before(:each) do
6
+ @cxt = V8::Context.new
7
+ @cxt['one'] = lambda do
8
+ @cxt.eval('two()', 'one.js')
9
+ end
10
+ @cxt['two'] = lambda do
11
+ @cxt.eval('three()', 'two.js')
12
+ end
13
+ end
14
+
15
+ it "captures a message without over nesting when the error is an error" do
16
+ throw! do |e|
17
+ e.message.should == "BOOM!"
18
+ end
19
+ end
20
+
21
+ it "captures the js message without over nesting when the error is a normal object" do
22
+ throw!('{foo: "bar"}') do |e|
23
+ e.message.should == "[object Object]"
24
+ end
25
+ throw!('{message: "bar"}') do |e|
26
+ e.message.should == "bar"
27
+ end
28
+ end
29
+
30
+ it "captures a thrown value as the message" do
31
+ throw!('"BOOM!"') do |e|
32
+ e.message.should == "BOOM!"
33
+ end
34
+ throw!('6') do |e|
35
+ e.message.should == '6'
36
+ end
37
+ end
38
+
39
+ it "has a reference to the root javascript cause" do
40
+ throw!('"I am a String"') do |e|
41
+ e.should_not be_in_ruby
42
+ e.should be_in_javascript
43
+ e.value.should == "I am a String"
44
+ end
45
+ end
46
+
47
+ it "has a reference to the root ruby cause if one exists" do
48
+ StandardError.new("BOOM!").tap do |bomb|
49
+ @cxt['boom'] = lambda do
50
+ raise bomb
51
+ end
52
+ lambda {
53
+ @cxt.eval('boom()', 'boom.js')
54
+ }.should(raise_error do |raised|
55
+ raised.should be_in_ruby
56
+ raised.should_not be_in_javascript
57
+ raised.value.should be(bomb)
58
+ end)
59
+ end
60
+ end
61
+
62
+ describe "backtrace" do
63
+
64
+ it "is mixed with ruby and javascript" do
65
+ throw! do |e|
66
+ e.backtrace.first.should == "at three.js:1:7"
67
+ e.backtrace[1].should =~ /error_spec.rb/
68
+ e.backtrace[2].should == "at two.js:1:1"
69
+ e.backtrace[3].should =~ /error_spec.rb/
70
+ e.backtrace[4].should == "at one.js:1:1"
71
+ end
72
+ end
73
+
74
+ it "can be set to show only ruby frames" do
75
+ throw! do |e|
76
+ e.backtrace(:ruby).each do |frame|
77
+ frame.should =~ /(\.rb|):\d+/
78
+ end
79
+ end
80
+ end
81
+
82
+ it "can be set to show only javascript frames" do
83
+ throw! do |e|
84
+ e.backtrace(:javascript).each do |frame|
85
+ frame.should =~ /\.js:\d:\d/
86
+ end
87
+ end
88
+ end
89
+
90
+ it "includes a mystery marker when the original frame is unavailable because what got thrown wasn't an error" do
91
+ throw!("6") do |e|
92
+ e.backtrace.first.should == 'at three.js:1:1'
93
+ end
94
+ end
95
+
96
+ it "has a source name and line number when there is a javascript SyntaxError" do
97
+ lambda do
98
+ @cxt.eval(<<-INVALID, 'source.js')
99
+ "this line is okay";
100
+ "this line has a syntax error because it ends with a colon":
101
+ "this line is also okay";
102
+ "how do I find out that line 2 has the syntax error?";
103
+ INVALID
104
+ end.should raise_error(V8::JSError) {|error|
105
+ error.backtrace.first.should == 'at source.js:2:60'
106
+ }
107
+ end
108
+
109
+ it "can start with ruby at the bottom" do
110
+ @cxt['boom'] = lambda do
111
+ raise StandardError, "Bif!"
112
+ end
113
+ lambda {
114
+ @cxt.eval('boom()', "boom.js")
115
+ }.should(raise_error {|e|
116
+ e.backtrace.first.should =~ /error_spec\.rb/
117
+ e.backtrace[1].should =~ /boom.js/
118
+ })
119
+ end
120
+ end
121
+
122
+
123
+ def throw!(js = "new Error('BOOM!')", &block)
124
+ @cxt['three'] = lambda do
125
+ @cxt.eval("throw #{js}", 'three.js')
126
+ end
127
+ lambda do
128
+ @cxt['one'].call()
129
+ end.should(raise_error(V8::JSError, &block))
130
+ end
131
+ end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::Portal::Proxies do
4
+ include V8::ExtSpec
5
+
6
+
7
+ context "for Ruby objects which are embedded into javascript" do
8
+
9
+ it "allows you to resolve the Ruby object's JavaScript proxy" do
10
+ js_proxy = c::Object::New()
11
+ rb_object = Object.new
12
+ subject.register_javascript_proxy js_proxy, :for => rb_object
13
+ subject.rb_object_2_js_proxy(rb_object).should be(js_proxy)
14
+ subject.js_proxy_2_rb_object(js_proxy).should be(rb_object)
15
+ end
16
+
17
+ it "requires a Ruby object which is the actual object that is proxied" do
18
+ expect {subject.register_javascript_proxy c::Object::New()}.should raise_error(ArgumentError)
19
+ end
20
+
21
+ it "can only register proxies which are low-level JavaScript objects" do
22
+ expect {subject.register_javascript_proxy Object.new, :for => Object.new}.should raise_error(ArgumentError)
23
+ end
24
+
25
+ it "is only allowed to have a single JavaScript proxy" do
26
+ rb_object = Object.new
27
+ subject.register_javascript_proxy c::Object::New(), :for => rb_object
28
+ expect {subject.register_javascript_proxy c::Object::New(), :for => rb_object}.should raise_error(V8::Portal::Proxies::DoubleProxyError)
29
+ end
30
+ end
31
+
32
+ context "for a JavaScript objects which are embedded into Ruby" do
33
+
34
+ it "allows you to resolve the JavaScript object's Ruby proxy" do
35
+ rb_proxy = Object.new
36
+ js_object = c::Object::New()
37
+ subject.register_ruby_proxy rb_proxy, :for => js_object
38
+ subject.js_object_2_rb_proxy(js_object).should be(rb_proxy)
39
+ subject.rb_proxy_2_js_object(rb_proxy).should be(js_object)
40
+ end
41
+
42
+ it "requires a JavaScript low level javascript object as the actual object that is proxied" do
43
+ expect {subject.register_javascript_proxy Object.new, :for => c::Object::New()}.should raise_error(ArgumentError)
44
+ end
45
+
46
+ it "will not a proxy twice if the proxy creator block actually registers the proxy inside it" do
47
+ target = Object.new
48
+ proxy = c::Object::New()
49
+ expect {subject.rb2js(target) do |object|
50
+ subject.register_javascript_proxy(proxy, :for => object)
51
+ c::Object::New()
52
+ end}.should_not raise_error
53
+ subject.rb2js(target).should be(proxy)
54
+ end
55
+
56
+ context "looking up a Ruby object from a random JavaScript object" do
57
+ it "checks first if it's a native Ruby object with a javascript proxy" do
58
+ target = Object.new
59
+ proxy = c::Object::New()
60
+ subject.register_javascript_proxy proxy, :for => target
61
+ subject.js2rb(proxy).should be(target)
62
+ end
63
+ it "then sees if maybe it's a native JavaScript that has a Ruby proxy" do
64
+ target = c::Object::New()
65
+ proxy = Object.new
66
+ subject.register_ruby_proxy proxy, :for => target
67
+ subject.js2rb(target).should be(proxy)
68
+ end
69
+ it "will assume that it is a native JavaScript object that needs a Ruby proxy if no corresponding Ruby object can be found" do
70
+ js = c::Object::New()
71
+ proxy = subject.js2rb(js) do |target|
72
+ {:target => target}
73
+ end
74
+ subject.js2rb(js).should be(proxy)
75
+ end
76
+ end
77
+
78
+ context "looking up a JavaScript object from a random Ruby object" do
79
+ it "checks first if it's a native JavaScript object with a Ruby proxy" do
80
+ target = c::Object::New()
81
+ proxy = Object.new
82
+ subject.register_ruby_proxy proxy, :for => target
83
+ subject.rb2js(proxy).should be(target)
84
+ end
85
+
86
+ it "then sees if maybe it's a native Ruby object that has a JavaScript proxy" do
87
+ target = Object.new
88
+ proxy = c::Object::New()
89
+ subject.register_javascript_proxy proxy, :for => target
90
+ subject.rb2js(target).should be(proxy)
91
+ end
92
+
93
+ it "assumes that it is a native Ruby object that needs a JavaScript proxy if no corresponding JavaScript object can be found" do
94
+ rb = Object.new
95
+ proxy = nil
96
+ js = subject.rb2js(rb) do |target|
97
+ target.should be(rb)
98
+ proxy = c::Object::New()
99
+ end
100
+ proxy.should_not be_nil
101
+ js.should be(proxy)
102
+ subject.rb2js(rb).should be(proxy)
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,41 @@
1
+
2
+ require 'spec_helper'
3
+
4
+ describe V8::C::Handle do
5
+ include V8::MemSpec
6
+ context "A JavaScript Object reflected into Ruby" do
7
+
8
+ before do
9
+ @weakref_callback = WeakrefCallback.new
10
+ end
11
+
12
+ it "has a strong reference from the ruby side, which is not released until the Ruby reference goes away" do
13
+ handle = c::Handle::New(object = c::Object::New())
14
+ handle.MakeWeak(nil, @weakref_callback)
15
+ ruby_gc do
16
+ v8_gc
17
+ @weakref_callback.should_not have_been_invoked
18
+ handle.should_not be_dead
19
+ end
20
+ ruby_gc do
21
+ object = nil
22
+ v8_gc
23
+ @weakref_callback.should have_been_invoked
24
+ handle.should be_dead
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ class WeakrefCallback
31
+
32
+ def call(value, parameters)
33
+ @invoked = true
34
+ end
35
+
36
+ def has_been_invoked?
37
+ @invoked
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,14 @@
1
+
2
+ require 'spec_helper'
3
+
4
+ describe V8::C::Object do
5
+ include V8::MemSpec
6
+ it "will return a new peer and not barf if the old peer has been garbage collected" do
7
+ v8_eval('var o = {foo: "bar"}')
8
+ old_id = v8_eval('o').object_id
9
+ ruby_gc do
10
+ v8_eval('o').Get(c::String::New("foo")).Utf8Value().should == "bar"
11
+ v8_eval('o').object_id.should_not be(old_id)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::Portal::Proxies do
4
+ include V8::MemSpec
5
+
6
+ context "A Ruby object embedded into JavaScript" do
7
+ it "holds a hard reference to any ruby object which is linked to a javascript proxy" do
8
+ subject.register_javascript_proxy c::Object::New(), :for => Object.new
9
+ ruby_gc do
10
+ subject.should_not be_empty
11
+ end
12
+ end
13
+
14
+ it "releases the hard reference if its corresponding javascript object has been garbage collected" do
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
21
+ subject.should_not be_empty
22
+ v8_gc()
23
+ end
24
+ subject.should be_empty
25
+ end
26
+ end
27
+
28
+ context "A JavaScript object embedded into Ruby" do
29
+ it "holds a hard reference to any JavaScript object which is linked to a Ruby proxy" do
30
+ proxy = Object.new
31
+ subject.register_ruby_proxy proxy, :for => c::Object::New()
32
+ ruby_gc do
33
+ subject.should_not be_empty
34
+ end
35
+ end
36
+
37
+ it "clears any strong references to the JavaScript object when it's Ruby proxy is garbage collected" do
38
+ subject.register_ruby_proxy Object.new, :for => c::Object::New()
39
+ subject.should_not be_empty
40
+ ruby_gc do
41
+ v8_gc
42
+ GC.start
43
+ v8_gc
44
+ end
45
+ subject.should be_empty
46
+ end
47
+ end
48
+
49
+ end