From 960e18352e80297c749c34b898233ffd4976a052 Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Fri, 7 Oct 2011 17:13:23 -0700 Subject: [PATCH] Sort out for in 1.9 mode --- lib/compiler/ast/sends.rb | 47 ++++++++++++++++++++++++++++++++++++ lib/melbourne/processor.rb | 6 +++++ rakelib/blueprint.rb | 4 +++ vm/bytecode_verification.cpp | 47 ++++++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+) diff --git a/lib/compiler/ast/sends.rb b/lib/compiler/ast/sends.rb index 74f46c2479..33d5d2fe79 100644 --- a/lib/compiler/ast/sends.rb +++ b/lib/compiler/ast/sends.rb @@ -734,6 +734,53 @@ def sexp_name end end + class For19Arguments < Node + def initialize(line, arguments) + @line = line + @arguments = arguments + + if @arguments.kind_of? MultipleAssignment + @args = 0 + @splat = 0 + else + @args = 1 + @splat = -1 + end + end + + def bytecode(g) + g.push_local 0 + @arguments.bytecode(g) + g.pop + end + + def required_args + @args + end + + def total_args + @args + end + + def post_args + @args + end + + def splat_index + @splat + end + end + + class For19 < For + def initialize(line, arguments, body) + @line = line + @arguments = For19Arguments.new line, arguments + @body = body || NilLiteral.new(line) + + new_local :"*for_args" + end + end + class Negate < Node attr_accessor :value diff --git a/lib/melbourne/processor.rb b/lib/melbourne/processor.rb index b28f7c255d..d0fa7815aa 100644 --- a/lib/melbourne/processor.rb +++ b/lib/melbourne/processor.rb @@ -541,6 +541,12 @@ def process_iter(line, method_send, scope) method_send end + def process_for(line, iter, arguments, body) + send = AST::Send.new line, iter, :each + send.block = AST::For19.new line, arguments, body + send + end + def process_lambda(line, scope) arguments = scope.array.shift if scope.array.size == 1 diff --git a/rakelib/blueprint.rb b/rakelib/blueprint.rb index 2df10c94bd..44f9a38ab4 100644 --- a/rakelib/blueprint.rb +++ b/rakelib/blueprint.rb @@ -16,6 +16,10 @@ gcc.cflags << "-O2" end + if ENV['POKE'] + gcc.mtime_only = true + end + # This is necessary for the gcc sync prims to fully work if Rubinius::BUILD_CONFIG[:x86_32] gcc.cflags << "-march=i686" diff --git a/vm/bytecode_verification.cpp b/vm/bytecode_verification.cpp index 1ab5add173..4560acfb12 100644 --- a/vm/bytecode_verification.cpp +++ b/vm/bytecode_verification.cpp @@ -12,6 +12,8 @@ #include "object_utils.hpp" #include "instruments/timing.hpp" +#include "configuration.hpp" + namespace rubinius { BytecodeVerification::BytecodeVerification(CompiledMethod* cm) : method_(cm) @@ -64,6 +66,51 @@ namespace rubinius { return false; } + // FIXME + // + // This is conditional because in 1.8 mode, CM's for blocks have arity + // info that isn't used, but therefore fails these checks because + // of the way 'for' works. + // + // FIXME + if(LANGUAGE_19_ENABLED(state) || LANGUAGE_20_ENABLED(state)) { + if(Fixnum* fix = try_as(method_->splat())) { + if(fix->to_native() >= locals_) { + fail("invalid splat position", -1); + return false; + } + } + + Fixnum* tot = try_as(method_->total_args()); + Fixnum* req = try_as(method_->required_args()); + Fixnum* post = try_as(method_->post_args()); + + if(!tot || !req || !post) { + fail("method not initialized properly (missing arg counts)", -1); + return false; + } + + if(tot->to_native() > locals_) { + fail("more arguments than local slots", -1); + return false; + } + + if(req->to_native() > tot->to_native()) { + fail("more required arguments than total", -1); + return false; + } + + if(post->to_native() > tot->to_native()) { + fail("more post arguments than total", -1); + return false; + } + + if(post->to_native() + req->to_native() > tot->to_native()) { + fail("more post + req arguments than total", -1); + return false; + } + } + total_ = ops_->num_fields(); stack_ = new int32_t[total_];