1
0
Fork 0
mirror of https://github.com/rubyjs/therubyracer synced 2023-03-27 23:21:42 -04:00

delegate invocation to callables via the context

This commit is contained in:
Charles Lowell 2012-06-16 07:39:11 -05:00
parent f65e3261a5
commit 0f691539e8
6 changed files with 58 additions and 5 deletions

View file

@ -21,6 +21,7 @@ require 'v8/conversion/string'
require 'v8/conversion'
require 'v8/access/names'
require 'v8/access/indices'
require 'v8/access/invocation'
require 'v8/access'
require 'v8/context'
require 'v8/object'

View file

@ -1,4 +1,5 @@
class V8::Access
include Names
include Indices
include Invocation
end

View file

@ -0,0 +1,47 @@
class V8::Access
module Invocation
def methodcall(code, this, args)
code.methodcall this, args
end
module Aritize
def aritize(args)
arity < 0 ? args : Array.new(arity).to_enum(:each_with_index).map {|item, i| args[i]}
end
end
module Proc
include Aritize
def methodcall(this, args)
call *aritize([this].concat(args))
end
::Proc.send :include, self
end
module Method
include Aritize
def methodcall(this, args)
context = V8::Context.current
access = context.access
if this.equal? self.receiver
call *aritize(args)
elsif this.class <= self.receiver.class
access.methodcall(unbind, this, args)
elsif this.equal? context.scope
call *aritize(args)
else
fail TypeError, "cannot invoke #{self} on #{this}"
end
end
::Method.send :include, self
end
module UnboundMethod
def methodcall(this, args)
access = V8::Context.current.access
access.methodcall bind(this), this, args
end
::UnboundMethod.send :include, self
end
end
end

View file

@ -9,7 +9,7 @@ class V8::Access
methods = accessible_names(obj)
if methods.include?(name)
method = obj.method(name)
method.arity == 0 ? method.call : method
method.arity == 0 ? method.call : method.unbind
elsif obj.respond_to?(:[]) && !special?(name)
obj.send(:[], name, &dontintercept)
else

View file

@ -23,6 +23,9 @@ for type in [Class, Object, Array, Hash, String, Symbol, Time, Proc, Method] do
include V8::Conversion.const_get(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

View file

@ -22,14 +22,15 @@ class V8::Conversion
def call(arguments)
protect do
context = V8::Context.current
length_of_given_args = arguments.Length()
args = ::Array.new(@code.arity < 0 ? length_of_given_args : @code.arity)
access = context.access
args = ::Array.new(arguments.Length())
0.upto(args.length - 1) do |i|
if i < length_of_given_args
if i < args.length
args[i] = context.to_ruby arguments[i]
end
end
context.to_v8 @code.call(*args)
this = context.to_ruby arguments.This()
context.to_v8 access.methodcall(@code, this, args)
end
end
end