inline PacketData *allocate_packet_data(NetworkState *net) { if (!net->first_free_data) { net->first_free_data = push_struct(&net->packet_memchunk, PacketData); net->first_free_data->next_free = 0; } PacketData *data = net->first_free_data; net->first_free_data = data->next_free; *data = {0}; data->next = data; data->prev = data; data->next_free = net->first_data; net->first_data = data; return data; }
static int emit_args(Vector *vals) { SAVE; int r = 0; for (int i = 0; i < vec_len(vals); i++) { Node *v = vec_get(vals, i); if (v->ty->kind == KIND_STRUCT) { emit_addr(v); r += push_struct(v->ty->size); } else if (is_flotype(v->ty)) { emit_expr(v); push_xmm(0); r += 8; } else { emit_expr(v); push("rax"); r += 8; } } return r; }
inline void packet_data_insert_before(NetworkState *net, PacketData *node, u32 sequence, f32 time, i32 size) { if (!net->first_free_data) { net->first_free_data = push_struct(&net->packet_memchunk, PacketData); net->first_free_data->next_free = 0; } PacketData *new_node = net->first_free_data; net->first_free_data = new_node->next_free; *new_node = {0}; new_node->sequence = sequence; new_node->time = time; new_node->size = size; new_node->next = node; new_node->prev = node->prev; new_node->next->prev = new_node; new_node->prev->next = new_node; new_node->next_free = net->first_data; net->first_data = new_node; }
/*-------------------------------------------------------------------------*/ svalue_t * x_map_struct (svalue_t *sp, int num_arg) /* EFUN map() on structs * * mixed * map(struct arg, string func, string|object ob, mixed extra...) * mixed * map(struct arg, closure cl, mixed extra...) * mixed * map(struct arr, mapping map [, int col]) * * Map the elements of <arr> through a filter defined by the other * arguments, and return an array of the elements returned by the filter. * * The filter can be a function call: * * <obj>-><fun>(elem, <extra>...) * * or a mapping query: * * <map>[elem[,idx]] * * In the mapping case, if <map>[elem[,idx]] does not exist, the original * value is returned in the result. * [Note: argument type and range checking for idx is done in v_map()] * * <obj> can both be an object reference or a filename. If <ob> is * omitted, or neither an object nor a string, then this_object() is used. * * As a bonus, all references to destructed objects in <arr> are replaced * by proper 0es. */ { struct_t *st; struct_t *res; svalue_t *arg; svalue_t *v, *w, *x; mp_int cnt; inter_sp = sp; arg = sp - num_arg + 1; st = arg->u.strct; cnt = (mp_int)struct_size(st); if (arg[1].type == T_MAPPING) { /* --- Map through mapping --- */ mapping_t *m; p_int column = 0; /* mapping column to use */ m = arg[1].u.map; if (num_arg > 2) column = arg[2].u.number; res = struct_new(st->type); if (!res) errorf("(map_struct) Out of memory: struct[%"PRIdMPINT"] for result\n", cnt); push_struct(inter_sp, res); /* In case of errors */ for (w = st->member, x = res->member; --cnt >= 0; w++, x++) { if (destructed_object_ref(w)) assign_svalue(w, &const0); v = get_map_value(m, w); if (v == &const0) assign_svalue_no_free(x, w); else assign_svalue_no_free(x, v + column); } if (num_arg > 2) free_svalue(arg+2); free_svalue(arg+1); /* the mapping */ sp = arg; } else { /* --- Map through function call --- */ callback_t cb; int error_index; error_index = setup_efun_callback(&cb, arg+1, num_arg-1); if (error_index >= 0) { vefun_bad_arg(error_index+2, arg); /* NOTREACHED */ return arg; } inter_sp = sp = arg+1; put_callback(sp, &cb); num_arg = 2; res = struct_new(st->type); if (!res) errorf("(map_struct) Out of memory: struct[%"PRIdMPINT"] for result\n", cnt); push_struct(inter_sp, res); /* In case of errors */ /* Loop through arr and res, mapping the values from arr */ for (w = st->member, x = res->member; --cnt >= 0; w++, x++) { if (current_object->flags & O_DESTRUCTED) continue; if (destructed_object_ref(w)) assign_svalue(w, &const0); if (!callback_object(&cb)) errorf("object used by map_array destructed"); push_svalue(w); v = apply_callback(&cb, 1); if (v) { transfer_svalue_no_free(x, v); v->type = T_INVALID; } } free_callback(&cb); } /* The arguments have been removed already, now just replace * the struct on the stack with the result. */ free_struct(st); arg->u.strct = res; /* Keep svalue type T_STRUCT */ return arg; } /* x_map_struct () */