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:
parent
f65e3261a5
commit
0f691539e8
6 changed files with 58 additions and 5 deletions
|
@ -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'
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
class V8::Access
|
||||
include Names
|
||||
include Indices
|
||||
include Invocation
|
||||
end
|
47
lib/v8/access/invocation.rb
Normal file
47
lib/v8/access/invocation.rb
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue