mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
Move Get,Set,Constructor and friends out of Class
Even though they had been moved into the `ClassAction` module, that module still had the potential for conflict. Instead, we'll just put evenything in the Conversion namespace. That way we need not worry.
This commit is contained in:
parent
7f3a8cb91f
commit
c5b13ea115
3 changed files with 99 additions and 110 deletions
|
@ -4,117 +4,115 @@ class V8::Conversion
|
||||||
|
|
||||||
def to_template
|
def to_template
|
||||||
weakcell(:constructor) do
|
weakcell(:constructor) do
|
||||||
template = V8::C::FunctionTemplate::New(V8::Conversion::ClassActions::Constructor.new(self))
|
template = V8::C::FunctionTemplate::New(V8::Conversion::Constructor.new(self))
|
||||||
prototype = template.InstanceTemplate()
|
prototype = template.InstanceTemplate()
|
||||||
prototype.SetNamedPropertyHandler(V8::Conversion::ClassActions::Get, V8::Conversion::ClassActions::Set)
|
prototype.SetNamedPropertyHandler(V8::Conversion::Get, V8::Conversion::Set)
|
||||||
prototype.SetIndexedPropertyHandler(V8::Conversion::ClassActions::IGet, V8::Conversion::ClassActions::ISet)
|
prototype.SetIndexedPropertyHandler(V8::Conversion::IGet, V8::Conversion::ISet)
|
||||||
if self != ::Object && superclass != ::Object && superclass != ::Class
|
if self != ::Object && superclass != ::Object && superclass != ::Class
|
||||||
template.Inherit(superclass.to_template)
|
template.Inherit(superclass.to_template)
|
||||||
end
|
end
|
||||||
template
|
template
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Constructor
|
||||||
|
include V8::Error::Protect
|
||||||
|
|
||||||
|
def initialize(cls)
|
||||||
|
@class = cls
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(arguments)
|
||||||
|
arguments.extend Args
|
||||||
|
protect do
|
||||||
|
if arguments.linkage_call?
|
||||||
|
arguments.link
|
||||||
|
else
|
||||||
|
arguments.construct @class
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return arguments.This()
|
||||||
|
end
|
||||||
|
|
||||||
|
module Args
|
||||||
|
def linkage_call?
|
||||||
|
self.Length() == 1 && self[0].IsExternal()
|
||||||
|
end
|
||||||
|
|
||||||
|
def link
|
||||||
|
external = self[0]
|
||||||
|
This().SetHiddenValue("rr::implementation", external)
|
||||||
|
context.link external.Value(), This()
|
||||||
|
end
|
||||||
|
|
||||||
|
def construct(cls)
|
||||||
|
context.link cls.new(*to_args), This()
|
||||||
|
end
|
||||||
|
|
||||||
|
def context
|
||||||
|
V8::Context.current
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_args
|
||||||
|
args = ::Array.new(Length())
|
||||||
|
0.upto(args.length - 1) do |i|
|
||||||
|
args[i] = self[i]
|
||||||
|
end
|
||||||
|
return args
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module ClassActions
|
module Accessor
|
||||||
class Constructor
|
include V8::Error::Protect
|
||||||
include V8::Error::Protect
|
def intercept(info, key, &block)
|
||||||
|
context = V8::Context.current
|
||||||
def initialize(cls)
|
access = context.access
|
||||||
@class = cls
|
object = context.to_ruby(info.This())
|
||||||
|
handles_property = true
|
||||||
|
dontintercept = proc do
|
||||||
|
handles_property = false
|
||||||
end
|
end
|
||||||
|
protect do
|
||||||
def call(arguments)
|
result = block.call(context, access, object, context.to_ruby(key), dontintercept)
|
||||||
arguments.extend Args
|
handles_property ? context.to_v8(result) : V8::C::Value::Empty
|
||||||
protect do
|
|
||||||
if arguments.linkage_call?
|
|
||||||
arguments.link
|
|
||||||
else
|
|
||||||
arguments.construct @class
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return arguments.This()
|
|
||||||
end
|
|
||||||
|
|
||||||
module Args
|
|
||||||
def linkage_call?
|
|
||||||
self.Length() == 1 && self[0].IsExternal()
|
|
||||||
end
|
|
||||||
|
|
||||||
def link
|
|
||||||
external = self[0]
|
|
||||||
This().SetHiddenValue("rr::implementation", external)
|
|
||||||
context.link external.Value(), This()
|
|
||||||
end
|
|
||||||
|
|
||||||
def construct(cls)
|
|
||||||
context.link cls.new(*to_args), This()
|
|
||||||
end
|
|
||||||
|
|
||||||
def context
|
|
||||||
V8::Context.current
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_args
|
|
||||||
args = ::Array.new(Length())
|
|
||||||
0.upto(args.length - 1) do |i|
|
|
||||||
args[i] = self[i]
|
|
||||||
end
|
|
||||||
return args
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
module Accessor
|
class Get
|
||||||
include V8::Error::Protect
|
extend Accessor
|
||||||
def intercept(info, key, &block)
|
def self.call(property, info)
|
||||||
context = V8::Context.current
|
intercept(info, property) do |context, access, object, key, dontintercept|
|
||||||
access = context.access
|
access.get(object, key, &dontintercept)
|
||||||
object = context.to_ruby(info.This())
|
|
||||||
handles_property = true
|
|
||||||
dontintercept = proc do
|
|
||||||
handles_property = false
|
|
||||||
end
|
|
||||||
protect do
|
|
||||||
result = block.call(context, access, object, context.to_ruby(key), dontintercept)
|
|
||||||
handles_property ? context.to_v8(result) : V8::C::Value::Empty
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class Get
|
class Set
|
||||||
extend Accessor
|
extend Accessor
|
||||||
def self.call(property, info)
|
def self.call(property, value, info)
|
||||||
intercept(info, property) do |context, access, object, key, dontintercept|
|
intercept(info, property) do |context, access, object, key, dontintercept|
|
||||||
access.get(object, key, &dontintercept)
|
access.set(object, key, context.to_ruby(value), &dontintercept)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class Set
|
class IGet
|
||||||
extend Accessor
|
extend Accessor
|
||||||
def self.call(property, value, info)
|
def self.call(property, info)
|
||||||
intercept(info, property) do |context, access, object, key, dontintercept|
|
intercept(info, property) do |context, access, object, key, dontintercept|
|
||||||
access.set(object, key, context.to_ruby(value), &dontintercept)
|
access.iget(object, key, &dontintercept)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class IGet
|
class ISet
|
||||||
extend Accessor
|
extend Accessor
|
||||||
def self.call(property, info)
|
def self.call(property, value, info)
|
||||||
intercept(info, property) do |context, access, object, key, dontintercept|
|
intercept(info, property) do |context, access, object, key, dontintercept|
|
||||||
access.iget(object, key, &dontintercept)
|
access.iset(object, key, context.to_ruby(value), &dontintercept)
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class ISet
|
|
||||||
extend Accessor
|
|
||||||
def self.call(property, value, info)
|
|
||||||
intercept(info, property) do |context, access, object, key, dontintercept|
|
|
||||||
access.iset(object, key, context.to_ruby(value), &dontintercept)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
# NOTE: This was written to reproduce a bug where V8::Conversion would load the wrong class
|
|
||||||
# when inside of an eigen class scope.
|
|
||||||
|
|
||||||
# We use Set because ::Set is a existing class and V8::Conversion::Class::Set also exists
|
|
||||||
require "set"
|
|
||||||
|
|
||||||
describe "Class scope" do
|
|
||||||
it "doesn't try to use V8::Conversion::Class::* as root objects" do
|
|
||||||
klass = Class.new do
|
|
||||||
class << self
|
|
||||||
def test
|
|
||||||
Set.new
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
klass.test.should be_instance_of(::Set)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -6,4 +6,16 @@ describe V8::Conversion do
|
||||||
cxt['big'] = BigDecimal.new('1.1')
|
cxt['big'] = BigDecimal.new('1.1')
|
||||||
cxt['big'].should eql BigDecimal.new('1.1')
|
cxt['big'].should eql BigDecimal.new('1.1')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "doesn't try to use V8::Conversion::Class::* as root objects" do
|
||||||
|
klass = Class.new do
|
||||||
|
class << self
|
||||||
|
def test
|
||||||
|
Set.new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
klass.test.should be_instance_of(::Set)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue