/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef ctypes_CTypes_h
#define ctypes_CTypes_h

#include "mozilla/UniquePtr.h"
#include "mozilla/Vector.h"

#include "ffi.h"
#include "jsalloc.h"
#include "jsprf.h"
#include "prlink.h"

#include "ctypes/typedefs.h"
#include "js/GCHashTable.h"
#include "js/Vector.h"
#include "vm/String.h"

namespace js {
namespace ctypes {

/*******************************************************************************
** Utility classes
*******************************************************************************/

// String and AutoString classes, based on Vector.
typedef Vector<char16_t,  0, SystemAllocPolicy> String;
typedef Vector<char16_t, 64, SystemAllocPolicy> AutoString;
typedef Vector<char,      0, SystemAllocPolicy> CString;
typedef Vector<char,     64, SystemAllocPolicy> AutoCString;

// Convenience functions to append, insert, and compare Strings.
template <class T, size_t N, class AP, size_t ArrayLength>
void
AppendString(mozilla::Vector<T, N, AP>& v, const char (&array)[ArrayLength])
{
  // Don't include the trailing '\0'.
  size_t alen = ArrayLength - 1;
  size_t vlen = v.length();
  if (!v.resize(vlen + alen))
    return;

  for (size_t i = 0; i < alen; ++i)
    v[i + vlen] = array[i];
}

template <class T, size_t N, class AP>
void
AppendChars(mozilla::Vector<T, N, AP>& v, const char c, size_t count)
{
  size_t vlen = v.length();
  if (!v.resize(vlen + count))
    return;

  for (size_t i = 0; i < count; ++i)
    v[i + vlen] = c;
}

template <class T, size_t N, class AP>
void
AppendUInt(mozilla::Vector<T, N, AP>& v, unsigned n)
{
  char array[16];
  size_t alen = JS_snprintf(array, 16, "%u", n);
  size_t vlen = v.length();
  if (!v.resize(vlen + alen))
    return;

  for (size_t i = 0; i < alen; ++i)
    v[i + vlen] = array[i];
}

template <class T, size_t N, size_t M, class AP>
void
AppendString(mozilla::Vector<T, N, AP>& v, mozilla::Vector<T, M, AP>& w)
{
  v.append(w.begin(), w.length());
}

template <size_t N, class AP>
void
AppendString(mozilla::Vector<char16_t, N, AP>& v, JSString* str)
{
  MOZ_ASSERT(str);
  JSLinearString* linear = str->ensureLinear(nullptr);
  if (!linear)
    return;
  JS::AutoCheckCannotGC nogc;
  if (linear->hasLatin1Chars())
    v.append(linear->latin1Chars(nogc), linear->length());
  else
    v.append(linear->twoByteChars(nogc), linear->length());
}

template <size_t N, class AP>
void
AppendString(mozilla::Vector<char, N, AP>& v, JSString* str)
{
  MOZ_ASSERT(str);
  size_t vlen = v.length();
  size_t alen = str->length();
  if (!v.resize(vlen + alen))
    return;

  JSLinearString* linear = str->ensureLinear(nullptr);
  if (!linear)
    return;

  JS::AutoCheckCannotGC nogc;
  if (linear->hasLatin1Chars()) {
    const Latin1Char* chars = linear->latin1Chars(nogc);
    for (size_t i = 0; i < alen; ++i)
      v[i + vlen] = char(chars[i]);
  } else {
    const char16_t* chars = linear->twoByteChars(nogc);
    for (size_t i = 0; i < alen; ++i)
      v[i + vlen] = char(chars[i]);
  }
}

template <class T, size_t N, class AP, size_t ArrayLength>
void
PrependString(mozilla::Vector<T, N, AP>& v, const char (&array)[ArrayLength])
{
  // Don't include the trailing '\0'.
  size_t alen = ArrayLength - 1;
  size_t vlen = v.length();
  if (!v.resize(vlen + alen))
    return;

  // Move vector data forward. This is safe since we've already resized.
  memmove(v.begin() + alen, v.begin(), vlen * sizeof(T));

  // Copy data to insert.
  for (size_t i = 0; i < alen; ++i)
    v[i] = array[i];
}

template <size_t N, class AP>
void
PrependString(mozilla::Vector<char16_t, N, AP>& v, JSString* str)
{
  MOZ_ASSERT(str);
  size_t vlen = v.length();
  size_t alen = str->length();
  if (!v.resize(vlen + alen))
    return;

  JSLinearString* linear = str->ensureLinear(nullptr);
  if (!linear)
    return;

  // Move vector data forward. This is safe since we've already resized.
  memmove(v.begin() + alen, v.begin(), vlen * sizeof(char16_t));

  // Copy data to insert.
  JS::AutoCheckCannotGC nogc;
  if (linear->hasLatin1Chars()) {
    const Latin1Char* chars = linear->latin1Chars(nogc);
    for (size_t i = 0; i < alen; i++)
      v[i] = chars[i];
  } else {
    memcpy(v.begin(), linear->twoByteChars(nogc), alen * sizeof(char16_t));
  }
}

template <typename CharT>
extern size_t
GetDeflatedUTF8StringLength(JSContext* maybecx, const CharT* chars,
                            size_t charsLength);

template <typename CharT>
bool
DeflateStringToUTF8Buffer(JSContext* maybecx, const CharT* src, size_t srclen,
                          char* dst, size_t* dstlenp);


/*******************************************************************************
** Function and struct API definitions
*******************************************************************************/

MOZ_ALWAYS_INLINE void
ASSERT_OK(bool ok)
{
  MOZ_ASSERT(ok);
}

// for JS error reporting
enum ErrorNum {
#define MSG_DEF(name, count, exception, format) \
  name,
#include "ctypes/ctypes.msg"
#undef MSG_DEF
  CTYPESERR_LIMIT
};

/**
 * ABI constants that specify the calling convention to use.
 * ctypes.default_abi corresponds to the cdecl convention, and in almost all
 * cases is the correct choice. ctypes.stdcall_abi is provided for calling
 * stdcall functions on Win32, and implies stdcall symbol name decoration;
 * ctypes.winapi_abi is just stdcall but without decoration.
 */
enum ABICode {
  ABI_DEFAULT,
  ABI_STDCALL,
  ABI_WINAPI,
  INVALID_ABI
};

enum TypeCode {
  TYPE_void_t,
#define DEFINE_TYPE(name, type, ffiType) TYPE_##name,
  CTYPES_FOR_EACH_TYPE(DEFINE_TYPE)
#undef DEFINE_TYPE
  TYPE_pointer,
  TYPE_function,
  TYPE_array,
  TYPE_struct
};

// Descriptor of one field in a StructType. The name of the field is stored
// as the key to the hash entry.
struct FieldInfo
{
  JS::Heap<JSObject*> mType;    // CType of the field
  size_t              mIndex;   // index of the field in the struct (first is 0)
  size_t              mOffset;  // offset of the field in the struct, in bytes

  void trace(JSTracer* trc) {
    JS_CallObjectTracer(trc, &mType, "fieldType");
  }
};

struct UnbarrieredFieldInfo
{
  JSObject*           mType;    // CType of the field
  size_t              mIndex;   // index of the field in the struct (first is 0)
  size_t              mOffset;  // offset of the field in the struct, in bytes
};
static_assert(sizeof(UnbarrieredFieldInfo) == sizeof(FieldInfo),
              "UnbarrieredFieldInfo should be the same as FieldInfo but with unbarriered mType");

// Hash policy for FieldInfos.
struct FieldHashPolicy : DefaultHasher<JSFlatString*>
{
  typedef JSFlatString* Key;
  typedef Key Lookup;

  template <typename CharT>
  static uint32_t hash(const CharT* s, size_t n) {
    uint32_t hash = 0;
    for (; n > 0; s++, n--)
      hash = hash * 33 + *s;
    return hash;
  }

  static uint32_t hash(const Lookup& l) {
    JS::AutoCheckCannotGC nogc;
    return l->hasLatin1Chars()
           ? hash(l->latin1Chars(nogc), l->length())
           : hash(l->twoByteChars(nogc), l->length());
  }

  static bool match(const Key& k, const Lookup& l) {
    if (k == l)
      return true;

    if (k->length() != l->length())
      return false;

    return EqualChars(k, l);
  }
};

using FieldInfoHash = GCHashMap<JSFlatString*, FieldInfo, FieldHashPolicy, SystemAllocPolicy>;

void
TraceFieldInfoHash(JSTracer* trc, FieldInfoHash* fields);

// Descriptor of ABI, return type, argument types, and variadicity for a
// FunctionType.
struct FunctionInfo
{
  // Initialized in NewFunctionInfo when !mIsVariadic, but only later, in
  // FunctionType::Call, when mIsVariadic. Not always consistent with
  // mFFITypes, due to lazy initialization when mIsVariadic.
  ffi_cif mCIF;

