int test_vm_alloc() { int i; int *baz, *buf = vm_zalloc(tvm, sizeof(int) * 16); ASSERT_NOTNULL(buf); for (i = 0; i < 16; ++i) ASSERT_EQ(int, buf[i], 0); vm_free(tvm, buf); buf = vm_zalloc(tvm, sizeof(int) * 4096); ASSERT_NOTNULL(buf); for (i = 0; i < 4096; ++i) ASSERT_EQ(int, buf[i], 0); vm_free(tvm, buf); buf = vm_zalloc(tvm, sizeof(int) * 32); for (i = 0; i < 32; ++i) ASSERT_EQ(int, buf[i], 0); baz = vm_realloc(tvm, buf, sizeof(int) * 4096); ASSERT_TRUE(buf == baz); for (i = 0; i < 32; ++i) ASSERT_EQ(int, baz[i], 0); vm_free(tvm, vm_zalloc(tvm, 16)); buf = vm_realloc(tvm, baz, sizeof(int) * 1024 * 4096); ASSERT_FALSE(buf == baz); return 0; }
void gamesnd_add_sound_slot(int type, int num) { const int increase_by = 5; int i; switch (type) { case GAME_SND: { Assert(Snds != NULL); Assert(num < (Num_game_sounds + increase_by)); if (num >= Num_game_sounds) { Snds = (game_snd*)vm_realloc(Snds, sizeof(game_snd) * (Num_game_sounds + increase_by)); Verify(Snds != NULL); Num_game_sounds += increase_by; // default all new entries for (i = (Num_game_sounds - increase_by); i < Num_game_sounds; i++) { gamesnd_init_struct(&Snds[i]); } } } break; case IFACE_SND: { Assert(Snds_iface != NULL); Assert(num < (Num_game_sounds + increase_by)); if (num >= Num_iface_sounds) { Snds_iface = (game_snd*)vm_realloc(Snds_iface, sizeof(game_snd) * (Num_iface_sounds + increase_by)); Verify(Snds_iface != NULL); Num_iface_sounds += increase_by; Assert(Snds_iface_handle != NULL); Snds_iface_handle = (int*)vm_realloc(Snds_iface_handle, sizeof(int) * Num_iface_sounds); Verify(Snds_iface_handle != NULL); // default all new entries for (i = (Num_iface_sounds - increase_by); i < Num_iface_sounds; i++) { gamesnd_init_struct(&Snds_iface[i]); Snds_iface_handle[i] = -1; } } } break; default: Int3(); } }
vector_t *vector_new(vm_t *vm, uint32_t count) { value_t *data = NULL; if (count > 0) { data = (value_t *) vm_realloc(vm, NULL, 0, sizeof(value_t) * count); } vector_t *vec = (vector_t *) vm_realloc(vm, NULL, 0, sizeof(vector_t)); ptr_init(vm, &vec->p, T_VECTOR); vec->capacity = count; vec->count = count; vec->data = data; return vec; }
// Pushes <val> to the back of <vec> // (equivalent to std::vector.push_back(val)) void vector_push(vm_t *vm, vector_t *vec, value_t val) { if (vec->count + 1 > vec->capacity) { uint32_t capacity = vec->capacity ? vec->capacity << 1 : 2; vec->data = (value_t *) vm_realloc(vm, vec->data, vec->capacity * sizeof(value_t), capacity * sizeof(value_t)); vec->capacity = capacity; } vec->data[vec->count++] = val; }
/* *** ptrvalue creating *** */ cons_t *cons_new(vm_t *vm) { cons_t *cons = (cons_t *) vm_realloc(vm, NULL, 0, sizeof(cons_t)); ptr_init(vm, &cons->p, T_CONS); cons->car = NIL_VAL; cons->cdr = NIL_VAL; return cons; }
primitive_t *primitive_new(vm_t *vm, primitive_fn fn) { primitive_t *prim = (primitive_t *) vm_realloc(vm, NULL, 0, sizeof(primitive_t)); ptr_init(vm, &prim->p, T_PRIMITIVE); prim->name = NULL; prim->fn = fn; return prim; }
env_t *env_new(vm_t *vm, value_t variables, env_t *up) { env_t *env = (env_t *) vm_realloc(vm, NULL, 0, sizeof(env_t)); ptr_init(vm, &env->p, T_ENV); env->variables = variables; env->up = up; vm->env = env; return env; }
function_t *function_new(vm_t *vm, env_t *env, value_t params, value_t body) { function_t *fn = (function_t *) vm_realloc(vm, NULL, 0, sizeof(function_t)); ptr_init(vm, &fn->p, T_FUNCTION); fn->name = NULL; fn->env = env; fn->params = params; fn->body = body; return fn; }
function_t *macro_new(vm_t *vm, env_t *env, value_t params, value_t body) { function_t *macro = (function_t *) vm_realloc(vm, NULL, 0, sizeof(function_t)); ptr_init(vm, ¯o->p, T_MACRO); macro->name = NULL; macro->env = env; macro->params = params; macro->body = body; return macro; }
static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { lua_State *L = (lua_State *)ud; int mode = L == NULL ? 0 : G(L)->egcmode; void *nptr; if (nsize == 0) { #ifdef __LINKIT_V1__ vm_free(ptr); #else free(ptr); #endif return NULL; } if (L != NULL && (mode & EGC_ALWAYS)) /* always collect memory if requested */ luaC_fullgc(L); if(nsize > osize && L != NULL) { #if defined(LUA_STRESS_EMERGENCY_GC) luaC_fullgc(L); #endif if(G(L)->memlimit > 0 && (mode & EGC_ON_MEM_LIMIT) && l_check_memlimit(L, nsize - osize)) return NULL; } #ifdef __LINKIT_V1__ nptr = vm_realloc(ptr, nsize); #else nptr = realloc(ptr, nsize); #endif if (nptr == NULL && L != NULL && (mode & EGC_ON_ALLOC_FAILURE)) { luaC_fullgc(L); /* emergency full collection. */ #ifdef __LINKIT_V1__ nptr = vm_realloc(ptr, nsize); #else nptr = realloc(ptr, nsize); /* try allocation again */ #endif } return nptr; }
string_t *string_new(vm_t *vm, const char *text, size_t len) { string_t *str = (string_t *) vm_realloc( vm, NULL, 0, sizeof(string_t) + sizeof(char) * (len + 1)); ptr_init(vm, &str->p, T_STRING); str->len = (uint32_t) len; str->value[len] = '\0'; if (len > 0 && text != NULL) { memcpy(str->value, text, len); } hash_string(str); return str; }
void ptr_free(vm_t *vm, ptrvalue_t *ptr) { if (ptr->type == T_STRING) { vm_realloc(vm, ptr, 0, 0); } else if (ptr->type == T_CONS) { vm_realloc(vm, ptr, 0, 0); } else if (ptr->type == T_SYMBOL) { symbol_t *ptr_sym = (symbol_t *) ptr; symbol_t *prev = NULL; symbol_t *s = vm->symbol_table; while (s != NULL) { if (s->len == ptr_sym->len && memcmp(s->name, ptr_sym->name, s->len * sizeof(char)) == 0) { if (prev != NULL) { prev->next = s->next; vm->symbol_table = prev; } else { vm->symbol_table = s->next; } break; } prev = s; s = s->next; } vm_realloc(vm, ptr, 0, 0); } else if (ptr->type == T_PRIMITIVE) { vm_realloc(vm, ptr, 0, 0); } else if (ptr->type == T_FUNCTION || ptr->type == T_MACRO) { vm_realloc(vm, ptr, 0, 0); } else if (ptr->type == T_VECTOR) { vector_t *vec = (vector_t *) ptr; vm_realloc(vm, vec->data, 0, 0); vec->data = NULL; vec->capacity = 0; vec->count = 0; vm_realloc(vm, ptr, 0, 0); } else if (ptr->type == T_ENV) { vm_realloc(vm, ptr, 0, 0); } }
static char *read_line_from_file(FILE *fp) { char *buf, *buf_start; int buflen, len, eol; buflen = 80; buf = (char *)vm_malloc(buflen); buf_start = buf; eol = 0; do { if (buf == NULL) { return NULL; } if (fgets(buf_start, 80, fp) == NULL) { if (buf_start == buf) { vm_free(buf); return NULL; } else { *buf_start = 0; return buf; } } len = strlen(buf_start); if (buf_start[len - 1] == '\n') { buf_start[len - 1] = 0; eol = 1; } else { buflen += 80; buf = (char *)vm_realloc(buf, buflen); /* be sure to skip over the proper amount of nulls */ buf_start = buf + (buflen - 80) - (buflen / 80) + 1; } } while (!eol); return buf; }
symbol_t *symbol_new(vm_t *vm, const char *name, size_t len) { if (len == 0 || name == NULL) { error_runtime(vm, "NULL or 0-length symbols are not allowed!"); return NULL; } symbol_t *sym = (symbol_t *) vm_realloc( vm, NULL, 0, sizeof(symbol_t) + sizeof(char) * (len + 1)); ptr_init(vm, &sym->p, T_SYMBOL); sym->len = (uint32_t) len; sym->name[len] = '\0'; sym->next = NULL; memcpy(sym->name, name, len); return sym; }
void *realloc_mre(void *memory, size_t new_size){ /* MSC: void* realloc(void *Memory, size_t NewSize); MRE: void *vm_realloc(void* p, int size); */ /* Update: This will fail if memory is 0x00000000. You'd except it to but in C, it realises that it is nothing and allocates new memory. The difference between realloc and free then malloc is that realloc preserves the contents. If memory variable is none, then we don't care because there is no array or information in this. So I think we should force this implementation to check and manually call malloc */ if (memory == NULL){ return vm_malloc((int)new_size); } vm_realloc(memory, (int)new_size); }
// Adds the pair to the pair list void obj_add_pair( object *A, object *B, int check_time, int add_to_end ) { uint ctype; int (*check_collision)( obj_pair *pair ); int swapped = 0; check_collision = NULL; if ( Num_pairs_allocated == 0 ) return; // don't have anything to add the pair too if ( A==B ) return; // Don't check collisions with yourself if ( !(A->flags[Object::Object_Flags::Collides]) ) return; // This object doesn't collide with anything if ( !(B->flags[Object::Object_Flags::Collides]) ) return; // This object doesn't collide with anything if ((A->flags[Object::Object_Flags::Immobile]) && (B->flags[Object::Object_Flags::Immobile])) return; // Two immobile objects will never collide with each other // Make sure you're not checking a parent with it's kid or vicy-versy // if ( A->parent_sig == B->signature && !(A->type == OBJ_SHIP && B->type == OBJ_DEBRIS) ) return; // if ( B->parent_sig == A->signature && !(A->type == OBJ_DEBRIS && B->type == OBJ_SHIP) ) return; if ( reject_obj_pair_on_parent(A,B) ) { return; } Assert( A->type < 127 ); Assert( B->type < 127 ); ctype = COLLISION_OF(A->type,B->type); switch( ctype ) { case COLLISION_OF(OBJ_WEAPON,OBJ_SHIP): swapped = 1; check_collision = collide_ship_weapon; break; case COLLISION_OF(OBJ_SHIP, OBJ_WEAPON): check_collision = collide_ship_weapon; break; case COLLISION_OF(OBJ_DEBRIS, OBJ_WEAPON): check_collision = collide_debris_weapon; break; case COLLISION_OF(OBJ_WEAPON, OBJ_DEBRIS): swapped = 1; check_collision = collide_debris_weapon; break; case COLLISION_OF(OBJ_DEBRIS, OBJ_SHIP): check_collision = collide_debris_ship; break; case COLLISION_OF(OBJ_SHIP, OBJ_DEBRIS): check_collision = collide_debris_ship; swapped = 1; break; case COLLISION_OF(OBJ_ASTEROID, OBJ_WEAPON): // Only check collision's with player weapons // if ( Objects[B->parent].flags[Object::Object_Flags::Player_ship] ) { check_collision = collide_asteroid_weapon; // } break; case COLLISION_OF(OBJ_WEAPON, OBJ_ASTEROID): swapped = 1; // Only check collision's with player weapons // if ( Objects[A->parent].flags[Object::Object_Flags::Player_ship] ) { check_collision = collide_asteroid_weapon; // } break; case COLLISION_OF(OBJ_ASTEROID, OBJ_SHIP): // Only check collisions with player ships // if ( B->flags[Object::Object_Flags::Player_ship] ) { check_collision = collide_asteroid_ship; // } break; case COLLISION_OF(OBJ_SHIP, OBJ_ASTEROID): // Only check collisions with player ships // if ( A->flags[Object::Object_Flags::Player_ship] ) { check_collision = collide_asteroid_ship; // } swapped = 1; break; case COLLISION_OF(OBJ_SHIP,OBJ_SHIP): check_collision = collide_ship_ship; break; case COLLISION_OF(OBJ_BEAM, OBJ_SHIP): if(beam_collide_early_out(A, B)){ return; } check_collision = beam_collide_ship; break; case COLLISION_OF(OBJ_BEAM, OBJ_ASTEROID): if(beam_collide_early_out(A, B)){ return; } check_collision = beam_collide_asteroid; break; case COLLISION_OF(OBJ_BEAM, OBJ_DEBRIS): if(beam_collide_early_out(A, B)){ return; } check_collision = beam_collide_debris; break; case COLLISION_OF(OBJ_BEAM, OBJ_WEAPON): if(beam_collide_early_out(A, B)){ return; } check_collision = beam_collide_missile; break; case COLLISION_OF(OBJ_WEAPON, OBJ_WEAPON): { weapon_info *awip, *bwip; awip = &Weapon_info[Weapons[A->instance].weapon_info_index]; bwip = &Weapon_info[Weapons[B->instance].weapon_info_index]; if ((awip->weapon_hitpoints > 0) || (bwip->weapon_hitpoints > 0)) { if (bwip->weapon_hitpoints == 0) { check_collision = collide_weapon_weapon; swapped=1; } else { check_collision = collide_weapon_weapon; } } /* if (awip->subtype != WP_LASER || bwip->subtype != WP_LASER) { if (awip->subtype == WP_LASER) { if ( bwip->wi_flags & WIF_BOMB ) { check_collision = collide_weapon_weapon; } } else if (bwip->subtype == WP_LASER) { if ( awip->wi_flags & WIF_BOMB ) { check_collision = collide_weapon_weapon; swapped=1; } } else { if ( (awip->wi_flags&WIF_BOMB) || (bwip->wi_flags&WIF_BOMB) ) { check_collision = collide_weapon_weapon; } } } */ /* int atype, btype; atype = Weapon_info[Weapons[A->instance].weapon_info_index].subtype; btype = Weapon_info[Weapons[B->instance].weapon_info_index].subtype; if ((atype == WP_LASER) && (btype == WP_MISSILE)) check_collision = collide_weapon_weapon; else if ((atype == WP_MISSILE) && (btype == WP_LASER)) { check_collision = collide_weapon_weapon; swapped = 1; } else if ((atype == WP_MISSILE) && (btype == WP_MISSILE)) check_collision = collide_weapon_weapon; */ break; } default: return; } // Swap them if needed if ( swapped ) { object *tmp = A; A = B; B = tmp; } // if there are any more obj_pair checks // we should then add function int maybe_not_add_obj_pair() // MWA -- 4/1/98 -- I'd do it, but I don't want to bust anything, so I'm doing my stuff here instead :-) //if ( MULTIPLAYER_CLIENT && !(Netgame.debug_flags & NETD_FLAG_CLIENT_NODAMAGE)){ // multiplayer clients will only do ship/ship collisions, and their own ship to boot // if ( check_collision != collide_ship_ship ){ // return; // } // if ( (A != Player_obj) && (B != Player_obj) ){ // return; // } //} // only check debris:weapon collisions for player if (check_collision == collide_debris_weapon) { // weapon is B if ( !(Weapon_info[Weapons[B->instance].weapon_info_index].wi_flags & WIF_TURNS) ) { // check for dumbfire weapon // check if debris is behind laser float vdot; if (Weapon_info[Weapons[B->instance].weapon_info_index].subtype == WP_LASER) { vec3d velocity_rel_weapon; vm_vec_sub(&velocity_rel_weapon, &B->phys_info.vel, &A->phys_info.vel); vdot = -vm_vec_dot(&velocity_rel_weapon, &B->orient.vec.fvec); } else { vdot = vm_vec_dot( &A->phys_info.vel, &B->phys_info.vel); } if ( vdot <= 0.0f ) { // They're heading in opposite directions... // check their positions vec3d weapon2other; vm_vec_sub( &weapon2other, &A->pos, &B->pos ); float pdot = vm_vec_dot( &B->orient.vec.fvec, &weapon2other ); if ( pdot <= -A->radius ) { // The other object is behind the weapon by more than // its radius, so it will never hit... return; } } // check dist vs. dist moved during weapon lifetime vec3d delta_v; vm_vec_sub(&delta_v, &B->phys_info.vel, &A->phys_info.vel); if (vm_vec_dist_squared(&A->pos, &B->pos) > (vm_vec_mag_squared(&delta_v)*Weapons[B->instance].lifeleft*Weapons[B->instance].lifeleft)) { return; } // for nonplayer ships, only create collision pair if close enough if ( (B->parent >= 0) && !((Objects[B->parent].signature == B->parent_sig) && (Objects[B->parent].flags[Object::Object_Flags::Player_ship])) && (vm_vec_dist(&B->pos, &A->pos) < (4.0f*A->radius + 200.0f)) ) return; } } // don't check same team laser:ship collisions on small ships if not player if (check_collision == collide_ship_weapon) { // weapon is B if ( (B->parent >= 0) && (Objects[B->parent].signature == B->parent_sig) && !(Objects[B->parent].flags[Object::Object_Flags::Player_ship]) && (Ships[Objects[B->parent].instance].team == Ships[A->instance].team) && (Ship_info[Ships[A->instance].ship_info_index].is_small_ship()) && (Weapon_info[Weapons[B->instance].weapon_info_index].subtype == WP_LASER) ) { pairs_not_created++; return; } } if ( !check_collision ) return; Pairs_created++; // At this point, we have determined that collisions between // these two should be checked, so add the pair to the // collision pair list. if ( pair_free_list.next == NULL ) { nprintf(( "collision", "Out of object pairs!! Not all collisions will work!\n" )); return; } Num_pairs++; /* if (Num_pairs > Num_pairs_hwm) { Num_pairs_hwm = Num_pairs; //nprintf(("AI", "Num_pairs high water mark = %i\n", Num_pairs_hwm)); } */ if ( Num_pairs >= (Num_pairs_allocated - 20) ) { int i; Assert( Obj_pairs != NULL ); int old_pair_count = Num_pairs_allocated; obj_pair *old_pairs_ptr = Obj_pairs; // determine where we need to update the "previous" ptrs to int prev_free_mark = (pair_free_list.next - old_pairs_ptr); int prev_used_mark = (pair_used_list.next - old_pairs_ptr); Obj_pairs = (obj_pair*) vm_realloc( Obj_pairs, sizeof(obj_pair) * (Num_pairs_allocated + PAIRS_BUMP) ); // allow us to fail here and only if we don't do we setup the new pairs if (Obj_pairs == NULL) { // failed, just go back to the way we were and use only the pairs we have already Obj_pairs = old_pairs_ptr; } else { Num_pairs_allocated += PAIRS_BUMP; Assert( Obj_pairs != NULL ); // have to reset all of the "next" ptrs for the old set and handle the new set for (i = 0; i < Num_pairs_allocated; i++) { if (i >= old_pair_count) { memset( &Obj_pairs[i], 0, sizeof(obj_pair) ); Obj_pairs[i].next = &Obj_pairs[i+1]; } else { if (Obj_pairs[i].next != NULL) { // the "next" ptr will end up going backwards for used pairs so we have // to allow for that with this craziness... int next_mark = (Obj_pairs[i].next - old_pairs_ptr); Obj_pairs[i].next = &Obj_pairs[next_mark]; } // catch that last NULL from the previously allocated set if ( i == (old_pair_count-1) ) { Obj_pairs[i].next = &Obj_pairs[i+1]; } } } Obj_pairs[Num_pairs_allocated-1].next = NULL; // reset the "previous" ptrs pair_free_list.next = &Obj_pairs[prev_free_mark]; pair_used_list.next = &Obj_pairs[prev_used_mark]; } } // get a new obj_pair from the free list obj_pair * new_pair = pair_free_list.next; pair_free_list.next = new_pair->next; if ( add_to_end ) { obj_pair *last, *tmp; last = tmp = pair_used_list.next; while( tmp != NULL ) { if ( tmp->next == NULL ) last = tmp; tmp = tmp->next; } if ( last == NULL ) last = &pair_used_list; last->next = new_pair; Assert(new_pair != NULL); new_pair->next = NULL; } else { new_pair->next = pair_used_list.next; pair_used_list.next = new_pair; } A->num_pairs++; B->num_pairs++; new_pair->a = A; new_pair->b = B; new_pair->check_collision = check_collision; if ( check_time == -1 ){ new_pair->next_check_time = timestamp(0); // 0 means instantly time out } else { new_pair->next_check_time = check_time; } }