mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
Merge pull request #370 from cowboyd/4.5/start-implementing-context-specs
add back simple evaluation specs
This commit is contained in:
commit
d9f7042704
8 changed files with 1152 additions and 111 deletions
|
@ -23,6 +23,7 @@ before_install:
|
|||
script:
|
||||
- bundle exec rake compile
|
||||
- bundle exec rspec spec/c
|
||||
- bundle exec rspec spec/v8/context_spec.rb
|
||||
sudo: false
|
||||
addons:
|
||||
apt:
|
||||
|
|
53
lib/v8.rb
53
lib/v8.rb
|
@ -1,30 +1,31 @@
|
|||
require "v8/version"
|
||||
|
||||
require 'v8/weak'
|
||||
require 'v8/init'
|
||||
require 'v8/error'
|
||||
require 'v8/stack'
|
||||
require 'v8/conversion/fundamental'
|
||||
require 'v8/conversion/indentity'
|
||||
require 'v8/conversion/reference'
|
||||
require 'v8/conversion/primitive'
|
||||
require 'v8/conversion/code'
|
||||
require 'v8/conversion/class'
|
||||
require 'v8/conversion/object'
|
||||
require 'v8/conversion/time'
|
||||
require 'v8/conversion/hash'
|
||||
require 'v8/conversion/array'
|
||||
require 'v8/conversion/proc'
|
||||
require 'v8/conversion/method'
|
||||
require 'v8/conversion/symbol'
|
||||
require 'v8/conversion/string'
|
||||
require 'v8/conversion/fixnum'
|
||||
require 'v8/conversion'
|
||||
require 'v8/access/names'
|
||||
require 'v8/access/indices'
|
||||
require 'v8/access/invocation'
|
||||
require 'v8/access'
|
||||
require 'v8/isolate'
|
||||
require 'v8/context'
|
||||
require 'v8/object'
|
||||
require 'v8/array'
|
||||
require 'v8/function'
|
||||
# require 'v8/error'
|
||||
# require 'v8/stack'
|
||||
require 'v8/conversion/fundamental'
|
||||
# require 'v8/conversion/indentity'
|
||||
# require 'v8/conversion/reference'
|
||||
# require 'v8/conversion/primitive'
|
||||
# require 'v8/conversion/code'
|
||||
# require 'v8/conversion/class'
|
||||
# require 'v8/conversion/object'
|
||||
# require 'v8/conversion/time'
|
||||
# require 'v8/conversion/hash'
|
||||
# require 'v8/conversion/array'
|
||||
# require 'v8/conversion/proc'
|
||||
# require 'v8/conversion/method'
|
||||
# require 'v8/conversion/symbol'
|
||||
# require 'v8/conversion/string'
|
||||
# require 'v8/conversion/fixnum'
|
||||
require 'v8/conversion'
|
||||
# require 'v8/access/names'
|
||||
# require 'v8/access/indices'
|
||||
# require 'v8/access/invocation'
|
||||
# require 'v8/access'
|
||||
# require 'v8/context'
|
||||
# require 'v8/object'
|
||||
# require 'v8/array'
|
||||
# require 'v8/function'
|
||||
|
|
|
@ -26,7 +26,7 @@ module V8
|
|||
# cxt.eval('num') # => 5
|
||||
# end
|
||||
class Context
|
||||
include V8::Error::Try
|
||||
# include V8::Error::Try
|
||||
|
||||
# @!attribute [r] conversion
|
||||
# @return [V8::Conversion] conversion behavior for this context
|
||||
|
@ -44,6 +44,10 @@ module V8
|
|||
# @return [Number] maximum execution time in milliseconds for scripts executed in this context
|
||||
attr_reader :timeout
|
||||
|
||||
# @!attribute [r] isolate
|
||||
# @return [V8::Isolate]
|
||||
attr_reader :isolate
|
||||
|
||||
# Creates a new context.
|
||||
#
|
||||
# If passed the `:with` option, that object will be used as
|
||||
|
@ -62,20 +66,24 @@ module V8
|
|||
# * :with scope serves as the global scope of the new context
|
||||
# @yield [V8::Context] the newly created context
|
||||
def initialize(options = {})
|
||||
@conversion = Conversion.new
|
||||
@access = Access.new
|
||||
@timeout = options[:timeout]
|
||||
if global = options[:with]
|
||||
Context.new.enter do
|
||||
global_template = global.class.to_template.InstanceTemplate()
|
||||
@native = V8::C::Context::New(nil, global_template)
|
||||
end
|
||||
enter {link global, @native.Global()}
|
||||
else
|
||||
V8::C::Locker() do
|
||||
@native = V8::C::Context::New()
|
||||
end
|
||||
@isolate = options[:isolate] || V8::Isolate.new
|
||||
V8::C::HandleScope(@isolate.native) do
|
||||
@native = V8::C::Context::New(@isolate.native)
|
||||
end
|
||||
@conversion = Conversion.new
|
||||
# @access = Access.new
|
||||
# @timeout = options[:timeout]
|
||||
# if global = options[:with]
|
||||
# Context.new.enter do
|
||||
# global_template = global.class.to_template.InstanceTemplate()
|
||||
# @native = V8::C::Context::New(nil, global_template)
|
||||
# end
|
||||
# enter {link global, @native.Global()}
|
||||
# else
|
||||
# V8::C::Locker() do
|
||||
# @native = V8::C::Context::New()
|
||||
# end
|
||||
# end
|
||||
yield self if block_given?
|
||||
end
|
||||
|
||||
|
@ -92,12 +100,11 @@ module V8
|
|||
source = source.read
|
||||
end
|
||||
enter do
|
||||
script = try { V8::C::Script::New(source.to_s, filename.to_s) }
|
||||
if @timeout
|
||||
to_ruby try {script.RunWithTimeout(@timeout)}
|
||||
else
|
||||
to_ruby try {script.Run()}
|
||||
end
|
||||
src = V8::C::String::NewFromUtf8(@isolate.native, source.to_s)
|
||||
filename = V8::C::String::NewFromUtf8(@isolate.native, filename.to_s)
|
||||
origin = V8::C::ScriptOrigin.new(filename);
|
||||
script = V8::C::Script::Compile(@native, src, origin).FromJust()
|
||||
to_ruby script.Run(@native).FromJust()
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -107,7 +114,7 @@ module V8
|
|||
# @return [Object] value the value at `key`
|
||||
def [](key)
|
||||
enter do
|
||||
to_ruby(@native.Global().Get(to_v8(key)))
|
||||
to_ruby(@native.Global().Get(@cnative, to_v8(key)).FromJust())
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -117,26 +124,11 @@ module V8
|
|||
# @param [Object] value the value to bind
|
||||
def []=(key, value)
|
||||
enter do
|
||||
@native.Global().Set(to_v8(key), to_v8(value))
|
||||
@native.Global().Set(@native, to_v8(key), to_v8(value))
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
# Destroy this context and release any internal references it may
|
||||
# contain to embedded Ruby objects.
|
||||
#
|
||||
# A disposed context may never again be used for anything, and all
|
||||
# objects created with it will become unusable.
|
||||
def dispose
|
||||
return unless @native
|
||||
@native.Dispose()
|
||||
@native = nil
|
||||
V8::C::V8::ContextDisposedNotification()
|
||||
def self.enter
|
||||
fail "cannot enter a context which has already been disposed"
|
||||
end
|
||||
end
|
||||
|
||||
# Returns this context's global object. This will be a `V8::Object`
|
||||
# if no scope was provided or just an `Object` if a Ruby object
|
||||
# is serving as the global scope.
|
||||
|
@ -165,7 +157,7 @@ module V8
|
|||
# @return [V8::C::Object] to pass to V8
|
||||
# @see V8::Conversion for customizing and extending this mechanism
|
||||
def to_v8(ruby_object)
|
||||
@conversion.to_v8(ruby_object)
|
||||
@conversion.to_v8(self, ruby_object)
|
||||
end
|
||||
|
||||
# Marks a Ruby object and a v8 C++ Object as being the same. In other
|
||||
|
@ -241,14 +233,12 @@ module V8
|
|||
def lock_scope_and_enter
|
||||
current = Context.current
|
||||
Context.current = self
|
||||
V8::C::Locker() do
|
||||
V8::C::HandleScope() do
|
||||
begin
|
||||
@native.Enter()
|
||||
yield if block_given?
|
||||
ensure
|
||||
@native.Exit()
|
||||
end
|
||||
V8::C::HandleScope(@isolate.native) do
|
||||
begin
|
||||
@native.Enter()
|
||||
yield if block_given?
|
||||
ensure
|
||||
@native.Exit()
|
||||
end
|
||||
end
|
||||
ensure
|
||||
|
|
|
@ -1,36 +1,62 @@
|
|||
|
||||
class V8::Conversion
|
||||
include Fundamental
|
||||
include Identity
|
||||
# include Identity
|
||||
|
||||
def to_ruby(v8_object)
|
||||
super v8_object
|
||||
end
|
||||
|
||||
def to_v8(ruby_object)
|
||||
super ruby_object
|
||||
def to_v8(context, ruby_object)
|
||||
super context, ruby_object
|
||||
end
|
||||
end
|
||||
|
||||
for type in [TrueClass, FalseClass, NilClass, Float] do
|
||||
type.class_eval do
|
||||
include V8::Conversion::Primitive
|
||||
module V8::C
|
||||
class String
|
||||
alias_method :to_ruby, :Utf8Value
|
||||
end
|
||||
|
||||
class Number
|
||||
alias_method :to_ruby, :Value
|
||||
end
|
||||
|
||||
class Undefined
|
||||
def to_ruby
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
class Boolean
|
||||
def to_ruby
|
||||
IsTrue()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for type in [Class, Object, Array, Hash, String, Symbol, Time, Proc, Method, Fixnum] do
|
||||
type.class_eval do
|
||||
include V8::Conversion.const_get(type.name)
|
||||
class String
|
||||
def to_v8(context)
|
||||
V8::C::String::NewFromUtf8(context.isolate.native, self)
|
||||
end
|
||||
end
|
||||
|
||||
class UnboundMethod
|
||||
include V8::Conversion::Method
|
||||
end
|
||||
# for type in [TrueClass, FalseClass, NilClass, Float] do
|
||||
# type.class_eval do
|
||||
# include V8::Conversion::Primitive
|
||||
# end
|
||||
# end
|
||||
|
||||
for type in [:Object, :String, :Date] do
|
||||
V8::C::const_get(type).class_eval do
|
||||
include V8::Conversion::const_get("Native#{type}")
|
||||
end
|
||||
end
|
||||
# for type in [Class, Object, Array, Hash, String, Symbol, Time, Proc, Method, Fixnum] do
|
||||
# type.class_eval do
|
||||
# include V8::Conversion.const_get(type.name)
|
||||
# end
|
||||
# end
|
||||
|
||||
# class UnboundMethod
|
||||
# include V8::Conversion::Method
|
||||
# end
|
||||
|
||||
# for type in [:Object, :String, :Date] do
|
||||
# V8::C::const_get(type).class_eval do
|
||||
# include V8::Conversion::const_get("Native#{type}")
|
||||
# end
|
||||
# end
|
||||
|
|
|
@ -4,8 +4,8 @@ class V8::Conversion
|
|||
v8_object.to_ruby
|
||||
end
|
||||
|
||||
def to_v8(ruby_object)
|
||||
ruby_object.to_v8
|
||||
def to_v8(context, ruby_object)
|
||||
ruby_object.to_v8 context
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
class V8::Conversion
|
||||
module Primitive
|
||||
def to_v8
|
||||
return self
|
||||
end
|
||||
end
|
||||
end
|
9
lib/v8/isolate.rb
Normal file
9
lib/v8/isolate.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
module V8
|
||||
class Isolate
|
||||
attr_reader :native
|
||||
|
||||
def initialize()
|
||||
@native = V8::C::Isolate::New()
|
||||
end
|
||||
end
|
||||
end
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue