Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #ifndef ctypes_CTypes_h |
michael@0 | 7 | #define ctypes_CTypes_h |
michael@0 | 8 | |
michael@0 | 9 | #include "ffi.h" |
michael@0 | 10 | #include "jsalloc.h" |
michael@0 | 11 | #include "prlink.h" |
michael@0 | 12 | |
michael@0 | 13 | #include "js/HashTable.h" |
michael@0 | 14 | #include "js/Vector.h" |
michael@0 | 15 | #include "vm/String.h" |
michael@0 | 16 | |
michael@0 | 17 | namespace js { |
michael@0 | 18 | namespace ctypes { |
michael@0 | 19 | |
michael@0 | 20 | /******************************************************************************* |
michael@0 | 21 | ** Utility classes |
michael@0 | 22 | *******************************************************************************/ |
michael@0 | 23 | |
michael@0 | 24 | // Class that takes ownership of a pointer T*, and calls cx->delete_() or |
michael@0 | 25 | // cx->array_delete() upon destruction. |
michael@0 | 26 | template<class T> |
michael@0 | 27 | class AutoPtr { |
michael@0 | 28 | private: |
michael@0 | 29 | typedef AutoPtr<T> self_type; |
michael@0 | 30 | |
michael@0 | 31 | public: |
michael@0 | 32 | AutoPtr() : mPtr(nullptr) { } |
michael@0 | 33 | explicit AutoPtr(T* ptr) : mPtr(ptr) { } |
michael@0 | 34 | ~AutoPtr() { js_delete(mPtr); } |
michael@0 | 35 | |
michael@0 | 36 | T* operator->() { return mPtr; } |
michael@0 | 37 | bool operator!() { return mPtr == nullptr; } |
michael@0 | 38 | T& operator[](size_t i) { return *(mPtr + i); } |
michael@0 | 39 | // Note: we cannot safely provide an 'operator T*()', since this would allow |
michael@0 | 40 | // the compiler to perform implicit conversion from one AutoPtr to another |
michael@0 | 41 | // via the constructor AutoPtr(T*). |
michael@0 | 42 | |
michael@0 | 43 | T* get() { return mPtr; } |
michael@0 | 44 | void set(T* other) { JS_ASSERT(mPtr == nullptr); mPtr = other; } |
michael@0 | 45 | T* forget() { T* result = mPtr; mPtr = nullptr; return result; } |
michael@0 | 46 | |
michael@0 | 47 | self_type& operator=(T* rhs) { mPtr = rhs; return *this; } |
michael@0 | 48 | |
michael@0 | 49 | private: |
michael@0 | 50 | // Do not allow copy construction or assignment from another AutoPtr. |
michael@0 | 51 | AutoPtr(AutoPtr<T>&); |
michael@0 | 52 | self_type& operator=(AutoPtr<T>& rhs); |
michael@0 | 53 | |
michael@0 | 54 | T* mPtr; |
michael@0 | 55 | }; |
michael@0 | 56 | |
michael@0 | 57 | // Container class for Vector, using SystemAllocPolicy. |
michael@0 | 58 | template<class T, size_t N = 0> |
michael@0 | 59 | class Array : public Vector<T, N, SystemAllocPolicy> |
michael@0 | 60 | { |
michael@0 | 61 | static_assert(!mozilla::IsSame<T, JS::Value>::value, |
michael@0 | 62 | "use JS::AutoValueVector instead"); |
michael@0 | 63 | }; |
michael@0 | 64 | |
michael@0 | 65 | // String and AutoString classes, based on Vector. |
michael@0 | 66 | typedef Vector<jschar, 0, SystemAllocPolicy> String; |
michael@0 | 67 | typedef Vector<jschar, 64, SystemAllocPolicy> AutoString; |
michael@0 | 68 | typedef Vector<char, 0, SystemAllocPolicy> CString; |
michael@0 | 69 | typedef Vector<char, 64, SystemAllocPolicy> AutoCString; |
michael@0 | 70 | |
michael@0 | 71 | // Convenience functions to append, insert, and compare Strings. |
michael@0 | 72 | template <class T, size_t N, class AP, size_t ArrayLength> |
michael@0 | 73 | void |
michael@0 | 74 | AppendString(Vector<T, N, AP> &v, const char (&array)[ArrayLength]) |
michael@0 | 75 | { |
michael@0 | 76 | // Don't include the trailing '\0'. |
michael@0 | 77 | size_t alen = ArrayLength - 1; |
michael@0 | 78 | size_t vlen = v.length(); |
michael@0 | 79 | if (!v.resize(vlen + alen)) |
michael@0 | 80 | return; |
michael@0 | 81 | |
michael@0 | 82 | for (size_t i = 0; i < alen; ++i) |
michael@0 | 83 | v[i + vlen] = array[i]; |
michael@0 | 84 | } |
michael@0 | 85 | |
michael@0 | 86 | template <class T, size_t N, size_t M, class AP> |
michael@0 | 87 | void |
michael@0 | 88 | AppendString(Vector<T, N, AP> &v, Vector<T, M, AP> &w) |
michael@0 | 89 | { |
michael@0 | 90 | v.append(w.begin(), w.length()); |
michael@0 | 91 | } |
michael@0 | 92 | |
michael@0 | 93 | template <size_t N, class AP> |
michael@0 | 94 | void |
michael@0 | 95 | AppendString(Vector<jschar, N, AP> &v, JSString* str) |
michael@0 | 96 | { |
michael@0 | 97 | JS_ASSERT(str); |
michael@0 | 98 | const jschar *chars = str->getChars(nullptr); |
michael@0 | 99 | if (!chars) |
michael@0 | 100 | return; |
michael@0 | 101 | v.append(chars, str->length()); |
michael@0 | 102 | } |
michael@0 | 103 | |
michael@0 | 104 | template <size_t N, class AP> |
michael@0 | 105 | void |
michael@0 | 106 | AppendString(Vector<char, N, AP> &v, JSString* str) |
michael@0 | 107 | { |
michael@0 | 108 | JS_ASSERT(str); |
michael@0 | 109 | size_t vlen = v.length(); |
michael@0 | 110 | size_t alen = str->length(); |
michael@0 | 111 | if (!v.resize(vlen + alen)) |
michael@0 | 112 | return; |
michael@0 | 113 | |
michael@0 | 114 | const jschar *chars = str->getChars(nullptr); |
michael@0 | 115 | if (!chars) |
michael@0 | 116 | return; |
michael@0 | 117 | |
michael@0 | 118 | for (size_t i = 0; i < alen; ++i) |
michael@0 | 119 | v[i + vlen] = char(chars[i]); |
michael@0 | 120 | } |
michael@0 | 121 | |
michael@0 | 122 | template <class T, size_t N, class AP, size_t ArrayLength> |
michael@0 | 123 | void |
michael@0 | 124 | PrependString(Vector<T, N, AP> &v, const char (&array)[ArrayLength]) |
michael@0 | 125 | { |
michael@0 | 126 | // Don't include the trailing '\0'. |
michael@0 | 127 | size_t alen = ArrayLength - 1; |
michael@0 | 128 | size_t vlen = v.length(); |
michael@0 | 129 | if (!v.resize(vlen + alen)) |
michael@0 | 130 | return; |
michael@0 | 131 | |
michael@0 | 132 | // Move vector data forward. This is safe since we've already resized. |
michael@0 | 133 | memmove(v.begin() + alen, v.begin(), vlen * sizeof(T)); |
michael@0 | 134 | |
michael@0 | 135 | // Copy data to insert. |
michael@0 | 136 | for (size_t i = 0; i < alen; ++i) |
michael@0 | 137 | v[i] = array[i]; |
michael@0 | 138 | } |
michael@0 | 139 | |
michael@0 | 140 | template <size_t N, class AP> |
michael@0 | 141 | void |
michael@0 | 142 | PrependString(Vector<jschar, N, AP> &v, JSString* str) |
michael@0 | 143 | { |
michael@0 | 144 | JS_ASSERT(str); |
michael@0 | 145 | size_t vlen = v.length(); |
michael@0 | 146 | size_t alen = str->length(); |
michael@0 | 147 | if (!v.resize(vlen + alen)) |
michael@0 | 148 | return; |
michael@0 | 149 | |
michael@0 | 150 | const jschar *chars = str->getChars(nullptr); |
michael@0 | 151 | if (!chars) |
michael@0 | 152 | return; |
michael@0 | 153 | |
michael@0 | 154 | // Move vector data forward. This is safe since we've already resized. |
michael@0 | 155 | memmove(v.begin() + alen, v.begin(), vlen * sizeof(jschar)); |
michael@0 | 156 | |
michael@0 | 157 | // Copy data to insert. |
michael@0 | 158 | memcpy(v.begin(), chars, alen * sizeof(jschar)); |
michael@0 | 159 | } |
michael@0 | 160 | |
michael@0 | 161 | extern size_t |
michael@0 | 162 | GetDeflatedUTF8StringLength(JSContext *maybecx, const jschar *chars, |
michael@0 | 163 | size_t charsLength); |
michael@0 | 164 | |
michael@0 | 165 | bool |
michael@0 | 166 | DeflateStringToUTF8Buffer(JSContext *maybecx, const jschar *src, size_t srclen, |
michael@0 | 167 | char *dst, size_t *dstlenp); |
michael@0 | 168 | |
michael@0 | 169 | |
michael@0 | 170 | /******************************************************************************* |
michael@0 | 171 | ** Function and struct API definitions |
michael@0 | 172 | *******************************************************************************/ |
michael@0 | 173 | |
michael@0 | 174 | MOZ_ALWAYS_INLINE void |
michael@0 | 175 | ASSERT_OK(bool ok) |
michael@0 | 176 | { |
michael@0 | 177 | JS_ASSERT(ok); |
michael@0 | 178 | } |
michael@0 | 179 | |
michael@0 | 180 | // for JS error reporting |
michael@0 | 181 | enum ErrorNum { |
michael@0 | 182 | #define MSG_DEF(name, number, count, exception, format) \ |
michael@0 | 183 | name = number, |
michael@0 | 184 | #include "ctypes/ctypes.msg" |
michael@0 | 185 | #undef MSG_DEF |
michael@0 | 186 | CTYPESERR_LIMIT |
michael@0 | 187 | }; |
michael@0 | 188 | |
michael@0 | 189 | /** |
michael@0 | 190 | * ABI constants that specify the calling convention to use. |
michael@0 | 191 | * ctypes.default_abi corresponds to the cdecl convention, and in almost all |
michael@0 | 192 | * cases is the correct choice. ctypes.stdcall_abi is provided for calling |
michael@0 | 193 | * stdcall functions on Win32, and implies stdcall symbol name decoration; |
michael@0 | 194 | * ctypes.winapi_abi is just stdcall but without decoration. |
michael@0 | 195 | */ |
michael@0 | 196 | enum ABICode { |
michael@0 | 197 | ABI_DEFAULT, |
michael@0 | 198 | ABI_STDCALL, |
michael@0 | 199 | ABI_WINAPI, |
michael@0 | 200 | INVALID_ABI |
michael@0 | 201 | }; |
michael@0 | 202 | |
michael@0 | 203 | enum TypeCode { |
michael@0 | 204 | TYPE_void_t, |
michael@0 | 205 | #define DEFINE_TYPE(name, type, ffiType) TYPE_##name, |
michael@0 | 206 | #include "ctypes/typedefs.h" |
michael@0 | 207 | TYPE_pointer, |
michael@0 | 208 | TYPE_function, |
michael@0 | 209 | TYPE_array, |
michael@0 | 210 | TYPE_struct |
michael@0 | 211 | }; |
michael@0 | 212 | |
michael@0 | 213 | // Descriptor of one field in a StructType. The name of the field is stored |
michael@0 | 214 | // as the key to the hash entry. |
michael@0 | 215 | struct FieldInfo |
michael@0 | 216 | { |
michael@0 | 217 | JS::Heap<JSObject*> mType; // CType of the field |
michael@0 | 218 | size_t mIndex; // index of the field in the struct (first is 0) |
michael@0 | 219 | size_t mOffset; // offset of the field in the struct, in bytes |
michael@0 | 220 | }; |
michael@0 | 221 | |
michael@0 | 222 | struct UnbarrieredFieldInfo |
michael@0 | 223 | { |
michael@0 | 224 | JSObject* mType; // CType of the field |
michael@0 | 225 | size_t mIndex; // index of the field in the struct (first is 0) |
michael@0 | 226 | size_t mOffset; // offset of the field in the struct, in bytes |
michael@0 | 227 | }; |
michael@0 | 228 | static_assert(sizeof(UnbarrieredFieldInfo) == sizeof(FieldInfo), |
michael@0 | 229 | "UnbarrieredFieldInfo should be the same as FieldInfo but with unbarriered mType"); |
michael@0 | 230 | |
michael@0 | 231 | // Hash policy for FieldInfos. |
michael@0 | 232 | struct FieldHashPolicy : DefaultHasher<JSFlatString*> |
michael@0 | 233 | { |
michael@0 | 234 | typedef JSFlatString* Key; |
michael@0 | 235 | typedef Key Lookup; |
michael@0 | 236 | |
michael@0 | 237 | static uint32_t hash(const Lookup &l) { |
michael@0 | 238 | const jschar* s = l->chars(); |
michael@0 | 239 | size_t n = l->length(); |
michael@0 | 240 | uint32_t hash = 0; |
michael@0 | 241 | for (; n > 0; s++, n--) |
michael@0 | 242 | hash = hash * 33 + *s; |
michael@0 | 243 | return hash; |
michael@0 | 244 | } |
michael@0 | 245 | |
michael@0 | 246 | static bool match(const Key &k, const Lookup &l) { |
michael@0 | 247 | if (k == l) |
michael@0 | 248 | return true; |
michael@0 | 249 | |
michael@0 | 250 | if (k->length() != l->length()) |
michael@0 | 251 | return false; |
michael@0 | 252 | |
michael@0 | 253 | return memcmp(k->chars(), l->chars(), k->length() * sizeof(jschar)) == 0; |
michael@0 | 254 | } |
michael@0 | 255 | }; |
michael@0 | 256 | |
michael@0 | 257 | typedef HashMap<JSFlatString*, FieldInfo, FieldHashPolicy, SystemAllocPolicy> FieldInfoHash; |
michael@0 | 258 | |
michael@0 | 259 | // Descriptor of ABI, return type, argument types, and variadicity for a |
michael@0 | 260 | // FunctionType. |
michael@0 | 261 | struct FunctionInfo |
michael@0 | 262 | { |
michael@0 | 263 | // Initialized in NewFunctionInfo when !mIsVariadic, but only later, in |
michael@0 | 264 | // FunctionType::Call, when mIsVariadic. Not always consistent with |
michael@0 | 265 | // mFFITypes, due to lazy initialization when mIsVariadic. |
michael@0 | 266 | ffi_cif mCIF; |
michael@0 | 267 | |
michael@0 | 268 | // Calling convention of the function. Convert to ffi_abi using GetABI |
michael@0 | 269 | // and OBJECT_TO_JSVAL. Stored as a JSObject* for ease of tracing. |
michael@0 | 270 | JS::Heap<JSObject*> mABI; |
michael@0 | 271 | |
michael@0 | 272 | // The CType of the value returned by the function. |
michael@0 | 273 | JS::Heap<JSObject*> mReturnType; |
michael@0 | 274 | |
michael@0 | 275 | // A fixed array of known parameter types, excluding any variadic |
michael@0 | 276 | // parameters (if mIsVariadic). |
michael@0 | 277 | Array<JS::Heap<JSObject*> > mArgTypes; |
michael@0 | 278 | |
michael@0 | 279 | // A variable array of ffi_type*s corresponding to both known parameter |
michael@0 | 280 | // types and dynamic (variadic) parameter types. Longer than mArgTypes |
michael@0 | 281 | // only if mIsVariadic. |
michael@0 | 282 | Array<ffi_type*> mFFITypes; |
michael@0 | 283 | |
michael@0 | 284 | // Flag indicating whether the function behaves like a C function with |
michael@0 | 285 | // ... as the final formal parameter. |
michael@0 | 286 | bool mIsVariadic; |
michael@0 | 287 | }; |
michael@0 | 288 | |
michael@0 | 289 | // Parameters necessary for invoking a JS function from a C closure. |
michael@0 | 290 | struct ClosureInfo |
michael@0 | 291 | { |
michael@0 | 292 | JSContext* cx; // JSContext to use |
michael@0 | 293 | JSRuntime* rt; // Used in the destructor, where cx might have already |
michael@0 | 294 | // been GCed. |
michael@0 | 295 | JS::Heap<JSObject*> closureObj; // CClosure object |
michael@0 | 296 | JS::Heap<JSObject*> typeObj; // FunctionType describing the C function |
michael@0 | 297 | JS::Heap<JSObject*> thisObj; // 'this' object to use for the JS function call |
michael@0 | 298 | JS::Heap<JSObject*> jsfnObj; // JS function |
michael@0 | 299 | void* errResult; // Result that will be returned if the closure throws |
michael@0 | 300 | ffi_closure* closure; // The C closure itself |
michael@0 | 301 | |
michael@0 | 302 | // Anything conditionally freed in the destructor should be initialized to |
michael@0 | 303 | // nullptr here. |
michael@0 | 304 | ClosureInfo(JSRuntime* runtime) |
michael@0 | 305 | : rt(runtime) |
michael@0 | 306 | , errResult(nullptr) |
michael@0 | 307 | , closure(nullptr) |
michael@0 | 308 | {} |
michael@0 | 309 | |
michael@0 | 310 | ~ClosureInfo() { |
michael@0 | 311 | if (closure) |
michael@0 | 312 | ffi_closure_free(closure); |
michael@0 | 313 | js_free(errResult); |
michael@0 | 314 | } |
michael@0 | 315 | }; |
michael@0 | 316 | |
michael@0 | 317 | bool IsCTypesGlobal(HandleValue v); |
michael@0 | 318 | bool IsCTypesGlobal(JSObject* obj); |
michael@0 | 319 | |
michael@0 | 320 | JSCTypesCallbacks* GetCallbacks(JSObject* obj); |
michael@0 | 321 | |
michael@0 | 322 | /******************************************************************************* |
michael@0 | 323 | ** JSClass reserved slot definitions |
michael@0 | 324 | *******************************************************************************/ |
michael@0 | 325 | |
michael@0 | 326 | enum CTypesGlobalSlot { |
michael@0 | 327 | SLOT_CALLBACKS = 0, // pointer to JSCTypesCallbacks struct |
michael@0 | 328 | SLOT_ERRNO = 1, // jsval for latest |errno| |
michael@0 | 329 | SLOT_LASTERROR = 2, // jsval for latest |GetLastError|, used only with Windows |
michael@0 | 330 | CTYPESGLOBAL_SLOTS |
michael@0 | 331 | }; |
michael@0 | 332 | |
michael@0 | 333 | enum CABISlot { |
michael@0 | 334 | SLOT_ABICODE = 0, // ABICode of the CABI object |
michael@0 | 335 | CABI_SLOTS |
michael@0 | 336 | }; |
michael@0 | 337 | |
michael@0 | 338 | enum CTypeProtoSlot { |
michael@0 | 339 | SLOT_POINTERPROTO = 0, // ctypes.PointerType.prototype object |
michael@0 | 340 | SLOT_ARRAYPROTO = 1, // ctypes.ArrayType.prototype object |
michael@0 | 341 | SLOT_STRUCTPROTO = 2, // ctypes.StructType.prototype object |
michael@0 | 342 | SLOT_FUNCTIONPROTO = 3, // ctypes.FunctionType.prototype object |
michael@0 | 343 | SLOT_CDATAPROTO = 4, // ctypes.CData.prototype object |
michael@0 | 344 | SLOT_POINTERDATAPROTO = 5, // common ancestor of all CData objects of PointerType |
michael@0 | 345 | SLOT_ARRAYDATAPROTO = 6, // common ancestor of all CData objects of ArrayType |
michael@0 | 346 | SLOT_STRUCTDATAPROTO = 7, // common ancestor of all CData objects of StructType |
michael@0 | 347 | SLOT_FUNCTIONDATAPROTO = 8, // common ancestor of all CData objects of FunctionType |
michael@0 | 348 | SLOT_INT64PROTO = 9, // ctypes.Int64.prototype object |
michael@0 | 349 | SLOT_UINT64PROTO = 10, // ctypes.UInt64.prototype object |
michael@0 | 350 | SLOT_CTYPES = 11, // ctypes object |
michael@0 | 351 | SLOT_OURDATAPROTO = 12, // the data prototype corresponding to this object |
michael@0 | 352 | CTYPEPROTO_SLOTS |
michael@0 | 353 | }; |
michael@0 | 354 | |
michael@0 | 355 | enum CTypeSlot { |
michael@0 | 356 | SLOT_PROTO = 0, // 'prototype' property of the CType object |
michael@0 | 357 | SLOT_TYPECODE = 1, // TypeCode of the CType object |
michael@0 | 358 | SLOT_FFITYPE = 2, // ffi_type representing the type |
michael@0 | 359 | SLOT_NAME = 3, // name of the type |
michael@0 | 360 | SLOT_SIZE = 4, // size of the type, in bytes |
michael@0 | 361 | SLOT_ALIGN = 5, // alignment of the type, in bytes |
michael@0 | 362 | SLOT_PTR = 6, // cached PointerType object for type.ptr |
michael@0 | 363 | // Note that some of the slots below can overlap, since they're for |
michael@0 | 364 | // mutually exclusive types. |
michael@0 | 365 | SLOT_TARGET_T = 7, // (PointerTypes only) 'targetType' property |
michael@0 | 366 | SLOT_ELEMENT_T = 7, // (ArrayTypes only) 'elementType' property |
michael@0 | 367 | SLOT_LENGTH = 8, // (ArrayTypes only) 'length' property |
michael@0 | 368 | SLOT_FIELDS = 7, // (StructTypes only) 'fields' property |
michael@0 | 369 | SLOT_FIELDINFO = 8, // (StructTypes only) FieldInfoHash table |
michael@0 | 370 | SLOT_FNINFO = 7, // (FunctionTypes only) FunctionInfo struct |
michael@0 | 371 | SLOT_ARGS_T = 8, // (FunctionTypes only) 'argTypes' property (cached) |
michael@0 | 372 | CTYPE_SLOTS |
michael@0 | 373 | }; |
michael@0 | 374 | |
michael@0 | 375 | enum CDataSlot { |
michael@0 | 376 | SLOT_CTYPE = 0, // CType object representing the underlying type |
michael@0 | 377 | SLOT_REFERENT = 1, // JSObject this object must keep alive, if any |
michael@0 | 378 | SLOT_DATA = 2, // pointer to a buffer containing the binary data |
michael@0 | 379 | SLOT_OWNS = 3, // JSVAL_TRUE if this CData owns its own buffer |
michael@0 | 380 | CDATA_SLOTS |
michael@0 | 381 | }; |
michael@0 | 382 | |
michael@0 | 383 | enum CClosureSlot { |
michael@0 | 384 | SLOT_CLOSUREINFO = 0, // ClosureInfo struct |
michael@0 | 385 | CCLOSURE_SLOTS |
michael@0 | 386 | }; |
michael@0 | 387 | |
michael@0 | 388 | enum CDataFinalizerSlot { |
michael@0 | 389 | // The type of the value (a CType JSObject). |
michael@0 | 390 | // We hold it to permit ImplicitConvert and ToSource. |
michael@0 | 391 | SLOT_DATAFINALIZER_VALTYPE = 0, |
michael@0 | 392 | // The type of the function used at finalization (a CType JSObject). |
michael@0 | 393 | // We hold it to permit |ToSource|. |
michael@0 | 394 | SLOT_DATAFINALIZER_CODETYPE = 1, |
michael@0 | 395 | CDATAFINALIZER_SLOTS |
michael@0 | 396 | }; |
michael@0 | 397 | |
michael@0 | 398 | enum TypeCtorSlot { |
michael@0 | 399 | SLOT_FN_CTORPROTO = 0 // ctypes.{Pointer,Array,Struct}Type.prototype |
michael@0 | 400 | // JSFunction objects always get exactly two slots. |
michael@0 | 401 | }; |
michael@0 | 402 | |
michael@0 | 403 | enum Int64Slot { |
michael@0 | 404 | SLOT_INT64 = 0, // pointer to a 64-bit buffer containing the integer |
michael@0 | 405 | INT64_SLOTS |
michael@0 | 406 | }; |
michael@0 | 407 | |
michael@0 | 408 | enum Int64FunctionSlot { |
michael@0 | 409 | SLOT_FN_INT64PROTO = 0 // ctypes.{Int64,UInt64}.prototype object |
michael@0 | 410 | // JSFunction objects always get exactly two slots. |
michael@0 | 411 | }; |
michael@0 | 412 | |
michael@0 | 413 | /******************************************************************************* |
michael@0 | 414 | ** Object API definitions |
michael@0 | 415 | *******************************************************************************/ |
michael@0 | 416 | |
michael@0 | 417 | namespace CType { |
michael@0 | 418 | JSObject* Create(JSContext* cx, HandleObject typeProto, HandleObject dataProto, |
michael@0 | 419 | TypeCode type, JSString* name, jsval size, jsval align, ffi_type* ffiType); |
michael@0 | 420 | |
michael@0 | 421 | JSObject* DefineBuiltin(JSContext* cx, JSObject* parent, const char* propName, |
michael@0 | 422 | JSObject* typeProto, JSObject* dataProto, const char* name, TypeCode type, |
michael@0 | 423 | jsval size, jsval align, ffi_type* ffiType); |
michael@0 | 424 | |
michael@0 | 425 | bool IsCType(JSObject* obj); |
michael@0 | 426 | bool IsCTypeProto(JSObject* obj); |
michael@0 | 427 | TypeCode GetTypeCode(JSObject* typeObj); |
michael@0 | 428 | bool TypesEqual(JSObject* t1, JSObject* t2); |
michael@0 | 429 | size_t GetSize(JSObject* obj); |
michael@0 | 430 | bool GetSafeSize(JSObject* obj, size_t* result); |
michael@0 | 431 | bool IsSizeDefined(JSObject* obj); |
michael@0 | 432 | size_t GetAlignment(JSObject* obj); |
michael@0 | 433 | ffi_type* GetFFIType(JSContext* cx, JSObject* obj); |
michael@0 | 434 | JSString* GetName(JSContext* cx, HandleObject obj); |
michael@0 | 435 | JSObject* GetProtoFromCtor(JSObject* obj, CTypeProtoSlot slot); |
michael@0 | 436 | JSObject* GetProtoFromType(JSContext* cx, JSObject* obj, CTypeProtoSlot slot); |
michael@0 | 437 | JSCTypesCallbacks* GetCallbacksFromType(JSObject* obj); |
michael@0 | 438 | } |
michael@0 | 439 | |
michael@0 | 440 | namespace PointerType { |
michael@0 | 441 | JSObject* CreateInternal(JSContext* cx, HandleObject baseType); |
michael@0 | 442 | |
michael@0 | 443 | JSObject* GetBaseType(JSObject* obj); |
michael@0 | 444 | } |
michael@0 | 445 | |
michael@0 | 446 | namespace ArrayType { |
michael@0 | 447 | JSObject* CreateInternal(JSContext* cx, HandleObject baseType, size_t length, |
michael@0 | 448 | bool lengthDefined); |
michael@0 | 449 | |
michael@0 | 450 | JSObject* GetBaseType(JSObject* obj); |
michael@0 | 451 | size_t GetLength(JSObject* obj); |
michael@0 | 452 | bool GetSafeLength(JSObject* obj, size_t* result); |
michael@0 | 453 | ffi_type* BuildFFIType(JSContext* cx, JSObject* obj); |
michael@0 | 454 | } |
michael@0 | 455 | |
michael@0 | 456 | namespace StructType { |
michael@0 | 457 | bool DefineInternal(JSContext* cx, JSObject* typeObj, JSObject* fieldsObj); |
michael@0 | 458 | |
michael@0 | 459 | const FieldInfoHash* GetFieldInfo(JSObject* obj); |
michael@0 | 460 | const FieldInfo* LookupField(JSContext* cx, JSObject* obj, JSFlatString *name); |
michael@0 | 461 | JSObject* BuildFieldsArray(JSContext* cx, JSObject* obj); |
michael@0 | 462 | ffi_type* BuildFFIType(JSContext* cx, JSObject* obj); |
michael@0 | 463 | } |
michael@0 | 464 | |
michael@0 | 465 | namespace FunctionType { |
michael@0 | 466 | JSObject* CreateInternal(JSContext* cx, jsval abi, jsval rtype, |
michael@0 | 467 | jsval* argtypes, unsigned arglen); |
michael@0 | 468 | |
michael@0 | 469 | JSObject* ConstructWithObject(JSContext* cx, JSObject* typeObj, |
michael@0 | 470 | JSObject* refObj, PRFuncPtr fnptr, JSObject* result); |
michael@0 | 471 | |
michael@0 | 472 | FunctionInfo* GetFunctionInfo(JSObject* obj); |
michael@0 | 473 | void BuildSymbolName(JSString* name, JSObject* typeObj, |
michael@0 | 474 | AutoCString& result); |
michael@0 | 475 | } |
michael@0 | 476 | |
michael@0 | 477 | namespace CClosure { |
michael@0 | 478 | JSObject* Create(JSContext* cx, HandleObject typeObj, HandleObject fnObj, |
michael@0 | 479 | HandleObject thisObj, jsval errVal, PRFuncPtr* fnptr); |
michael@0 | 480 | } |
michael@0 | 481 | |
michael@0 | 482 | namespace CData { |
michael@0 | 483 | JSObject* Create(JSContext* cx, HandleObject typeObj, HandleObject refObj, |
michael@0 | 484 | void* data, bool ownResult); |
michael@0 | 485 | |
michael@0 | 486 | JSObject* GetCType(JSObject* dataObj); |
michael@0 | 487 | void* GetData(JSObject* dataObj); |
michael@0 | 488 | bool IsCData(JSObject* obj); |
michael@0 | 489 | bool IsCData(HandleValue v); |
michael@0 | 490 | bool IsCDataProto(JSObject* obj); |
michael@0 | 491 | |
michael@0 | 492 | // Attached by JSAPI as the function 'ctypes.cast' |
michael@0 | 493 | bool Cast(JSContext* cx, unsigned argc, jsval* vp); |
michael@0 | 494 | // Attached by JSAPI as the function 'ctypes.getRuntime' |
michael@0 | 495 | bool GetRuntime(JSContext* cx, unsigned argc, jsval* vp); |
michael@0 | 496 | } |
michael@0 | 497 | |
michael@0 | 498 | namespace Int64 { |
michael@0 | 499 | bool IsInt64(JSObject* obj); |
michael@0 | 500 | } |
michael@0 | 501 | |
michael@0 | 502 | namespace UInt64 { |
michael@0 | 503 | bool IsUInt64(JSObject* obj); |
michael@0 | 504 | } |
michael@0 | 505 | |
michael@0 | 506 | } |
michael@0 | 507 | } |
michael@0 | 508 | |
michael@0 | 509 | #endif /* ctypes_CTypes_h */ |