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/conversion'
|
||||||
require 'v8/access/names'
|
require 'v8/access/names'
|
||||||
require 'v8/access/indices'
|
require 'v8/access/indices'
|
||||||
|
require 'v8/access/invocation'
|
||||||
require 'v8/access'
|
require 'v8/access'
|
||||||
require 'v8/context'
|
require 'v8/context'
|
||||||
require 'v8/object'
|
require 'v8/object'
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
class V8::Access
|
class V8::Access
|
||||||
include Names
|
include Names
|
||||||
include Indices
|
include Indices
|
||||||
|
include Invocation
|
||||||
end
|
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)
|
methods = accessible_names(obj)
|
||||||
if methods.include?(name)
|
if methods.include?(name)
|
||||||
method = obj.method(name)
|
method = obj.method(name)
|
||||||
method.arity == 0 ? method.call : method
|
method.arity == 0 ? method.call : method.unbind
|
||||||
elsif obj.respond_to?(:[]) && !special?(name)
|
elsif obj.respond_to?(:[]) && !special?(name)
|
||||||
obj.send(:[], name, &dontintercept)
|
obj.send(:[], name, &dontintercept)
|
||||||
else
|
else
|
||||||
|
|
|
@ -23,6 +23,9 @@ for type in [Class, Object, Array, Hash, String, Symbol, Time, Proc, Method] do
|
||||||
include V8::Conversion.const_get(name)
|
include V8::Conversion.const_get(name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
class UnboundMethod
|
||||||
|
include V8::Conversion::Method
|
||||||
|
end
|
||||||
|
|
||||||
for type in [:Object, :String, :Date] do
|
for type in [:Object, :String, :Date] do
|
||||||
V8::C::const_get(type).class_eval do
|
V8::C::const_get(type).class_eval do
|
||||||
|
|
|
@ -22,14 +22,15 @@ class V8::Conversion
|
||||||
def call(arguments)
|
def call(arguments)
|
||||||
protect do
|
protect do
|
||||||
context = V8::Context.current
|
context = V8::Context.current
|
||||||
length_of_given_args = arguments.Length()
|
access = context.access
|
||||||
args = ::Array.new(@code.arity < 0 ? length_of_given_args : @code.arity)
|
args = ::Array.new(arguments.Length())
|
||||||
0.upto(args.length - 1) do |i|
|
0.upto(args.length - 1) do |i|
|
||||||
if i < length_of_given_args
|
if i < args.length
|
||||||
args[i] = context.to_ruby arguments[i]
|
args[i] = context.to_ruby arguments[i]
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue