From 29f92c2ad5dca3a3cedca3e2bbbb9b72c87c9f2e Mon Sep 17 00:00:00 2001 From: Ryo Onodera Date: Tue, 10 Jul 2012 23:20:18 +0900 Subject: [PATCH] Correctly use block call frame --- kernel/common/env.rb | 4 ++++ kernel/loader.rb | 2 -- vm/arguments.hpp | 8 +++++++- vm/builtin/block_environment.cpp | 2 +- vm/builtin/system.cpp | 2 +- vm/builtin/variable_scope.hpp | 5 +++++ vm/capi/capi.cpp | 4 ++-- vm/instructions.def | 21 +++++++++++---------- vm/stack_variables.cpp | 1 + vm/stack_variables.hpp | 8 +++++++- vm/vmmethod.cpp | 6 +++--- 11 files changed, 42 insertions(+), 21 deletions(-) diff --git a/kernel/common/env.rb b/kernel/common/env.rb index 5f4667a373..ad69288777 100644 --- a/kernel/common/env.rb +++ b/kernel/common/env.rb @@ -246,3 +246,7 @@ def update(other, &block) # Missing and deprecated: indexes, indices end end + +class Object + ENV = Rubinius::EnvironmentVariables.new +end diff --git a/kernel/loader.rb b/kernel/loader.rb index 9ca01cb53b..5d55c4f264 100644 --- a/kernel/loader.rb +++ b/kernel/loader.rb @@ -44,8 +44,6 @@ def self.debugger=(prc) def preamble @stage = "running Loader preamble" - Object.const_set :ENV, EnvironmentVariables.new - # Set the default visibility for the top level binding TOPLEVEL_BINDING.variables.method_visibility = :private diff --git a/vm/arguments.hpp b/vm/arguments.hpp index 229e66069f..601d9ba2b0 100644 --- a/vm/arguments.hpp +++ b/vm/arguments.hpp @@ -14,16 +14,18 @@ namespace rubinius { Symbol* name_; Object* recv_; Object* block_; + CallFrame* block_call_frame_; uint32_t total_; Object** arguments_; Tuple* argument_container_; public: - Arguments(Symbol* name, Object* recv, Object* block, uint32_t total, Object** buffer) + Arguments(Symbol* name, Object* recv, Object* block, CallFrame* block_call_frame, uint32_t total, Object** buffer) : name_(name) , recv_(recv) , block_(block) + , block_call_frame_(block_call_frame) , total_(total) , arguments_(buffer) , argument_container_(0) @@ -84,6 +86,10 @@ namespace rubinius { return block_; } + CallFrame* block_call_frame() { + return block_call_frame_; + } + void set_block(Object* val) { block_ = val; } diff --git a/vm/builtin/block_environment.cpp b/vm/builtin/block_environment.cpp index 137ef44004..ea754339a8 100644 --- a/vm/builtin/block_environment.cpp +++ b/vm/builtin/block_environment.cpp @@ -285,7 +285,7 @@ namespace rubinius { Module* mod = invocation.module; if(!mod) mod = env->module(); - scope->initialize(invocation.self, env->top_scope_->block(), + scope->initialize(invocation.self, env->top_scope_->block(), env->top_scope_->block_frame(), mod, vmm->number_of_locals); scope->set_parent(env->scope_); diff --git a/vm/builtin/system.cpp b/vm/builtin/system.cpp index 17e6ddb772..ffcd92e3c9 100644 --- a/vm/builtin/system.cpp +++ b/vm/builtin/system.cpp @@ -1555,7 +1555,7 @@ namespace rubinius { CallFrame* calling_environment) { Dispatch msg(state->symbol("__script__"), G(object), cm); - Arguments args(state->symbol("__script__"), G(main), cNil, 0, 0); + Arguments args(state->symbol("__script__"), G(main), cNil, NULL, 0, 0); OnStack<1> os(state, cm); diff --git a/vm/builtin/variable_scope.hpp b/vm/builtin/variable_scope.hpp index fbeffb091f..a0a0c4844b 100644 --- a/vm/builtin/variable_scope.hpp +++ b/vm/builtin/variable_scope.hpp @@ -36,6 +36,7 @@ namespace rubinius { public: Object* self_; // slot + CallFrame* block_frame_; int number_of_locals_; bool isolated_; Object** locals_; @@ -99,6 +100,10 @@ namespace rubinius { return locals_[pos]; } + CallFrame* block_frame() { + return block_frame_; + } + int number_of_locals() { return number_of_locals_; } diff --git a/vm/capi/capi.cpp b/vm/capi/capi.cpp index 5d42b60727..3155f232c8 100644 --- a/vm/capi/capi.cpp +++ b/vm/capi/capi.cpp @@ -200,7 +200,7 @@ namespace rubinius { LEAVE_CAPI(env->state()); LookupData lookup(recv, recv->lookup_begin(env->state()), env->state()->globals().sym_private.get()); - Arguments args_o(method, recv, block, arg_count, args); + Arguments args_o(method, recv, block, env->current_call_frame(), arg_count, args); Dispatch dis(method); Object* ret = dis.send(env->state(), env->current_call_frame(), @@ -244,7 +244,7 @@ namespace rubinius { Symbol* method = (Symbol*)method_name; LookupData lookup(recv, recv->lookup_begin(env->state()), env->state()->globals().sym_private.get()); - Arguments args_o(method, recv, cNil, arg_count, args); + Arguments args_o(method, recv, cNil, NULL, arg_count, args); Dispatch dis(method); Object* ret = dis.send(env->state(), env->current_call_frame(), diff --git a/vm/instructions.def b/vm/instructions.def index 2a8b51d37b..dbc3dc0e24 100644 --- a/vm/instructions.def +++ b/vm/instructions.def @@ -385,6 +385,7 @@ instruction set_local_depth(depth index) [ value -- value ] } if(index >= scope->number_of_locals()) { + std::cout << depth << " " << index << " " << scope->number_of_locals() << std::endl; Exception::internal_error(state, call_frame, "illegal set_local_depth usage, bad index"); RUN_EXCEPTION(); @@ -905,7 +906,7 @@ instruction send_method(literal) [ receiver -- value ] => send Object* recv = stack_top(); InlineCache* cache = reinterpret_cast(literal); - Arguments args(cache->name, recv, cNil, 0, 0); + Arguments args(cache->name, recv, cNil, NULL, 0, 0); Object* ret = cache->execute(state, call_frame, args); (void)stack_pop(); @@ -942,7 +943,7 @@ instruction send_stack(literal count) [ receiver +count -- value ] => send Object* recv = stack_back(count); InlineCache* cache = reinterpret_cast(literal); - Arguments args(cache->name, recv, cNil, count, + Arguments args(cache->name, recv, cNil, NULL, count, stack_back_position(count)); Object* ret = cache->execute(state, call_frame, args); @@ -983,7 +984,7 @@ instruction send_stack_with_block(literal count) [ block receiver +count -- valu Object* recv = stack_back(count); InlineCache* cache = reinterpret_cast(literal); - Arguments args(cache->name, recv, block, count, + Arguments args(cache->name, recv, block, call_frame, count, stack_back_position(count)); Object* ret = cache->execute(state, call_frame, args); @@ -1026,7 +1027,7 @@ instruction send_stack_with_splat(literal count) [ block array receiver +count - Object* recv = stack_back(count); InlineCache* cache = reinterpret_cast(literal); - Arguments args(cache->name, recv, block, count, + Arguments args(cache->name, recv, block, call_frame, count, stack_back_position(count)); if(!ary->nil_p()) { @@ -1068,7 +1069,7 @@ instruction send_super_stack_with_block(literal count) [ block +count -- value ] InlineCache* cache = reinterpret_cast(literal); Object* const recv = call_frame->self(); - Arguments new_args(cache->name, recv, block, count, + Arguments new_args(cache->name, recv, block, call_frame, count, stack_back_position(count)); Object* ret = cache->execute(state, call_frame, new_args); @@ -1101,7 +1102,7 @@ instruction send_super_stack_with_splat(literal count) [ block array +count -- v Object* const recv = call_frame->self(); InlineCache* cache = reinterpret_cast(literal); - Arguments new_args(cache->name, recv, block, count, + Arguments new_args(cache->name, recv, block, call_frame, count, stack_back_position(count)); if(!ary->nil_p()) { @@ -1344,7 +1345,7 @@ instruction yield_stack(count) [ +count -- value ] => yield } else if(CompiledMethod *cm = try_as(t1)) { // TODO: We do not need to be doing this everytime. cm->scope(state, call_frame->previous->constant_scope()); - BlockEnvironment* env = BlockEnvironment::under_call_frame(state, gct, cm, call_frame->previous); + BlockEnvironment* env = BlockEnvironment::under_call_frame(state, gct, cm, call_frame->scope->block_frame()); ret = env->call(state, call_frame, args); } else if(t1->nil_p()) { state->raise_exception(Exception::make_lje(state, call_frame)); @@ -2081,7 +2082,7 @@ instruction zsuper(literal) [ block -- value ] InlineCache* cache = reinterpret_cast(literal); - Arguments new_args(cache->name, recv, block, arg_count, 0); + Arguments new_args(cache->name, recv, block, call_frame, arg_count, 0); new_args.use_tuple(tup, arg_count); Object* ret; @@ -2281,7 +2282,7 @@ instruction call_custom(literal count) [ receiver +count -- value ] => send Object* recv = stack_back(count); InlineCache* cache = reinterpret_cast(literal); - Arguments args(cache->name, recv, cNil, count, + Arguments args(cache->name, recv, cNil, NULL, count, stack_back_position(count)); Object* ret = cache->execute(state, call_frame, args); @@ -2304,7 +2305,7 @@ instruction meta_to_s(literal) [ object -- string ] => send flush_ip(); InlineCache* cache = reinterpret_cast(literal); - Arguments args(cache->name, stack_top(), cNil, 0, 0); + Arguments args(cache->name, stack_top(), cNil, NULL, 0, 0); Object* ret = cache->execute(state, call_frame, args); if(ret && !kind_of(ret)) { ret = stack_top()->to_s(state, false); diff --git a/vm/stack_variables.cpp b/vm/stack_variables.cpp index e4a1a648cf..65b7c92a2c 100644 --- a/vm/stack_variables.cpp +++ b/vm/stack_variables.cpp @@ -28,6 +28,7 @@ namespace rubinius { scope->fiber(state, state->vm()->current_fiber.get()); scope->number_of_locals_ = vmm->number_of_locals; + scope->block_frame_ = block_frame_; if(full) { scope->isolated_ = false; diff --git a/vm/stack_variables.hpp b/vm/stack_variables.hpp index 55f0b9272f..73bdc10752 100644 --- a/vm/stack_variables.hpp +++ b/vm/stack_variables.hpp @@ -12,16 +12,18 @@ namespace rubinius { VariableScope* parent_; Object* self_; Object* block_; + CallFrame *block_frame_; Module* module_; Object* last_match_; Object* locals_[0]; public: - void initialize(Object* self, Object* block, Module* module, int locals) { + void initialize(Object* self, Object* block, CallFrame *block_frame, Module* module, int locals) { on_heap_ = 0; parent_ = 0; self_ = self; block_ = block; + block_frame_ = block_frame; module_ = module; last_match_ = cNil; @@ -50,6 +52,10 @@ namespace rubinius { return block_; } + CallFrame* block_frame() { + return block_frame_; + } + Module* module() { return module_; } diff --git a/vm/vmmethod.cpp b/vm/vmmethod.cpp index df7c7bf4e3..d1eef1dd15 100644 --- a/vm/vmmethod.cpp +++ b/vm/vmmethod.cpp @@ -568,7 +568,7 @@ namespace rubinius { // look in the wrong place. // // Thus, we have to cache the value in the StackVariables. - scope->initialize(args.recv(), args.block(), mod, vmm->number_of_locals); + scope->initialize(args.recv(), args.block(), args.block_call_frame(), mod, vmm->number_of_locals); InterpreterCallFrame* frame = ALLOCA_CALLFRAME(vmm->stack_size); frame->prepare(vmm->stack_size); @@ -640,13 +640,13 @@ namespace rubinius { // look in the wrong place. // // Thus, we have to cache the value in the StackVariables. - scope->initialize(G(main), cNil, G(object), vmm->number_of_locals); + scope->initialize(G(main), cNil, NULL, G(object), vmm->number_of_locals); InterpreterCallFrame* frame = ALLOCA_CALLFRAME(vmm->stack_size); frame->prepare(vmm->stack_size); - Arguments args(state->symbol("__script__"), G(main), cNil, 0, 0); + Arguments args(state->symbol("__script__"), G(main), cNil, NULL, 0, 0); frame->previous = previous; frame->flags = 0;