From 9f0f36db9b6b1e7ff8ea0d45d2f1662d9af36d61 Mon Sep 17 00:00:00 2001 From: Charles Lowell Date: Tue, 26 Apr 2011 20:50:36 -0500 Subject: [PATCH] extract the function tracking into its own separate module. --- lib/v8/portal.rb | 4 +- lib/v8/portal/functions.rb | 75 +++++++++++++++++++++----------------- spec/redjs | 2 +- 3 files changed, 45 insertions(+), 36 deletions(-) diff --git a/lib/v8/portal.rb b/lib/v8/portal.rb index 0283fd9..ba487a4 100644 --- a/lib/v8/portal.rb +++ b/lib/v8/portal.rb @@ -42,7 +42,9 @@ module V8 when Symbol C::String::NewSymbol(value.to_s) when Proc,Method,UnboundMethod - @functions[value] + @proxies.rb2js(value) do + @functions.to_function(value).function + end when ::Array C::Array::New(value.length).tap do |a| value.each_with_index do |item, i| diff --git a/lib/v8/portal/functions.rb b/lib/v8/portal/functions.rb index acf2105..5b7662d 100644 --- a/lib/v8/portal/functions.rb +++ b/lib/v8/portal/functions.rb @@ -3,49 +3,56 @@ module V8 class Functions def initialize(portal) @portal = portal - @procs, @methods = {},{} - end - - def [](code) - self.send(code.class.name, code) + @procs = {} + @methods = {} end - def Proc(p) - #TODO: check this for memory leaks - @procs[p] ||= begin - template = C::FunctionTemplate::New(method(:callproc), p) - template.GetFunction() + def to_function(code) + case code + when Method, UnboundMethod + #TODO: clear this reference when the C::FunctionTemplate becomes weak. + @methods[code.to_s] ||= Template.new(@portal, code.kind_of?(Method) ? :invoke_callable : :invoke_unbound_method, code) + else + if code.respond_to?(:call) + #TODO: clear with reference when the C::FunctionTemplate becomes weak. + @procs[code] ||= Template.new(@portal, :invoke_callable, code) + else + fail "invalid code type: #{code.class}" + end end end - def UnboundMethod(method) - #TODO: check this for memory leaks. - @methods[method.to_s] ||= begin - template = C::FunctionTemplate::New(method(:callmethod), method) - template.GetFunction() - end - end + class Template + attr_reader :template, :function - alias_method :Method, :Proc + def initialize(portal, impl, code) + @portal = portal + @template = V8::C::FunctionTemplate::New(method(impl), code) + end - def callproc(arguments) - proc = arguments.Data() - rbargs = [] - for i in 0..arguments.Length() - 1 - rbargs << @portal.rb(arguments[i]) + def function + @template.GetFunction() end - @portal.rubycall(proc, *rbargs) - end - - def callmethod(arguments) - method = arguments.Data() - rbargs = [] - for i in 0..arguments.Length() - 1 - rbargs << @portal.rb(arguments[i]) + + def invoke_callable(arguments) + proc = arguments.Data() + rbargs = [] + for i in 0..arguments.Length() - 1 + rbargs << @portal.rb(arguments[i]) + end + @portal.rubycall(proc, *rbargs) end - this = @portal.rb(arguments.This()) - @portal.rubyprotect do - method.bind(this).call(*rbargs) + + def invoke_unbound_method(arguments) + method = arguments.Data() + rbargs = [] + for i in 0..arguments.Length() - 1 + rbargs << @portal.rb(arguments[i]) + end + this = @portal.rb(arguments.This()) + @portal.rubyprotect do + method.bind(this).call(*rbargs) + end end end end diff --git a/spec/redjs b/spec/redjs index 8ea1e0d..ff7bd68 160000 --- a/spec/redjs +++ b/spec/redjs @@ -1 +1 @@ -Subproject commit 8ea1e0d6b9e0a77b026b1b5d80a39c8eff486b92 +Subproject commit ff7bd687925baf2c207a987c9dc973452236415f