зеркало из https://github.com/mozilla/pjs.git
Bug 748776 - Record a more precise type in CDataFinalizer::Construct. r=jorendorff
This commit is contained in:
Родитель
535ea13aea
Коммит
97635f8e85
|
@ -6621,10 +6621,28 @@ CDataFinalizer::Construct(JSContext* cx, unsigned argc, jsval *vp)
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
// If our argument is a CData, it holds a type.
|
||||
// This is the type that we should capture, not that
|
||||
// of the function, which may be less precise.
|
||||
JSObject *objBestArgType = objArgType;
|
||||
if (!JSVAL_IS_PRIMITIVE(valData)) {
|
||||
JSObject *objData = JSVAL_TO_OBJECT(valData);
|
||||
if (CData::IsCData(objData)) {
|
||||
objBestArgType = CData::GetCType(objData);
|
||||
size_t sizeBestArg;
|
||||
if (!CType::GetSafeSize(objBestArgType, &sizeBestArg)) {
|
||||
JS_NOT_REACHED("object with unknown size");
|
||||
}
|
||||
if (sizeBestArg != sizeArg) {
|
||||
return TypeError(cx, "(an object with the same size as that expected by the C finalization function)", valData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Used by GetCType
|
||||
JS_SetReservedSlot(objResult,
|
||||
SLOT_DATAFINALIZER_VALTYPE,
|
||||
OBJECT_TO_JSVAL(objArgType));
|
||||
OBJECT_TO_JSVAL(objBestArgType));
|
||||
|
||||
// Used by ToSource
|
||||
JS_SetReservedSlot(objResult,
|
||||
|
|
|
@ -171,6 +171,32 @@ test_finalizer_cmp_ptr_t(void *a, void *b)
|
|||
return a==b;
|
||||
}
|
||||
|
||||
// Resource type: int32_t*
|
||||
|
||||
// Acquire resource i
|
||||
int32_t*
|
||||
test_finalizer_acq_int32_ptr_t(size_t i)
|
||||
{
|
||||
gFinalizerTestResources[i] = 1;
|
||||
return (int32_t*)&gFinalizerTestResources[i];
|
||||
}
|
||||
|
||||
// Release resource i
|
||||
void
|
||||
test_finalizer_rel_int32_ptr_t(int32_t *i)
|
||||
{
|
||||
-- (*i);
|
||||
if (*i < 0) {
|
||||
MOZ_NOT_REACHED("Assertion failed");
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
test_finalizer_cmp_int32_ptr_t(int32_t *a, int32_t *b)
|
||||
{
|
||||
return a==b;
|
||||
}
|
||||
|
||||
// Resource type: NULL
|
||||
|
||||
// Acquire resource i
|
||||
|
|
|
@ -30,6 +30,10 @@ NS_EXTERN_C
|
|||
EXPORT_CDECL(void) test_finalizer_rel_ptr_t(void *i);
|
||||
EXPORT_CDECL(bool) test_finalizer_cmp_ptr_t(void *a, void *b);
|
||||
|
||||
EXPORT_CDECL(int32_t*) test_finalizer_acq_int32_ptr_t(size_t i);
|
||||
EXPORT_CDECL(void) test_finalizer_rel_int32_ptr_t(int32_t *i);
|
||||
EXPORT_CDECL(bool) test_finalizer_cmp_int32_ptr_t(int32_t *a, int32_t *b);
|
||||
|
||||
EXPORT_CDECL(char*) test_finalizer_acq_string_t(int i);
|
||||
EXPORT_CDECL(void) test_finalizer_rel_string_t(char *i);
|
||||
EXPORT_CDECL(bool) test_finalizer_cmp_string_t(char *a, char *b);
|
||||
|
|
|
@ -5,7 +5,7 @@ try {
|
|||
} catch(e) {
|
||||
}
|
||||
|
||||
let acquire, dispose, reset_errno, dispose_errno;
|
||||
let acquire, dispose, reset_errno, dispose_errno, acquire_ptr, dispose_ptr;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
|
@ -32,10 +32,20 @@ function run_test()
|
|||
ctypes.default_abi,
|
||||
ctypes.void_t,
|
||||
ctypes.size_t);
|
||||
acquire_ptr = library.declare("test_finalizer_acq_int32_ptr_t",
|
||||
ctypes.default_abi,
|
||||
ctypes.int32_t.ptr,
|
||||
ctypes.size_t);
|
||||
dispose_ptr = library.declare("test_finalizer_rel_int32_ptr_t",
|
||||
ctypes.default_abi,
|
||||
ctypes.void_t,
|
||||
ctypes.int32_t.ptr);
|
||||
|
||||
tester.launch(10, test_to_string);
|
||||
tester.launch(10, test_to_source);
|
||||
tester.launch(10, test_to_int);
|
||||
tester.launch(10, test_errno);
|
||||
tester.launch(10, test_to_pointer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,3 +132,17 @@ function test_errno(size, tc, cleanup)
|
|||
trigger_gc();
|
||||
do_check_eq(ctypes.errno, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a finalizable of a pointer can be used as a pointer
|
||||
*/
|
||||
function test_to_pointer()
|
||||
{
|
||||
let ptr = ctypes.int32_t(2).address();
|
||||
let finalizable = ctypes.CDataFinalizer(ptr, dispose_ptr);
|
||||
let unwrapped = ctypes.int32_t.ptr(finalizable);
|
||||
|
||||
do_check_eq(""+ptr, ""+unwrapped);
|
||||
|
||||
finalizable.forget(); // Do not dispose: This is not a real pointer.
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ try {
|
|||
} catch(e) {
|
||||
}
|
||||
|
||||
let acquire, dispose, null_dispose, compare;
|
||||
let acquire, dispose, null_dispose, compare, dispose_64;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
|
@ -31,6 +31,11 @@ function run_test()
|
|||
ctypes.size_t,
|
||||
ctypes.size_t);
|
||||
|
||||
dispose_64 = library.declare("test_finalizer_rel_int64_t",
|
||||
ctypes.default_abi,
|
||||
ctypes.void_t,
|
||||
ctypes.int64_t);
|
||||
|
||||
let type_afun = ctypes.FunctionType(ctypes.default_abi,
|
||||
ctypes.void_t,
|
||||
[ctypes.size_t]).ptr;
|
||||
|
@ -46,6 +51,7 @@ function run_test()
|
|||
tester.launch(10, test_finalize_bad_construction);
|
||||
tester.launch(10, test_null_dispose);
|
||||
tester.launch(10, test_pass_disposed);
|
||||
tester.launch(10, test_wrong_type);
|
||||
}
|
||||
|
||||
|
||||
|
@ -153,4 +159,18 @@ function test_pass_disposed()
|
|||
exception = true;
|
||||
}
|
||||
do_check_true(exception);
|
||||
}
|
||||
}
|
||||
|
||||
function test_wrong_type()
|
||||
{
|
||||
let int32_v = ctypes.int32_t(99);
|
||||
let exception;
|
||||
try {
|
||||
ctypes.CDataFinalizer(int32_v, dispose_64);
|
||||
} catch (x) {
|
||||
exception = x;
|
||||
}
|
||||
|
||||
do_check_true(!!exception);
|
||||
do_check_eq(exception.constructor.name, "TypeError");
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче