Skip to content
Browse files

Dozens more c2 and spec fixes

  • Loading branch information...
1 parent 7fa8f2e commit 3073442500beab599eec62d65dab0fcbb7b4d35a @evanphx evanphx committed Dec 29, 2007
Showing with 315 additions and 182 deletions.
  1. +24 −3 Rakefile
  2. +0 −5 kernel/bootstrap/bignum.rb
  3. +5 −8 kernel/bootstrap/bytearray.rb
  4. +9 −9 kernel/bootstrap/class.rb
  5. +1 −1 kernel/bootstrap/context.rb
  6. +29 −30 kernel/bootstrap/object.rb
  7. +1 −6 kernel/bootstrap/string.rb
  8. +2 −0 kernel/core/array.rb
  9. +1 −1 kernel/core/bignum.rb
  10. +1 −1 kernel/core/class.rb
  11. +3 −1 kernel/core/compile.rb
  12. +12 −12 kernel/core/compiled_method.rb
  13. +1 −1 kernel/core/exception.rb
  14. +2 −1 kernel/core/iseq.rb
  15. +2 −2 kernel/core/kernel.rb
  16. +11 −5 kernel/core/module.rb
  17. +11 −2 kernel/core/string.rb
  18. +6 −9 kernel/core/thread.rb
  19. +8 −2 kernel/core/throw_catch.rb
  20. +2 −1 lib/compiler1/bytecode/encoder.rb
  21. +32 −19 lib/compiler2/bytecode.rb
  22. +3 −0 lib/compiler2/compiler.rb
  23. +0 −2 lib/compiler2/garnet/cerberus.rb
  24. +0 −30 lib/compiler2/garnet/test.rb
  25. +9 −1 lib/compiler2/generator.rb
  26. +56 −5 lib/compiler2/nodes.rb
  27. +23 −1 lib/compiler2/text.rb
  28. +7 −5 ruby/spec/1.8/core/bignum/right_shift_spec.rb
  29. +8 −6 ruby/spec/1.8/core/exception/no_method_error_spec.rb
  30. +1 −1 ruby/spec/1.8/core/file/ftype_spec.rb
  31. +1 −1 ruby/spec/1.8/language/block_spec.rb
  32. +1 −1 ruby/spec/1.8/language/metaclass_spec.rb
  33. +7 −7 ruby/spec/1.8/language/variables_spec.rb
  34. BIN runtime/stable/bootstrap.rba
  35. BIN runtime/stable/compiler1.rba
  36. BIN runtime/stable/core.rba
  37. BIN runtime/stable/loader.rbc
  38. BIN runtime/stable/platform.rba
  39. +4 −1 shotgun/lib/cpu_instructions.c
  40. +7 −1 shotgun/lib/grammar_runtime.c
  41. +24 −0 shotgun/lib/instructions.rb
  42. +1 −1 shotgun/lib/primitives.rb
