Object* rbx_create_block_multi(STATE, CompiledCode* cm, int count, ...) { va_list ap; CallFrame* closest = 0; VariableScope* top = 0; VariableScope* parent = 0; va_start(ap, count); for(int i = 0; i < count; i++) { closest = va_arg(ap, CallFrame*); closest->scope->set_parent(parent); parent = closest->promote_scope(state); if(!top) { top = parent; } else { closest->flags |= CallFrame::cMultipleScopes; closest->top_scope_ = top; } } va_end(ap); // TODO: We don't need to be doing this everytime. cm->scope(state, closest->constant_scope()); VMMethod* vmm = closest->cm->backend_method(); GCTokenImpl gct; return BlockEnvironment::under_call_frame(state, gct, cm, vmm, closest); }
void CallFrame::print_backtrace(STATE, std::ostream& stream, int total, bool filter) { CallFrame* cf = this; int i = -1; while(cf) { i++; if(total > 0 && i == total) return; if(NativeMethodFrame* nmf = cf->native_method_frame()) { stream << static_cast<void*>(cf) << ": "; NativeMethod* nm = try_as<NativeMethod>(nmf->get_object(nmf->method())); if(nm && nm->name()->symbol_p()) { stream << "capi:" << nm->name()->debug_str(state) << " at "; stream << nm->file()->c_str(state); } else { stream << "unknown capi"; } stream << std::endl; cf = cf->previous; continue; } if(!cf->compiled_code) { cf = cf->previous; continue; } if(filter && cf->compiled_code->kernel_method(state)) { cf = cf->previous; continue; } stream << static_cast<void*>(cf) << ": "; if(cf->is_block_p(state)) { stream << "__block__"; } else { if(SingletonClass* sc = try_as<SingletonClass>(cf->module())) { Object* obj = sc->attached_instance(); if(Module* mod = try_as<Module>(obj)) { stream << mod->debug_str(state) << "."; } else { if(obj == G(main)) { stream << "MAIN."; } else { stream << "#<" << obj->class_object(state)->debug_str(state) << ":" << (void*)obj->id(state)->to_native() << ">."; } } } else if(IncludedModule* im = try_as<IncludedModule>(cf->module())) { stream << im->module()->debug_str(state) << "#"; } else { Symbol* name; std::string mod_name; if(cf->module()->nil_p()) { mod_name = cf->constant_scope()->module()->debug_str(state); } else { if((name = try_as<Symbol>(cf->module()->module_name()))) { mod_name = name->debug_str(state); } else if((name = try_as<Symbol>( cf->constant_scope()->module()->module_name()))) { mod_name = name->debug_str(state); } else { mod_name = "<anonymous module>"; } } stream << mod_name << "#"; } Symbol* name = try_as<Symbol>(cf->name()); if(name) { stream << name->debug_str(state); } else { stream << cf->compiled_code->name()->debug_str(state); } } stream << " in "; if(Symbol* file_sym = try_as<Symbol>(cf->compiled_code->file())) { stream << file_sym->debug_str(state) << ":" << cf->line(state); } else { stream << "<unknown>"; } stream << " (+" << cf->ip(); if(cf->is_inline_frame()) { stream << " inline"; } else if(cf->jitted_p()) { stream << " jit"; } stream << ")"; stream << std::endl; cf = cf->previous; } }
void SignalThread::print_backtraces() { STATE = shared_.env()->state; ThreadList* threads = shared_.threads(); for(ThreadList::iterator i = threads->begin(); i != threads->end(); ++i) { VM* vm = (*i)->as_vm(); if(!vm) continue; if(vm->saved_call_frame()) { utilities::logger::fatal("--- Thread %d backtrace ---", vm->thread_id()); } for(CallFrame* frame = vm->saved_call_frame(); frame; frame = frame->previous) { std::ostringstream stream; if(NativeMethodFrame* nmf = frame->native_method_frame()) { stream << static_cast<void*>(frame) << ": "; NativeMethod* nm = try_as<NativeMethod>(nmf->get_object(nmf->method())); if(nm && nm->name()->symbol_p()) { stream << "capi:" << nm->name()->debug_str(state) << " at "; stream << nm->file()->c_str(state); } else { stream << "unknown capi"; } } else if(frame->compiled_code) { if(frame->is_block_p(state)) { stream << "__block__"; } else { if(SingletonClass* sc = try_as<SingletonClass>(frame->module())) { Object* obj = sc->singleton(); if(Module* mod = try_as<Module>(obj)) { stream << mod->debug_str(state) << "."; } else { if(obj == G(main)) { stream << "MAIN."; } else { stream << "#<" << obj->class_object(state)->debug_str(state) << ":" << (void*)obj->id(state)->to_native() << ">."; } } } else if(IncludedModule* im = try_as<IncludedModule>(frame->module())) { stream << im->module()->debug_str(state) << "#"; } else { Symbol* name; std::string mod_name; if(frame->module()->nil_p()) { mod_name = frame->constant_scope()->module()->debug_str(state); } else { if((name = try_as<Symbol>(frame->module()->module_name()))) { mod_name = name->debug_str(state); } else if((name = try_as<Symbol>( frame->constant_scope()->module()->module_name()))) { mod_name = name->debug_str(state); } else { mod_name = "<anonymous module>"; } } stream << mod_name << "#"; } Symbol* name = try_as<Symbol>(frame->name()); if(name) { stream << name->debug_str(state); } else { stream << frame->compiled_code->name()->debug_str(state); } } stream << " in "; if(Symbol* file_sym = try_as<Symbol>(frame->compiled_code->file())) { stream << file_sym->debug_str(state) << ":" << frame->line(state); } else { stream << "<unknown>"; } stream << " (+" << frame->ip(); if(frame->is_inline_frame()) { stream << " inline"; } else if(frame->jitted_p()) { stream << " jit"; } stream << ")"; } utilities::logger::fatal(stream.str().c_str()); } } }