From c5b13ea1150ffc3a14b48e8dec5d04cc0e486a0c Mon Sep 17 00:00:00 2001 From: Charles Lowell Date: Tue, 24 Jul 2012 23:25:04 +0300 Subject: [PATCH] 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. --- lib/v8/conversion/class.rb | 176 ++++++++++++++++++------------------- spec/class_scope_spec.rb | 21 ----- spec/v8/conversion_spec.rb | 12 +++ 3 files changed, 99 insertions(+), 110 deletions(-) delete mode 100644 spec/class_scope_spec.rb diff --git a/lib/v8/conversion/class.rb b/lib/v8/conversion/class.rb index 3e7a663..8a224a2 100644 --- a/lib/v8/conversion/class.rb +++ b/lib/v8/conversion/class.rb @@ -4,117 +4,115 @@ class V8::Conversion def to_template 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.SetNamedPropertyHandler(V8::Conversion::ClassActions::Get, V8::Conversion::ClassActions::Set) - prototype.SetIndexedPropertyHandler(V8::Conversion::ClassActions::IGet, V8::Conversion::ClassActions::ISet) + prototype.SetNamedPropertyHandler(V8::Conversion::Get, V8::Conversion::Set) + prototype.SetIndexedPropertyHandler(V8::Conversion::IGet, V8::Conversion::ISet) if self != ::Object && superclass != ::Object && superclass != ::Class template.Inherit(superclass.to_template) end template 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 - module ClassActions - class Constructor - include V8::Error::Protect - - def initialize(cls) - @class = cls + module Accessor + include V8::Error::Protect + def intercept(info, key, &block) + context = V8::Context.current + access = context.access + object = context.to_ruby(info.This()) + handles_property = true + dontintercept = proc do + handles_property = false 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 + 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 - module Accessor - include V8::Error::Protect - def intercept(info, key, &block) - context = V8::Context.current - access = context.access - 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 + class Get + extend Accessor + def self.call(property, info) + intercept(info, property) do |context, access, object, key, dontintercept| + access.get(object, key, &dontintercept) end end + end - class Get - extend Accessor - def self.call(property, info) - intercept(info, property) do |context, access, object, key, dontintercept| - access.get(object, key, &dontintercept) - end + class Set + extend Accessor + def self.call(property, value, info) + intercept(info, property) do |context, access, object, key, dontintercept| + access.set(object, key, context.to_ruby(value), &dontintercept) end end + end - class Set - extend Accessor - def self.call(property, value, info) - intercept(info, property) do |context, access, object, key, dontintercept| - access.set(object, key, context.to_ruby(value), &dontintercept) - end + class IGet + extend Accessor + def self.call(property, info) + intercept(info, property) do |context, access, object, key, dontintercept| + access.iget(object, key, &dontintercept) end end + end - class IGet - extend Accessor - def self.call(property, info) - intercept(info, property) do |context, access, object, key, dontintercept| - access.iget(object, key, &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 + 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 diff --git a/spec/class_scope_spec.rb b/spec/class_scope_spec.rb deleted file mode 100644 index bc9be01..0000000 --- a/spec/class_scope_spec.rb +++ /dev/null @@ -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 \ No newline at end of file diff --git a/spec/v8/conversion_spec.rb b/spec/v8/conversion_spec.rb index 54934d3..e942113 100644 --- a/spec/v8/conversion_spec.rb +++ b/spec/v8/conversion_spec.rb @@ -6,4 +6,16 @@ describe V8::Conversion do cxt['big'] = BigDecimal.new('1.1') cxt['big'].should eql BigDecimal.new('1.1') 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