зеркало из https://github.com/mozilla/pjs.git
Bug 551982 - Generate t.name and t.fields lazily. Part 3: lazy ffi_type. r=benjamn
This commit is contained in:
Родитель
16d3bc6a6e
Коммит
9cecf41fe6
|
@ -2516,7 +2516,7 @@ CType::Create(JSContext* cx,
|
|||
|
||||
// Set up the reserved slots.
|
||||
if (!JS_SetReservedSlot(cx, typeObj, SLOT_TYPECODE, INT_TO_JSVAL(type)) ||
|
||||
!JS_SetReservedSlot(cx, typeObj, SLOT_FFITYPE, PRIVATE_TO_JSVAL(ffiType)) ||
|
||||
(ffiType && !JS_SetReservedSlot(cx, typeObj, SLOT_FFITYPE, PRIVATE_TO_JSVAL(ffiType))) ||
|
||||
(name && !JS_SetReservedSlot(cx, typeObj, SLOT_NAME, STRING_TO_JSVAL(name))) ||
|
||||
!JS_SetReservedSlot(cx, typeObj, SLOT_SIZE, size) ||
|
||||
!JS_SetReservedSlot(cx, typeObj, SLOT_ALIGN, align))
|
||||
|
@ -2611,7 +2611,7 @@ CType::Finalize(JSContext* cx, JSObject* obj)
|
|||
// Free the ffi_type info.
|
||||
jsval slot;
|
||||
ASSERT_OK(JS_GetReservedSlot(cx, obj, SLOT_FFITYPE, &slot));
|
||||
if (!JSVAL_IS_VOID(slot) && JSVAL_TO_PRIVATE(slot)) {
|
||||
if (!JSVAL_IS_VOID(slot)) {
|
||||
ffi_type* ffiType = static_cast<ffi_type*>(JSVAL_TO_PRIVATE(slot));
|
||||
delete[] ffiType->elements;
|
||||
delete ffiType;
|
||||
|
@ -2849,9 +2849,29 @@ CType::GetFFIType(JSContext* cx, JSObject* obj)
|
|||
jsval slot;
|
||||
ASSERT_OK(JS_GetReservedSlot(cx, obj, SLOT_FFITYPE, &slot));
|
||||
|
||||
ffi_type* result = static_cast<ffi_type*>(JSVAL_TO_PRIVATE(slot));
|
||||
JS_ASSERT(result);
|
||||
return result;
|
||||
if (!JSVAL_IS_VOID(slot)) {
|
||||
return static_cast<ffi_type*>(JSVAL_TO_PRIVATE(slot));
|
||||
}
|
||||
|
||||
AutoPtr<ffi_type> result;
|
||||
switch (CType::GetTypeCode(cx, obj)) {
|
||||
case TYPE_array:
|
||||
result = ArrayType::BuildFFIType(cx, obj);
|
||||
break;
|
||||
|
||||
case TYPE_struct:
|
||||
result = StructType::BuildFFIType(cx, obj);
|
||||
break;
|
||||
|
||||
default:
|
||||
JS_NOT_REACHED("simple types must have an ffi_type");
|
||||
}
|
||||
|
||||
if (!result ||
|
||||
!JS_SetReservedSlot(cx, obj, SLOT_FFITYPE, PRIVATE_TO_JSVAL(result.get())))
|
||||
return NULL;
|
||||
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
JSString*
|
||||
|
@ -3365,9 +3385,6 @@ ArrayType::CreateInternal(JSContext* cx,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ffi_type* ffiType = NULL;
|
||||
size_t align = CType::GetAlignment(cx, baseType);
|
||||
|
||||
jsval sizeVal = JSVAL_VOID;
|
||||
jsval lengthVal = JSVAL_VOID;
|
||||
if (lengthDefined) {
|
||||
|
@ -3380,39 +3397,13 @@ ArrayType::CreateInternal(JSContext* cx,
|
|||
if (!SizeTojsval(cx, size, &sizeVal) ||
|
||||
!SizeTojsval(cx, length, &lengthVal))
|
||||
return NULL;
|
||||
|
||||
// Create an ffi_type to represent the array. This is necessary for the case
|
||||
// where the array is part of a struct. Since libffi has no intrinsic
|
||||
// support for array types, we approximate it by creating a struct type
|
||||
// with elements of type 'baseType' and with appropriate size and alignment
|
||||
// values. It would be nice to not do all the work of setting up 'elements',
|
||||
// but some libffi platforms currently require that it be meaningful. I'm
|
||||
// looking at you, x86_64.
|
||||
ffiType = new ffi_type;
|
||||
if (!ffiType) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ffiType->type = FFI_TYPE_STRUCT;
|
||||
ffiType->size = size;
|
||||
ffiType->alignment = align;
|
||||
ffiType->elements = new ffi_type*[length + 1];
|
||||
if (!ffiType->elements) {
|
||||
delete ffiType;
|
||||
JS_ReportAllocationOverflow(cx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ffi_type* ffiBaseType = CType::GetFFIType(cx, baseType);
|
||||
for (size_t i = 0; i < length; ++i)
|
||||
ffiType->elements[i] = ffiBaseType;
|
||||
ffiType->elements[length] = NULL;
|
||||
}
|
||||
|
||||
size_t align = CType::GetAlignment(cx, baseType);
|
||||
|
||||
// Create a new CType object with the common properties and slots.
|
||||
JSObject* typeObj = CType::Create(cx, typeProto, dataProto, TYPE_array, NULL,
|
||||
sizeVal, INT_TO_JSVAL(align), ffiType);
|
||||
sizeVal, INT_TO_JSVAL(align), NULL);
|
||||
if (!typeObj)
|
||||
return NULL;
|
||||
js::AutoValueRooter root(cx, typeObj);
|
||||
|
@ -3585,6 +3576,49 @@ ArrayType::GetLength(JSContext* cx, JSObject* obj)
|
|||
return Convert<size_t>(*JSVAL_TO_DOUBLE(length));
|
||||
}
|
||||
|
||||
ffi_type*
|
||||
ArrayType::BuildFFIType(JSContext* cx, JSObject* obj)
|
||||
{
|
||||
JS_ASSERT(CType::IsCType(cx, obj));
|
||||
JS_ASSERT(CType::GetTypeCode(cx, obj) == TYPE_array);
|
||||
JS_ASSERT(CType::IsSizeDefined(cx, obj));
|
||||
|
||||
JSObject* baseType = ArrayType::GetBaseType(cx, obj);
|
||||
ffi_type* ffiBaseType = CType::GetFFIType(cx, baseType);
|
||||
if (!ffiBaseType)
|
||||
return NULL;
|
||||
|
||||
size_t length = ArrayType::GetLength(cx, obj);
|
||||
|
||||
// Create an ffi_type to represent the array. This is necessary for the case
|
||||
// where the array is part of a struct. Since libffi has no intrinsic
|
||||
// support for array types, we approximate it by creating a struct type
|
||||
// with elements of type 'baseType' and with appropriate size and alignment
|
||||
// values. It would be nice to not do all the work of setting up 'elements',
|
||||
// but some libffi platforms currently require that it be meaningful. I'm
|
||||
// looking at you, x86_64.
|
||||
AutoPtr<ffi_type> ffiType(new ffi_type);
|
||||
if (!ffiType) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ffiType->type = FFI_TYPE_STRUCT;
|
||||
ffiType->size = CType::GetSize(cx, obj);
|
||||
ffiType->alignment = CType::GetAlignment(cx, obj);
|
||||
ffiType->elements = new ffi_type*[length + 1];
|
||||
if (!ffiType->elements) {
|
||||
JS_ReportAllocationOverflow(cx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < length; ++i)
|
||||
ffiType->elements[i] = ffiBaseType;
|
||||
ffiType->elements[length] = NULL;
|
||||
|
||||
return ffiType.forget();
|
||||
}
|
||||
|
||||
JSBool
|
||||
ArrayType::ElementTypeGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
|
||||
{
|
||||
|
@ -3778,7 +3812,7 @@ ExtractStructField(JSContext* cx, jsval val, FieldInfo* field)
|
|||
}
|
||||
|
||||
JSString* name = JSVAL_TO_STRING(nameVal.value());
|
||||
field->mName.clear();
|
||||
JS_ASSERT(field->mName.length() == 0);
|
||||
AppendString(field->mName, name);
|
||||
|
||||
js::AutoValueRooter propVal(cx);
|
||||
|
@ -3896,13 +3930,6 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj, JSObject* fieldsObj
|
|||
NULL, NULL, JSPROP_READONLY | JSPROP_PERMANENT))
|
||||
return JS_FALSE;
|
||||
|
||||
AutoPtr<ffi_type> ffiType(new ffi_type);
|
||||
if (!ffiType) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return JS_FALSE;
|
||||
}
|
||||
ffiType->type = FFI_TYPE_STRUCT;
|
||||
|
||||
// Create an array of FieldInfo objects to stash on the type object.
|
||||
AutoPtr< Array<FieldInfo> > fields(new Array<FieldInfo>);
|
||||
if (!fields || !fields->resize(len)) {
|
||||
|
@ -3910,17 +3937,11 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj, JSObject* fieldsObj
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
AutoPtr<ffi_type*>::Array elements;
|
||||
|
||||
// Process the field types and fill in the ffi_type fields.
|
||||
size_t structSize = 0, structAlign = 0;
|
||||
// Process the field types.
|
||||
size_t structSize, structAlign;
|
||||
if (len != 0) {
|
||||
elements = new ffi_type*[len + 1];
|
||||
if (!elements) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return JS_FALSE;
|
||||
}
|
||||
elements[len] = NULL;
|
||||
structSize = 0;
|
||||
structAlign = 0;
|
||||
|
||||
for (jsuint i = 0; i < len; ++i) {
|
||||
js::AutoValueRooter item(cx);
|
||||
|
@ -3947,8 +3968,6 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj, JSObject* fieldsObj
|
|||
JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT))
|
||||
return JS_FALSE;
|
||||
|
||||
elements[i] = CType::GetFFIType(cx, info->mType);
|
||||
|
||||
size_t fieldSize = CType::GetSize(cx, info->mType);
|
||||
size_t fieldAlign = CType::GetAlignment(cx, info->mType);
|
||||
size_t fieldOffset = Align(structSize, fieldAlign);
|
||||
|
@ -3981,10 +4000,71 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj, JSObject* fieldsObj
|
|||
// no getters or setters, and will be initialized to zero.
|
||||
structSize = 1;
|
||||
structAlign = 1;
|
||||
}
|
||||
|
||||
jsval sizeVal;
|
||||
if (!SizeTojsval(cx, structSize, &sizeVal))
|
||||
return JS_FALSE;
|
||||
|
||||
if (!JS_SetReservedSlot(cx, typeObj, SLOT_SIZE, sizeVal) ||
|
||||
!JS_SetReservedSlot(cx, typeObj, SLOT_ALIGN, INT_TO_JSVAL(structAlign)) ||
|
||||
//!JS_SealObject(cx, prototype, JS_FALSE) || // XXX fixme - see bug 541212!
|
||||
!JS_SetReservedSlot(cx, typeObj, SLOT_PROTO, OBJECT_TO_JSVAL(prototype)))
|
||||
return JS_FALSE;
|
||||
|
||||
// Stash the FieldInfo array in a reserved slot.
|
||||
if (!JS_SetReservedSlot(cx, typeObj, SLOT_FIELDINFO,
|
||||
PRIVATE_TO_JSVAL(fields.get())))
|
||||
return JS_FALSE;
|
||||
fields.forget();
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
ffi_type*
|
||||
StructType::BuildFFIType(JSContext* cx, JSObject* obj)
|
||||
{
|
||||
JS_ASSERT(CType::IsCType(cx, obj));
|
||||
JS_ASSERT(CType::GetTypeCode(cx, obj) == TYPE_struct);
|
||||
JS_ASSERT(CType::IsSizeDefined(cx, obj));
|
||||
|
||||
Array<FieldInfo>* fields = GetFieldInfo(cx, obj);
|
||||
size_t len = fields->length();
|
||||
|
||||
size_t structSize = CType::GetSize(cx, obj);
|
||||
size_t structAlign = CType::GetAlignment(cx, obj);
|
||||
|
||||
AutoPtr<ffi_type> ffiType(new ffi_type);
|
||||
if (!ffiType) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return NULL;
|
||||
}
|
||||
ffiType->type = FFI_TYPE_STRUCT;
|
||||
|
||||
AutoPtr<ffi_type*>::Array elements;
|
||||
if (len != 0) {
|
||||
elements = new ffi_type*[len + 1];
|
||||
if (!elements) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return NULL;
|
||||
}
|
||||
elements[len] = NULL;
|
||||
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
FieldInfo* info = fields->begin() + i;
|
||||
elements[i] = CType::GetFFIType(cx, info->mType);
|
||||
if (!elements[i])
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Represent an empty struct as having a size of 1 byte, just like C++.
|
||||
JS_ASSERT(structSize == 1);
|
||||
JS_ASSERT(structAlign == 1);
|
||||
elements = new ffi_type*[2];
|
||||
if (!elements) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return JS_FALSE;
|
||||
return NULL;
|
||||
}
|
||||
elements[0] = &ffi_type_uint8;
|
||||
elements[1] = NULL;
|
||||
|
@ -4012,30 +4092,8 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj, JSObject* fieldsObj
|
|||
ffiType->alignment = structAlign;
|
||||
#endif
|
||||
|
||||
jsval sizeVal;
|
||||
if (!SizeTojsval(cx, structSize, &sizeVal))
|
||||
return JS_FALSE;
|
||||
|
||||
// Set up the reserved slots.
|
||||
if (!JS_SetReservedSlot(cx, typeObj, SLOT_FFITYPE,
|
||||
PRIVATE_TO_JSVAL(ffiType.get())))
|
||||
return JS_FALSE;
|
||||
ffiType.forget();
|
||||
elements.forget();
|
||||
|
||||
if (!JS_SetReservedSlot(cx, typeObj, SLOT_SIZE, sizeVal) ||
|
||||
!JS_SetReservedSlot(cx, typeObj, SLOT_ALIGN, INT_TO_JSVAL(structAlign)) ||
|
||||
//!JS_SealObject(cx, prototype, JS_FALSE) || // XXX fixme - see bug 541212!
|
||||
!JS_SetReservedSlot(cx, typeObj, SLOT_PROTO, OBJECT_TO_JSVAL(prototype)))
|
||||
return JS_FALSE;
|
||||
|
||||
// Stash the FieldInfo array in a reserved slot.
|
||||
if (!JS_SetReservedSlot(cx, typeObj, SLOT_FIELDINFO,
|
||||
PRIVATE_TO_JSVAL(fields.get())))
|
||||
return JS_FALSE;
|
||||
fields.forget();
|
||||
|
||||
return JS_TRUE;
|
||||
return ffiType.forget();
|
||||
}
|
||||
|
||||
JSBool
|
||||
|
@ -4476,11 +4534,15 @@ PrepareCIF(JSContext* cx,
|
|||
return false;
|
||||
}
|
||||
|
||||
ffi_type* rtype = CType::GetFFIType(cx, fninfo->mReturnType);
|
||||
if (!rtype)
|
||||
return false;
|
||||
|
||||
ffi_status status =
|
||||
ffi_prep_cif(&fninfo->mCIF,
|
||||
abi,
|
||||
fninfo->mFFITypes.length(),
|
||||
CType::GetFFIType(cx, fninfo->mReturnType),
|
||||
rtype,
|
||||
fninfo->mFFITypes.begin());
|
||||
|
||||
switch (status) {
|
||||
|
@ -4557,8 +4619,12 @@ NewFunctionInfo(JSContext* cx,
|
|||
if (!argType)
|
||||
return NULL;
|
||||
|
||||
ffi_type* ffiType = CType::GetFFIType(cx, argType);
|
||||
if (!ffiType)
|
||||
return NULL;
|
||||
|
||||
fninfo->mArgTypes.append(argType);
|
||||
fninfo->mFFITypes.append(CType::GetFFIType(cx, argType));
|
||||
fninfo->mFFITypes.append(ffiType);
|
||||
}
|
||||
|
||||
if (fninfo->mIsVariadic)
|
||||
|
@ -4642,9 +4708,8 @@ FunctionType::CreateInternal(JSContext* cx,
|
|||
SLOT_FUNCTIONDATAPROTO);
|
||||
|
||||
// Create a new CType object with the common properties and slots.
|
||||
// We use ffi_type_void here in its capacity as "a type of undefined size".
|
||||
JSObject* typeObj = CType::Create(cx, typeProto, dataProto, TYPE_function,
|
||||
NULL, JSVAL_VOID, JSVAL_VOID, &ffi_type_void);
|
||||
NULL, JSVAL_VOID, JSVAL_VOID, NULL);
|
||||
if (!typeObj)
|
||||
return NULL;
|
||||
js::AutoValueRooter root(cx, typeObj);
|
||||
|
@ -4805,11 +4870,11 @@ FunctionType::Call(JSContext* cx,
|
|||
!(type = PrepareType(cx, OBJECT_TO_JSVAL(type))) ||
|
||||
// Relying on ImplicitConvert only for the limited purpose of
|
||||
// converting one CType to another (e.g., T[] to T*).
|
||||
!ConvertArgument(cx, argv[i], type, &values[i], &strings)) {
|
||||
!ConvertArgument(cx, argv[i], type, &values[i], &strings) ||
|
||||
!(fninfo->mFFITypes[i] = CType::GetFFIType(cx, type))) {
|
||||
// These functions report their own errors.
|
||||
return false;
|
||||
}
|
||||
fninfo->mFFITypes[i] = CType::GetFFIType(cx, type);
|
||||
}
|
||||
if (!PrepareCIF(cx, fninfo))
|
||||
return false;
|
||||
|
|
|
@ -417,6 +417,7 @@ namespace ArrayType {
|
|||
JSObject* GetBaseType(JSContext* cx, JSObject* obj);
|
||||
size_t GetLength(JSContext* cx, JSObject* obj);
|
||||
bool GetSafeLength(JSContext* cx, JSObject* obj, size_t* result);
|
||||
ffi_type* BuildFFIType(JSContext* cx, JSObject* obj);
|
||||
}
|
||||
|
||||
namespace StructType {
|
||||
|
@ -425,6 +426,7 @@ namespace StructType {
|
|||
Array<FieldInfo>* GetFieldInfo(JSContext* cx, JSObject* obj);
|
||||
FieldInfo* LookupField(JSContext* cx, JSObject* obj, jsval idval);
|
||||
JSObject* BuildFieldsArray(JSContext* cx, JSObject* obj);
|
||||
ffi_type* BuildFFIType(JSContext* cx, JSObject* obj);
|
||||
}
|
||||
|
||||
namespace FunctionType {
|
||||
|
|
|
@ -1454,69 +1454,57 @@ function run_StructType_tests() {
|
|||
do_check_throws(function() { t_t.fields[4].e = 0; }, Error);
|
||||
|
||||
// Check that struct size bounds work, and that large, but not illegal, sizes
|
||||
// are OK. This gets tricky. The type constructor needs to allocate 'n'
|
||||
// fields for the type descriptor, so we have to build up structs of structs
|
||||
// to avoid trying to allocate an insane size.
|
||||
// are OK.
|
||||
if (ctypes.size_t.size == 4) {
|
||||
// Test 1: overflow struct size + field padding + field size.
|
||||
let large_t = ctypes.int8_t;
|
||||
while (large_t.size != 0xffffffff)
|
||||
large_t = ctypes.StructType("large_t",
|
||||
[{"a": large_t.array(2)}, {"b": ctypes.int8_t}]);
|
||||
let large_t = ctypes.StructType("large_t",
|
||||
[{"a": ctypes.int8_t.array(0xffffffff)}]);
|
||||
do_check_eq(large_t.size, 0xffffffff);
|
||||
do_check_throws(function() {
|
||||
ctypes.StructType("large_t", [{"a": large_t}, {"b": ctypes.int8_t}]);
|
||||
}, Error);
|
||||
|
||||
// Test 2: overflow struct size + struct tail padding.
|
||||
// To do this, we use a struct with maximum size and alignment 2.
|
||||
large_t = ctypes.int16_t;
|
||||
while (large_t.size != 0xfffffffe)
|
||||
large_t = ctypes.StructType("large_t",
|
||||
[{"a": large_t.array(2)}, {"b": ctypes.int16_t}]);
|
||||
large_t = ctypes.StructType("large_t",
|
||||
[{"a": ctypes.int16_t.array(0xfffffffe / 2)}]);
|
||||
do_check_eq(large_t.size, 0xfffffffe);
|
||||
do_check_throws(function() {
|
||||
ctypes.StructType("large_t", [{"a": large_t}, {"b": ctypes.int8_t}]);
|
||||
}, Error);
|
||||
|
||||
} else {
|
||||
// Test 1: overflow struct size when converting from size_t to jsdouble.
|
||||
let small_t = ctypes.int8_t.array(0x800);
|
||||
let large_t = small_t;
|
||||
while (large_t.size != 0xfffffffffffff800)
|
||||
large_t = ctypes.StructType("large_t",
|
||||
[{"a": large_t.array(2)}, {"b": small_t}]);
|
||||
let large_t = ctypes.StructType("large_t",
|
||||
[{"a": ctypes.int8_t.array(0xfffffffffffff800)}]);
|
||||
do_check_eq(large_t.size, 0xfffffffffffff800);
|
||||
do_check_throws(function() {
|
||||
ctypes.StructType("large_t", [{"a": large_t}, {"b": ctypes.int8_t}]);
|
||||
}, Error);
|
||||
small_t = ctypes.int8_t.array(0x400);
|
||||
let small_t = ctypes.int8_t.array(0x400);
|
||||
do_check_throws(function() {
|
||||
ctypes.StructType("large_t", [{"a": large_t}, {"b": small_t}]);
|
||||
}, Error);
|
||||
|
||||
large_t = ctypes.int8_t;
|
||||
while (large_t.size != 0x1fffffffffffff)
|
||||
large_t = ctypes.StructType("large_t",
|
||||
[{"a": large_t.array(2)}, {"b": ctypes.int8_t}]);
|
||||
large_t = ctypes.StructType("large_t",
|
||||
[{"a": ctypes.int8_t.array(0x1fffffffffffff)}]);
|
||||
do_check_eq(large_t.size, 0x1fffffffffffff);
|
||||
do_check_throws(function() {
|
||||
ctypes.StructType("large_t", [{"a": large_t.array(2)}, {"b": ctypes.int8_t}]);
|
||||
}, Error);
|
||||
|
||||
// Test 2: overflow struct size + field padding + field size.
|
||||
large_t = ctypes.int8_t.array(0xfffffffffffff800);
|
||||
small_t = ctypes.int8_t.array(0x800);
|
||||
large_t = small_t;
|
||||
while (large_t.size != 0xfffffffffffff800)
|
||||
large_t = ctypes.StructType("large_t",
|
||||
[{"a": large_t.array(2)}, {"b": small_t}]);
|
||||
do_check_throws(function() {
|
||||
ctypes.StructType("large_t", [{"a": large_t}, {"b": small_t}]);
|
||||
}, Error);
|
||||
|
||||
// Test 3: overflow struct size + struct tail padding.
|
||||
// To do this, we use a struct with maximum size and alignment 2.
|
||||
small_t = ctypes.int16_t.array(0x800);
|
||||
large_t = small_t;
|
||||
while (large_t.size != 0xfffffffffffff000)
|
||||
large_t = ctypes.StructType("large_t",
|
||||
[{"a": large_t.array(2)}, {"b": small_t}]);
|
||||
large_t = ctypes.StructType("large_t",
|
||||
[{"a": ctypes.int16_t.array(0xfffffffffffff000 / 2)}]);
|
||||
do_check_eq(large_t.size, 0xfffffffffffff000);
|
||||
small_t = ctypes.int8_t.array(0xfff);
|
||||
do_check_throws(function() {
|
||||
ctypes.StructType("large_t", [{"a": large_t}, {"b": small_t}]);
|
||||
|
@ -1896,9 +1884,7 @@ function run_ArrayType_tests() {
|
|||
do_check_eq(b_t.length, 0xffff);
|
||||
|
||||
// Check that array size bounds work, and that large, but not illegal, sizes
|
||||
// are OK. This gets tricky. The type constructor needs to allocate 'n'
|
||||
// elements for the type descriptor, so we have to build up arrays of arrays
|
||||
// to avoid trying to allocate an insane size.
|
||||
// are OK.
|
||||
if (ctypes.size_t.size == 4) {
|
||||
do_check_throws(function() {
|
||||
ctypes.ArrayType(ctypes.int8_t, 0x100000000);
|
||||
|
@ -1907,9 +1893,7 @@ function run_ArrayType_tests() {
|
|||
ctypes.ArrayType(ctypes.int16_t, 0x80000000);
|
||||
}, Error);
|
||||
|
||||
let large_t = ctypes.int8_t;
|
||||
while (large_t.size != 0x80000000)
|
||||
large_t = large_t.array(2);
|
||||
let large_t = ctypes.int8_t.array(0x80000000);
|
||||
do_check_throws(function() { large_t.array(2); }, Error);
|
||||
|
||||
} else {
|
||||
|
@ -1920,9 +1904,7 @@ function run_ArrayType_tests() {
|
|||
ctypes.ArrayType(ctypes.int16_t, ctypes.UInt64("0x8000000000000000"));
|
||||
}, Error);
|
||||
|
||||
let large_t = ctypes.int8_t;
|
||||
while (large_t.size != 0x8000000000000000)
|
||||
large_t = large_t.array(2);
|
||||
let large_t = ctypes.int8_t.array(0x8000000000000000);
|
||||
do_check_throws(function() { large_t.array(2); }, Error);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче