inline bool push_local_depth(STATE, CallFrame* call_frame, intptr_t depth, intptr_t index) { if(depth == 0) { Exception::internal_error(state, "illegal push_local_depth usage"); return false; } else { VariableScope* scope = call_frame->scope->parent(); if(!scope || scope->nil_p()) { Exception::internal_error(state, "illegal push_local_depth usage, no parent"); return false; } for(int j = 1; j < depth; j++) { scope = scope->parent(); if(!scope || scope->nil_p()) { Exception::internal_error(state, "illegal push_local_depth usage, no parent"); return false; } } if(index >= scope->number_of_locals()) { Exception::internal_error(state, "illegal push_local_depth usage, bad index"); return false; } stack_push(scope->get_local(state, index)); return true; } }
Object* VariableScope::set_locked(STATE) { _flags_ |= CallFrame::cScopeLocked; VariableScope* parent = this->parent(); while(parent && !parent->nil_p()) { parent->set_locked(state); parent = parent->parent(); } return cNil; }
/** * Walks the chain of objects accessible from the specified CallFrame. */ void GarbageCollector::verify_call_frame(CallFrame* top_call_frame, AddressDisplacement* offset) { CallFrame* call_frame = top_call_frame; while(call_frame) { call_frame = displace(call_frame, offset); if(call_frame->constant_scope_) { call_frame->constant_scope_->validate(); } if(call_frame->compiled_code) { call_frame->compiled_code->validate(); } if(call_frame->compiled_code) { native_int stack_size = call_frame->compiled_code->stack_size()->to_native(); for(native_int i = 0; i < stack_size; i++) { Object* obj = call_frame->stk[i]; obj->validate(); } } VariableScope* scope = call_frame->top_scope_; if(call_frame->multiple_scopes_p() && scope && !scope->nil_p()) { scope->validate(); } if(BlockEnvironment* env = call_frame->block_env()) { env->validate(); } Arguments* args = displace(call_frame->arguments, offset); if(!call_frame->inline_method_p() && args) { args->recv()->validate(); args->block()->validate(); Object** ary = displace(args->arguments(), offset); for(uint32_t i = 0; i < args->total(); i++) { ary[i]->validate(); } } if(call_frame->scope && call_frame->compiled_code) { verify_variable_scope(call_frame, displace(call_frame->scope, offset)); } call_frame = call_frame->previous; } }
VariableScope* CallFrame::method_scope(STATE) { VariableScope* current = promote_scope(state); if(!multiple_scopes_p()) return current; for(;;) { if(current->block_as_method_p()) return current; VariableScope* parent = current->parent(); if(!parent->nil_p()) { current = parent; } else { return current; } } assert("should not be here" && 0); }
VariableScope* CallFrame::method_scope(STATE) { VariableScope* current = promote_scope(state); if(!multiple_scopes_p()) return current; for(;;) { if(current->block_as_method_p()) return current; VariableScope* parent = current->parent(); if(!parent->nil_p()) { current = parent; } else { return current; } } // Shouldn't ever get here. return 0; }