void NativeThread::perform() { // Grab the GIL // (automatically unlocked at the end of this function) GlobalLock::LockGuard x(vm_->global_lock()); NativeMethod::init_thread(vm_); VM::set_current(vm_); // Register that when the perform returns and the thread is exitting, to // run delete on this object to free up the memory. set_delete_on_exit(); int stack_boundary = 0; vm_->set_stack_bounds(reinterpret_cast<uintptr_t>(&stack_boundary), stack_size()); vm_->shared.tool_broker()->thread_start(vm_); Object* ret = vm_->thread.get()->send(vm_, NULL, vm_->symbol("__run__")); vm_->shared.tool_broker()->thread_stop(vm_); if(!ret) { if(vm_->thread_state()->raise_reason() == cExit) { if(Fixnum* fix = try_as<Fixnum>(vm_->thread_state()->raise_value())) { exit(fix->to_native()); } else { exit(-1); } } if(Exception* exc = try_as<Exception>(vm_->thread_state()->raise_value())) { std::cout << "Exception at thread toplevel:\n"; std::cout << exc->message_c_str(vm_) << " ("; std::cout << exc->class_object(vm_)->name()->c_str(vm_) << ")\n\n"; // This can blow up. Don't do it. // exc->print_locations(vm_); } } NativeMethod::cleanup_thread(vm_); vm_->thread.get()->detach_native_thread(); VM::discard(vm_); vm_ = NULL; }
void NativeThread::perform() { NativeMethod::init_thread(vm_); // Grab the GIL // (automatically unlocked at the end of this function) GlobalLock::LockGuard x(vm_->global_lock()); // Register that when the perform returns and the thread is exitting, to // run delete on this object to free up the memory. set_delete_on_exit(); CallFrame cf; cf.previous = NULL; cf.static_scope = NULL; cf.name = NULL; cf.cm = NULL; cf.top_scope = NULL; cf.scope = NULL; cf.stack_size = 0; cf.current_unwind = 0; cf.ip = 0; vm_->set_stack_start(&cf); Object* ret = vm_->thread.get()->send(vm_, &cf, vm_->symbol("__run__")); if(!ret) { if(Exception* exc = try_as<Exception>(vm_->thread_state()->raise_value())) { std::cout << "Exception at thread toplevel:\n"; String* message = exc->message(); if(message->nil_p()) { std::cout << "<no message> ("; } else { std::cout << exc->message()->c_str() << " ("; } std::cout << exc->class_object(vm_)->name()->c_str(vm_) << ")\n\n"; // This can blow up. Don't do it. // exc->print_locations(vm_); } } vm_->thread.get()->detach_native_thread(); vm_->discard(); }