#ifndef COMMON_H
#define COMMON_H

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

typedef enum {
  SLOT_NONE = 0,
  SLOT_PID,
  SLOT_ASYNC,
  SLOT_WITH,
  SLOT_THIS,
  SLOT_NEW_TARGET,
  SLOT_FIELD_COUNT,
  SLOT_FIELDS,
  SLOT_STRICT,
  SLOT_CODE,
  SLOT_CODE_LEN,
  SLOT_CFUNC,
  SLOT_CORO,
  SLOT_PROTO,
  SLOT_FUNC_PROTO,
  SLOT_ASYNC_PROTO,
  SLOT_BUFFER,
  SLOT_TARGET_FUNC,
  SLOT_NAME,
  SLOT_MODULE_CTX,
  SLOT_MAP,
  SLOT_SET,
  SLOT_PRIMITIVE,
  SLOT_PROXY_REF,
  SLOT_BUILTIN,
  SLOT_BRAND,
  SLOT_DATA,
  SLOT_CTOR,
  SLOT_FS_FLAGS,
  SLOT_DEFAULT,
  SLOT_ERROR_BRAND,
  SLOT_ERR_TYPE,
  SLOT_OBSERVABLE_SUBSCRIBER,
  SLOT_SUBSCRIPTION_OBSERVER,
  SLOT_SUBSCRIPTION_CLEANUP,
  SLOT_HOISTED_VARS,
  SLOT_HOISTED_VARS_LEN,
  SLOT_STRICT_ARGS,
  SLOT_NO_FUNC_DECLS,
  SLOT_ITER_STATE,
  SLOT_BYTECODE,
  SLOT_ENTRIES,
  SLOT_SETTLED,
  SLOT_WT_ON_MESSAGE,
  SLOT_WT_ONCE_MESSAGE,
  SLOT_WT_ON_EXIT,
  SLOT_WT_ONCE_EXIT,
  SLOT_WT_PORT_TAG,
  SLOT_WT_PORT_QUEUE,
  SLOT_WT_PORT_HEAD,
  SLOT_WT_PORT_PEER,
  SLOT_WT_PORT_CLOSED,
  SLOT_WT_PORT_STARTED,
  SLOT_WT_PORT_ON_MESSAGE,
  SLOT_WT_PORT_ONCE_MESSAGE,
  SLOT_WT_PORT_PROTO,
  SLOT_WT_ENV_STORE,
  SLOT_NAPI_EXTERNAL_ID,
  SLOT_NAPI_WRAP_ID,
  SLOT_RS_PULL,
  SLOT_RS_CANCEL,
  SLOT_RS_SIZE,
  SLOT_RS_CLOSED,
  SLOT_WS_WRITE,
  SLOT_WS_CLOSE,
  SLOT_WS_ABORT,
  SLOT_WS_READY,
  SLOT_WS_SIGNAL,
  SLOT_HEADERS_GUARD,
  SLOT_REQUEST_HEADERS,
  SLOT_REQUEST_SIGNAL,
  SLOT_REQUEST_ABORT_REASON,
  SLOT_REQUEST_BODY_STREAM,
  SLOT_RESPONSE_HEADERS,
  SLOT_RESPONSE_BODY_STREAM,
  SLOT_PIPE_ABORT_LISTENER,
  SLOT_MATCHALL_RX,
  SLOT_MATCHALL_STR,
  SLOT_MATCHALL_DONE,
  SLOT_MAX = 255
} internal_slot_t;

typedef enum {
  BUILTIN_NONE = 0,
  BUILTIN_OBJECT = 1
} builtin_fn_id_t;

typedef enum {
  BRAND_NONE = 0,
  BRAND_BLOB,
  BRAND_FILE,
  BRAND_HEADERS,
  BRAND_FORMDATA,
  BRAND_URLSEARCHPARAMS,
  BRAND_DATAVIEW,
  BRAND_REQUEST,
  BRAND_RESPONSE,
  BRAND_READABLE_STREAM,
  BRAND_READABLE_STREAM_READER,
  BRAND_READABLE_STREAM_CONTROLLER,
  BRAND_WRITABLE_STREAM,
  BRAND_WRITABLE_STREAM_WRITER,
  BRAND_WRITABLE_STREAM_CONTROLLER,
  BRAND_TRANSFORM_STREAM,
  BRAND_TRANSFORM_STREAM_CONTROLLER,
  BRAND_WASM_MODULE,
  BRAND_WASM_INSTANCE,
  BRAND_WASM_GLOBAL,
  BRAND_WASM_MEMORY,
  BRAND_WASM_TABLE,
  BRAND_WASM_TAG,
  BRAND_WASM_EXCEPTION,
  BRAND_DATE,
  BRAND_MODULE_NAMESPACE
} object_brand_id_t;

static inline void *mantissa_chk(void *p, const char *func) {
  if (!p || ((uintptr_t)p >> 47) == 0) goto ok;

  fprintf(
    stderr,
    "FATAL: %s returned pointer %p outside 47-bit NaN-boxing range\n"
    "Please report this issue with your OS/architecture details.\n", func, p
  );
  
  abort();
  ok: return p;
}

#define ant_calloc(size)       mantissa_chk(calloc(1, size),    "calloc")
#define ant_realloc(ptr, size) mantissa_chk(realloc(ptr, size), "realloc")

#endif
