示例#1
0
  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;
  }
示例#2
0
  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();
  }