From 6e7edd638265503c129fdc0a7b44a301cc3ca4f7 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 1 Aug 2009 13:02:30 -0400 Subject: [PATCH] Fixes for broken handling of method calls without explicit receiver, and start of handling attr_accessor etc. --- compiler.rb | 30 ++++++++++++++++++++++++++---- scope.rb | 3 ++- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/compiler.rb b/compiler.rb index 9f74d65..9415df9 100644 --- a/compiler.rb +++ b/compiler.rb @@ -298,7 +298,7 @@ def compile_eval_arg(scope, arg) @e.load_instance_var(ret, aparam) return @e.result_value elsif atype == :possible_callm - return compile_eval_arg(scope, [:callm, :self, arg,[]]) + return compile_callm(scope,:self,aparam,[]) end return @e.load(atype, aparam) end @@ -347,6 +347,12 @@ def compile_call(scope, func, args) # %eax is the result of a yield we've not done... Temporary hack return [:subexpr] end + + # This is a bit of a hack. get_arg will also be called from + # compile_eval_arg below, but we need to know if it's a callm + fargs = get_arg(scope, func) + return compile_callm(scope,:self, func, args) if fargs[0] == :possible_callm + args = [args] if !args.is_a?(Array) @e.with_stack(args.length, true) do args.each_with_index do |a, i| @@ -484,13 +490,29 @@ def compile_class(scope, name,superclass, *exps) cscope = ClassScope.new(scope, name, @vtableoffsets) # FIXME: Need to be able to handle re-opening of classes - # FIXME: Fill in all unused vtable slots with __method_missing # FIXME: Need to generate "thunks" for __method_missing that knows the name of the slot they are in, and # then jump into __method_missing. exps.each do |l2| l2.each do |e| - if e.is_a?(Array) && e[0] == :defun - cscope.add_vtable_entry(e[1]) # add method into vtable of class-scope to associate with class + if e.is_a?(Array) + if e[0] == :defun + cscope.add_vtable_entry(e[1]) # add method into vtable of class-scope to associate with class + elsif e[0] == :call && e[1] == :attr_accessor + # This is a bit presumptious, assuming noone are stupid enough to overload + # attr_accessor, attr_reader without making them do more or less the same thing. + # but the right thing to do is actually to call the method. + # + # In any case there is no actual harm in allocating the vtable + # entry.` + # + # We may do a quick temporary hack to synthesize the methods, + # though, as otherwise we need to implement the full define_method + # etc. + arr = e[1].is_a?(Array) ? e[2] : [e[2]] + arr.each {|entry| + cscope.add_vtable_entry(entry.to_s[1..-1].to_sym) + } + end end end end diff --git a/scope.rb b/scope.rb index 86ec1db..7fa47b3 100644 --- a/scope.rb +++ b/scope.rb @@ -114,6 +114,7 @@ def alloc_offset(name) @vtable[name] = @vtable_max @vtable_max += 1 end + @vtable[name] end @@ -257,7 +258,7 @@ def add_vtable_entry(name) @vtable[name] ||= VTableEntry.new v = @vtable[name] v.name = name.to_s - v.offset = @vtableoffsets.get_offset(name) if !v.offset + v.offset = @vtableoffsets.alloc_offset(name) if !v.offset return v end