Esempio n. 1
0
Value wrenListRemoveAt(WrenVM* vm, ObjList* list, int index)
{
  Value removed = list->elements[index];

  if (IS_OBJ(removed)) WREN_PIN(vm, AS_OBJ(removed));

  // Shift items up.
  for (int i = index; i < list->count - 1; i++)
  {
    list->elements[i] = list->elements[i + 1];
  }

  // If we have too much excess capacity, shrink it.
  if (list->capacity / LIST_GROW_FACTOR >= list->count)
  {
    list->elements = wrenReallocate(vm, list->elements,
        sizeof(Value) * list->capacity,
        sizeof(Value) * (list->capacity / LIST_GROW_FACTOR));
    list->capacity /= LIST_GROW_FACTOR;
  }

  if (IS_OBJ(removed)) WREN_UNPIN(vm);

  list->count--;
  return removed;
}
Esempio n. 2
0
void wrenSymbolTableClear(WrenVM* vm, SymbolTable* symbols)
{
  for (int i = 0; i < symbols->names.count; i++)
  {
    wrenReallocate(vm, symbols->names.data[i], 0, 0);
  }

  wrenStringBufferClear(vm, &symbols->names);
}
Esempio n. 3
0
void wrenFreeObj(WrenVM* vm, Obj* obj)
{
#if WREN_DEBUG_TRACE_MEMORY
  printf("free ");
  wrenPrintValue(OBJ_VAL(obj));
  printf(" @ %p\n", obj);
#endif

  switch (obj->type)
  {
    case OBJ_CLASS:
      wrenMethodBufferClear(vm, &((ObjClass*)obj)->methods);
      break;

    case OBJ_FIBER:
    {
      ObjFiber* fiber = ((ObjFiber*)obj);
      if (fiber->error != NULL) wrenReallocate(vm, fiber->error, 0, 0);
      break;
    }

    case OBJ_FN:
    {
      ObjFn* fn = (ObjFn*)obj;
      wrenReallocate(vm, fn->constants, 0, 0);
      wrenReallocate(vm, fn->bytecode, 0, 0);
      wrenReallocate(vm, fn->debug->name, 0, 0);
      wrenReallocate(vm, fn->debug->sourceLines, 0, 0);
      wrenReallocate(vm, fn->debug, 0, 0);
      break;
    }

    case OBJ_LIST:
      wrenReallocate(vm, ((ObjList*)obj)->elements, 0, 0);
      break;

    case OBJ_STRING:
      wrenReallocate(vm, ((ObjString*)obj)->value, 0, 0);
      break;

    case OBJ_CLOSURE:
    case OBJ_INSTANCE:
    case OBJ_RANGE:
    case OBJ_UPVALUE:
      break;
  }

  wrenReallocate(vm, obj, 0, 0);
}
Esempio n. 4
0
static int addSymbol(WrenVM* vm, SymbolTable* symbols,
                     const char* name, size_t length)
{
  char* heapString = wrenReallocate(vm, NULL, 0, sizeof(char) * (length + 1));
  strncpy(heapString, name, length);
  heapString[length] = '\0';

  wrenStringBufferWrite(vm, &symbols->names, heapString);
  return symbols->names.count - 1;
}
Esempio n. 5
0
// Grows [list] if needed to ensure it can hold [count] elements.
static void ensureListCapacity(WrenVM* vm, ObjList* list, int count)
{
  if (list->capacity >= count) return;

  int capacity = list->capacity * LIST_GROW_FACTOR;
  if (capacity < LIST_MIN_CAPACITY) capacity = LIST_MIN_CAPACITY;

  list->capacity *= 2;
  list->elements = wrenReallocate(vm, list->elements,
      list->capacity * sizeof(Value), capacity * sizeof(Value));
  // TODO: Handle allocation failure.
  list->capacity = capacity;
}
Esempio n. 6
0
void wrenFreeVM(WrenVM* vm)
{
  // TODO: Check for already freed.
  // Free all of the GC objects.
  Obj* obj = vm->first;
  while (obj != NULL)
  {
    Obj* next = obj->next;
    wrenFreeObj(vm, obj);
    obj = next;
  }

  wrenSymbolTableClear(vm, &vm->methodNames);
  wrenSymbolTableClear(vm, &vm->globalNames);
  wrenValueBufferClear(vm, &vm->globals);

  wrenReallocate(vm, vm, 0, 0);
}
Esempio n. 7
0
static void* allocate(WrenVM* vm, size_t size)
{
  return wrenReallocate(vm, NULL, 0, size);
}