therubyracer-st 0.11.0beta5-x86-mingw32

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 (93) hide show
  1. data/.gitignore +23 -0
  2. data/.travis.yml +10 -0
  3. data/Changelog.md +242 -0
  4. data/Gemfile +15 -0
  5. data/README.md +185 -0
  6. data/Rakefile +58 -0
  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 +54 -0
  11. data/ext/v8/build.rb +53 -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 +23 -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 +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 +883 -0
  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 +36 -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 +243 -0
  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 +25 -0
  62. data/lib/v8/error/protect.rb +20 -0
  63. data/lib/v8/error/try.rb +15 -0
  64. data/lib/v8/function.rb +28 -0
  65. data/lib/v8/helper.rb +30 -0
  66. data/lib/v8/object.rb +79 -0
  67. data/lib/v8/util/weakcell.rb +29 -0
  68. data/lib/v8/version.rb +3 -0
  69. data/spec/c/array_spec.rb +17 -0
  70. data/spec/c/constants_spec.rb +20 -0
  71. data/spec/c/exception_spec.rb +26 -0
  72. data/spec/c/external_spec.rb +9 -0
  73. data/spec/c/function_spec.rb +46 -0
  74. data/spec/c/handles_spec.rb +35 -0
  75. data/spec/c/locker_spec.rb +38 -0
  76. data/spec/c/object_spec.rb +46 -0
  77. data/spec/c/script_spec.rb +28 -0
  78. data/spec/c/string_spec.rb +16 -0
  79. data/spec/c/template_spec.rb +30 -0
  80. data/spec/c/trycatch_spec.rb +51 -0
  81. data/spec/mem/blunt_spec.rb +42 -0
  82. data/spec/redjs_spec.rb +10 -0
  83. data/spec/spec_helper.rb +45 -0
  84. data/spec/threading_spec.rb +52 -0
  85. data/spec/v8/context_spec.rb +19 -0
  86. data/spec/v8/conversion_spec.rb +9 -0
  87. data/spec/v8/error_spec.rb +21 -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 +20 -0
  92. data/vendor/v8.dll +0 -0
  93. metadata +161 -0
@@ -0,0 +1,65 @@
1
+ require 'set'
2
+ class V8::Access
3
+ module Names
4
+ def names(obj)
5
+ accessible_names(obj)
6
+ end
7
+
8
+ def get(obj, name, &dontintercept)
9
+ methods = accessible_names(obj)
10
+ if methods.include?(name)
11
+ method = obj.method(name)
12
+ method.arity == 0 ? method.call : method.unbind
13
+ elsif obj.respond_to?(:[]) && !special?(name)
14
+ obj.send(:[], name, &dontintercept)
15
+ else
16
+ yield
17
+ end
18
+ end
19
+
20
+ def set(obj, name, value, &dontintercept)
21
+ setter = name + "="
22
+ methods = accessible_names(obj, true)
23
+ if methods.include?(setter)
24
+ obj.send(setter, value)
25
+ elsif obj.respond_to?(:[]=) && !special?(name)
26
+ obj.send(:[]=, name, value, &dontintercept)
27
+ else
28
+ yield
29
+ end
30
+ end
31
+
32
+ def query(obj, name, attributes, &dontintercept)
33
+ if obj.respond_to?(name)
34
+ attributes.dont_delete
35
+ unless obj.respond_to?(name + "=")
36
+ attributes.read_only
37
+ end
38
+ else
39
+ yield
40
+ end
41
+ end
42
+
43
+ def delete(obj, name, &dontintercept)
44
+ yield
45
+ end
46
+
47
+ def accessible_names(obj, special_methods = false)
48
+ obj.public_methods(false).map {|m| m.to_s}.to_set.tap do |methods|
49
+ ancestors = obj.class.ancestors.dup
50
+ while ancestor = ancestors.shift
51
+ break if ancestor == ::Object
52
+ methods.merge(ancestor.public_instance_methods(false).map {|m| m.to_s})
53
+ end
54
+ methods.reject!(&special?) unless special_methods
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def special?(name = nil)
61
+ @special ||= lambda {|m| m == "[]" || m == "[]=" || m =~ /=$/}
62
+ name.nil? ? @special : @special[name]
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,26 @@
1
+ class V8::Array < V8::Object
2
+
3
+ def initialize(native_or_length = nil)
4
+ super do
5
+ if native_or_length.is_a?(Numeric)
6
+ V8::C::Array::New(native_or_length)
7
+ elsif native_or_length.is_a?(V8::C::Array)
8
+ native_or_length
9
+ else
10
+ V8::C::Array::New()
11
+ end
12
+ end
13
+ end
14
+
15
+ def each
16
+ @context.enter do
17
+ 0.upto(@native.Length() - 1) do |i|
18
+ yield @context.to_ruby(@native.Get(i))
19
+ end
20
+ end
21
+ end
22
+
23
+ def length
24
+ @native.Length()
25
+ end
26
+ end
@@ -0,0 +1,243 @@
1
+ require 'stringio'
2
+ module V8
3
+ # All JavaScript must be executed in a context. This context consists of a global scope containing the
4
+ # standard JavaScript objects¨and functions like Object, String, Array, as well as any objects or
5
+ # functions from Ruby which have been embedded into it from the containing enviroment. E.g.
6
+ #
7
+ # V8::Context.new do |cxt|
8
+ # cxt['num'] = 5
9
+ # cxt.eval('num + 5') #=> 10
10
+ # end
11
+ #
12
+ # The same object may appear in any number of contexts, but only one context may be executing JavaScript code
13
+ # in any given thread. If a new context is opened in a thread in which a context is already opened, the second
14
+ # context will "mask" the old context e.g.
15
+ #
16
+ # six = 6
17
+ # Context.new do |cxt|
18
+ # cxt['num'] = 5
19
+ # cxt.eval('num') # => 5
20
+ # Context.new do |cxt|
21
+ # cxt['num'] = 10
22
+ # cxt.eval('num') # => 10
23
+ # cxt.eval('++num') # => 11
24
+ # end
25
+ # cxt.eval('num') # => 5
26
+ # end
27
+ class Context
28
+ include V8::Error::Try
29
+
30
+ # @!attribute [r] conversion
31
+ # @return [V8::Conversion] conversion behavior for this context
32
+ attr_reader :conversion
33
+
34
+ # @!attrribute [r] access
35
+ # @return [V8::Access] Ruby access behavior for this context
36
+ attr_reader :access
37
+
38
+ # @!attribute [r] native
39
+ # @return [V8::C::Context] the underlying C++ object
40
+ attr_reader :native
41
+
42
+ # Creates a new context.
43
+ #
44
+ # If passed the `:with` option, that object will be used as
45
+ # the global scope of the newly creating context. e.g.
46
+ #
47
+ # scope = Object.new
48
+ # def scope.hello; "Hi"; end
49
+ # V8::Context.new(:with => scope) do |cxt|
50
+ # cxt['hello'] #=> 'Hi'
51
+ # end
52
+ #
53
+ # @param [Hash<Symbol, Object>] options initial context configuration
54
+ # * :with scope serves as the global scope of the new context
55
+ # @yield [V8::Context] the newly created context
56
+ def initialize(options = {})
57
+ @conversion = Conversion.new
58
+ @access = Access.new
59
+ if global = options[:with]
60
+ Context.new.enter do
61
+ global_template = global.class.to_template.InstanceTemplate()
62
+ @native = V8::C::Context::New(nil, global_template)
63
+ end
64
+ enter {link global, @native.Global()}
65
+ else
66
+ @native = V8::C::Context::New()
67
+ end
68
+ yield self if block_given?
69
+ end
70
+
71
+ # Compile and execute a string of JavaScript source.
72
+ #
73
+ # If `source` is an IO object it will be read fully before being evaluated
74
+ #
75
+ # @param [String,IO] source the source code to compile and execute
76
+ # @param [String] filename the name to use for this code when generating stack traces
77
+ # @param [Integer] line the line number to start with
78
+ # @return [Object] the result of the evaluation
79
+ def eval(source, filename = '<eval>', line = 1)
80
+ if IO === source || StringIO === source
81
+ source = source.read
82
+ end
83
+ enter do
84
+ script = try { V8::C::Script::New(source.to_s, filename.to_s) }
85
+ to_ruby try {script.Run()}
86
+ end
87
+ end
88
+
89
+ # Read a value from the global scope of this context
90
+ #
91
+ # @param [Object] key the name of the value to read
92
+ # @return [Object] value the value at `key`
93
+ def [](key)
94
+ enter do
95
+ to_ruby(@native.Global().Get(to_v8(key)))
96
+ end
97
+ end
98
+
99
+ # Binds `value` to the name `key` in the global scope of this context.
100
+ #
101
+ # @param [Object] key the name to bind to
102
+ # @param [Object] value the value to bind
103
+ def []=(key, value)
104
+ enter do
105
+ @native.Global().Set(to_v8(key), to_v8(value))
106
+ end
107
+ return value
108
+ end
109
+
110
+ # Destroy this context and release any internal references it may
111
+ # contain to embedded Ruby objects.
112
+ #
113
+ # A disposed context may never again be used for anything, and all
114
+ # objects created with it will become unusable.
115
+ def dispose
116
+ return unless @native
117
+ @native.Dispose()
118
+ @native = nil
119
+ V8::C::V8::ContextDisposedNotification()
120
+ def self.enter
121
+ fail "cannot enter a context which has already been disposed"
122
+ end
123
+ end
124
+
125
+ # Returns this context's global object. This will be a `V8::Object`
126
+ # if no scope was provided or just an `Object` if a Ruby object
127
+ # is serving as the global scope.
128
+ #
129
+ # @return [Object] scope the context's global scope.
130
+ def scope
131
+ enter { to_ruby @native.Global() }
132
+ end
133
+
134
+ # Converts a v8 C++ object into its ruby counterpart. This is method
135
+ # is used to translate all values passed to Ruby from JavaScript, either
136
+ # as return values or as callback parameters.
137
+ #
138
+ # @param [V8::C::Object] v8_object the native c++ object to convert.
139
+ # @return [Object] to pass to Ruby
140
+ # @see V8::Conversion for how to customize and extend this mechanism
141
+ def to_ruby(v8_object)
142
+ @conversion.to_ruby(v8_object)
143
+ end
144
+
145
+ # Converts a Ruby object into a native v8 C++ object. This method is
146
+ # used to translate all values passed to JavaScript from Ruby, either
147
+ # as return value or as callback parameters.
148
+ #
149
+ # @param [Object] ruby_object the Ruby object to convert
150
+ # @return [V8::C::Object] to pass to V8
151
+ # @see V8::Conversion for customizing and extending this mechanism
152
+ def to_v8(ruby_object)
153
+ @conversion.to_v8(ruby_object)
154
+ end
155
+
156
+ # Marks a Ruby object and a v8 C++ Object as being the same. In other
157
+ # words whenever `ruby_object` is passed to v8, the result of the
158
+ # conversion should be `v8_object`. Conversely, whenever `v8_object`
159
+ # is passed to Ruby, the result of the conversion should be `ruby_object`.
160
+ # The Ruby Racer uses this mechanism to maintain referential integrity
161
+ # between Ruby and JavaScript peers
162
+ #
163
+ # @param [Object] ruby_object the Ruby half of the object identity
164
+ # @param [V8::C::Object] v8_object the V8 half of the object identity.
165
+ # @see V8::Conversion::Identity
166
+ def link(ruby_object, v8_object)
167
+ @conversion.equate ruby_object, v8_object
168
+ end
169
+
170
+ # Links `ruby_object` and `v8_object` inside the currently entered
171
+ # context. This is an error if no context has been entered.
172
+ #
173
+ # @param [Object] ruby_object the Ruby half of the object identity
174
+ # @param [V8::C::Object] v8_object the V8 half of the object identity.
175
+ def self.link(ruby_object, v8_object)
176
+ current.link ruby_object, v8_object
177
+ end
178
+
179
+ # Run some Ruby code in the context of this context.
180
+ #
181
+ # This will acquire the V8 interpreter lock (possibly blocking
182
+ # until it is available), and prepare V8 for JavaScript execution.
183
+ #
184
+ # Only one context may be running at a time per thread.
185
+ #
186
+ # @return [Object] the result of executing `block`
187
+ def enter(&block)
188
+ if !entered?
189
+ lock_scope_and_enter(&block)
190
+ else
191
+ yield
192
+ end
193
+ end
194
+
195
+ # Indicates if this context is the currently entered context
196
+ #
197
+ # @return true if this context is currently entered
198
+ def entered?
199
+ Context.current == self
200
+ end
201
+
202
+ # Get the currently entered context.
203
+ #
204
+ # @return [V8::Context] currently entered context, nil if none entered.
205
+ def self.current
206
+ Thread.current[:v8_context]
207
+ end
208
+
209
+ # Compile and execute the contents of the file with path `filename`
210
+ # as JavaScript code.
211
+ #
212
+ # @param [String] filename path to the file to execute.
213
+ # @return [Object] the result of the evaluation.
214
+ def load(filename)
215
+ File.open(filename) do |file|
216
+ self.eval file, filename
217
+ end
218
+ end
219
+
220
+ private
221
+
222
+ def self.current=(context)
223
+ Thread.current[:v8_context] = context
224
+ end
225
+
226
+ def lock_scope_and_enter
227
+ current = Context.current
228
+ Context.current = self
229
+ V8::C::Locker() do
230
+ V8::C::HandleScope() do
231
+ begin
232
+ @native.Enter()
233
+ yield if block_given?
234
+ ensure
235
+ @native.Exit()
236
+ end
237
+ end
238
+ end
239
+ ensure
240
+ Context.current = current
241
+ end
242
+ end
243
+ end
@@ -0,0 +1,35 @@
1
+
2
+ class V8::Conversion
3
+ include Fundamental
4
+ include Identity
5
+
6
+ def to_ruby(v8_object)
7
+ super v8_object
8
+ end
9
+
10
+ def to_v8(ruby_object)
11
+ super ruby_object
12
+ end
13
+ end
14
+
15
+ for type in [TrueClass, FalseClass, NilClass, Float, Fixnum] do
16
+ type.class_eval do
17
+ include V8::Conversion::Primitive
18
+ end
19
+ end
20
+
21
+ for type in [Class, Object, Array, Hash, String, Symbol, Time, Proc, Method] do
22
+ type.class_eval do
23
+ include V8::Conversion.const_get(name)
24
+ end
25
+ end
26
+ class UnboundMethod
27
+ include V8::Conversion::Method
28
+ end
29
+
30
+ for type in [:Object, :String, :Date] do
31
+ V8::C::const_get(type).class_eval do
32
+ include V8::Conversion::const_get("Native#{type}")
33
+ end
34
+ end
35
+
@@ -0,0 +1,11 @@
1
+ class V8::Conversion
2
+ module Array
3
+ def to_v8
4
+ array = V8::Array.new(length)
5
+ each_with_index do |item, i|
6
+ array[i] = item
7
+ end
8
+ return array.to_v8
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,120 @@
1
+ class V8::Conversion
2
+ module Class
3
+ include V8::Conversion::Code
4
+
5
+ def to_template
6
+ weakcell(:constructor) do
7
+ template = V8::C::FunctionTemplate::New(Constructor.new(self))
8
+ prototype = template.InstanceTemplate()
9
+ prototype.SetNamedPropertyHandler(Get, Set)
10
+ prototype.SetIndexedPropertyHandler(IGet, ISet)
11
+ if self != ::Object && superclass != ::Object && superclass != ::Class
12
+ template.Inherit(superclass.to_template)
13
+ end
14
+ template
15
+ end
16
+ end
17
+
18
+ class Constructor
19
+ include V8::Error::Protect
20
+
21
+ def initialize(cls)
22
+ @class = cls
23
+ end
24
+
25
+ def call(arguments)
26
+ arguments.extend Args
27
+ protect do
28
+ if arguments.linkage_call?
29
+ arguments.link
30
+ else
31
+ arguments.construct @class
32
+ end
33
+ end
34
+ return arguments.This()
35
+ end
36
+
37
+ module Args
38
+ def linkage_call?
39
+ self.Length() == 1 && self[0].IsExternal()
40
+ end
41
+
42
+ def link
43
+ external = self[0]
44
+ This().SetHiddenValue("rr::implementation", external)
45
+ context.link external.Value(), This()
46
+ end
47
+
48
+ def construct(cls)
49
+ context.link cls.new(*to_args), This()
50
+ end
51
+
52
+ def context
53
+ V8::Context.current
54
+ end
55
+
56
+ def to_args
57
+ args = ::Array.new(Length())
58
+ 0.upto(args.length - 1) do |i|
59
+ args[i] = self[i]
60
+ end
61
+ return args
62
+ end
63
+ end
64
+ end
65
+
66
+ module Accessor
67
+ include V8::Error::Protect
68
+ def intercept(info, key, &block)
69
+ context = V8::Context.current
70
+ access = context.access
71
+ object = context.to_ruby(info.This())
72
+ handles_property = true
73
+ dontintercept = proc do
74
+ handles_property = false
75
+ end
76
+ protect do
77
+ result = block.call(context, access, object, context.to_ruby(key), dontintercept)
78
+ handles_property ? context.to_v8(result) : V8::C::Value::Empty
79
+ end
80
+ end
81
+ end
82
+
83
+ class Get
84
+ extend Accessor
85
+ def self.call(property, info)
86
+ intercept(info, property) do |context, access, object, key, dontintercept|
87
+ access.get(object, key, &dontintercept)
88
+ end
89
+ end
90
+ end
91
+
92
+ class Set
93
+ extend Accessor
94
+ def self.call(property, value, info)
95
+ intercept(info, property) do |context, access, object, key, dontintercept|
96
+ access.set(object, key, context.to_ruby(value), &dontintercept)
97
+ end
98
+ end
99
+ end
100
+
101
+ class IGet
102
+ extend Accessor
103
+ def self.call(property, info)
104
+ intercept(info, property) do |context, access, object, key, dontintercept|
105
+ access.iget(object, key, &dontintercept)
106
+ end
107
+ end
108
+ end
109
+
110
+ class ISet
111
+ extend Accessor
112
+ def self.call(property, value, info)
113
+ intercept(info, property) do |context, access, object, key, dontintercept|
114
+ access.iset(object, key, context.to_ruby(value), &dontintercept)
115
+ end
116
+ end
117
+ end
118
+
119
+ end
120
+ end