Skip to content

Instantly share code, notes, and snippets.

@pbevin
Created September 7, 2009 16:16
Show Gist options
  • Save pbevin/182430 to your computer and use it in GitHub Desktop.
Save pbevin/182430 to your computer and use it in GitHub Desktop.
diff --git a/kernel/compiler/bytecode.rb b/kernel/compiler/bytecode.rb
index 13e40fb..4cd22ea 100644
--- a/kernel/compiler/bytecode.rb
+++ b/kernel/compiler/bytecode.rb
@@ -153,13 +153,19 @@ class Compiler
splat = @body.pop
end
- @body.each do |x|
- x.bytecode(g)
- end
+ if splat && @body.empty?
+ # Special case for [*a]
+ splat.bytecode(g)
+ g.cast_array
+ else
+ @body.each do |x|
+ x.bytecode(g)
+ end
- g.make_array @body.size
+ g.make_array @body.size
- splat.bytecode_in_array_literal(g) if splat
+ splat.bytecode_in_array_literal(g) if splat
+ end
end
end
@@ -1392,16 +1398,20 @@ class Compiler
def bytecode(g)
pos(g)
- if @value
- @value.bytecode(g)
- end
-
- if @splat then
+ if @splat && @value.empty?
@splat.bytecode(g)
g.cast_array
- g.send :+, 1
+ else
+ if @value
+ @value.bytecode(g)
+ end
+ if @splat then
+ @splat.bytecode(g)
+ g.cast_array
+ g.send :+, 1
+ end
end
-
+
# No @value means assume that someone else put the value on the
# stack (ie, an masgn)
@@ -2187,10 +2197,15 @@ class Compiler
# Literal ArrayList and a splat
if @splat
- splat_node = @value.body.pop
- @value.bytecode(g)
- splat_node.call_bytecode(g)
- g.send :+, 1
+ if @value.size == 1
+ @value.bytecode(g)
+ g.cast_array
+ else
+ splat_node = @value.body.pop
+ @value.bytecode(g)
+ splat_node.call_bytecode(g)
+ g.send :+, 1
+ end
elsif @value
@value.bytecode(g)
else
diff --git a/kernel/compiler/nodes.rb b/kernel/compiler/nodes.rb
index 97839e1..af02ab0 100644
--- a/kernel/compiler/nodes.rb
+++ b/kernel/compiler/nodes.rb
@@ -202,6 +202,14 @@ class Compiler
@body = body
end
+ def size
+ @body.size
+ end
+
+ def empty?
+ @body.empty?
+ end
+
attr_accessor :body
end
diff --git a/spec/compiler/array_spec.rb b/spec/compiler/array_spec.rb
index 8e7c345..8934959 100644
--- a/spec/compiler/array_spec.rb
+++ b/spec/compiler/array_spec.rb
@@ -96,7 +96,8 @@ describe "An Array node" do
end
compile do |g|
- g.array_of_splatted_array
+ g.push 1
+ g.make_array 1
end
end
@@ -106,10 +107,8 @@ describe "An Array node" do
end
compile do |g|
- g.make_array 0
g.push 1
g.cast_array
- g.send :+, 1
end
end
@@ -119,10 +118,8 @@ describe "An Array node" do
end
compile do |g|
- g.make_array 0
g.push 1
g.cast_array
- g.send :+, 1
g.make_array 1
end
end
diff --git a/spec/compiler/call_spec.rb b/spec/compiler/call_spec.rb
index 9e289b4..088caeb 100644
--- a/spec/compiler/call_spec.rb
+++ b/spec/compiler/call_spec.rb
@@ -718,7 +718,8 @@ describe "A Call node" do
compile do |g|
g.push :self
- g.array_of_splatted_array
+ g.push 1
+ g.make_array 1
g.send :meth, 1, true
end
diff --git a/spec/compiler/hash_spec.rb b/spec/compiler/hash_spec.rb
index f778350..ed87592 100644
--- a/spec/compiler/hash_spec.rb
+++ b/spec/compiler/hash_spec.rb
@@ -50,10 +50,8 @@ describe "A Hash node" do
g.find_const :Hash
g.push 1
- g.make_array 0
g.push 1
g.cast_array
- g.send :+, 1
g.send :[], 2
end
diff --git a/spec/compiler/iter_spec.rb b/spec/compiler/iter_spec.rb
index c8c1b2c..2c0c220 100644
--- a/spec/compiler/iter_spec.rb
+++ b/spec/compiler/iter_spec.rb
@@ -785,7 +785,8 @@ describe "An Iter node" do
g.push :self
g.in_block_send :m, :none do |d|
- d.array_of_splatted_array
+ d.push 1
+ d.make_array 1
d.ret
end
end
@@ -824,10 +825,9 @@ describe "An Iter node" do
g.push :self
g.in_block_send :m, :none do |d|
- d.array_of_splatted_array 2 do
- d.push 1
- d.push 2
- end
+ d.push 1
+ d.push 2
+ d.make_array 2
d.ret
end
end
@@ -947,7 +947,8 @@ describe "An Iter node" do
g.push :self
g.in_block_send :m, :none do |d|
- d.array_of_splatted_array
+ d.push 1
+ d.make_array 1
d.raise_break
end
end
@@ -986,10 +987,9 @@ describe "An Iter node" do
g.push :self
g.in_block_send :m, :none do |d|
- d.array_of_splatted_array 2 do
- d.push 1
- d.push 2
- end
+ d.push 1
+ d.push 2
+ d.make_array 2
d.raise_break
end
end
@@ -1109,7 +1109,8 @@ describe "An Iter node" do
g.push :self
g.in_block_send :m, :none do |d|
- d.array_of_splatted_array
+ d.push 1
+ d.make_array 1
d.raise_return
end
end
@@ -1148,10 +1149,9 @@ describe "An Iter node" do
g.push :self
g.in_block_send :m, :none do |d|
- d.array_of_splatted_array 2 do
- d.push 1
- d.push 2
- end
+ d.push 1
+ d.push 2
+ d.make_array 2
d.raise_return
end
end
diff --git a/spec/compiler/lasgn_spec.rb b/spec/compiler/lasgn_spec.rb
index a84a989..fe7d8d4 100644
--- a/spec/compiler/lasgn_spec.rb
+++ b/spec/compiler/lasgn_spec.rb
@@ -217,7 +217,8 @@ describe "An Lasgn node" do
end
compile do |g|
- g.array_of_splatted_array
+ g.push 1
+ g.make_array 1
g.set_local 0
end
end
diff --git a/spec/compiler/return_spec.rb b/spec/compiler/return_spec.rb
index 588e50f..b304279 100644
--- a/spec/compiler/return_spec.rb
+++ b/spec/compiler/return_spec.rb
@@ -89,7 +89,8 @@ describe "A Return node" do
end
compile do |g|
- g.array_of_splatted_array
+ g.push 1
+ g.make_array 1
g.ret
end
end
diff --git a/spec/compiler/super_spec.rb b/spec/compiler/super_spec.rb
index aa38e87..e5f9a08 100644
--- a/spec/compiler/super_spec.rb
+++ b/spec/compiler/super_spec.rb
@@ -151,7 +151,8 @@ describe "A Super node" do
end
compile do |g|
- g.array_of_splatted_array
+ g.push 1
+ g.make_array 1
g.push_block
g.send_super nil, 1
diff --git a/spec/compiler/yield_spec.rb b/spec/compiler/yield_spec.rb
index 63bda7c..0faa465 100644
--- a/spec/compiler/yield_spec.rb
+++ b/spec/compiler/yield_spec.rb
@@ -76,8 +76,8 @@ describe "A Yield node" do
end
compile do |g|
- g.array_of_splatted_array
-
+ g.push 1
+ g.make_array 1
g.yield_stack 1
end
end
@@ -88,11 +88,9 @@ describe "A Yield node" do
end
compile do |g|
- g.array_of_splatted_array 2 do
- g.push 1
- g.push 2
- end
-
+ g.push 1
+ g.push 2
+ g.make_array 2
g.yield_stack 1
end
end
diff --git a/spec/tags/frozen/language/array_tags.txt b/spec/tags/frozen/language/array_tags.txt
deleted file mode 100644
index e3ac2e6..0000000
--- a/spec/tags/frozen/language/array_tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-fails:The unpacking splat operator (*) when applied to a value with no other items in the containing array, coerces the passed value to an array and returns it unchanged
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment