therubyracer 0.10.2 → 0.11.0beta1

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.

Files changed (159) hide show
  1. data/.gitignore +21 -11
  2. data/.travis.yml +2 -1
  3. data/Changelog.md +46 -0
  4. data/Gemfile +16 -1
  5. data/README.md +31 -13
  6. data/Rakefile +42 -23
  7. data/benchmarks.rb +217 -0
  8. data/ext/v8/accessor.cc +181 -0
  9. data/ext/v8/array.cc +26 -0
  10. data/ext/v8/backref.cc +56 -0
  11. data/ext/v8/build.rb +51 -0
  12. data/ext/v8/constants.cc +34 -0
  13. data/ext/v8/constraints.cc +52 -0
  14. data/ext/v8/context.cc +130 -0
  15. data/ext/v8/date.cc +18 -0
  16. data/ext/v8/exception.cc +38 -0
  17. data/ext/v8/extconf.rb +14 -18
  18. data/ext/v8/external.cc +43 -0
  19. data/ext/v8/function.cc +58 -0
  20. data/ext/v8/gc.cc +43 -0
  21. data/ext/v8/handles.cc +34 -0
  22. data/ext/v8/heap.cc +31 -0
  23. data/ext/v8/init.cc +39 -0
  24. data/ext/v8/invocation.cc +86 -0
  25. data/ext/v8/locker.cc +77 -0
  26. data/ext/v8/message.cc +51 -0
  27. data/ext/v8/object.cc +334 -0
  28. data/ext/v8/primitive.cc +8 -0
  29. data/ext/v8/rr.cc +83 -0
  30. data/ext/v8/rr.h +878 -36
  31. data/ext/v8/script.cc +80 -0
  32. data/ext/v8/signature.cc +18 -0
  33. data/ext/v8/stack.cc +75 -0
  34. data/ext/v8/string.cc +47 -0
  35. data/ext/v8/template.cc +175 -0
  36. data/ext/v8/trycatch.cc +86 -0
  37. data/ext/v8/v8.cc +87 -0
  38. data/ext/v8/value.cc +239 -0
  39. data/lib/v8.rb +30 -22
  40. data/lib/v8/access.rb +5 -87
  41. data/lib/v8/access/indices.rb +40 -0
  42. data/lib/v8/access/invocation.rb +47 -0
  43. data/lib/v8/access/names.rb +65 -0
  44. data/lib/v8/array.rb +19 -10
  45. data/lib/v8/context.rb +85 -78
  46. data/lib/v8/conversion.rb +35 -0
  47. data/lib/v8/conversion/array.rb +11 -0
  48. data/lib/v8/conversion/class.rb +120 -0
  49. data/lib/v8/conversion/code.rb +38 -0
  50. data/lib/v8/conversion/fundamental.rb +11 -0
  51. data/lib/v8/conversion/hash.rb +11 -0
  52. data/lib/v8/conversion/indentity.rb +31 -0
  53. data/lib/v8/conversion/method.rb +26 -0
  54. data/lib/v8/conversion/object.rb +28 -0
  55. data/lib/v8/conversion/primitive.rb +7 -0
  56. data/lib/v8/conversion/proc.rb +5 -0
  57. data/lib/v8/conversion/reference.rb +16 -0
  58. data/lib/v8/conversion/string.rb +12 -0
  59. data/lib/v8/conversion/symbol.rb +7 -0
  60. data/lib/v8/conversion/time.rb +13 -0
  61. data/lib/v8/error.rb +18 -123
  62. data/lib/v8/error/protect.rb +20 -0
  63. data/lib/v8/error/try.rb +15 -0
  64. data/lib/v8/function.rb +18 -34
  65. data/lib/v8/object.rb +48 -52
  66. data/lib/v8/util/weakcell.rb +29 -0
  67. data/lib/v8/version.rb +2 -2
  68. data/spec/c/array_spec.rb +17 -0
  69. data/spec/c/constants_spec.rb +20 -0
  70. data/spec/c/exception_spec.rb +26 -0
  71. data/spec/c/external_spec.rb +9 -0
  72. data/spec/c/function_spec.rb +46 -0
  73. data/spec/c/handles_spec.rb +35 -0
  74. data/spec/c/locker_spec.rb +38 -0
  75. data/spec/c/object_spec.rb +46 -0
  76. data/spec/c/script_spec.rb +28 -0
  77. data/spec/c/string_spec.rb +16 -0
  78. data/spec/c/template_spec.rb +30 -0
  79. data/spec/c/trycatch_spec.rb +51 -0
  80. data/spec/mem/blunt_spec.rb +42 -0
  81. data/spec/redjs_spec.rb +10 -0
  82. data/spec/spec_helper.rb +40 -4
  83. data/spec/threading_spec.rb +52 -0
  84. data/spec/v8/context_spec.rb +19 -0
  85. data/spec/v8/conversion_spec.rb +9 -0
  86. data/spec/v8/error_spec.rb +15 -125
  87. data/spec/v8/function_spec.rb +9 -0
  88. data/therubyracer.gemspec +15 -24
  89. metadata +102 -135
  90. data/.gitmodules +0 -3
  91. data/.rspec +0 -1
  92. data/.yardopts +0 -1
  93. data/bin/therubyracer +0 -11
  94. data/ext/v8/rr.cpp +0 -189
  95. data/ext/v8/v8.cpp +0 -48
  96. data/ext/v8/v8_array.cpp +0 -48
  97. data/ext/v8/v8_array.h +0 -8
  98. data/ext/v8/v8_callbacks.cpp +0 -81
  99. data/ext/v8/v8_callbacks.h +0 -8
  100. data/ext/v8/v8_context.cpp +0 -92
  101. data/ext/v8/v8_context.h +0 -6
  102. data/ext/v8/v8_date.cpp +0 -34
  103. data/ext/v8/v8_date.h +0 -6
  104. data/ext/v8/v8_debug.cpp +0 -17
  105. data/ext/v8/v8_debug.h +0 -6
  106. data/ext/v8/v8_exception.cpp +0 -133
  107. data/ext/v8/v8_exception.h +0 -11
  108. data/ext/v8/v8_external.cpp +0 -70
  109. data/ext/v8/v8_external.h +0 -8
  110. data/ext/v8/v8_function.cpp +0 -69
  111. data/ext/v8/v8_function.h +0 -11
  112. data/ext/v8/v8_handle.cpp +0 -186
  113. data/ext/v8/v8_handle.h +0 -48
  114. data/ext/v8/v8_locker.cpp +0 -139
  115. data/ext/v8/v8_locker.h +0 -6
  116. data/ext/v8/v8_message.cpp +0 -67
  117. data/ext/v8/v8_message.h +0 -10
  118. data/ext/v8/v8_object.cpp +0 -122
  119. data/ext/v8/v8_object.h +0 -10
  120. data/ext/v8/v8_script.cpp +0 -36
  121. data/ext/v8/v8_script.h +0 -8
  122. data/ext/v8/v8_string.cpp +0 -52
  123. data/ext/v8/v8_string.h +0 -9
  124. data/ext/v8/v8_template.cpp +0 -344
  125. data/ext/v8/v8_template.h +0 -8
  126. data/ext/v8/v8_try_catch.cpp +0 -70
  127. data/ext/v8/v8_try_catch.h +0 -5
  128. data/ext/v8/v8_v8.cpp +0 -35
  129. data/ext/v8/v8_v8.h +0 -6
  130. data/ext/v8/v8_value.cpp +0 -175
  131. data/ext/v8/v8_value.h +0 -10
  132. data/ext/v8/v8_weakref.cpp +0 -61
  133. data/ext/v8/v8_weakref.h +0 -29
  134. data/lib/v8/c/locker.rb +0 -18
  135. data/lib/v8/cli.rb +0 -133
  136. data/lib/v8/portal.rb +0 -86
  137. data/lib/v8/portal/caller.rb +0 -37
  138. data/lib/v8/portal/constructor.rb +0 -98
  139. data/lib/v8/portal/function.rb +0 -63
  140. data/lib/v8/portal/interceptors.rb +0 -152
  141. data/lib/v8/portal/proxies.rb +0 -151
  142. data/lib/v8/portal/templates.rb +0 -73
  143. data/lib/v8/stack.rb +0 -66
  144. data/lib/v8/tap.rb +0 -9
  145. data/spec/ext/array_spec.rb +0 -15
  146. data/spec/ext/cxt_spec.rb +0 -57
  147. data/spec/ext/ext_spec_helper.rb +0 -27
  148. data/spec/ext/func_spec.rb +0 -64
  149. data/spec/ext/object_spec.rb +0 -10
  150. data/spec/ext/string_spec.rb +0 -11
  151. data/spec/ext/try_catch_spec.rb +0 -60
  152. data/spec/redjs_helper.rb +0 -3
  153. data/spec/v8/portal/proxies_spec.rb +0 -106
  154. data/specmem/handle_memspec.rb +0 -41
  155. data/specmem/object_memspec.rb +0 -14
  156. data/specmem/proxies_memspec.rb +0 -49
  157. data/specmem/spec_helper.rb +0 -24
  158. data/specthread/spec_helper.rb +0 -2
  159. data/specthread/threading_spec.rb +0 -13
@@ -1,73 +0,0 @@
1
-
2
- module V8
3
- class Portal
4
- class Templates
5
-
6
- attr_reader :portal
7
-
8
- def initialize(portal)
9
- @portal = portal
10
- @constructors = {}
11
- @methods = {}
12
- @procs = {}
13
- @releases = {}
14
- end
15
-
16
- def to_constructor(ruby_class)
17
- class_id = ruby_class.object_id
18
- if constructor = @constructors[class_id]
19
- return constructor
20
- else
21
- constructor = @constructors[class_id] = ConstructorAdapter.new(self, class_id)
22
- ObjectSpace.define_finalizer(ruby_class, release(@constructors, class_id))
23
- return constructor
24
- end
25
- end
26
-
27
- def to_function(code)
28
- case code
29
- when Method, UnboundMethod
30
- if fn = @methods[code.to_s]
31
- return fn
32
- else
33
- function = @methods[code.to_s] = FunctionAdapter.new(@portal, code)
34
- #TODO: test this weak behavior
35
- function.template.MakeWeak(0, release(@methods, code.to_s))
36
- return function
37
- end
38
- else
39
- if fn = @procs[code]
40
- return fn
41
- else
42
- function = @procs[code] = FunctionAdapter.new(@portal, code)
43
- #TODO: test this weak behavior
44
- function.template.MakeWeak(0, release(@procs, code))
45
- return function
46
- end
47
- end
48
- end
49
-
50
- def proxies
51
- @portal.proxies
52
- end
53
-
54
- def release(refs, id)
55
- release = Release.new(@releases, refs, id)
56
- @releases[release] = true
57
- return release
58
- end
59
-
60
- class Release
61
- def initialize(releases, refs, id)
62
- @releases, @refs, @id = releases, refs, id
63
- end
64
-
65
- def call(*args)
66
- @refs.delete(@id)
67
- @releases.delete(self)
68
- end
69
-
70
- end
71
- end
72
- end
73
- end
data/lib/v8/stack.rb DELETED
@@ -1,66 +0,0 @@
1
-
2
- module V8
3
-
4
- class StackTrace
5
- include Enumerable
6
-
7
- def initialize(to, native)
8
- @to = to
9
- @native = native
10
- end
11
-
12
- def length
13
- @native.GetFrameCount()
14
- end
15
-
16
- def each
17
- for i in 0..length - 1
18
- yield V8::StackFrame.new(@to, @native.GetFrame(i))
19
- end
20
- end
21
-
22
- def to_s
23
- map {|f|"at #{f}"}.join("\n")
24
- end
25
- end
26
-
27
- class StackFrame
28
-
29
- def initialize(portal, native)
30
- @to = portal
31
- @native = native
32
- end
33
-
34
- def script_name
35
- @to.rb(@native.GetScriptName())
36
- end
37
-
38
- def function_name
39
- @to.rb(@native.GetFunctionName())
40
- end
41
-
42
- def line_number
43
- @native.GetLineNumber()
44
- end
45
-
46
- def column
47
- @native.GetColumn()
48
- end
49
-
50
- def eval?
51
- @native.IsEval()
52
- end
53
-
54
- def constructor?
55
- @native.IsConstructor()
56
- end
57
-
58
- def to_s
59
- if @native.GetFunctionName()
60
- "#{function_name} (#{script_name}:#{line_number}:#{column})"
61
- else
62
- "#{script_name}:#{line_number}:#{column}"
63
- end
64
- end
65
- end
66
- end
data/lib/v8/tap.rb DELETED
@@ -1,9 +0,0 @@
1
-
2
- unless Object.method_defined?(:tap)
3
- class Object
4
- def tap
5
- yield self
6
- return self
7
- end
8
- end
9
- end
@@ -1,15 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe V8::C::Array do
4
- include V8::ExtSpec
5
-
6
- it "can be instantiated" do
7
- a = c::Array::New()
8
- a.Length().should eql(0)
9
- end
10
-
11
- it "maintains referential integrity" do
12
- v8_eval('a = []')
13
- v8_eval('a').should be(v8_eval('a'))
14
- end
15
- end
data/spec/ext/cxt_spec.rb DELETED
@@ -1,57 +0,0 @@
1
-
2
- require "#{File.dirname(__FILE__)}/../spec_helper.rb"
3
-
4
- include V8
5
-
6
- describe C::Context do
7
-
8
- before {@lock = C::Locker.new}
9
- after {@lock.delete}
10
-
11
- it "should not have a current context if no context is open" do
12
- C::Context::GetEntered().should be_nil
13
- end
14
-
15
- it "can javascript properties on the global scope via ruby when the default scope is a ruby object" do
16
- V8::Context.new(:with => Object.new) do |cxt|
17
- cxt['foo'] = 'bar'
18
- cxt.eval('foo').should eql('bar')
19
- end
20
- end
21
-
22
- it "can get the current javascript execution stack" do
23
- V8::Context.new do |cxt|
24
- trace = nil
25
- cxt['getTrace'] = lambda do
26
- trace = V8::Context.stack
27
- end
28
- cxt.eval(<<-JS, 'trace.js')
29
- function one() {
30
- return two();
31
- }
32
-
33
- function two() {
34
- return three();
35
- }
36
-
37
- function three() {
38
- return getTrace()
39
- }
40
- one();
41
- JS
42
- trace.length.should be(4)
43
- trace.to_a[0].tap do |frame|
44
- frame.line_number.should == 10
45
- frame.column.should == 16
46
- frame.script_name.should == 'trace.js'
47
- frame.function_name.should == 'three'
48
- frame.should_not be_eval
49
- frame.should_not be_constructor
50
- end
51
- end
52
- end
53
-
54
- it "has an empty stack if there is no enterned context" do
55
- V8::Context.stack.should be_empty
56
- end
57
- end
@@ -1,27 +0,0 @@
1
-
2
- module V8::ExtSpec
3
-
4
- def self.included(object)
5
- object.class_eval do
6
- before do
7
- @lock = c::Locker.new
8
- @cxt = c::Context::New()
9
- @cxt.Enter()
10
- end
11
- after do
12
- @cxt.Exit()
13
- @cxt.Dispose()
14
- @lock.delete
15
- end
16
- end
17
- end
18
-
19
- def v8_eval(script, sourcename = "<eval>")
20
- c::Script::New(c::String::New(script), c::String::New(sourcename)).Run()
21
- end
22
-
23
- def c
24
- V8::C
25
- end
26
-
27
- end
@@ -1,64 +0,0 @@
1
- require "#{File.dirname(__FILE__)}/../spec_helper.rb"
2
-
3
- include V8
4
-
5
- describe C::Function do
6
- it "is callable" do
7
- Context.new do |cxt|
8
- f = cxt.eval('(function() {return "Hello World"})', '<eval>');
9
- f.call().should == "Hello World"
10
- end
11
- end
12
-
13
- it "receives proper argument length from ruby" do
14
- Context.new do |cxt|
15
- f = cxt.eval('(function() {return arguments.length})', 'eval')
16
- f.call(1, 2, 3).should == 3
17
- end
18
- end
19
-
20
- it "maps all arguments from ruby" do
21
- Context.new do |cxt|
22
- f = cxt.eval('(function(one, two, three) {return one + two + three})', 'eval')
23
- f.call(1,2,3).should == 6
24
- end
25
- end
26
-
27
- it "properly maps ruby objects back and forth from arguments to return value" do
28
- Context.new do |cxt|
29
- Object.new.tap do |this|
30
- f = cxt.eval('(function() {return this})', 'eval')
31
- f.methodcall(this).should be(this)
32
- end
33
- end
34
- end
35
-
36
- it "can be called outside of a context" do
37
- Context.new do |cxt|
38
- @f = cxt.eval('(function() {return "Call Me"})', 'eval')
39
- end
40
- @f.call().should == "Call Me"
41
- end
42
-
43
- it "is reflected properly" do
44
- Context.new do |cxt|
45
- cxt['say'] = lambda {|this, word, times| word * times}
46
- cxt.eval('say("Hello", 3)').should == "HelloHelloHello"
47
- end
48
- end
49
-
50
- it "has a name" do
51
- Context.new do |cxt|
52
- f = cxt.eval('(function hi() {return "Hello World"})', '<eval>')
53
- f.name.should == "hi"
54
- end
55
- end
56
-
57
- it "can have its name set" do
58
- Context.new do |cxt|
59
- f = cxt.eval('(function () {return "Goodbye World"})', '<eval>')
60
- f.name = 'bye'
61
- f.name.should == 'bye'
62
- end
63
- end
64
- end
@@ -1,10 +0,0 @@
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
@@ -1,11 +0,0 @@
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
@@ -1,60 +0,0 @@
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
data/spec/redjs_helper.rb DELETED
@@ -1,3 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
-
3
- include V8
@@ -1,106 +0,0 @@
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