Exemple #1
0
void wrenDebugPrintStackTrace(ObjFiber* fiber)
{
  if (IS_STRING(fiber->error))
  {
    fprintf(stderr, "%s\n", AS_CSTRING(fiber->error));
  }
  else
  {
    // TODO: Print something a little useful here. Maybe the name of the error's
    // class?
    fprintf(stderr, "[error object]\n");
  }

  for (int i = fiber->numFrames - 1; i >= 0; i--)
  {
    CallFrame* frame = &fiber->frames[i];
    ObjFn* fn = wrenGetFrameFunction(frame);

    // Built-in libraries and method call stubs have no source path and are
    // explicitly omitted from stack traces since we don't want to highlight to
    // a user the implementation detail of what part of a core library is
    // implemented in C and what is in Wren.
    if (fn->debug->sourcePath == NULL ||
        fn->debug->sourcePath->length == 0)
    {
      continue;
    }

    // -1 because IP has advanced past the instruction that it just executed.
    int line = fn->debug->sourceLines[frame->ip - fn->bytecode - 1];
    fprintf(stderr, "[%s line %d] in %s\n",
            fn->debug->sourcePath->value, line, fn->debug->name);
  }
}
Exemple #2
0
const char* wrenGetArgumentString(WrenVM* vm, int index)
{
  ASSERT(vm->foreignCallSlot != NULL, "Must be in foreign call.");
  ASSERT(index >= 0, "index cannot be negative.");
  ASSERT(index < vm->foreignCallNumArgs, "Not that many arguments.");

  // TODO: Check actual value type first.
  return AS_CSTRING(*(vm->foreignCallSlot + index));
}
Exemple #3
0
void wrenDebugPrintStackTrace(WrenVM* vm)
{
  // Bail if the host doesn't enable printing errors.
  if (vm->config.errorFn == NULL) return;
  
  ObjFiber* fiber = vm->fiber;
  if (IS_STRING(fiber->error))
  {
    vm->config.errorFn(vm, WREN_ERROR_RUNTIME,
                       NULL, -1, AS_CSTRING(fiber->error));
  }
  else
  {
    // TODO: Print something a little useful here. Maybe the name of the error's
    // class?
    vm->config.errorFn(vm, WREN_ERROR_RUNTIME,
                       NULL, -1, "[error object]");
  }

  for (int i = fiber->numFrames - 1; i >= 0; i--)
  {
    CallFrame* frame = &fiber->frames[i];
    ObjFn* fn = frame->closure->fn;

    // Skip over stub functions for calling methods from the C API.
    if (fn->module == NULL) continue;
    
    // The built-in core module has no name. We explicitly omit it from stack
    // traces since we don't want to highlight to a user the implementation
    // detail of what part of the core module is written in C and what is Wren.
    if (fn->module->name == NULL) continue;
    
    // -1 because IP has advanced past the instruction that it just executed.
    int line = fn->debug->sourceLines.data[frame->ip - fn->code.data - 1];
    vm->config.errorFn(vm, WREN_ERROR_STACK_TRACE,
                       fn->module->name->value, line,
                       fn->debug->name);
  }
}