Bug 748776 - Record a more precise type in CDataFinalizer::Construct. r=jorendorff

This commit is contained in:
David Rajchenbach-Teller 2012-05-09 10:33:30 +02:00
Родитель 535ea13aea
Коммит 97635f8e85
5 изменённых файлов: 96 добавлений и 4 удалений

Просмотреть файл

@ -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");
}