  // Calling convention of the function. Convert to ffi_abi using GetABI
  // and ObjectValue. Stored as a JSObject* for ease of tracing.
  JS::Heap<JSObject*> mABI;

  // The CType of the value returned by the function.
  JS::Heap<JSObject*> mReturnType;

  // A fixed array of known parameter types, excluding any variadic
  // parameters (if mIsVariadic).
  Vector<JS::Heap<JSObject*>, 0, SystemAllocPolicy> mArgTypes;

  // A variable array of ffi_type*s corresponding to both known parameter
  // types and dynamic (variadic) parameter types. Longer than mArgTypes
  // only if mIsVariadic.
  Vector<ffi_type*, 0, SystemAllocPolicy> mFFITypes;

  // Flag indicating whether the function behaves like a C function with
  // ... as the final formal parameter.
  bool mIsVariadic;
};

// Parameters necessary for invoking a JS function from a C closure.
struct ClosureInfo
{
  JSRuntime* rt;
  JS::Heap<JSObject*> closureObj;  // CClosure object
  JS::Heap<JSObject*> typeObj;     // FunctionType describing the C function
  JS::Heap<JSObject*> thisObj;     // 'this' object to use for the JS function call
  JS::Heap<JSObject*> jsfnObj;     // JS function
  void* errResult;                 // Result that will be returned if the closure throws
  ffi_closure* closure;            // The C closure itself

  // Anything conditionally freed in the destructor should be initialized to
  // nullptr here.
  explicit ClosureInfo(JSRuntime* runtime)
    : rt(runtime)
    , errResult(nullptr)
    , closure(nullptr)
  {}

  ~ClosureInfo() {
    if (closure)
      ffi_closure_free(closure);
    js_free(errResult);
  }
};

bool IsCTypesGlobal(HandleValue v);
bool IsCTypesGlobal(JSObject* obj);

const JSCTypesCallbacks* GetCallbacks(JSObject* obj);

/*******************************************************************************
** JSClass reserved slot definitions
*******************************************************************************/

enum CTypesGlobalSlot {
  SLOT_CALLBACKS = 0, // pointer to JSCTypesCallbacks struct
  SLOT_ERRNO = 1,     // Value for latest |errno|
  SLOT_LASTERROR = 2, // Value for latest |GetLastError|, used only with Windows
  CTYPESGLOBAL_SLOTS
};

enum CABISlot {
  SLOT_ABICODE = 0, // ABICode of the CABI object
  CABI_SLOTS
};

enum CTypeProtoSlot {
  SLOT_POINTERPROTO      = 0,  // ctypes.PointerType.prototype object
  SLOT_ARRAYPROTO        = 1,  // ctypes.ArrayType.prototype object
  SLOT_STRUCTPROTO       = 2,  // ctypes.StructType.prototype object
  SLOT_FUNCTIONPROTO     = 3,  // ctypes.FunctionType.prototype object
  SLOT_CDATAPROTO        = 4,  // ctypes.CData.prototype object
  SLOT_POINTERDATAPROTO  = 5,  // common ancestor of all CData objects of PointerType
  SLOT_ARRAYDATAPROTO    = 6,  // common ancestor of all CData objects of ArrayType
  SLOT_STRUCTDATAPROTO   = 7,  // common ancestor of all CData objects of StructType
  SLOT_FUNCTIONDATAPROTO = 8,  // common ancestor of all CData objects of FunctionType
  SLOT_INT64PROTO        = 9,  // ctypes.Int64.prototype object
  SLOT_UINT64PROTO       = 10, // ctypes.UInt64.prototype object
  SLOT_CTYPES            = 11, // ctypes object
  SLOT_OURDATAPROTO      = 12, // the data prototype corresponding to this object
  CTYPEPROTO_SLOTS
};

enum CTypeSlot {
  SLOT_PROTO     = 0, // 'prototype' property of the CType object
  SLOT_TYPECODE  = 1, // TypeCode of the CType object
  SLOT_FFITYPE   = 2, // ffi_type representing the type
  SLOT_NAME      = 3, // name of the type
  SLOT_SIZE      = 4, // size of the type, in bytes
  SLOT_ALIGN     = 5, // alignment of the type, in bytes
  SLOT_PTR       = 6, // cached PointerType object for type.ptr
  // Note that some of the slots below can overlap, since they're for
  // mutually exclusive types.
  SLOT_TARGET_T  = 7, // (PointerTypes only) 'targetType' property
  SLOT_ELEMENT_T = 7, // (ArrayTypes only) 'elementType' property
  SLOT_LENGTH    = 8, // (ArrayTypes only) 'length' property
  SLOT_FIELDS    = 7, // (StructTypes only) 'fields' property
  SLOT_FIELDINFO = 8, // (StructTypes only) FieldInfoHash table
  SLOT_FNINFO    = 7, // (FunctionTypes only) FunctionInfo struct
  SLOT_ARGS_T    = 8, // (FunctionTypes only) 'argTypes' property (cached)
  CTYPE_SLOTS
};

enum CDataSlot {
  SLOT_CTYPE    = 0, // CType object representing the underlying type
  SLOT_REFERENT = 1, // JSObject this object must keep alive, if any
  SLOT_DATA     = 2, // pointer to a buffer containing the binary data
  SLOT_OWNS     = 3, // TrueValue() if this CData owns its own buffer
  SLOT_FUNNAME  = 4, // JSString representing the function name
  CDATA_SLOTS
};

enum CClosureSlot {
  SLOT_CLOSUREINFO = 0, // ClosureInfo struct
  CCLOSURE_SLOTS
};

enum CDataFinalizerSlot {
  // The type of the value (a CType JSObject).
  // We hold it to permit ImplicitConvert and ToSource.
  SLOT_DATAFINALIZER_VALTYPE           = 0,
  // The type of the function used at finalization (a CType JSObject).
  // We hold it to permit |ToSource|.
  SLOT_DATAFINALIZER_CODETYPE          = 1,
  CDATAFINALIZER_SLOTS
};

enum TypeCtorSlot {
  SLOT_FN_CTORPROTO = 0 // ctypes.{Pointer,Array,Struct}Type.prototype
  // JSFunction objects always get exactly two slots.
};

enum Int64Slot {
  SLOT_INT64 = 0, // pointer to a 64-bit buffer containing the integer
  INT64_SLOTS
};

enum Int64FunctionSlot {
  SLOT_FN_INT64PROTO = 0 // ctypes.{Int64,UInt64}.prototype object
  // JSFunction objects always get exactly two slots.
};

/*******************************************************************************
** Object API definitions
*******************************************************************************/

namespace CType {
  JSObject* Create(JSContext* cx, HandleObject typeProto, HandleObject dataProto,
    TypeCode type, JSString* name, Value size, Value align, ffi_type* ffiType);

  JSObject* DefineBuiltin(JSContext* cx, HandleObject ctypesObj, const char* propName,
    JSObject* typeProto, JSObject* dataProto, const char* name, TypeCode type,
    Value size, Value align, ffi_type* ffiType);

  bool IsCType(JSObject* obj);
  bool IsCTypeProto(JSObject* obj);
  TypeCode GetTypeCode(JSObject* typeObj);
  bool TypesEqual(JSObject* t1, JSObject* t2);
  size_t GetSize(JSObject* obj);
  bool GetSafeSize(JSObject* obj, size_t* result);
  bool IsSizeDefined(JSObject* obj);
  size_t GetAlignment(JSObject* obj);
  ffi_type* GetFFIType(JSContext* cx, JSObject* obj);
  JSString* GetName(JSContext* cx, HandleObject obj);
  JSObject* GetProtoFromCtor(JSObject* obj, CTypeProtoSlot slot);
  JSObject* GetProtoFromType(JSContext* cx, JSObject* obj, CTypeProtoSlot slot);
  const JSCTypesCallbacks* GetCallbacksFromType(JSObject* obj);
} // namespace CType

namespace PointerType {
  JSObject* CreateInternal(JSContext* cx, HandleObject baseType);

  JSObject* GetBaseType(JSObject* obj);
} // namespace PointerType

typedef mozilla::UniquePtr<ffi_type, JS::DeletePolicy<ffi_type>> UniquePtrFFIType;

namespace ArrayType {
  JSObject* CreateInternal(JSContext* cx, HandleObject baseType, size_t length,
    bool lengthDefined);

  JSObject* GetBaseType(JSObject* obj);
  size_t GetLength(JSObject* obj);
  bool GetSafeLength(JSObject* obj, size_t* result);
  UniquePtrFFIType BuildFFIType(JSContext* cx, JSObject* obj);
} // namespace ArrayType

namespace StructType {
  bool DefineInternal(JSContext* cx, JSObject* typeObj, JSObject* fieldsObj);

  const FieldInfoHash* GetFieldInfo(JSObject* obj);
  const FieldInfo* LookupField(JSContext* cx, JSObject* obj, JSFlatString* name);
  JSObject* BuildFieldsArray(JSContext* cx, JSObject* obj);
  UniquePtrFFIType BuildFFIType(JSContext* cx, JSObject* obj);
} // namespace StructType

namespace FunctionType {
  JSObject* CreateInternal(JSContext* cx, HandleValue abi, HandleValue rtype,
    const HandleValueArray& args);

  JSObject* ConstructWithObject(JSContext* cx, JSObject* typeObj,
    JSObject* refObj, PRFuncPtr fnptr, JSObject* result);

  FunctionInfo* GetFunctionInfo(JSObject* obj);
  void BuildSymbolName(JSString* name, JSObject* typeObj,
    AutoCString& result);
} // namespace FunctionType

namespace CClosure {
  JSObject* Create(JSContext* cx, HandleObject typeObj, HandleObject fnObj,
    HandleObject thisObj, Value errVal, PRFuncPtr* fnptr);
} // namespace CClosure

namespace CData {
  JSObject* Create(JSContext* cx, HandleObject typeObj, HandleObject refObj,
    void* data, bool ownResult);

  JSObject* GetCType(JSObject* dataObj);
  void* GetData(JSObject* dataObj);
  bool IsCData(JSObject* obj);
  bool IsCData(HandleValue v);
  bool IsCDataProto(JSObject* obj);

  // Attached by JSAPI as the function 'ctypes.cast'
  bool Cast(JSContext* cx, unsigned argc, Value* vp);
  // Attached by JSAPI as the function 'ctypes.getRuntime'
  bool GetRuntime(JSContext* cx, unsigned argc, Value* vp);
} // namespace CData

namespace Int64 {
  bool IsInt64(JSObject* obj);
} // namespace Int64

namespace UInt64 {
  bool IsUInt64(JSObject* obj);
} // namespace UInt64

} // namespace ctypes
} // namespace js

#endif /* ctypes_CTypes_h */
