therubyracer-xcode 0.12.2

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 (92) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/.travis.yml +14 -0
  4. data/Changelog.md +263 -0
  5. data/Gemfile +12 -0
  6. data/README.md +227 -0
  7. data/Rakefile +42 -0
  8. data/benchmarks.rb +218 -0
  9. data/ext/v8/accessor.cc +181 -0
  10. data/ext/v8/array.cc +26 -0
  11. data/ext/v8/backref.cc +45 -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 +34 -0
  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 +35 -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 +335 -0
  28. data/ext/v8/primitive.cc +8 -0
  29. data/ext/v8/rr.cc +83 -0
  30. data/ext/v8/rr.h +934 -0
  31. data/ext/v8/script.cc +115 -0
  32. data/ext/v8/signature.cc +18 -0
  33. data/ext/v8/stack.cc +76 -0
  34. data/ext/v8/string.cc +47 -0
  35. data/ext/v8/template.cc +175 -0
  36. data/ext/v8/trycatch.cc +87 -0
  37. data/ext/v8/v8.cc +87 -0
  38. data/ext/v8/value.cc +239 -0
  39. data/lib/therubyracer.rb +1 -0
  40. data/lib/v8/access/indices.rb +40 -0
  41. data/lib/v8/access/invocation.rb +47 -0
  42. data/lib/v8/access/names.rb +65 -0
  43. data/lib/v8/access.rb +5 -0
  44. data/lib/v8/array.rb +26 -0
  45. data/lib/v8/context.rb +258 -0
  46. data/lib/v8/conversion/array.rb +11 -0
  47. data/lib/v8/conversion/class.rb +119 -0
  48. data/lib/v8/conversion/code.rb +38 -0
  49. data/lib/v8/conversion/fixnum.rb +11 -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/conversion.rb +36 -0
  62. data/lib/v8/error.rb +169 -0
  63. data/lib/v8/function.rb +28 -0
  64. data/lib/v8/object.rb +79 -0
  65. data/lib/v8/stack.rb +85 -0
  66. data/lib/v8/version.rb +3 -0
  67. data/lib/v8/weak.rb +82 -0
  68. data/lib/v8.rb +30 -0
  69. data/spec/c/array_spec.rb +19 -0
  70. data/spec/c/constants_spec.rb +22 -0
  71. data/spec/c/exception_spec.rb +28 -0
  72. data/spec/c/external_spec.rb +11 -0
  73. data/spec/c/function_spec.rb +48 -0
  74. data/spec/c/handles_spec.rb +31 -0
  75. data/spec/c/locker_spec.rb +36 -0
  76. data/spec/c/object_spec.rb +47 -0
  77. data/spec/c/script_spec.rb +30 -0
  78. data/spec/c/string_spec.rb +18 -0
  79. data/spec/c/template_spec.rb +31 -0
  80. data/spec/c/trycatch_spec.rb +52 -0
  81. data/spec/mem/blunt_spec.rb +42 -0
  82. data/spec/redjs_spec.rb +10 -0
  83. data/spec/spec_helper.rb +41 -0
  84. data/spec/threading_spec.rb +64 -0
  85. data/spec/v8/context_spec.rb +19 -0
  86. data/spec/v8/conversion_spec.rb +52 -0
  87. data/spec/v8/error_spec.rb +167 -0
  88. data/spec/v8/function_spec.rb +9 -0
  89. data/spec/v8/object_spec.rb +15 -0
  90. data/thefrontside.png +0 -0
  91. data/therubyracer.gemspec +22 -0
  92. metadata +186 -0
data/lib/v8/stack.rb ADDED
@@ -0,0 +1,85 @@
1
+
2
+ module V8
3
+
4
+ class StackTrace
5
+ include Enumerable
6
+
7
+ def initialize(native)
8
+ @context = V8::Context.current
9
+ @native = native
10
+ end
11
+
12
+ def length
13
+ @context.enter do
14
+ @native ? @native.GetFrameCount() : 0
15
+ end
16
+ end
17
+
18
+ def each
19
+ return unless @native
20
+ @context.enter do
21
+ for i in 0..length - 1
22
+ yield V8::StackFrame.new(@native.GetFrame(i), @context)
23
+ end
24
+ end
25
+ end
26
+
27
+ def to_s
28
+ @native ? map(&:to_s).join("\n") : ""
29
+ end
30
+ end
31
+
32
+ class StackFrame
33
+
34
+ def initialize(native, context)
35
+ @context = context
36
+ @native = native
37
+ end
38
+
39
+ def script_name
40
+ @context.enter do
41
+ @context.to_ruby(@native.GetScriptName())
42
+ end
43
+ end
44
+
45
+ def function_name
46
+ @context.enter do
47
+ @context.to_ruby(@native.GetFunctionName())
48
+ end
49
+ end
50
+
51
+ def line_number
52
+ @context.enter do
53
+ @native.GetLineNumber()
54
+ end
55
+ end
56
+
57
+ def column
58
+ @context.enter do
59
+ @native.GetColumn()
60
+ end
61
+ end
62
+
63
+ def eval?
64
+ @context.enter do
65
+ @native.IsEval()
66
+ end
67
+ end
68
+
69
+ def constructor?
70
+ @context.enter do
71
+ @native.IsConstructor()
72
+ end
73
+ end
74
+
75
+ def to_s
76
+ @context.enter do
77
+ "at " + if !function_name.empty?
78
+ "#{function_name} (#{script_name}:#{line_number}:#{column})"
79
+ else
80
+ "#{script_name}:#{line_number}:#{column}"
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
data/lib/v8/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module V8
2
+ VERSION = "0.12.2"
3
+ end
data/lib/v8/weak.rb ADDED
@@ -0,0 +1,82 @@
1
+ module V8
2
+ module Weak
3
+ # weak refs are broken on MRI 1.9 and merely slow on 1.8
4
+ # so we mitigate this by using the 'ref' gem. However, this
5
+ # only mitigates the problem. Under heavy load, you will still
6
+ # get different or terminated objects being returned. bad stuff.
7
+ #
8
+ # If you are having problems with this, an upgrade to 2.0 is *highly*
9
+ # recommended.
10
+ #
11
+ # for other platforms we just use the stdlib 'weakref'
12
+ # implementation
13
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ruby' && RUBY_VERSION < '2.0.0'
14
+ require 'ref'
15
+ Ref = ::Ref::WeakReference
16
+ WeakValueMap = ::Ref::WeakValueMap
17
+ else
18
+ require 'weakref'
19
+ class Ref
20
+ def initialize(object)
21
+ @ref = ::WeakRef.new(object)
22
+ end
23
+ def object
24
+ @ref.__getobj__
25
+ rescue ::WeakRef::RefError
26
+ nil
27
+ end
28
+ end
29
+
30
+ class WeakValueMap
31
+ def initialize
32
+ @values = {}
33
+ end
34
+
35
+ def [](key)
36
+ if ref = @values[key]
37
+ ref.object
38
+ end
39
+ end
40
+
41
+ def []=(key, value)
42
+ ref = V8::Weak::Ref.new(value)
43
+ ObjectSpace.define_finalizer(value, self.class.ensure_cleanup(@values, key, ref))
44
+
45
+ @values[key] = ref
46
+ end
47
+
48
+ def self.ensure_cleanup(values,key,ref)
49
+ proc {
50
+ values.delete(key) if values[key] == ref
51
+ }
52
+ end
53
+ end
54
+ end
55
+
56
+ module Cell
57
+ def weakcell(name, &block)
58
+ unless storage = instance_variable_get("@#{name}")
59
+ storage = instance_variable_set("@#{name}", Storage.new)
60
+ end
61
+ storage.access(&block)
62
+ end
63
+ class Storage
64
+ def access(&block)
65
+ if @ref
66
+ @ref.object || populate(block)
67
+ else
68
+ populate(block)
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ def populate(block)
75
+ occupant = block.call()
76
+ @ref = V8::Weak::Ref.new(occupant)
77
+ return occupant
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
data/lib/v8.rb ADDED
@@ -0,0 +1,30 @@
1
+ require "v8/version"
2
+
3
+ require 'v8/weak'
4
+ require 'v8/init'
5
+ require 'v8/error'
6
+ require 'v8/stack'
7
+ require 'v8/conversion/fundamental'
8
+ require 'v8/conversion/indentity'
9
+ require 'v8/conversion/reference'
10
+ require 'v8/conversion/primitive'
11
+ require 'v8/conversion/code'
12
+ require 'v8/conversion/class'
13
+ require 'v8/conversion/object'
14
+ require 'v8/conversion/time'
15
+ require 'v8/conversion/hash'
16
+ require 'v8/conversion/array'
17
+ require 'v8/conversion/proc'
18
+ require 'v8/conversion/method'
19
+ require 'v8/conversion/symbol'
20
+ require 'v8/conversion/string'
21
+ require 'v8/conversion/fixnum'
22
+ require 'v8/conversion'
23
+ require 'v8/access/names'
24
+ require 'v8/access/indices'
25
+ require 'v8/access/invocation'
26
+ require 'v8/access'
27
+ require 'v8/context'
28
+ require 'v8/object'
29
+ require 'v8/array'
30
+ require 'v8/function'
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C::Array do
4
+ requires_v8_context
5
+
6
+ it "can store and retrieve a value" do
7
+ o = V8::C::Object::New()
8
+ a = V8::C::Array::New()
9
+ a.Length().should eql 0
10
+ a.Set(0, o)
11
+ a.Length().should eql 1
12
+ a.Get(0).Equals(o).should be_truthy
13
+ end
14
+
15
+ it "can be initialized with a length" do
16
+ a = V8::C::Array::New(5)
17
+ a.Length().should eql 5
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C do
4
+ requires_v8_context
5
+
6
+ it "has constant methods for Undefined, Null, True and False" do
7
+ [:Undefined, :Null, :True, :False].each do |name|
8
+ constant = V8::C.send(name)
9
+ constant.should_not be_nil
10
+ V8::C.send(name).should be constant
11
+ end
12
+ end
13
+
14
+ it "has a value for the Empty handle" do
15
+ V8::C::Value::Empty.should_not be_nil
16
+ V8::C::Value::Empty.should be V8::C::Value::Empty
17
+ end
18
+
19
+ it "can access the V8 version" do
20
+ V8::C::V8::GetVersion().should match /^3\.16/
21
+ end
22
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C::Exception do
4
+ requires_v8_context
5
+
6
+ it "can be thrown from Ruby" do
7
+ t = V8::C::FunctionTemplate::New(method(:explode))
8
+ @cxt.Global().Set("explode", t.GetFunction())
9
+ script = V8::C::Script::New(<<-JS, '<eval>')
10
+ (function() {
11
+ try {
12
+ explode()
13
+ } catch (e) {
14
+ return e.message
15
+ }
16
+ })()
17
+ JS
18
+ result = script.Run()
19
+ result.should_not be_nil
20
+ result.should be_kind_of(V8::C::String)
21
+ result.Utf8Value().should eql 'did not pay syntax'
22
+ end
23
+
24
+ def explode(arguments)
25
+ error = V8::C::Exception::SyntaxError('did not pay syntax')
26
+ V8::C::ThrowException(error)
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C::External do
4
+ requires_v8_context
5
+
6
+ it "can store and retrieve a value" do
7
+ o = Object.new
8
+ external = V8::C::External::New(o)
9
+ external.Value().should be(o)
10
+ end
11
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C::Function do
4
+ requires_v8_context
5
+
6
+ it "can be called" do
7
+ fn = run '(function() {return "foo"})'
8
+ fn.Call(@cxt.Global(), []).Utf8Value().should eql "foo"
9
+ end
10
+
11
+ it "can be called with arguments and context" do
12
+ fn = run '(function(one, two, three) {this.one = one; this.two = two; this.three = three})'
13
+ one = V8::C::Object::New()
14
+ two = V8::C::Object::New()
15
+ fn.Call(@cxt.Global(), [one, two, 3])
16
+ @cxt.Global().Get("one").should eql one
17
+ @cxt.Global().Get("two").should eql two
18
+ @cxt.Global().Get("three").should eql 3
19
+ end
20
+
21
+ it "can be called as a constructor" do
22
+ fn = run '(function() {this.foo = "foo"})'
23
+ fn.NewInstance().Get(V8::C::String::New('foo')).Utf8Value().should eql "foo"
24
+ end
25
+
26
+ it "can be called as a constructor with arguments" do
27
+ fn = run '(function(foo) {this.foo = foo})'
28
+ object = fn.NewInstance([V8::C::String::New("bar")])
29
+ object.Get(V8::C::String::New('foo')).Utf8Value().should eql "bar"
30
+ end
31
+
32
+ it "doesn't kill the world if invoking it throws a javascript exception" do
33
+ V8::C::TryCatch() do
34
+ fn = run '(function() { throw new Error("boom!")})'
35
+ fn.Call(@cxt.Global(), [])
36
+ fn.NewInstance([])
37
+ end
38
+ end
39
+
40
+
41
+ def run(source)
42
+ source = V8::C::String::New(source.to_s)
43
+ filename = V8::C::String::New("<eval>")
44
+ script = V8::C::Script::New(source, filename)
45
+ result = script.Run()
46
+ result.kind_of?(V8::C::String) ? result.Utf8Value() : result
47
+ end
48
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe "setting up handles scopes" do
4
+ around(:each) do |example|
5
+ V8::C::Locker() do
6
+ cxt = V8::C::Context::New()
7
+ begin
8
+ cxt.Enter()
9
+ example.run
10
+ ensure
11
+ cxt.Exit()
12
+ end
13
+ end
14
+ end
15
+
16
+ it "can allocate handle scopes" do
17
+ V8::C::HandleScope() do
18
+ V8::C::Object::New()
19
+ end.class.should eql V8::C::Object
20
+ end
21
+
22
+ it "isn't the end of the world if a ruby exception is raised inside a HandleScope" do
23
+ begin
24
+ V8::C::HandleScope() do
25
+ raise "boom!"
26
+ end
27
+ rescue StandardError => e
28
+ e.message.should eql "boom!"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C::Locker do
4
+ it "can lock and unlock the VM" do
5
+ V8::C::Locker::IsLocked().should be_falsey
6
+ V8::C::Locker() do
7
+ V8::C::Locker::IsLocked().should be_truthy
8
+ V8::C::Unlocker() do
9
+ V8::C::Locker::IsLocked().should be_falsey
10
+ end
11
+ end
12
+ V8::C::Locker::IsLocked().should be_falsey
13
+ end
14
+
15
+ it "properly unlocks if an exception is thrown inside a lock block" do
16
+ begin
17
+ V8::C::Locker() do
18
+ raise "boom!"
19
+ end
20
+ rescue
21
+ V8::C::Locker::IsLocked().should be_falsey
22
+ end
23
+ end
24
+
25
+ it "properly re-locks if an exception is thrown inside an un-lock block" do
26
+ V8::C::Locker() do
27
+ begin
28
+ V8::C::Unlocker() do
29
+ raise "boom!"
30
+ end
31
+ rescue
32
+ V8::C::Locker::IsLocked().should be_truthy
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C::Object do
4
+ requires_v8_context
5
+
6
+ it "can store and retrieve a value" do
7
+ o = V8::C::Object::New()
8
+ key = V8::C::String::New("foo")
9
+ value = V8::C::String::New("bar")
10
+ o.Set(key, value)
11
+ o.Get(key).Utf8Value().should eql "bar"
12
+ end
13
+
14
+ it "can retrieve all property names" do
15
+ o = V8::C::Object::New()
16
+ o.Set(V8::C::String::New("foo"), V8::C::String::New("bar"))
17
+ o.Set(V8::C::String::New("baz"), V8::C::String::New("bang"))
18
+ names = o.GetPropertyNames()
19
+ names.Length().should eql 2
20
+ names.Get(0).Utf8Value().should eql "foo"
21
+ names.Get(1).Utf8Value().should eql "baz"
22
+ end
23
+ it "can set an accessor from ruby" do
24
+ o = V8::C::Object::New()
25
+ property = V8::C::String::New("statement")
26
+ callback_data = V8::C::String::New("I am Legend")
27
+ left = V8::C::String::New("Yo! ")
28
+ getter = proc do |name, info|
29
+ info.This().StrictEquals(o).should be_truthy
30
+ info.Holder().StrictEquals(o).should be_truthy
31
+ V8::C::String::Concat(left, info.Data())
32
+ end
33
+ setter = proc do |name, value, info|
34
+ left = value
35
+ end
36
+ o.SetAccessor(property, getter, setter, callback_data)
37
+ o.Get(property).Utf8Value().should eql "Yo! I am Legend"
38
+ o.Set(property, V8::C::String::New("Bro! "))
39
+ o.Get(property).Utf8Value().should eql "Bro! I am Legend"
40
+ end
41
+ it "always returns the same ruby object for the same V8 object" do
42
+ one = V8::C::Object::New()
43
+ two = V8::C::Object::New()
44
+ one.Set("two", two)
45
+ one.Get("two").should be two
46
+ end
47
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ describe V8::C::Script do
5
+ requires_v8_context
6
+
7
+ it "can run a script and return a polymorphic result" do
8
+ source = V8::C::String::New("(new Array())")
9
+ filename = V8::C::String::New("<eval>")
10
+ script = V8::C::Script::New(source, filename)
11
+ result = script.Run()
12
+ result.should be_kind_of V8::C::Array
13
+ end
14
+
15
+ it "can accept precompiled script data" do
16
+ source = "7 * 6"
17
+ name = V8::C::String::New("<spec>")
18
+ origin = V8::C::ScriptOrigin.new(name)
19
+ data = V8::C::ScriptData::PreCompile(source, source.length)
20
+ data.HasError().should be_falsey
21
+ script = V8::C::Script::New(V8::C::String::New(source), origin, data)
22
+ script.Run().should eql 42
23
+ end
24
+
25
+ it "can detect errors in the script data" do
26
+ source = "^ = ;"
27
+ data = V8::C::ScriptData::PreCompile(source, source.length)
28
+ data.HasError().should be_truthy
29
+ end
30
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C::String do
4
+ requires_v8_context
5
+
6
+ it "can hold Unicode values outside the Basic Multilingual Plane" do
7
+ string = V8::C::String::New("\u{100000}")
8
+ string.Utf8Value().should eql "\u{100000}"
9
+ end
10
+
11
+ it "can naturally translate ruby strings into v8 strings" do
12
+ V8::C::String::Concat(V8::C::String::New("Hello "), "World").Utf8Value().should eql "Hello World"
13
+ end
14
+
15
+ it "can naturally translate ruby objects into v8 strings" do
16
+ V8::C::String::Concat(V8::C::String::New("forty two is "), 42).Utf8Value().should eql "forty two is 42"
17
+ end
18
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C::Template do
4
+ requires_v8_context
5
+
6
+ describe V8::C::FunctionTemplate do
7
+ it "can be created with no arguments" do
8
+ t = V8::C::FunctionTemplate::New()
9
+ t.GetFunction().Call(@cxt.Global(),[]).StrictEquals(@cxt.Global()).should be_truthy
10
+ end
11
+
12
+ it "can be created with a callback" do
13
+ receiver = V8::C::Object::New()
14
+ f = nil
15
+ callback = lambda do |arguments|
16
+ arguments.Length().should be(2)
17
+ arguments[0].Utf8Value().should eql 'one'
18
+ arguments[1].Utf8Value().should eql 'two'
19
+ arguments.Callee().StrictEquals(f).should be_truthy
20
+ arguments.This().StrictEquals(receiver).should be_truthy
21
+ arguments.Holder().StrictEquals(receiver).should be_truthy
22
+ arguments.IsConstructCall().should be_falsey
23
+ arguments.Data().Value().should be(42)
24
+ V8::C::String::New("result")
25
+ end
26
+ t = V8::C::FunctionTemplate::New(callback, V8::C::External::New(42))
27
+ f = t.GetFunction()
28
+ f.Call(receiver, [V8::C::String::New('one'), V8::C::String::New('two')]).Utf8Value().should eql "result"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C::External do
4
+ requires_v8_context
5
+
6
+ it "can catch javascript exceptions" do
7
+ V8::C::V8::SetCaptureStackTraceForUncaughtExceptions(true, 99, V8::C::StackTrace::kDetailed)
8
+ V8::C::TryCatch() do |trycatch|
9
+ source = V8::C::String::New(<<-JS)
10
+ function one() {
11
+ two()
12
+ }
13
+ function two() {
14
+ three()
15
+ }
16
+ function three() {
17
+ boom()
18
+ }
19
+ function boom() {
20
+ throw new Error('boom!')
21
+ }
22
+ eval('one()')
23
+ JS
24
+ filename = V8::C::String::New("<eval>")
25
+ script = V8::C::Script::New(source, filename)
26
+ result = script.Run()
27
+ trycatch.HasCaught().should be_truthy
28
+ trycatch.CanContinue().should be_truthy
29
+ exception = trycatch.Exception()
30
+ exception.should_not be_nil
31
+ exception.IsNativeError().should be_truthy
32
+ trycatch.StackTrace().Utf8Value().should match /boom.*three.*two.*one/m
33
+ message = trycatch.Message();
34
+ message.should_not be_nil
35
+ message.Get().Utf8Value().should eql "Uncaught Error: boom!"
36
+ message.GetSourceLine().Utf8Value().should eql " throw new Error('boom!')"
37
+ message.GetScriptResourceName().Utf8Value().should eql "<eval>"
38
+ message.GetLineNumber().should eql 11
39
+ stack = message.GetStackTrace()
40
+ stack.should_not be_nil
41
+ stack.GetFrameCount().should eql 6
42
+ frame = stack.GetFrame(0)
43
+ frame.GetLineNumber().should eql 11
44
+ frame.GetColumn().should eql 15
45
+ frame.GetScriptName().Utf8Value().should eql "<eval>"
46
+ frame.GetScriptNameOrSourceURL().Utf8Value().should eql "<eval>"
47
+ frame.IsEval().should be_falsey
48
+ stack.GetFrame(4).IsEval().should be_truthy
49
+ frame.IsConstructor().should be_falsey
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe "A Very blunt test to make sure that we aren't doing stupid leaks", :memory => true do
4
+ before do
5
+ if Object.const_defined?(:RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
6
+ pending 'need to figure out how to do memory sanity checks on rbx'
7
+ end
8
+ #allocate a single context to make sure that v8 loads its snapshot and
9
+ #we pay the overhead.
10
+ V8::Context.new
11
+ @start_memory = process_memory
12
+ GC.stress = true
13
+ end
14
+
15
+ after do
16
+ GC.stress = false
17
+ end
18
+ it "won't increase process memory by more than 50% no matter how many contexts we create" do
19
+ 500.times do
20
+ V8::Context.new
21
+ run_v8_gc
22
+ end
23
+ process_memory.should <= @start_memory * 1.5
24
+ end
25
+
26
+ it "can eval simple value passing statements repeatedly without significantly increasing memory" do
27
+ V8::C::Locker() do
28
+ cxt = V8::Context.new
29
+ 500.times do
30
+ cxt.eval('7 * 6')
31
+ run_v8_gc
32
+ end
33
+ end
34
+ process_memory.should <= @start_memory * 1.1
35
+ end
36
+
37
+ def process_memory
38
+ /\w*[ ]*#{Process.pid}[ ]*([.,\d]*)[ ]*([.,\d]*)[ ]*([\d]*)[ ]*([\d]*)/.match(`ps aux`)[4].to_i
39
+ end
40
+
41
+ end
42
+
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+ require 'redjs/load_specs'
3
+ module RedJS
4
+ Context = V8::Context
5
+ Error = V8::Error
6
+ end
7
+ describe V8::Context do
8
+ skip "not ready for prime-time"
9
+ #it_behaves_like 'RedJS::Context'
10
+ end
@@ -0,0 +1,41 @@
1
+ require 'v8'
2
+
3
+ def run_v8_gc
4
+ V8::C::V8::LowMemoryNotification()
5
+ while !V8::C::V8::IdleNotification() do
6
+ end
7
+ end
8
+
9
+ def rputs(msg)
10
+ puts "<pre>#{ERB::Util.h(msg)}</pre>"
11
+ $stdout.flush
12
+ end
13
+
14
+ module V8ContextHelpers
15
+ module GroupMethods
16
+ def requires_v8_context
17
+ around(:each) do |example|
18
+ bootstrap_v8_context(&example)
19
+ end
20
+ end
21
+ end
22
+
23
+ def bootstrap_v8_context
24
+ V8::C::Locker() do
25
+ V8::C::HandleScope() do
26
+ @cxt = V8::C::Context::New()
27
+ begin
28
+ @cxt.Enter()
29
+ yield
30
+ ensure
31
+ @cxt.Exit()
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ RSpec.configure do |c|
39
+ c.include V8ContextHelpers
40
+ c.extend V8ContextHelpers::GroupMethods
41
+ end