// Copies one term 't' to 'dstheap' returns new clone term located in new heap Term copy_one_term(VM& vm, Heap* dstheap, Term t) { // Immediate values go immediately out if (t.is_non_value() || t.is_nil() || t.is_small() || t.is_atom() || t.is_short_pid() || t.is_short_port()) { return t; } if (t.is_tuple()) { Word arity = t.tuple_get_arity(); Term* new_t = (Term*)dstheap->allocate<Word>(layout::Tuple::box_size(arity)); Term* this_t = t.boxed_get_ptr<Term>(); layout::Tuple::arity(new_t) = layout::Tuple::arity(this_t); // Deep clone for (Word i = 0; i < arity; ++i) { layout::Tuple::element(new_t, i) = copy_one_term(vm, dstheap, layout::Tuple::element(this_t, i)); } return Term::make_tuple_prepared(new_t); } if (t.is_boxed()) { if (t.is_boxed_fun()) { BoxedFun* bf = t.boxed_get_ptr<BoxedFun>(); return fun::box_fun(dstheap, bf->fun_entry, bf->pid, bf->frozen); } } t.println(vm); G_TODO("notimpl copy_one_term for some type of term"); }
Term bif_is_process_alive_1(Process* proc, Term pid) { if (!pid.is_short_pid()) { return proc->error_badarg(pid); } if (proc->vm().scheduler().find(pid) == nullptr) { return atom::FALSE; } return atom::TRUE; }
Term bif_exit_2(Process *proc, Term pid, Term what) { // If the first argument is not a pid, or a local port it is an error. if (pid.is_short_port()) { // TODO: check erts_port_synchronous_ops and lookup the port // TODO: call port exit with reason // TODO: check if exited, or if op was scheduled on port throw err::TODO("exit/2 for local port"); } // not sure why? // TODO: if (pid.is_remote_port() && belongs to current node) return TRUE // If it is a remote pid, send a signal to the remote node. if (pid.is_remote_pid()) { // TODO: lookup the remote pid // TODO: if remote pid refers to current node: return TRUE // TODO: prepare distributed signal and send it if possible throw err::TODO("exit/2 for remote pid"); } else if (!pid.is_short_pid()) { return proc->error_badarg(); } else { // The pid is internal. Verify that it refers to an existing process. // TODO: Find process, honour locks (for SMP) Process* p = proc->vm().scheduler().find(pid); // TODO: Send an exit signal if (p) { throw err::TODO("notimpl exit signals"); } // TODO: if sending to self - remove ERTS_PROC_LOCK_MAIN (whatever that is) // TODO: (smp) unlock // We may have exited ourselves and may have to take action. // TODO: if we killed self, do a nice exit: ERTS_BIF_CHK_EXITED(BIF_P) return atom::TRUE; } }