void VariableScope::Info::mark(Object* obj, ObjectMark& mark) { auto_mark(obj, mark); VariableScope* vs = as<VariableScope>(obj); vs->fixup(); if(!vs->isolated()) { Object** ary = vs->stack_locals(); if(Fiber* fib = try_as<Fiber>(vs->fiber())) { FiberData* data = fib->data(); AddressDisplacement dis(data->data_offset(), data->data_lower_bound(), data->data_upper_bound()); ary = dis.displace(ary); } size_t locals = vs->number_of_locals(); for(size_t i = 0; i < locals; i++) { Object* tmp = mark.call(ary[i]); if(tmp) { ary[i] = tmp; } } } }
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; } }
void VariableScope::Info::visit(Object* obj, ObjectVisitor& visit) { auto_visit(obj, visit); VariableScope* vs = as<VariableScope>(obj); if(!vs->isolated()) { Object** ary = vs->stack_locals(); if(Fiber* fib = try_as<Fiber>(vs->fiber())) { FiberData* data = fib->data(); AddressDisplacement dis(data->data_offset(), data->data_lower_bound(), data->data_upper_bound()); ary = dis.displace(ary); } size_t locals = vs->number_of_locals(); for(size_t i = 0; i < locals; i++) { visit.call(ary[i]); } } }
VariableScope* StackVariables::create_heap_alias(STATE, CallFrame* call_frame, bool full) { if(on_heap_) return on_heap_; MachineCode* mcode = call_frame->compiled_code->machine_code(); VariableScope* scope = state->memory()->new_object<VariableScope>(state, G(variable_scope)); if(parent_) { scope->parent(state, parent_); } else { scope->parent(state, nil<VariableScope>()); } scope->self(state, self_); scope->block(state, block_); scope->module(state, module_); scope->method(state, call_frame->compiled_code); scope->heap_locals(state, nil<Tuple>()); scope->last_match(state, last_match_); scope->fiber(state, state->vm()->thread()->current_fiber()); scope->number_of_locals(mcode->number_of_locals); scope->isolated(0); scope->flags(call_frame->flags); scope->_lock_.init(); if(!full) { scope->isolated(1); scope->heap_locals(state, Tuple::create(state, mcode->number_of_locals)); for(int i = 0; i < scope->number_of_locals(); i++) { scope->set_local(state, i, locals_[i]); } } scope->locals(locals_); scope->dynamic_locals(state, nil<LookupTable>()); on_heap_ = scope; return scope; }
void VariableScope::Info::visit(Object* obj, ObjectVisitor& visit) { auto_visit(obj, visit); VariableScope* vs = as<VariableScope>(obj); size_t locals = vs->number_of_locals(); for(size_t i = 0; i < locals; i++) { visit.call(vs->get_local(i)); } }
void VariableScope::Info::visit(Object* obj, ObjectVisitor& visit) { auto_visit(obj, visit); VariableScope* vs = as<VariableScope>(obj); if(!vs->isolated()) { Object** ary = vs->stack_locals(); size_t locals = vs->number_of_locals(); for(size_t i = 0; i < locals; i++) { visit.call(ary[i]); } } }
void VariableScope::Info::mark(Object* obj, ObjectMark& mark) { auto_mark(obj, mark); VariableScope* vs = as<VariableScope>(obj); vs->fixup(); Object* tmp; size_t locals = vs->number_of_locals(); for(size_t i = 0; i < locals; i++) { tmp = mark.call(vs->get_local(i)); if(tmp) vs->set_local(mark.state(), i, tmp); } }
void VariableScope::Info::mark(Object* obj, memory::ObjectMark& mark) { auto_mark(obj, mark); VariableScope* vs = as<VariableScope>(obj); if(!vs->isolated_p()) { Object** ary = vs->locals(); size_t locals = vs->number_of_locals(); for(size_t i = 0; i < locals; i++) { if(Object* tmp = mark.call(ary[i])) { ary[i] = tmp; } } } }
VariableScope* VariableScope::synthesize(STATE, CompiledCode* method, Module* module, Object* parent, Object* self, Object* block, Tuple* locals) { VariableScope* scope = state->memory()->new_object<VariableScope>(state, G(variable_scope)); scope->block(state, block); scope->module(state, module); scope->method(state, method); if(VariableScope* vs = try_as<VariableScope>(parent)) { scope->parent(state, vs); } else { scope->parent(state, nil<VariableScope>()); } scope->heap_locals(state, locals); scope->self(state, self); scope->number_of_locals(locals->num_fields()); return scope; }