Skip to content
This repository was archived by the owner on Dec 4, 2023. It is now read-only.

Commit e567976

Browse files
committed
Merge pull request #380 from cowboyd/4.5/embed-lambdas-into-javascript
Embed lambdas and procs into V8::Context
2 parents 1fa84a0 + 250b8e7 commit e567976

3 files changed

Lines changed: 67 additions & 31 deletions

File tree

lib/v8/conversion.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,28 @@ def to_v8(context)
140140
V8::C::Symbol::For(context.isolate.native, V8::C::String::NewFromUtf8(isolate, to_s))
141141
end
142142
end
143+
144+
class Object
145+
def to_v8(context)
146+
V8::C::Object::New(context.isolate.native)
147+
end
148+
end
149+
150+
class Proc
151+
def to_v8(context)
152+
isolate = context.isolate.native
153+
callback = lambda do |info|
154+
args = []
155+
arity = info.Length()
156+
if self.arity > -1
157+
arity = self.arity
158+
end
159+
arity.times do |i|
160+
args << context.to_ruby(info[i])
161+
end
162+
result = context.to_v8 self.call(*args)
163+
info.GetReturnValue().Set(result)
164+
end
165+
V8::C::Function::New(isolate, callback)
166+
end
167+
end

lib/v8/conversion/fundamental.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,18 @@ def to_ruby(v8_object)
4343
# First it checks to see if there is an entry in the id map for
4444
# this object. Otherwise, it will run the default conversion.
4545
def to_v8(context, ruby_object)
46-
rb_idmap[ruby_object.object_id] || ruby_object.to_v8(context)
46+
if v8_object = rb_idmap[ruby_object.object_id]
47+
v8_object
48+
else
49+
v8_object = ruby_object.to_v8(context)
50+
if v8_object.kind_of? V8::C::Object
51+
v8_object.tap do
52+
equate ruby_object, v8_object
53+
end
54+
else
55+
v8_object
56+
end
57+
end
4758
end
4859

4960
##

spec/v8/context_spec.rb

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,12 @@
9393
end
9494
end
9595

96-
# xit "unwraps ruby objects returned by embedded ruby code to maintain referential integrity" do
97-
# Object.new.tap do |o|
98-
# @cxt['get'] = lambda {o}
99-
# @cxt.eval('get()').should be(o)
100-
# end
101-
# end
96+
it "unwraps ruby objects returned by embedded ruby code to maintain referential integrity" do
97+
Object.new.tap do |o|
98+
@cxt['get'] = lambda {o}
99+
@cxt.eval('get()').should be(o)
100+
end
101+
end
102102

103103
it "always returns the same ruby object for a single javascript object" do
104104
obj = @cxt.eval('obj = {}')
@@ -133,25 +133,25 @@
133133
# end
134134
end
135135

136-
# describe "Calling Ruby Code From Within Javascript", :compat => '0.1.0' do
136+
describe "Calling Ruby Code From Within Javascript" do
137137

138-
# before(:each) do
138+
before(:each) do
139139
# @class = Class.new
140140
# @instance = @class.new
141-
# @cxt = V8::Context.new
141+
@cxt = V8::Context.new
142142
# @cxt['o'] = @instance
143-
# end
143+
end
144144

145-
# xit "can embed a closure into a context and call it" do
146-
# @cxt["say"] = lambda { |*args| args[-2] * args[-1] }
147-
# @cxt.eval("say('Hello', 2)").should == "HelloHello"
148-
# end
145+
it "can embed a closure into a context and call it" do
146+
@cxt["say"] = lambda { |*args| args[-2] * args[-1] }
147+
@cxt.eval("say('Hello', 2)").should == "HelloHello"
148+
end
149149

150-
# xit "recognizes the same closure embedded into the same context as the same function object" do
151-
# @cxt['say'] = @cxt['declare'] = lambda { |*args| args }
152-
# @cxt.eval('say == declare').should be(true)
153-
# @cxt.eval('say === declare').should be(true)
154-
# end
150+
it "recognizes the same closure embedded into the same context as the same function object" do
151+
@cxt['say'] = @cxt['declare'] = lambda { |*args| args }
152+
@cxt.eval('say == declare').should be(true)
153+
@cxt.eval('say === declare').should be(true)
154+
end
155155

156156
# xit "translates ruby Array to Javascript Array" do
157157
# class_eval do
@@ -275,17 +275,17 @@
275275
# @cxt.eval('typeof(RObject)').should == 'function'
276276
# end
277277

278-
# xit "truncates lambda arguments passed in to match the arity of the function", :compat => '0.4.2' do
279-
# @cxt['testing'] = lambda { |arg| arg }
280-
# lambda {
281-
# @cxt.eval('testing(1,2,3)')
282-
# }.should_not raise_error
278+
it "truncates lambda arguments passed in to match the arity of the function", :compat => '0.4.2' do
279+
@cxt['testing'] = lambda { |arg| arg }
280+
lambda {
281+
@cxt.eval('testing(1,2,3)')
282+
}.should_not raise_error
283283

284-
# @cxt['testing'] = lambda { }
285-
# lambda {
286-
# @cxt.eval('testing(1,2,3)')
287-
# }.should_not raise_error
288-
# end
284+
@cxt['testing'] = lambda { }
285+
lambda {
286+
@cxt.eval('testing(1,2,3)')
287+
}.should_not raise_error
288+
end
289289

290290
# xit "truncates method arguments passed in to match the arity of the function", :compat => '0.4.3' do
291291
# @instance.instance_eval do
@@ -652,7 +652,7 @@
652652
# @class.class_eval &body
653653
# end
654654

655-
# end
655+
end
656656

657657
describe "Calling JavaScript Code From Within Ruby" do
658658

0 commit comments

Comments
 (0)