therubyracer-discourse 0.12.0

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 (91) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/.travis.yml +11 -0
  4. data/Changelog.md +247 -0
  5. data/Gemfile +9 -0
  6. data/README.md +176 -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/v8.rb +30 -0
  40. data/lib/v8/access.rb +5 -0
  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 +26 -0
  45. data/lib/v8/context.rb +256 -0
  46. data/lib/v8/conversion.rb +36 -0
  47. data/lib/v8/conversion/array.rb +11 -0
  48. data/lib/v8/conversion/class.rb +119 -0
  49. data/lib/v8/conversion/code.rb +38 -0
  50. data/lib/v8/conversion/fixnum.rb +11 -0
  51. data/lib/v8/conversion/fundamental.rb +11 -0
  52. data/lib/v8/conversion/hash.rb +11 -0
  53. data/lib/v8/conversion/indentity.rb +31 -0
  54. data/lib/v8/conversion/method.rb +26 -0
  55. data/lib/v8/conversion/object.rb +28 -0
  56. data/lib/v8/conversion/primitive.rb +7 -0
  57. data/lib/v8/conversion/proc.rb +5 -0
  58. data/lib/v8/conversion/reference.rb +16 -0
  59. data/lib/v8/conversion/string.rb +12 -0
  60. data/lib/v8/conversion/symbol.rb +7 -0
  61. data/lib/v8/conversion/time.rb +13 -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 +73 -0
  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 +45 -0
  83. data/spec/threading_spec.rb +64 -0
  84. data/spec/v8/context_spec.rb +19 -0
  85. data/spec/v8/conversion_spec.rb +52 -0
  86. data/spec/v8/error_spec.rb +165 -0
  87. data/spec/v8/function_spec.rb +9 -0
  88. data/spec/v8/object_spec.rb +15 -0
  89. data/thefrontside.png +0 -0
  90. data/therubyracer.gemspec +21 -0
  91. metadata +163 -0
@@ -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
@@ -0,0 +1,3 @@
1
+ module V8
2
+ VERSION = "0.12.0"
3
+ end
@@ -0,0 +1,73 @@
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
+ @values[key] = V8::Weak::Ref.new(value)
43
+ end
44
+ end
45
+ end
46
+
47
+ module Cell
48
+ def weakcell(name, &block)
49
+ unless storage = instance_variable_get("@#{name}")
50
+ storage = instance_variable_set("@#{name}", Storage.new)
51
+ end
52
+ storage.access(&block)
53
+ end
54
+ class Storage
55
+ def access(&block)
56
+ if @ref
57
+ @ref.object || populate(block)
58
+ else
59
+ populate(block)
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def populate(block)
66
+ occupant = block.call()
67
+ @ref = V8::Weak::Ref.new(occupant)
68
+ return occupant
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C::Array do
4
+ it "can store and retrieve a value" do
5
+ o = V8::C::Object::New()
6
+ a = V8::C::Array::New()
7
+ a.Length().should eql 0
8
+ a.Set(0, o)
9
+ a.Length().should eql 1
10
+ a.Get(0).Equals(o).should be_true
11
+ end
12
+
13
+ it "can be initialized with a length" do
14
+ a = V8::C::Array::New(5)
15
+ a.Length().should eql 5
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C do
4
+ it "has constant methods for Undefined, Null, True and False" do
5
+ [:Undefined, :Null, :True, :False].each do |name|
6
+ constant = V8::C.send(name)
7
+ constant.should_not be_nil
8
+ V8::C.send(name).should be constant
9
+ end
10
+ end
11
+
12
+ it "has a value for the Empty handle" do
13
+ V8::C::Value::Empty.should_not be_nil
14
+ V8::C::Value::Empty.should be V8::C::Value::Empty
15
+ end
16
+
17
+ it "can access the V8 version" do
18
+ V8::C::V8::GetVersion().should match /^3\.16/
19
+ end
20
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C::Exception do
4
+ it "can be thrown from Ruby" do
5
+ t = V8::C::FunctionTemplate::New(method(:explode))
6
+ @cxt.Global().Set("explode", t.GetFunction())
7
+ script = V8::C::Script::New(<<-JS, '<eval>')
8
+ (function() {
9
+ try {
10
+ explode()
11
+ } catch (e) {
12
+ return e.message
13
+ }
14
+ })()
15
+ JS
16
+ result = script.Run()
17
+ result.should_not be_nil
18
+ result.should be_kind_of(V8::C::String)
19
+ result.Utf8Value().should eql 'did not pay syntax'
20
+ end
21
+
22
+ def explode(arguments)
23
+ error = V8::C::Exception::SyntaxError('did not pay syntax')
24
+ V8::C::ThrowException(error)
25
+ end
26
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C::External do
4
+ it "can store and retrieve a value" do
5
+ o = Object.new
6
+ external = V8::C::External::New(o)
7
+ external.Value().should be(o)
8
+ end
9
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C::Function do
4
+ it "can be called" do
5
+ fn = run '(function() {return "foo"})'
6
+ fn.Call(@cxt.Global(), []).Utf8Value().should eql "foo"
7
+ end
8
+
9
+ it "can be called with arguments and context" do
10
+ fn = run '(function(one, two, three) {this.one = one; this.two = two; this.three = three})'
11
+ one = V8::C::Object::New()
12
+ two = V8::C::Object::New()
13
+ fn.Call(@cxt.Global(), [one, two, 3])
14
+ @cxt.Global().Get("one").should eql one
15
+ @cxt.Global().Get("two").should eql two
16
+ @cxt.Global().Get("three").should eql 3
17
+ end
18
+
19
+ it "can be called as a constructor" do
20
+ fn = run '(function() {this.foo = "foo"})'
21
+ fn.NewInstance().Get(V8::C::String::New('foo')).Utf8Value().should eql "foo"
22
+ end
23
+
24
+ it "can be called as a constructor with arguments" do
25
+ fn = run '(function(foo) {this.foo = foo})'
26
+ object = fn.NewInstance([V8::C::String::New("bar")])
27
+ object.Get(V8::C::String::New('foo')).Utf8Value().should eql "bar"
28
+ end
29
+
30
+ it "doesn't kill the world if invoking it throws a javascript exception" do
31
+ V8::C::TryCatch() do
32
+ fn = run '(function() { throw new Error("boom!")})'
33
+ fn.Call(@cxt.Global(), [])
34
+ fn.NewInstance([])
35
+ end
36
+ end
37
+
38
+
39
+ def run(source)
40
+ source = V8::C::String::New(source.to_s)
41
+ filename = V8::C::String::New("<eval>")
42
+ script = V8::C::Script::New(source, filename)
43
+ result = script.Run()
44
+ result.kind_of?(V8::C::String) ? result.Utf8Value() : result
45
+ end
46
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe "setting up handles scopes" do
4
+ include ExplicitScoper
5
+
6
+ before do
7
+ def self.instance_eval(*args, &block)
8
+ V8::C::Locker() do
9
+ cxt = V8::C::Context::New()
10
+ begin
11
+ cxt.Enter()
12
+ super(*args, &block)
13
+ ensure
14
+ cxt.Exit()
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ it "can allocate handle scopes" do
21
+ V8::C::HandleScope() do
22
+ V8::C::Object::New()
23
+ end.class.should eql V8::C::Object
24
+ end
25
+
26
+ it "isn't the end of the world if a ruby exception is raised inside a HandleScope" do
27
+ begin
28
+ V8::C::HandleScope() do
29
+ raise "boom!"
30
+ end
31
+ rescue StandardError => e
32
+ e.message.should eql "boom!"
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C::Locker do
4
+ include ExplicitScoper
5
+
6
+ it "can lock and unlock the VM" do
7
+ V8::C::Locker::IsLocked().should be_false
8
+ V8::C::Locker() do
9
+ V8::C::Locker::IsLocked().should be_true
10
+ V8::C::Unlocker() do
11
+ V8::C::Locker::IsLocked().should be_false
12
+ end
13
+ end
14
+ V8::C::Locker::IsLocked().should be_false
15
+ end
16
+
17
+ it "properly unlocks if an exception is thrown inside a lock block" do
18
+ begin
19
+ V8::C::Locker() do
20
+ raise "boom!"
21
+ end
22
+ rescue
23
+ V8::C::Locker::IsLocked().should be_false
24
+ end
25
+ end
26
+
27
+ it "properly re-locks if an exception is thrown inside an un-lock block" do
28
+ V8::C::Locker() do
29
+ begin
30
+ V8::C::Unlocker() do
31
+ raise "boom!"
32
+ end
33
+ rescue
34
+ V8::C::Locker::IsLocked().should be_true
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C::Object do
4
+
5
+ it "can store and retrieve a value" do
6
+ o = V8::C::Object::New()
7
+ key = V8::C::String::New("foo")
8
+ value = V8::C::String::New("bar")
9
+ o.Set(key, value)
10
+ o.Get(key).Utf8Value().should eql "bar"
11
+ end
12
+
13
+ it "can retrieve all property names" do
14
+ o = V8::C::Object::New()
15
+ o.Set(V8::C::String::New("foo"), V8::C::String::New("bar"))
16
+ o.Set(V8::C::String::New("baz"), V8::C::String::New("bang"))
17
+ names = o.GetPropertyNames()
18
+ names.Length().should eql 2
19
+ names.Get(0).Utf8Value().should eql "foo"
20
+ names.Get(1).Utf8Value().should eql "baz"
21
+ end
22
+ it "can set an accessor from ruby" do
23
+ o = V8::C::Object::New()
24
+ property = V8::C::String::New("statement")
25
+ callback_data = V8::C::String::New("I am Legend")
26
+ left = V8::C::String::New("Yo! ")
27
+ getter = proc do |name, info|
28
+ info.This().StrictEquals(o).should be_true
29
+ info.Holder().StrictEquals(o).should be_true
30
+ V8::C::String::Concat(left, info.Data())
31
+ end
32
+ setter = proc do |name, value, info|
33
+ left = value
34
+ end
35
+ o.SetAccessor(property, getter, setter, callback_data)
36
+ o.Get(property).Utf8Value().should eql "Yo! I am Legend"
37
+ o.Set(property, V8::C::String::New("Bro! "))
38
+ o.Get(property).Utf8Value().should eql "Bro! I am Legend"
39
+ end
40
+ it "always returns the same ruby object for the same V8 object" do
41
+ one = V8::C::Object::New()
42
+ two = V8::C::Object::New()
43
+ one.Set("two", two)
44
+ one.Get("two").should be two
45
+ end
46
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ describe V8::C::Script do
5
+ it "can run a script and return a polymorphic result" do
6
+ source = V8::C::String::New("(new Array())")
7
+ filename = V8::C::String::New("<eval>")
8
+ script = V8::C::Script::New(source, filename)
9
+ result = script.Run()
10
+ result.should be_kind_of V8::C::Array
11
+ end
12
+
13
+ it "can accept precompiled script data" do
14
+ source = "7 * 6"
15
+ name = V8::C::String::New("<spec>")
16
+ origin = V8::C::ScriptOrigin.new(name)
17
+ data = V8::C::ScriptData::PreCompile(source, source.length)
18
+ data.HasError().should be_false
19
+ script = V8::C::Script::New(V8::C::String::New(source), origin, data)
20
+ script.Run().should eql 42
21
+ end
22
+
23
+ it "can detect errors in the script data" do
24
+ source = "^ = ;"
25
+ data = V8::C::ScriptData::PreCompile(source, source.length)
26
+ data.HasError().should be_true
27
+ end
28
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe V8::C::String do
4
+ it "can hold Unicode values outside the Basic Multilingual Plane" do
5
+ string = V8::C::String::New("\u{100000}")
6
+ string.Utf8Value().should eql "\u{100000}"
7
+ end
8
+
9
+ it "can naturally translate ruby strings into v8 strings" do
10
+ V8::C::String::Concat(V8::C::String::New("Hello "), "World").Utf8Value().should eql "Hello World"
11
+ end
12
+
13
+ it "can naturally translate ruby objects into v8 strings" do
14
+ V8::C::String::Concat(V8::C::String::New("forty two is "), 42).Utf8Value().should eql "forty two is 42"
15
+ end
16
+ end