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.
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