static void dump_process_info(int to, void *to_arg, Process *p) { Eterm* sp; ErlMessage* mp; int yreg = -1; ERTS_SMP_MSGQ_MV_INQ2PRIVQ(p); if ((p->trace_flags & F_SENSITIVE) == 0 && p->msg.first) { erts_print(to, to_arg, "=proc_messages:%T\n", p->id); for (mp = p->msg.first; mp != NULL; mp = mp->next) { Eterm mesg = ERL_MESSAGE_TERM(mp); if (is_value(mesg)) dump_element(to, to_arg, mesg); else dump_dist_ext(to, to_arg, mp->data.dist_ext); mesg = ERL_MESSAGE_TOKEN(mp); erts_print(to, to_arg, ":"); dump_element(to, to_arg, mesg); erts_print(to, to_arg, "\n"); } } if ((p->trace_flags & F_SENSITIVE) == 0) { if (p->dictionary) { erts_print(to, to_arg, "=proc_dictionary:%T\n", p->id); erts_deep_dictionary_dump(to, to_arg, p->dictionary, dump_element_nl); } } if ((p->trace_flags & F_SENSITIVE) == 0) { erts_print(to, to_arg, "=proc_stack:%T\n", p->id); for (sp = p->stop; sp < STACK_START(p); sp++) { yreg = stack_element_dump(to, to_arg, p, sp, yreg); } erts_print(to, to_arg, "=proc_heap:%T\n", p->id); for (sp = p->stop; sp < STACK_START(p); sp++) { Eterm term = *sp; if (!is_catch(term) && !is_CP(term)) { heap_dump(to, to_arg, term); } } for (mp = p->msg.first; mp != NULL; mp = mp->next) { Eterm mesg = ERL_MESSAGE_TERM(mp); if (is_value(mesg)) heap_dump(to, to_arg, mesg); mesg = ERL_MESSAGE_TOKEN(mp); heap_dump(to, to_arg, mesg); } if (p->dictionary) { erts_deep_dictionary_dump(to, to_arg, p->dictionary, heap_dump); } } }
void add_event(pthread_t tid, msg_t * data) { if (strlen(data->sender) == 0 || index(data->sender, '!') == NULL) return; field_t field = get_nick(data->sender); seen_t * seen_data = been_seen(tid, field.field); seen_t * kick_data = NULL; if (is_value(data->command, "KICK")) { field_t knick = get_kicked_nick(data->message); kick_data = been_seen(tid, knick.field); } if (seen_data == NULL) { seen_data = malloc(sizeof(seen_t)); memset(seen_data, 0, sizeof(seen_t)); llist_t * result = append_item(seen_list, seen_data); if (result == NULL) free(seen_data); else { time(&(seen_data->time)); memcpy(&(seen_data->msg), data, sizeof(msg_t)); seen_data->tid = tid; seen_list = result; } } else { time(&(seen_data->time)); memcpy(&(seen_data->msg), data, sizeof(msg_t)); } if (kick_data == NULL && is_value(data->command, "KICK")) { kick_data = malloc(sizeof(seen_t)); memset(kick_data, 0, sizeof(seen_t)); llist_t * result = append_item(seen_list, kick_data); if (result == NULL) free(kick_data); else { time(&(kick_data->time)); memcpy(&(kick_data->msg), data, sizeof(msg_t)); kick_data->tid = tid; seen_list = result; } } else if (kick_data != NULL) { time(&(kick_data->time)); memcpy(&(kick_data->msg), data, sizeof(msg_t)); } }
Type* Type_cast_specializeType(Term* caller) { if (is_value(caller->input(0)) && is_type(caller->input(0))) return as_type(term_value(caller->input(0))); return NULL; }
void Term__is_value(VM* vm) { Term* t = as_term_ref(vm->input(0)); bool consideredValue = is_value(t) || t->function == FUNCS.require; set_bool(vm->output(), consideredValue); }
void ExtendedValue::set_obj(Oop* value) { if (value->is_null()) { is_value(T_OBJECT); this->value().set_obj(value); } else { // IMPL_NOTE: Can we merge the code below with Value::set_value() ?? set_oop(value); if (!ObjectHeap::contains_moveable(value->obj())) { _value.set_not_on_heap(); } #if ENABLE_COMPILER_TYPE_INFO FarClass::Raw value_class = value->blueprint(); GUARANTEE(value_class.not_null(), "Sanity"); if (value_class.is_java_class()) { JavaClass::Raw java_class = value_class.obj(); _value.set_class_id(java_class().class_id()); _value.set_is_exact_type(); } #else if (value->is_string()) { _value.set_is_string(); } #endif _value.set_must_be_nonnull(); } }
Export * erts_suspend_process_on_pending_purge_lambda(Process *c_p) { erts_smp_mtx_lock(&purge_state.mtx); if (is_value(purge_state.module)) { /* * The process c_p is about to call a fun in the code * that we are trying to purge. Suspend it and call * erts_code_purger:pending_purge_lambda/3. The process * will be resumed when the purge completes or aborts, * and will then try to do the call again. */ if (purge_state.sp_ix >= purge_state.sp_size) { Eterm *sprocs; purge_state.sp_size += 100; sprocs = erts_alloc(ERTS_ALC_T_PURGE_DATA, (sizeof(ErlFunEntry *) * purge_state.sp_size)); sys_memcpy((void *) sprocs, (void *) purge_state.sprocs, purge_state.sp_ix*sizeof(ErlFunEntry *)); if (purge_state.sprocs != &purge_state.def_sprocs[0]) erts_free(ERTS_ALC_T_PURGE_DATA, purge_state.sprocs); purge_state.sprocs = sprocs; } purge_state.sprocs[purge_state.sp_ix++] = c_p->common.id; erts_suspend(c_p, ERTS_PROC_LOCK_MAIN, NULL); ERTS_VBUMP_ALL_REDS(c_p); } erts_smp_mtx_unlock(&purge_state.mtx); return purge_state.pending_purge_lambda; }
static int within2(Eterm *ptr, Process *p, Eterm *real_htop) { ErlHeapFragment* bp = MBUF(p); ErlMessage* mp = p->msg.first; Eterm *htop = real_htop ? real_htop : HEAP_TOP(p); if (OLD_HEAP(p) && (OLD_HEAP(p) <= ptr && ptr < OLD_HEND(p))) { return 1; } if (HEAP_START(p) <= ptr && ptr < htop) { return 1; } while (bp != NULL) { if (bp->mem <= ptr && ptr < bp->mem + bp->used_size) { return 1; } bp = bp->next; } while (mp) { if (mp->data.attached) { ErlHeapFragment *hfp; if (is_value(ERL_MESSAGE_TERM(mp))) hfp = mp->data.heap_frag; else if (is_not_nil(ERL_MESSAGE_TOKEN(mp))) hfp = erts_dist_ext_trailer(mp->data.dist_ext); else hfp = NULL; if (hfp && hfp->mem <= ptr && ptr < hfp->mem + hfp->used_size) return 1; } mp = mp->next; } return 0; }
BIF_RETTYPE erts_internal_check_process_code_2(BIF_ALIST_2) { int reds = 0; Uint flags; Eterm res; if (is_not_atom(BIF_ARG_1)) goto badarg; if (is_not_small(BIF_ARG_2)) goto badarg; flags = unsigned_val(BIF_ARG_2); if (flags & ~ERTS_CPC_ALL) { goto badarg; } res = erts_check_process_code(BIF_P, BIF_ARG_1, flags, &reds, BIF_P->fcalls); ASSERT(is_value(res)); BIF_RET2(res, reds); badarg: BIF_ERROR(BIF_P, BADARG); }
static Eterm staging_epilogue(Process* c_p, int commit, Eterm res, int is_blocking, struct m* loaded, int nloaded) { #ifdef ERTS_SMP if (is_blocking || !commit) #endif { if (commit) { erts_end_staging_code_ix(); erts_commit_staging_code_ix(); if (loaded) { int i; for (i=0; i < nloaded; i++) { set_default_trace_pattern(loaded[i].module); } } } else { erts_abort_staging_code_ix(); } if (loaded) { erts_free(ERTS_ALC_T_LOADER_TMP, loaded); } if (is_blocking) { erts_smp_thr_progress_unblock(); erts_smp_proc_lock(c_p, ERTS_PROC_LOCK_MAIN); } erts_release_code_write_permission(); return res; } #ifdef ERTS_SMP else { ErtsThrPrgrVal later; ASSERT(is_value(res)); if (loaded) { erts_free(ERTS_ALC_T_LOADER_TMP, loaded); } erts_end_staging_code_ix(); /* * Now we must wait for all schedulers to do a memory barrier before * we can activate and let them access the new staged code. This allows * schedulers to read active code_ix in a safe way while executing * without any memory barriers at all. */ later = erts_thr_progress_later(); erts_thr_progress_wakeup(c_p->scheduler_data, later); erts_notify_code_ix_activation(c_p, later); erts_suspend(c_p, ERTS_PROC_LOCK_MAIN, NULL); /* * handle_code_ix_activation() will do the rest "later" * and resume this process to return 'res'. */ ERTS_BIF_YIELD_RETURN(c_p, res); } #endif }
static int get_nbr(const char *str, char *values) { int i; int nbr; nbr = 1; i = 0; while (str[i] && str[i + 1]) { if (is_value(values, str[i])) { if (!is_value(values, str[i + 1])) nbr++; } i++; } return (nbr); }
Type* type_make_specializeType(Term* caller) { Term* input = caller->input(0); if (input == NULL) return TYPES.any; if (is_value(input) && is_type(input)) return as_type(input); return TYPES.any; }
BIF_RETTYPE erts_internal_check_process_code_2(BIF_ALIST_2) { int reds = 0; Eterm res; Eterm olist = BIF_ARG_2; int allow_gc = 1; if (is_not_atom(BIF_ARG_1)) goto badarg; while (is_list(olist)) { Eterm *lp = list_val(olist); Eterm opt = CAR(lp); if (is_tuple(opt)) { Eterm* tp = tuple_val(opt); switch (arityval(tp[0])) { case 2: switch (tp[1]) { case am_allow_gc: switch (tp[2]) { case am_false: allow_gc = 0; break; case am_true: allow_gc = 1; break; default: goto badarg; } break; default: goto badarg; } break; default: goto badarg; } } else goto badarg; olist = CDR(lp); } if (is_not_nil(olist)) goto badarg; res = erts_check_process_code(BIF_P, BIF_ARG_1, allow_gc, &reds); ASSERT(is_value(res)); BIF_RET2(res, reds); badarg: BIF_ERROR(BIF_P, BADARG); }
Type* specializeType(Term* caller) { Term* input = caller->input(0); if (input == NULL) return &ANY_T; if (is_value(input) && is_type(input)) return as_type(input); return &ANY_T; }
BIF_RETTYPE lists_keymember_3(Process* p, Eterm Key, Eterm Pos, Eterm List) { Eterm res; res = keyfind(BIF_lists_keymember_3, p, Key, Pos, List); if (is_value(res) && is_tuple(res)) { return am_true; } else { return res; } }
int validate_expr(char *expression) { char x, op; int vt, opt, level; char ops[STACK_SIZE]; vt = -1; opt = -1; while ((x = *expression++) != '\0') if (is_value(x)) { vt += 1; } else if (is_op(x)) { level = op_level(x); while (opt >= 0 && level < op_level(ops[opt]) && \ ops[opt] != LEFTP) { op = ops[opt]; opt -= 1; if (op == PLUS || op == MULT) vt -= 1; if (vt < 0) return 0; } if (x == RIGHP) { while (opt >=0 && ops[opt] != LEFTP) { op = ops[opt]; if (op == PLUS || op == MULT) vt -= 1; if (vt < 0) return 0; opt -= 1; } if (opt < 0) return 0; opt -= 1; } else { ops[++opt] = x; } } else if (!is_whitespace(x)){ return 0; } while (opt >= 0) { op = ops[opt]; if (op == LEFTP) return 0; if (op == PLUS || op == MULT) vt -= 1; if (vt < 0) return 0; opt -= 1; } return vt == 0 && opt == -1; }
void find_target_seen(irccfg_t * info, char * nick, char * target) { seen_t * seen_data = been_seen(info->tid, nick); if (seen_data == NULL) respond(info, "PRIVMSG %s :Sorry, I have not seen %s", target, nick); else { time_t temp; time(&temp); temp = temp - seen_data->time; char buffer[CFG_FLD+1]; memset(buffer, 0, CFG_FLD+1); _timetostr(buffer, temp); if (is_value(seen_data->msg.command, "PART") || is_value(seen_data->msg.command, "QUIT")) respond(info, "PRIVMSG %s :%s left approximately %s ago", target, nick, buffer); else if (is_value(seen_data->msg.command, "KICK")) respond(info, "PRIVMSG %s :%s was kicked approximately %s ago", target, nick, buffer); else respond(info, "PRIVMSG %s :%s is right here!\n", target, nick); } }
bool is_considered_config(Term* term) { if (term == NULL) return false; if (has_empty_name(term)) return false; if (!is_value(term)) return false; if (is_declared_state(term)) return false; if (is_hidden(term)) return false; if (is_function(term)) return false; if (is_type(term)) return false; return true; }
void statically_infer_result(Term* term, caValue* result) { Branch scratch; Term* resultTerm = statically_infer_result(&scratch, term); if (is_value(resultTerm)) copy(term_value(resultTerm), result); else { Stack context; evaluate_minimum(&context, resultTerm, result); } }
BIF_RETTYPE lists_keymember_3(BIF_ALIST_3) { Eterm res; res = keyfind(BIF_lists_keymember_3, BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3); if (is_value(res) && is_tuple(res)) { return am_true; } else { return res; } }
Term AtomStore::insert(const char* str) { auto found = find_atom(str); if (found.is_value()) { return found; } auto a = Term::make_atom(atom_id_++); auto interned_str = intern(str); atom_to_str_[a] = interned_str; str_to_atom_[interned_str] = a; return a; }
bool term_needs_no_evaluation(Term* term) { if (term == NULL || is_value(term) || term->function == FUNCS.lambda || term->function == FUNCS.case_func || term->function == FUNCS.input || term->function == FUNCS.output || term->function == FUNCS.extra_output || term->function == FUNCS.comment) return true; return false; }
void find_target_last(irccfg_t * info, char * nick, char * target) { seen_t * seen_data = been_seen(info->tid, nick); if (seen_data == NULL) respond(info, "PRIVMSG %s :Sorry, I have not seen %s\n", target, nick); else { time_t timetmp; time(&timetmp); timetmp = timetmp - seen_data->time; char buff[CFG_FLD+1]; memset(buff, 0 , CFG_FLD+1); _timetostr(buff, timetmp); msg_t * msg = &(seen_data->msg); if (is_value(msg->command, "PART")) respond(info, "PRIVMSG %s :%s left channel %s stating \"%s\" %s ago", target, nick, msg->target, msg->message, buff); else if (is_value(msg->command, "PRIVMSG")) respond(info, "PRIVMSG %s :%s said \"%s\" to %s %s ago", target, nick, msg->message, msg->target, buff); else if (is_value(msg->command, "QUIT")) respond(info, "PRIVMSG %s :%s quit the server stating \"%s\" %s ago", target, nick, msg->message, buff); else if (is_value(msg->command, "KICK")) { field_t field = get_nick(msg->sender); field_t kicked = get_kicked_nick(msg->message); char * reason = index(msg->message, ':'); if (reason == NULL) reason = ""; else reason++; if (strcasecmp(field.field, nick) == 0) respond(info, "PRIVMSG %s :%s kicked %s from %s stating \"%s\" %s ago", target, nick, kicked.field, msg->target, reason, buff); else respond(info, "PRIVMSG %s :%s was kicked by %s from %s (%s) %s ago", target, nick, field.field, msg->target, reason, buff); } else if (is_value(msg->command, "NOTICE")) respond(info, "PRIVMSG %s :%s noted \"%s\" to %s %s ago", target, nick, msg->message, msg->target, buff); else if (is_value(msg->command, "JOIN")) respond(info, "PRIVMSG %s :%s joined %s %s ago", target, nick, msg->target, buff); else if (is_value(msg->command, "MODE")) respond(info, "PRIVMSG %s :%s set \"%s\" on %s %s ago", target, nick, msg->message, msg->target, buff); else if (is_value(msg->command, "NICK")) respond(info, "PRIVMSG %s :%s was last seen changing nicks to %s %s ago", target, nick, msg->target, buff); else respond(info, "PRIVMSG %s :%s issued a %s on %s stating \"%s\" %s ago", target, nick, msg->command, msg->target, msg->message, buff); } }
void if_block_fix_outer_pointers(Term* ifCall, Branch* caseContents) { // disable this return; Branch* contents = nested_contents(ifCall); for (OuterInputIterator it(caseContents); it.unfinished(); ++it) { // Don't worry about outer pointers to values. (This should probably be // standard behavior) if (is_value(it.currentTerm())) continue; // Fetch values from OuterInputIterator, while it's safe. The iterator // may get confused soon, due to inserted terms. Term* currentTerm = it.currentTerm(); Term* input = it.currentInput(); int currentInputIndex = it.currentInputIndex(); // Check if this pointer goes outside the if-block. If so, we'll have to // find the corresponding placeholder (or create a new one). if (input->owningBranch != contents) { Term* placeholder = NULL; int inputIndex = find_input_index_for_pointer(ifCall, input); if (inputIndex >= 0) { placeholder = get_input_placeholder(contents, inputIndex); } else { // Create a new placeholder // This call will result in an inserted term, which will confuse // our OuterInputIterator. So, don't use the iterator again until // the next iteration. placeholder = if_block_add_input(ifCall, input); } input = placeholder; } // Now 'input' points to an if-block placeholder, remap it to the case-local // placeholder. Term* caseLocal = get_input_placeholder(caseContents, input->index); ca_assert(caseLocal != NULL); set_input(currentTerm, currentInputIndex, caseLocal); } }
BIF_RETTYPE erts_internal_check_process_code_1(BIF_ALIST_1) { int reds = 0; Eterm res; if (is_not_atom(BIF_ARG_1)) goto badarg; res = erts_check_process_code(BIF_P, BIF_ARG_1, &reds, BIF_P->fcalls); ASSERT(is_value(res)); BIF_RET2(res, reds); badarg: BIF_ERROR(BIF_P, BADARG); }
void selector_format_source(caValue* source, Term* term) { // Append subscripts for each selector element for (int i=0; i < term->numInputs(); i++) { Term* input = term->input(i); if (is_value(input) && is_string(term_value(input))) { append_phrase(source, ".", input, tok_Dot); append_phrase(source, as_string(term_value(input)), input, tok_Identifier); } else { append_phrase(source, "[", term, tok_LBracket); format_source_for_input(source, term, i, "", ""); append_phrase(source, "]", term, tok_LBracket); } } }
void erts_purge_state_add_fun(ErlFunEntry *fe) { ASSERT(is_value(purge_state.module)); if (purge_state.fe_ix >= purge_state.fe_size) { ErlFunEntry **funs; purge_state.fe_size += 100; funs = erts_alloc(ERTS_ALC_T_PURGE_DATA, sizeof(ErlFunEntry *)*purge_state.fe_size); sys_memcpy((void *) funs, (void *) purge_state.funs, purge_state.fe_ix*sizeof(ErlFunEntry *)); if (purge_state.funs != &purge_state.def_funs[0]) erts_free(ERTS_ALC_T_PURGE_DATA, purge_state.funs); purge_state.funs = funs; } purge_state.funs[purge_state.fe_ix++] = fe; }
bool UsedVarsFixpointIterator::is_used_or_escaping_write( const ptrs::Environment& env, const UsedVarsSet& used_vars, reg_t obj_reg) const { auto pointers = env.get_pointers(obj_reg); if (!pointers.is_value()) { return true; } const auto& heap = env.get_heap(); for (auto pointer : pointers.elements()) { if (used_vars.contains(pointer)) { return true; } if (heap.get(pointer).equals(EscapeDomain(EscapeState::MAY_ESCAPE))) { return true; } } return false; }
void write_expression(CppWriter& writer, Term* term) { if (is_value(term)) { write_value(writer, term); } else if (term->stringProp("syntax:declarationStyle") == "infix") { write_expression(writer, term->input(0)); writer.write(" "); writer.write(term->stringProp("syntax:functionName")); writer.write(" "); write_expression(writer, term->input(1)); } else { writer.write(term->function->name); writer.write("("); for (int i=0; i < term->numInputs(); i++) { if (i != 0) writer.write(", "); write_expression(writer, term->input(0)); } writer.write(")"); } }
seen_t * been_seen(pthread_t tid, char * nick) { llist_t * iterator = seen_list; while (iterator != NULL) { seen_t * seen_data = (seen_t *)(iterator->item); if (seen_data->tid == tid) { field_t anick = get_nick(seen_data->msg.sender); if (strcasecmp(anick.field, nick) == 0) return seen_data; if (is_value(seen_data->msg.command, "KICK")) { field_t kicked = get_kicked_nick(seen_data->msg.message); if (strcasecmp(kicked.field, nick) == 0) return seen_data; } } iterator = iterator->next; } return NULL; }
void write_term(SourceWriter* writer, Term* term) { if (is_comment(term)) { if (is_empty_comment(term)) return; writer->write("// "); writer->write(term->stringProp("comment","").c_str()); writer->newline(); return; } if (is_function(term)) { write_function(writer, term); return; } writer->write(get_unique_name(term)); writer->write(" = "); if (is_value(term)) { write_term_value(writer, term); } else { // function call syntax writer->write(term->function->name.c_str()); writer->write("("); // write inputs for (int i=0; i < term->numInputs(); i++) { if (i > 0) { writer->write(", "); } writer->write(get_unique_name(term)); } } writer->write(";"); writer->newline(); }