View
27 Rakefile
@@ -113,7 +113,9 @@ def compile(name, output, check_mtime=false)
return
end
- if $compiler
+ if $compiler == :c2
+ inc = "-Iruntime/stable/compiler2.rba -rcompiler2/init"
+ elsif $compiler
inc = "-I#{$compiler}"
else
inc = ""
@@ -136,7 +138,11 @@ task :stable_compiler do
if ENV['USE_CURRENT']
puts "Use current versions, not stable."
else
- $compiler = "runtime/stable/compiler1.rba"
+ if ENV['USE_C1']
+ $compiler = "runtime/stable/compiler1.rba"
+ else
+ $compiler = :c2
+ end
ENV['RBX_BOOTSTRAP'] = "runtime/stable/bootstrap.rba"
ENV['RBX_CORE'] = "runtime/stable/core.rba"
ENV['RBX_LOADER'] = "runtime/stable/loader.rbc"
@@ -148,7 +154,7 @@ task :stable_shell => :stable_compiler do
sh "shotgun/rubinius --gdb"
end
-rule ".rbc" => %w[compiler .rb] do |t|
+rule ".rbc" => %w[.rb] do |t|
compile t.source, t.name
end
@@ -264,6 +270,10 @@ file 'runtime/stable/compiler1.rba' => 'build:compiler1' do
sh "cd lib; zip -r ../runtime/stable/compiler1.rba compiler1 -x \\*.rb"
end
+file 'runtime/stable/compiler2.rba' => 'build:compiler2' do
+ sh "cd lib; zip -r ../runtime/stable/compiler2.rba compiler2 -x \\*.rb"
+end
+
Rake::StructGeneratorTask.new do |t|
t.dest = "lib/etc.rb"
end
@@ -399,6 +409,7 @@ task :pristine do
next if /^runtime/.match(fn)
next if %r!fixtures/require!.match(fn)
next if %r!lib/compiler1!.match(fn)
+ next if %r!lib/compiler2!.match(fn)
FileUtils.rm fn rescue nil
end
end
@@ -415,6 +426,10 @@ namespace :clean do
rm_f f, :verbose => $verbose
end
+ (Dir["lib/compiler2/*.rbc"] + Dir["lib/compiler2/**/*.rbc"]).each do |f|
+ rm_f f, :verbose => $verbose
+ end
+
rm_f "runtime/platform.conf"
end
@@ -436,6 +451,7 @@ namespace :build do
build:platform
build:rbc
compiler1
+ compiler2
lib/etc.rb
lib/rbconfig.rb
extensions
@@ -475,13 +491,18 @@ namespace :build do
task :compiler1 => :stable_compiler do
compile_dir "lib/compiler1"
end
+
+ task :compiler2 => :stable_compiler do
+ compile_dir "lib/compiler2"
+ end
desc "Rebuild runtime/stable/*. If you don't know why you're running this, don't."
task :stable => %w[
build:all
runtime/stable/bootstrap.rba
runtime/stable/core.rba
runtime/stable/compiler1.rba
+ runtime/stable/compiler2.rba
runtime/stable/loader.rbc
runtime/stable/platform.rba
]
View
5 kernel/bootstrap/bignum.rb
@@ -63,11 +63,6 @@ def ==(o)
super(o)
end
- def eql?(other)
- false unless other.is_a?(Bignum)
- self == other
- end
-
def __bignum_left_shift__(s)
Ruby.primitive :bignum_left_shift
end
View
13 kernel/bootstrap/bytearray.rb
@@ -5,14 +5,11 @@ def self.allocate(cnt)
def self.new(cnt)
obj = allocate(cnt)
- Ruby.asm <<-CODE
-push_block
-#local obj
-push 0
-set_args
-set_call_flags 1
-&send initialize +
- CODE
+ Rubinius.asm(obj) do |obj|
+ push_block
+ run obj
+ send_with_block :initialize, 0, true
+ end
return obj
end
View
18 kernel/bootstrap/class.rb
@@ -10,15 +10,15 @@ def allocate
def new(*args)
obj = allocate()
- Ruby.asm <<-CODE
-#local args
-cast_array_for_args 0
-push_array
-push_block
-#local obj
-set_call_flags 1
-&send initialize +
- CODE
+ Rubinius.asm(args, obj) do |args, obj|
+ run args
+ cast_array_for_args 0
+ push_array
+ push_block
+ run obj
+ set_call_flags 1
+ send_with_register :initialize
+ end
return obj
end
View
2 kernel/bootstrap/context.rb
@@ -1,6 +1,6 @@
class MethodContext
def self.current
- cur = Ruby.asm "push_context\n"
+ cur = Rubinius.asm { push_context }
return cur.sender
end
View
59 kernel/bootstrap/object.rb
@@ -33,51 +33,50 @@ def equal?(other)
end
def kind_of?(cls)
- Ruby.asm <<-ASM
-#local cls
-push self
-kind_of
- ASM
+ Rubinius.asm(cls) do |c|
+ run c
+ push :self
+ kind_of
+ end
end
def respond_to?(meth,include_private=false)
meth = meth.to_sym
- cm = Ruby.asm <<-ASM
-push self
-#local meth
-#local include_private
-locate_method
- ASM
+ cm = Rubinius.asm(meth, include_private) do |m,i|
+ push :self
+ run m
+ run i
+ locate_method
+ end
!cm.nil?
end
def __send__(name, *args)
meth = name.to_sym
count = args.size.to_i
- prc = Ruby.asm "push_block\n"
-
- Ruby.asm <<-ASM
-#local args
-push_array
-push self
-#local prc
-#local meth
-#local count
-set_args
-set_call_flags 1
-send_off_stack
- ASM
+ Rubinius.asm(args, meth, count) do |a,m,c|
+ run a
+ push_array
+ push :self
+ push_block
+ run m
+ run c
+ set_args
+ set_call_flags 1
+ send_off_stack
+ end
end
def __find_method__(meth)
meth = meth.to_sym
- cm = Ruby.asm <<-ASM
-push self
-#local meth
-push true
-locate_method
- ASM
+ cm = Rubinius.asm(meth) do |m|
+ push :self
+ run m
+ push :true
+ locate_method
+ end
+
return cm
end
View
7 kernel/bootstrap/string.rb
@@ -22,16 +22,11 @@ def __crypt__(other_str)
def append(str)
Ruby.primitive :string_append
- unless str.kind_of? String
- raise TypeError, "only a String instance is accepted"
- end
-
- Ruby.asm "#local str\npush self\nstring_append\n"
+ raise TypeError, "only a String instance is accepted"
end
def dup
Ruby.primitive :string_dup
- Ruby.asm "push self\nstring_dup\n"
end
def to_s
View
2 kernel/core/array.rb
@@ -493,6 +493,8 @@ def delete(obj)
i += 1
end
+
+ yield if block_given?
end
# Deletes the element at the given index and returns
View
2 kernel/core/bignum.rb
@@ -45,7 +45,7 @@ def <<(s)
end
def eql?(value)
- return false unless value.kind_of?(Bignum)
+ return false unless value.kind_of?(Integer)
self == value
end
View
2 kernel/core/class.rb
@@ -4,7 +4,7 @@ def self.new(sclass=Object)
raise TypeError, "superclass must be a Class (#{sclass.class.name} given)" unless sclass.kind_of?(Class)
obj = Rubinius.class_constitute(sclass, nil)
- block = Ruby.asm "push_block"
+ block = block_given?
obj.class_eval(&block) if block
# add clas to sclass's subclass list, for ObjectSpace.each_object(Class)
# NOTE: This is non-standard; Ruby does not normally track subclasses
View
4 kernel/core/compile.rb
@@ -9,7 +9,7 @@ module Compile
@compiler = nil
- DefaultCompiler = "compiler1"
+ DefaultCompiler = "compiler2"
def self.register_compiler(obj)
if $DEBUG
@@ -121,6 +121,8 @@ def self.single_load(dir, rb, rbc, ext, requiring = nil)
if File.file? rb_path
rbc_path = "#{dir}#{rbc}"
+
+ cm = nil
# Use source only if it is newer
if !File.file?(rbc_path) or File.mtime(rb_path) > File.mtime(rbc_path)
View
24 kernel/core/compiled_method.rb
@@ -119,18 +119,18 @@ def activate(recv, mod, args, locals=nil, &prc)
block = nil
end
- out = Ruby.asm <<-ASM
-#local args
-push_array
-#local block
-#local locals
-#local sz
-#local mod
-push self
-#local recv
-activate_method
- ASM
-
+ out = Rubinius.asm(args, block, locals, sz, mod, recv) do |a,b,l,s,m,r|
+ run a
+ push_array
+ run b
+ run l
+ run s
+ run m
+ push :self
+ run r
+ activate_method 0
+ end
+
return out
end
View
2 kernel/core/exception.rb
@@ -182,7 +182,7 @@ class ReturnException
attr_reader :return_value
def initialize(val)
- super()
+ super(nil) # HACK
@return_value = val
end
end
View
3 kernel/core/iseq.rb
@@ -117,7 +117,8 @@ class InstructionSet
{:opcode => :set_literal, :args => [:literal]},
{:opcode => :passed_blockarg, :args => [:int]},
{:opcode => :create_block2, :args => [], :vm_flags => [:check_interrupts]},
- {:opcode => :cast_for_single_block_arg, :args => []}
+ {:opcode => :cast_for_single_block_arg, :args => []},
+ {:opcode => :cast_for_multi_block_arg, :args => []}
]
InstructionSize = 4
View
4 kernel/core/kernel.rb
@@ -94,7 +94,7 @@ def raise(exc=$!, msg=nil, trace=nil)
end
exc.set_backtrace MethodContext.current.sender unless exc.backtrace
- Ruby.asm "#local exc\nraise_exc"
+ Rubinius.asm(exc) { |e| e.bytecode(self); raise_exc }
end
alias_method :fail, :raise
@@ -203,7 +203,7 @@ def rand(max=nil)
end
def lambda
- block = Ruby.asm "push_block"
+ block = block_given?
raise ArgumentError, "block required" if block.nil?
block.disable_long_return!
View
16 kernel/core/module.rb
@@ -12,7 +12,7 @@ def self.new(*args)
mod = self.allocate
Rubinius.module_setup_fields(mod)
- block = Ruby.asm "push_block"
+ block = block_given?
if block
mod.initialize(*args, &block)
else
@@ -36,7 +36,7 @@ def self.nesting
end
def initialize
- block = Ruby.asm "push_block"
+ block = block_given?
instance_eval(&block) if block
# I think we need this for constant lookups
@parent = ::Object
@@ -129,9 +129,14 @@ def alias_method_cv(new_name, current_name)
def undef_method(name)
# Will raise a NameError if the method doesn't exist.
- instance_method(name)
+ meth = instance_method(name)
method_table[name] = false
VM.reset_method_cache(name)
+ if respond_to? :method_undefined
+ method_undefined(name)
+ end
+
+ return meth
end
def public_method_defined?(sym)
@@ -288,9 +293,9 @@ def set_class_visibility(meth, vis)
end
mc = self.metaclass
- mc.method_table[name] = tup.dup
if tup.kind_of?(Tuple)
+ mc.method_table[name] = tup.dup
mc.method_table[name][0] = vis
else
mc.method_table[name] = Tuple[vis, tup]
@@ -549,7 +554,8 @@ def normalize_name(name)
# Get a constant with the given name. If the constant does not exist, return nil.
def recursive_const_get(name)
name = normalize_const_name(name)
-
+
+ constant = nil
current = self
while current
return constant if constant = current.constants_table[name]
View
13 kernel/core/string.rb
@@ -199,7 +199,10 @@ def ==(other)
def =~(pattern)
case pattern
when Regexp
- pattern.match(self)
+ if m = pattern.match(self)
+ return m.begin(0)
+ end
+ return nil
when String
raise TypeError, "type mismatch: String given"
else
@@ -1218,6 +1221,8 @@ def split(pattern = nil, limit = nil)
start = 0
ret = []
+ last_match = nil
+
while match = pattern.match_from(self, start)
break if limited && limit - ret.size <= 1
collapsed = match.collapsing?
@@ -1401,6 +1406,7 @@ def succ
carry = false
c = 0
+ last_alnum = nil
start.step(0, -1) do |idx|
c = out[idx]
carry = true
@@ -1989,7 +1995,10 @@ def splice(start, count, replacement)
# TODO: Make string_dup compatible with String subclasses
#+++
def dup
- out = Ruby.asm "push self\nstring_dup\n"
+ out = Rubinius.asm do
+ push :self
+ string_dup
+ end
out.taint if self.tainted?
return out
end
View
15 kernel/core/thread.rb
@@ -40,7 +40,7 @@ def initialize(*args)
Kernel.raise ThreadError, "must be called with a block"
end
- block = Ruby.asm "push_block"
+ block = block_given?
block.disable_long_return!
setup(false)
@@ -74,12 +74,12 @@ def initialize(*args)
end
def setup_task
- block = Ruby.asm "push_block"
+ block = block_given?
@task.associate block
end
def self.new(*args)
- block = Ruby.asm "push_block"
+ block = block_given?
th = allocate()
th.initialize(*args, &block)
th.wakeup
@@ -134,10 +134,7 @@ def self.critical=(value)
end
def join(timeout = Undefined)
- join_inner(timeout) do
- break nil if @alive
- self
- end
+ join_inner(timeout) { @alive ? nil : self }
end
def group
@@ -162,8 +159,8 @@ def join_inner(timeout = Undefined)
@lock.send nil
begin
unless timeout == Undefined
- timeout = Time.at timeout
- Scheduler.send_in_microseconds(jc, (timeout.to_f * 1_000_000).to_i)
+ msecs = (timeout.to_f * 1_000_000).to_i
+ Scheduler.send_in_microseconds(jc, msecs)
end
jc.receive
ensure
View
10 kernel/core/throw_catch.rb
@@ -60,7 +60,10 @@ def catch(sym)
end
rescue ThrownValue => val
return val.value if val.name == sym
- Ruby.asm "#local val\nraise_exc\n"
+ Rubinius.asm(val) do |v|
+ v.bytecode(self)
+ raise_exc
+ end
end
end
@@ -70,7 +73,10 @@ def throw(sym, value = nil)
end
exc = ThrownValue.new(sym, value, MethodContext.current.sender)
- Ruby.asm "#local exc\nraise_exc\n"
+ Rubinius.asm(exc) do |v|
+ v.bytecode(self)
+ raise_exc
+ end
end
end
View
3 lib/compiler1/bytecode/encoder.rb
@@ -225,7 +225,8 @@ class InvalidOpCode < RuntimeError
:set_literal,
:passed_blockarg,
:create_block2,
- :cast_for_single_block_arg
+ :cast_for_single_block_arg,
+ :cast_for_multi_block_arg
]
CheckInterupts = [
View
51 lib/compiler2/bytecode.rb
@@ -144,6 +144,11 @@ def bytecode(g)
g.set_line @line, @file
@child.bytecode(g) if @child
end
+
+ def call_bytecode(g)
+ g.set_line @line, @file
+ @child.call_bytecode(g)
+ end
end
# TESTED
@@ -218,11 +223,11 @@ def bytecode(g)
# TESTED
class Negate
def bytecode(g)
- if @child.kind_of? NumberLiteral
+ if @child.is? NumberLiteral
g.push -@child.value
else
@child.bytecode(g)
- g.send :"@-", 0
+ g.send :"-@", 0
end
end
end
@@ -237,7 +242,7 @@ def bytecode(g)
# TESTED
class Literal
def bytecode(g)
- g.push_literal @value
+ g.push_unique_literal @value
end
end
@@ -263,13 +268,15 @@ def bytecode(g)
class HashLiteral
def bytecode(g)
count = @body.size
+ i = count - 1
- until @body.empty?
- v = @body.pop
- k = @body.pop
+ while i > 0
+ v = @body[i]
+ k = @body[i - 1]
v.bytecode(g)
k.bytecode(g)
+ i -= 2
end
g.push_cpath_top
@@ -431,16 +438,17 @@ def bytecode(g)
return
end
- fin = @body.pop
- @body.each do |part|
+ count = @body.size - 1
+ i = 0
+ while i < count
ip = g.ip
- part.bytecode(g)
+ @body[i].bytecode(g)
# guards for things that plugins might optimize away.
g.pop if g.advanced_since?(ip)
+ i += 1
end
- @body << fin
- fin.bytecode(g)
+ @body[count].bytecode(g)
end
end
@@ -1095,15 +1103,17 @@ def bytecode(g)
# TESTED
class ConstSet
def bytecode(g)
- @value.bytecode(g)
if @parent
@parent.bytecode(g)
+ @value.bytecode(g)
g.set_const @name, true
else
if @from_top
g.push_cpath_top
+ @value.bytecode(g)
g.set_const @name, true
else
+ @value.bytecode(g) if @value
g.set_const @name
end
end
@@ -1485,8 +1495,9 @@ class IterArgs
def bytecode(g)
case @child
when MAsgn
+ g.cast_for_multi_block_arg
@child.bytecode(g)
- when LocalAssignment, IVarAssign
+ when LocalAssignment, IVarAssign, GVarAssign, AttrAssign
g.cast_for_single_block_arg
@child.bytecode(g)
g.pop
@@ -1520,7 +1531,7 @@ class MAsgn
# the outermost masgn.
def bytecode(g)
if @source
- if @source.kind_of? ArrayLiteral
+ if @source.is? ArrayLiteral
if @splat
array_bytecode(g)
else
@@ -1564,7 +1575,7 @@ def flip_assign_bytecode(g)
# Now all the source data is on the stack.
@assigns.body.each do |x|
- if x.kind_of? AttrAssign
+ if x.is? AttrAssign
x.bytecode(g, true)
else
x.bytecode(g)
@@ -1608,9 +1619,11 @@ def array_bytecode(g)
end
def statement_bytecode(g)
- if @source.kind_of? Splat or @source.kind_of? ToArray
+ if @source.nil?
+ # skip
+ elsif @source.is? Splat or @source.is? ToArray
@source.child.bytecode(g)
- elsif @source.kind_of? ConcatArgs
+ elsif @source.is? ConcatArgs
@source.bytecode(g)
elsif @source
raise Error, "Unknown form: #{@source.class}"
@@ -1705,12 +1718,12 @@ def emit_args(g)
x.bytecode(g)
end
@argcount = @arguments.size
- elsif @arguments.kind_of? ConcatArgs
+ elsif @arguments.is? ConcatArgs
@arguments.call_bytecode(g)
# ConcatArgs calls get_args on its own, so we don't need to
@dynamic = true
else
- if @arguments.kind_of? Splat
+ if @arguments.is? Splat
@arguments.call_bytecode(g)
else
@arguments.bytecode(g)
View
3 lib/compiler2/compiler.rb
@@ -1,3 +1,5 @@
+require 'compiler2/system_hints'
+
class Compiler2
class Error < RuntimeError
@@ -43,6 +45,7 @@ def load_plugins
activate :primitive
activate :assembly
activate :method_visibility
+ activate :fastmath
end
def activate(name)
View
2 lib/compiler2/garnet/cerberus.rb
@@ -35,5 +35,3 @@ def to_cerb(e)
end
end
-
-
View
30 lib/compiler2/garnet/test.rb
@@ -1,30 +0,0 @@
-
-class Primitives
-
- def add(x, y)
- x.fixnum!
- y.fixnum!
- stack_push fixnum_add(@state, x, y)
- end
-
- def bignum_add(x, y)
- x.bignum!
- y.bignum!
-
-
- end
-
-end
-
-
-class Object
- def equal(other)
- Ruby.primitive do
- if self == other
- stack_push true
- else
- stack_push false
- end
- end
- end
-end
View
10 lib/compiler2/generator.rb
@@ -89,7 +89,7 @@ def encode_literals
def encode_exceptions
@exceptions.sort!
-
+
tup = Tuple.new(@exceptions.size)
i = 0
@exceptions.each do |e|
@@ -306,6 +306,14 @@ def push_literal(what)
add :push_literal, idx
return idx
end
+
+ # Puts +what+ is the literals tuple without trying to see if
+ # something that is like +what+ is already there.
+ def push_unique_literal(what)
+ idx = add_literal(what)
+ add :push_literal, idx
+ return idx
+ end
# Pushes the literal value on the stack into the specified position in the
# literals tuple. Most timees, push_literal should be used instead; this
View
61 lib/compiler2/nodes.rb
@@ -393,7 +393,7 @@ class Match3 < Node
kind :match3
def args(pattern, target)
- @target, @pattern = target, pattern
+ @pattern, @target = pattern, target
end
attr_accessor :target, :pattern
@@ -816,7 +816,17 @@ def args(obj, method, kind, assign, value)
class ArrayLiteral < Node
kind :array
- def args(*body)
+ # We do this to get around having to do *body in
+ # args. 1024 is the max number of args, so if an
+ # array had more elements that than, args would
+ # get an args error. This lets us leave it as an
+ # Array.
+ def consume(sexp)
+ sexp.map! { |s| convert(s) }
+ [sexp]
+ end
+
+ def args(body)
@body = body
end
@@ -1065,14 +1075,43 @@ def consume(sexp)
parent = name.parent
end
- body = set(:family, self) do
+ # We have to set this before converting the body, because
+ # we'll need to know it to use find_ivar_index properly.
+ sup = sexp[1]
+ if sup and sup[0] == :const
+ @superclass_name = sup[1]
+ else
+ @superclass_name = nil
+ end
+ @name = sym
+
+ @namespace = get(:namespace)
+
+ body = set(:family => self, :namespace => sym) do
super([sexp[2]])
end
[sym, parent, convert(sexp[1]), body]
end
attr_accessor :name, :parent, :superclass, :body
+
+ def find_ivar_index(name)
+ slot = super(name)
+ if slot
+ return slot
+ elsif !@namespace
+ if tbl = Compiler2::Bootstrap::HINTS[@name]
+ return tbl[name]
+ elsif @superclass_name
+ if tbl = Compiler2::Bootstrap::HINTS[@superclass_name]
+ return tbl[name]
+ end
+ end
+ end
+
+ return nil
+ end
end
class Module < ClosedScope
@@ -1088,11 +1127,17 @@ def consume(sexp)
if name.is? ConstFind
parent = nil
+ elsif name.is? ConstAtTop
+ parent = name
else
parent = name.parent
end
- [sym, parent, super([sexp[1]])]
+ body = set(:namespace, sym) do
+ super([sexp[1]])
+ end
+
+ [sym, parent, body]
end
attr_accessor :name, :body, :parent
@@ -1129,6 +1174,10 @@ def args(cond, body, nxt)
else
raise Error, "Unknown rescue condition form"
end
+
+ if body.nil?
+ @body = Nil.new(@compiler)
+ end
end
attr_accessor :conditions, :splat, :body, :next
@@ -1449,7 +1498,7 @@ def args(obj, meth, args=nil)
class Super < Call
kind :super
- def args(args)
+ def args(args=nil)
@method = get(:scope)
@arguments = args
@@ -1514,6 +1563,8 @@ def args(child)
end
def names
+ return [] if @child.nil?
+
if @child.is? LocalAssignment
[@child.name]
else
View
24 lib/compiler2/text.rb
@@ -47,6 +47,11 @@ def new_label
def set_label(idx)
@text << "l#{idx}:\n"
end
+
+ def add_text(text)
+ @text << text
+ @text << "\n"
+ end
def run(node)
node.bytecode(self)
@@ -111,8 +116,25 @@ def as_primitive(name)
@text << "#primitive #{name}\n"
end
+ class EB
+ @@ids = 0
+
+ def initialize(gen)
+ @gen = gen
+ @idx = (@@ids += 1)
+ end
+
+ def start!
+ @gen.add_text "; exc#{@idx} start"
+ end
+
+ def handle!
+ @gen.add_text "; exc#{@idx} end"
+ end
+ end
+
def exceptions
- ex = Compiler2::Generator::ExceptionBlock.new(self)
+ ex = EB.new(self)
ex.start!
yield ex
end
View
12 ruby/spec/1.8/core/bignum/right_shift_spec.rb
@@ -31,11 +31,13 @@
lambda { @bignum >> obj }.should raise_error(TypeError)
end
- # This test was added as the result of ruby-core:9020.
- platform_is :darwin, :version => '1.8.5' do
- it "shows the bug described in ruby-core:9020" do
- ((1 - 2**32) >> 32).should == 0
- ((1 - 2**64) >> 64).should == 0
+ compliant_on :ruby do
+ # This test was added as the result of ruby-core:9020.
+ platform_is :darwin, :version => '1.8.5' do
+ it "shows the bug described in ruby-core:9020" do
+ ((1 - 2**32) >> 32).should == 0
+ ((1 - 2**64) >> 64).should == 0
+ end
end
end
View
14 ruby/spec/1.8/core/exception/no_method_error_spec.rb
@@ -54,12 +54,14 @@ class NoMethodErrorD; end
end
end
- it "for private method match /private method/" do
- begin
- NoMethodErrorC.new.a_protected_method
- rescue Exception => e
- e.class.should == NoMethodError
- e.message.match(/protected method/).should_not == nil
+ not_compliant_on :rubinius do
+ it "for private method match /private method/" do
+ begin
+ NoMethodErrorC.new.a_protected_method
+ rescue Exception => e
+ e.class.should == NoMethodError
+ e.message.match(/private method/).should_not == nil
+ end
end
end
end
View
2 ruby/spec/1.8/core/file/ftype_spec.rb
@@ -30,7 +30,7 @@
# Symlinks
%w[/dev /usr/bin /usr/local/bin].each do |dir|
- links = `find /usr/local/bin -type l 2> /dev/null`.split("\n")
+ links = `find #{dir} -type l 2> /dev/null`.split("\n")
next if links.empty?
@link = links.first
break
View
2 ruby/spec/1.8/language/block_spec.rb
@@ -48,7 +48,7 @@
end
end
-compliant_on :ruby18 do
+not_compliant_on :rubinius do
# This functionality is being removed from MRI and has never
# been used in 1.8, therefore rubinius doesn't support
# it already.
View
2 ruby/spec/1.8/language/metaclass_spec.rb
@@ -28,7 +28,7 @@ class << nil; self; end.should == NilClass
cls.equal?(Object).should == false
end
- extension(:rubinius) do
+ deviates_on(:rubinius) do
it "is a MetaClass instance" do
cls = class << mock('x'); self; end
cls.is_a?(MetaClass).should == true
View
14 ruby/spec/1.8/language/variables_spec.rb
@@ -143,7 +143,7 @@
b.should == 1
end
- compliant :ruby, :jruby do
+ compliant_on :ruby, :jruby do
it "evaluates rhs left-to-right" do
a = VariablesSpecs::ParAsgn.new
d,e,f = a.inc, a.inc, a.inc
@@ -156,7 +156,7 @@
# Rubinius evaluates the rhs args right-to-left, not left-to-right.
# In most cases, this should make no noticeable difference, and it is felt
# that RHS evaluation order ought to be left to the implementation.
- noncompliant :rubinius do
+ deviates_on :rubinius do
it "evaluates rhs right-to-left" do
a = VariablesSpecs::ParAsgn.new
d,e,f = a.inc, a.inc, a.inc
@@ -688,7 +688,7 @@
describe 'Multiple assignments with splats' do
# TODO make this normal once rubinius eval works
- compliant :ruby do
+ compliant_on :ruby do
it '* on the lhs has to be applied to the last parameter' do
lambda { eval 'a, *b, c = 1, 2, 3' }.should raise_error(SyntaxError)
end
@@ -757,14 +757,14 @@
d.should == 4
end
- compliant :ruby do
+ compliant_on :ruby do
it 'rhs cannot use parameter grouping, it is a syntax error' do
lambda { eval '(a, b) = (1, 2)' }.should raise_error(SyntaxError)
end
end
end
-compliant :ruby do
+compliant_on :ruby do
describe "Multiple assignment" do
@@ -796,7 +796,7 @@
# containing all the elements on the rhs. As this result is never used, the cost
# of creating and then discarding this array is avoided
describe "Multiple assignment, array-style" do
- compliant :ruby do
+ compliant_on :ruby do
it "returns an array of all rhs values" do
(a,b = 5,6,7).should == [5,6,7]
a.should == 5
@@ -814,7 +814,7 @@
end
end
- noncompliant :rubinius do
+ deviates_on :rubinius do
it "returns true" do
(a,b = 5,6,7).should == true
a.should == 5
View
BIN runtime/stable/bootstrap.rba
Binary file not shown.
View
BIN runtime/stable/compiler1.rba
Binary file not shown.
View
BIN runtime/stable/core.rba
Binary file not shown.
View
BIN runtime/stable/loader.rbc
Binary file not shown.
View
BIN runtime/stable/platform.rba
Binary file not shown.
View
5 shotgun/lib/cpu_instructions.c
@@ -157,7 +157,7 @@ static inline OBJECT cpu_check_for_method(STATE, cpu c, OBJECT hsh, OBJECT name,
} else if(vis == state->global->sym_protected) {
/* If it's protected, bail if the receiver isn't the same
class as self. */
- if(!ISA(recv, object_class(state, c->self))) return Qnil;
+ if(object_class(state, recv) != object_class(state, c->self)) return Qnil;
}
}
@@ -1020,6 +1020,8 @@ void cpu_unified_send(STATE, cpu c, OBJECT recv, OBJECT sym, int args, OBJECT bl
static inline void cpu_unified_send_super(STATE, cpu c, OBJECT recv, OBJECT sym, int args, OBJECT block) {
OBJECT mo, klass, mod;
int missing;
+
+ c->call_flags = 1;
missing = 0;
@@ -1036,6 +1038,7 @@ static inline void cpu_unified_send_super(STATE, cpu c, OBJECT recv, OBJECT sym,
/* Make sure no one else sees the a recently set cache_index, it was
only for us! */
c->cache_index = -1;
+ c->call_flags = 0;
_cpu_build_and_activate(state, c, mo, recv, sym, args, block, missing, mod);
}
View
8 shotgun/lib/grammar_runtime.c
@@ -577,7 +577,13 @@ void syd_add_to_parse_tree(STATE, OBJECT ary,
} else {
array_push(current, Q2SYM(node->nd_vid));
}
- add_to_parse_tree(current, node->nd_value, newlines, locals, line_numbers);
+
+ if(node->nd_value) {
+ add_to_parse_tree(current, node->nd_value, newlines, locals, line_numbers);
+ } else{
+ array_push(current, Qnil);
+ }
+
if(node->nd_next) {
add_to_parse_tree(current, node->nd_next, newlines, locals, line_numbers);
} else {
View
24 shotgun/lib/instructions.rb
@@ -553,6 +553,30 @@ def cast_for_single_block_arg
CODE
end
+ def cast_for_multi_block_arg
+ <<-CODE
+ t1 = stack_top();
+ k = NUM_FIELDS(t1);
+ /* If there is only one thing in the tuple... */
+ if(k == 1) {
+ t1 = tuple_at(state, t1, 0);
+ /* and that thing is an array... */
+ if(RISA(t1, array)) {
+ /* make a tuple out of the array contents... */
+ j = FIXNUM_TO_INT(array_get_total(t1));
+ t2 = tuple_new(state, j);
+
+ for(k = 0; k < j; k++) {
+ tuple_put(state, t2, k, array_get(state, t1, k));
+ }
+
+ /* and put it on the top o the stack. */
+ stack_set_top(t2);
+ }
+ }
+ CODE
+ end
+
def make_hash
<<-CODE
next_int;
View
2 shotgun/lib/primitives.rb
@@ -2736,7 +2736,7 @@ def string_equal
t2 = string_get_data(self);
t3 = string_get_data(t1);
- k = strncmp(BYTEARRAY_ADDRESS(t2), BYTEARRAY_ADDRESS(t3), j);
+ k = memcmp(BYTEARRAY_ADDRESS(t2), BYTEARRAY_ADDRESS(t3), j);
stack_push(k == 0 ? Qtrue : Qfalse);
}
}

0 comments on commit 3073442

Please sign in to comment.
Something went wrong with that request. Please try again.