Issue #439 - Remove tests from toolkit/

This commit is contained in:
Matt A. Tobin 2020-02-25 15:07:00 -05:00 • committed by Roy Tam
commit e5bacc6f6e
2362 changed files with 95 additions and 246993 deletions

View file

@ -4,21 +4,10 @@
# 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/.
TEST_DIRS += ['tests']
LOCAL_INCLUDES += ['/js/xpconnect/loader']
SOURCES += [
'ctypes.cpp',
]
SOURCES += ['ctypes.cpp']
LOCAL_INCLUDES += [
'/js/xpconnect/loader',
]
EXTRA_JS_MODULES += [
'ctypes.jsm',
]
EXTRA_JS_MODULES += ['ctypes.jsm']
FINAL_LIBRARY = 'xul'
with Files('**'):
BUG_COMPONENT = ('Core', 'js-ctypes')

View file

@ -1,7 +0,0 @@
"use strict";
module.exports = {
"extends": [
"../../../../../testing/mochitest/chrome.eslintrc.js"
]
};

View file

@ -1,8 +0,0 @@
[DEFAULT]
skip-if = os == 'android'
support-files =
xpcshellTestHarnessAdaptor.js
ctypes_worker.js
../unit/test_jsctypes.js
[test_ctypes.xul]

View file

@ -1,14 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
importScripts("xpcshellTestHarnessAdaptor.js");
onmessage = function(event) {
_WORKINGDIR_ = event.data.dir;
_OS_ = event.data.os;
importScripts("test_jsctypes.js");
run_test();
postMessage("Done!");
}

View file

@ -1,106 +0,0 @@
<?xml version="1.0"?>
<!-- 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/. -->
<window title="DOM Worker Threads Test"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="test();">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/chrome-harness.js"/>
<script type="application/javascript">
<![CDATA[
Components.utils.import("resource://gre/modules/ctypes.jsm");
CTYPES_TEST_LIB = ctypes.libraryName("jsctypes-test");
CTYPES_UNICODE_LIB = ctypes.libraryName("jsctyp\u00E8s-t\u00EB\u00DFt");
/*
* input: string of the url where we are running from
* return: nsILocalFile
*/
function getCurrentDir(path) {
var rootDir = getRootDirectory(window.location.href);
var jar = getJar(rootDir);
if (jar) {
return extractJarToTmp(jar);
} else {
return getLocalDir(path);
}
}
function getLocalDir(path) {
let dir = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("CurWorkD", Components.interfaces.nsILocalFile);
path = location.pathname;
path = path.slice("content/".length,
-1 * "/test_ctypes.xul".length);
let components = path.split("/");
for (let part in components) {
dir.append(components[part]);
}
return dir;
}
function setupLibs(path) {
let libFile = path.clone();
libFile.append(CTYPES_TEST_LIB);
ok(libFile.exists(), "ctypes test library doesn't exist!?");
libFile.copyTo(null, CTYPES_UNICODE_LIB);
}
function cleanupLibs(path) {
let unicodeFile = path.clone();
unicodeFile.append(CTYPES_UNICODE_LIB);
ok(unicodeFile.exists(), "ctypes unicode test library doesn't exist!?");
unicodeFile.remove(false);
}
function test()
{
SimpleTest.waitForExplicitFinish();
var dir = getCurrentDir(location.path);
ok(dir.exists() && dir.isDirectory(), "Chrome test dir doesn't exist?!");
setupLibs(dir);
var worker = new ChromeWorker("ctypes_worker.js");
worker.onmessage = function(event) {
is(event.data, "Done!", "Wrong message!");
cleanupLibs(dir);
SimpleTest.finish();
}
worker.onerror = function(event) {
if (event.message == "uncaught exception: 7.5 million years for that?" ||
event.message == "uncaught exception: Just following orders, sir!") {
// We throw those on purpose in the worker, so ignore them.
return true;
}
ok(false, "Worker had an error: " + event.message);
worker.terminate();
cleanupLibs(dir);
SimpleTest.finish();
}
worker.postMessage({dir: dir.path, os: Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime).OS});
}
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display"></p>
<div id="content" style="display:none;"></div>
<pre id="test"></pre>
</body>
<label id="test-result"/>
</window>

View file

@ -1,100 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
var _WORKINGDIR_ = null;
var _OS_ = null;
var Components = {
classes: { },
interfaces: { },
stack: {
caller: null
},
utils: {
import: function() { }
}
};
function do_throw(message, stack) {
do_print("error: " + message);
do_print("stack: " + (stack ? stack : new Error().stack));
throw message;
}
function do_check_neq(left, right, stack) {
if (left == right) {
var text = "do_check_neq failed";
try {
text += ": " + left + " == " + right;
} catch (e) {
}
do_throw(text, stack);
}
}
function do_check_eq(left, right, stack) {
if (left != right) {
var text = "do_check_eq failed";
try {
text += ": " + left + " != " + right;
} catch (e) {
}
do_throw(text, stack);
}
}
function do_check_true(condition, stack) {
do_check_eq(condition, true, stack);
}
function do_check_false(condition, stack) {
do_check_eq(condition, false, stack);
}
function do_print(text) {
dump("INFO: " + text + "\n");
}
function FileFaker(path) {
this._path = path;
}
FileFaker.prototype = {
get path() {
return this._path;
},
get parent() {
let lastSlash = this._path.lastIndexOf("/");
if (lastSlash == -1) {
return "";
}
this._path = this._path.substring(0, lastSlash);
return this;
},
append: function(leaf) {
this._path = this._path + "/" + leaf;
}
};
function do_get_file(path, allowNonexistent) {
if (!_WORKINGDIR_) {
do_throw("No way to fake files if working directory is unknown!");
}
let lf = new FileFaker(_WORKINGDIR_);
let bits = path.split("/");
for (let i = 0; i < bits.length; i++) {
if (bits[i]) {
if (bits[i] == "..")
lf = lf.parent;
else
lf.append(bits[i]);
}
}
return lf;
}
function get_os() {
return _OS_;
}

View file

@ -1,41 +0,0 @@
/* -*- 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/. */
#include <stdio.h>
#include <errno.h>
#if defined(XP_WIN)
#include <windows.h>
#endif // defined(XP_WIN)
#include "jsctypes-test-errno.h"
#define FAIL \
{ \
fprintf(stderr, "Assertion failed at line %i\n", __LINE__); \
(*(int*)nullptr)++; \
}
void set_errno(int status)
{
errno = status;
}
int get_errno()
{
return errno;
}
#if defined(XP_WIN)
void set_last_error(int status)
{
SetLastError((int)status);
}
int get_last_error()
{
return (int)GetLastError();
}
#endif // defined(XP_WIN)

View file

@ -1,21 +0,0 @@
/* -*- 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/. */
#include "mozilla/Attributes.h"
#include "mozilla/Types.h"
#define EXPORT_CDECL(type) MOZ_EXPORT type
MOZ_BEGIN_EXTERN_C
EXPORT_CDECL(void) set_errno(int status);
EXPORT_CDECL(int) get_errno();
#if defined(XP_WIN)
EXPORT_CDECL(void) set_last_error(int status);
EXPORT_CDECL(int) get_last_error();
#endif // defined(XP_WIN)
MOZ_END_EXTERN_C

View file

@ -1,323 +0,0 @@
#include "errno.h"
#include "jsctypes-test.h"
#include "jsctypes-test-finalizer.h"
/**
* Shared infrastructure
*/
/**
* An array of integers representing resources.
* - 0: unacquired
* - 1: acquired
* - < 0: error, resource has been released several times.
*/
int *gFinalizerTestResources = nullptr;
char **gFinalizerTestNames = nullptr;
size_t gFinalizerTestSize;
void
test_finalizer_start(size_t size)
{
gFinalizerTestResources = new int[size];
gFinalizerTestNames = new char*[size];
gFinalizerTestSize = size;
for (size_t i = 0; i < size; ++i) {
gFinalizerTestResources[i] = 0;
gFinalizerTestNames[i] = nullptr;
}
}
void
test_finalizer_stop()
{
delete[] gFinalizerTestResources;
}
/**
* Check if an acquired resource has been released
*/
bool
test_finalizer_resource_is_acquired(size_t i)
{
return gFinalizerTestResources[i] == 1;
}
// Resource type: size_t
// Acquire resource i
size_t
test_finalizer_acq_size_t(size_t i)
{
gFinalizerTestResources[i] = 1;
return i;
}
// Release resource i
void
test_finalizer_rel_size_t(size_t i)
{
if (--gFinalizerTestResources[i] < 0) {
MOZ_CRASH("Assertion failed");
}
}
size_t
test_finalizer_rel_size_t_return_size_t(size_t i)
{
if (-- gFinalizerTestResources[i] < 0) {
MOZ_CRASH("Assertion failed");
}
return i;
}
myRECT
test_finalizer_rel_size_t_return_struct_t(size_t i)
{
if (-- gFinalizerTestResources[i] < 0) {
MOZ_CRASH("Assertion failed");
}
const int32_t narrowed = (int32_t)i;
myRECT result = { narrowed, narrowed, narrowed, narrowed };
return result;
}
bool
test_finalizer_cmp_size_t(size_t a, size_t b)
{
return a==b;
}
// Resource type: int32_t
// Acquire resource i
int32_t
test_finalizer_acq_int32_t(size_t i)
{
gFinalizerTestResources[i] = 1;
return i;
}
// Release resource i
void
test_finalizer_rel_int32_t(int32_t i)
{
if (--gFinalizerTestResources[i] < 0) {
MOZ_CRASH("Assertion failed");
}
}
bool
test_finalizer_cmp_int32_t(int32_t a, int32_t b)
{
return a==b;
}
// Resource type: int64_t
// Acquire resource i
int64_t
test_finalizer_acq_int64_t(size_t i)
{
gFinalizerTestResources[i] = 1;
return i;
}
// Release resource i
void
test_finalizer_rel_int64_t(int64_t i)
{
if (-- gFinalizerTestResources[i] < 0) {
MOZ_CRASH("Assertion failed");
}
}
bool
test_finalizer_cmp_int64_t(int64_t a, int64_t b)
{
return a==b;
}
// Resource type: void*
// Acquire resource i
void*
test_finalizer_acq_ptr_t(size_t i)
{
gFinalizerTestResources[i] = 1;
return (void*)&gFinalizerTestResources[i];
}
// Release resource i
void
test_finalizer_rel_ptr_t(void *i)
{
int *as_int = (int*)i;
-- (*as_int);
if (*as_int < 0) {
MOZ_CRASH("Assertion failed");
}
}
bool
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_CRASH("Assertion failed");
}
}
bool
test_finalizer_cmp_int32_ptr_t(int32_t *a, int32_t *b)
{
return a==b;
}
// Resource type: nullptr
// Acquire resource i
void*
test_finalizer_acq_null_t(size_t i)
{
gFinalizerTestResources[0] = 1;//Always index 0
return nullptr;
}
// Release resource i
void
test_finalizer_rel_null_t(void *i)
{
if (i != nullptr) {
MOZ_CRASH("Assertion failed");
}
gFinalizerTestResources[0] --;
}
bool
test_finalizer_null_resource_is_acquired(size_t)
{
return gFinalizerTestResources[0] == 1;
}
bool
test_finalizer_cmp_null_t(void *a, void *b)
{
return a==b;
}
// Resource type: char*
// Acquire resource i
char*
test_finalizer_acq_string_t(int i)
{
gFinalizerTestResources[i] = 1;
if (!gFinalizerTestNames[i]) {
char* buf = new char[12];
snprintf(buf, 12, "%d", i);
gFinalizerTestNames[i] = buf;
return buf;
}
return gFinalizerTestNames[i];
}
// Release resource i
void
test_finalizer_rel_string_t(char *i)
{
int index = atoi(i);
if (index < 0 || index >= (int)gFinalizerTestSize) {
MOZ_CRASH("Assertion failed");
}
gFinalizerTestResources[index] --;
}
bool
test_finalizer_string_resource_is_acquired(size_t i)
{
return gFinalizerTestResources[i] == 1;
}
bool
test_finalizer_cmp_string_t(char *a, char *b)
{
return !strncmp(a, b, 10);
}
// Resource type: myRECT
// Acquire resource i
myRECT
test_finalizer_acq_struct_t(int i)
{
gFinalizerTestResources[i] = 1;
myRECT result = { i, i, i, i };
return result;
}
// Release resource i
void
test_finalizer_rel_struct_t(myRECT i)
{
int index = i.top;
if (index < 0 || index >= (int)gFinalizerTestSize) {
MOZ_CRASH("Assertion failed");
}
gFinalizerTestResources[index] --;
}
bool
test_finalizer_struct_resource_is_acquired(myRECT i)
{
int index = i.top;
if (index < 0 || index >= (int)gFinalizerTestSize) {
MOZ_CRASH("Assertion failed");
}
return gFinalizerTestResources[index] == 1;
}
bool
test_finalizer_cmp_struct_t(myRECT a, myRECT b)
{
return a.top == b.top;
}
// Support for checking that we reject nullptr finalizer
afun* test_finalizer_rel_null_function()
{
return nullptr;
}
void
test_finalizer_rel_size_t_set_errno(size_t i)
{
if (-- gFinalizerTestResources[i] < 0) {
MOZ_CRASH("Assertion failed");
}
errno = 10;
}
void
reset_errno()
{
errno = 0;
}

View file

@ -1,57 +0,0 @@
/* 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/. */
#include "mozilla/Attributes.h"
#include "mozilla/Types.h"
#define EXPORT_CDECL(type) MOZ_EXPORT type
MOZ_BEGIN_EXTERN_C
EXPORT_CDECL(void) test_finalizer_start(size_t size);
EXPORT_CDECL(void) test_finalizer_stop();
EXPORT_CDECL(bool) test_finalizer_resource_is_acquired(size_t i);
EXPORT_CDECL(size_t) test_finalizer_acq_size_t(size_t i);
EXPORT_CDECL(void) test_finalizer_rel_size_t(size_t i);
EXPORT_CDECL(size_t) test_finalizer_rel_size_t_return_size_t(size_t i);
EXPORT_CDECL(myRECT) test_finalizer_rel_size_t_return_struct_t(size_t i);
EXPORT_CDECL(bool) test_finalizer_cmp_size_t(size_t a, size_t b);
EXPORT_CDECL(int32_t) test_finalizer_acq_int32_t(size_t i);
EXPORT_CDECL(void) test_finalizer_rel_int32_t(int32_t i);
EXPORT_CDECL(bool) test_finalizer_cmp_int32_t(int32_t a, int32_t b);
EXPORT_CDECL(int64_t) test_finalizer_acq_int64_t(size_t i);
EXPORT_CDECL(void) test_finalizer_rel_int64_t(int64_t i);
EXPORT_CDECL(bool) test_finalizer_cmp_int64_t(int64_t a, int64_t b);
EXPORT_CDECL(void*) test_finalizer_acq_ptr_t(size_t i);
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);
EXPORT_CDECL(void*) test_finalizer_acq_null_t(size_t i);
EXPORT_CDECL(void) test_finalizer_rel_null_t(void *i);
EXPORT_CDECL(bool) test_finalizer_cmp_null_t(void *a, void *b);
EXPORT_CDECL(bool) test_finalizer_null_resource_is_acquired(size_t i);
EXPORT_CDECL(myRECT) test_finalizer_acq_struct_t(int i);
EXPORT_CDECL(void) test_finalizer_rel_struct_t(myRECT i);
EXPORT_CDECL(bool) test_finalizer_cmp_struct_t(myRECT a, myRECT b);
typedef void (*afun)(size_t);
EXPORT_CDECL(afun*) test_finalizer_rel_null_function();
EXPORT_CDECL(void) test_finalizer_rel_size_t_set_errno(size_t i);
EXPORT_CDECL(void) reset_errno();
MOZ_END_EXTERN_C

View file

@ -1,394 +0,0 @@
/* -*- 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/. */
#include "jsctypes-test.h"
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include "typedefs.h"
template <typename T> struct ValueTraits {
static T literal() { return static_cast<T>(109.25); }
static T sum(T a, T b) { return a + b; }
static T sum_many(
T a, T b, T c, T d, T e, T f, T g, T h, T i,
T j, T k, T l, T m, T n, T o, T p, T q, T r)
{
return a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r;
}
};
template <> struct ValueTraits<bool> {
typedef bool T;
static T literal() { return true; }
static T sum(T a, T b) { return a || b; }
static T sum_many(
T a, T b, T c, T d, T e, T f, T g, T h, T i,
T j, T k, T l, T m, T n, T o, T p, T q, T r)
{
return a || b || c || d || e || f || g || h || i ||
j || k || l || m || n || o || p || q || r;
}
};
void
test_void_t_cdecl()
{
// do nothing
return;
}
// The "AndUnderscore" bit here is an unfortunate hack: the first argument to
// DEFINE_CDECL_FUNCTIONS and DEFINE_STDCALL_FUNCTIONS, in addition to being a
// type, may also be a *macro* on NetBSD -- #define int8_t __int8_t and so on.
// See <http://mail-index.netbsd.org/tech-toolchain/2014/12/18/msg002479.html>.
// And unfortunately, passing that macro as an argument to this macro causes it
// to be expanded -- producing get___int8_t_cdecl() and so on. Concatenating
// int8_t with _ slightly muddies this code but inhibits expansion. See also
// bug 1113379.
#define FUNCTION_TESTS(nameAndUnderscore, type, ffiType, suffix) \
type ABI \
get_##nameAndUnderscore##suffix() \
{ \
return ValueTraits<type>::literal(); \
} \
\
type ABI \
set_##nameAndUnderscore##suffix(type x) \
{ \
return x; \
} \
\
type ABI \
sum_##nameAndUnderscore##suffix(type x, type y) \
{ \
return ValueTraits<type>::sum(x, y); \
} \
\
type ABI \
sum_alignb_##nameAndUnderscore##suffix(char a, type x, char b, type y, char c)\
{ \
return ValueTraits<type>::sum(x, y); \
} \
\
type ABI \
sum_alignf_##nameAndUnderscore##suffix(float a, type x, float b, type y, float c)\
{ \
return ValueTraits<type>::sum(x, y); \
} \
\
type ABI \
sum_many_##nameAndUnderscore##suffix( \
type a, type b, type c, type d, type e, type f, type g, type h, type i, \
type j, type k, type l, type m, type n, type o, type p, type q, type r) \
{ \
return ValueTraits<type>::sum_many(a, b, c, d, e, f, g, h, i, \
j, k, l, m, n, o, p, q, r); \
}
#define ABI /* cdecl */
#define DEFINE_CDECL_FUNCTIONS(x, y, z) FUNCTION_TESTS(x##_, y, z, cdecl)
CTYPES_FOR_EACH_TYPE(DEFINE_CDECL_FUNCTIONS)
#undef DEFINE_CDECL_FUNCTIONS
#undef ABI
#if defined(_WIN32)
void NS_STDCALL
test_void_t_stdcall()
{
// do nothing
return;
}
#define ABI NS_STDCALL
#define DEFINE_STDCALL_FUNCTIONS(x, y, z) FUNCTION_TESTS(x##_, y, z, stdcall)
CTYPES_FOR_EACH_TYPE(DEFINE_STDCALL_FUNCTIONS)
#undef DEFINE_STDCALL_FUNCTIONS
#undef ABI
#endif /* defined(_WIN32) */
#define DEFINE_CDECL_TYPE_STATS(name, type, ffiType) \
struct align_##name { \
char x; \
type y; \
}; \
struct nested_##name { \
char a; \
align_##name b; \
char c; \
}; \
\
void \
get_##name##_stats(size_t* align, size_t* size, size_t* nalign, size_t* nsize, \
size_t offsets[]) \
{ \
*align = offsetof(align_##name, y); \
*size = sizeof(align_##name); \
*nalign = offsetof(nested_##name, b); \
*nsize = sizeof(nested_##name); \
offsets[0] = offsetof(align_##name, y); \
offsets[1] = offsetof(nested_##name, b); \
offsets[2] = offsetof(nested_##name, c); \
}
CTYPES_FOR_EACH_TYPE(DEFINE_CDECL_TYPE_STATS)
#undef DEFINE_CDECL_TYPE_STATS
template <typename T>
int32_t StrLen(const T* string)
{
const T *end;
for (end = string; *end; ++end);
return end - string;
}
int32_t
test_ansi_len(const char* string)
{
return StrLen(string);
}
int32_t
test_wide_len(const char16_t* string)
{
return StrLen(string);
}
const char *
test_ansi_ret()
{
return "success";
}
const char16_t *
test_wide_ret()
{
static const char16_t kSuccess[] = {'s', 'u', 'c', 'c', 'e', 's', 's', '\0'};
return kSuccess;
}
char *
test_ansi_echo(const char* string)
{
return (char*)string;
}
int32_t
test_pt_in_rect(myRECT rc, myPOINT pt)
{
if (pt.x < rc.left || pt.x > rc.right)
return 0;
if (pt.y < rc.bottom || pt.y > rc.top)
return 0;
return 1;
}
void
test_init_pt(myPOINT* pt, int32_t x, int32_t y)
{
pt->x = x;
pt->y = y;
}
int32_t
test_nested_struct(NESTED n)
{
return int32_t(n.n1 + n.n2 + n.inner.i1 + n.inner.i2 + n.inner.i3 + n.n3 + n.n4);
}
myPOINT
test_struct_return(myRECT r)
{
myPOINT p;
p.x = r.left; p.y = r.top;
return p;
}
myRECT
test_large_struct_return(myRECT a, myRECT b)
{
myRECT r;
r.left = a.left; r.right = a.right;
r.top = b.top; r.bottom = b.bottom;
return r;
}
ONE_BYTE
test_1_byte_struct_return(myRECT r)
{
ONE_BYTE s;
s.a = r.top;
return s;
}
TWO_BYTE
test_2_byte_struct_return(myRECT r)
{
TWO_BYTE s;
s.a = r.top;
s.b = r.left;
return s;
}
THREE_BYTE
test_3_byte_struct_return(myRECT r)
{
THREE_BYTE s;
s.a = r.top;
s.b = r.left;
s.c = r.bottom;
return s;
}
FOUR_BYTE
test_4_byte_struct_return(myRECT r)
{
FOUR_BYTE s;
s.a = r.top;
s.b = r.left;
s.c = r.bottom;
s.d = r.right;
return s;
}
FIVE_BYTE
test_5_byte_struct_return(myRECT r)
{
FIVE_BYTE s;
s.a = r.top;
s.b = r.left;
s.c = r.bottom;
s.d = r.right;
s.e = r.top;
return s;
}
SIX_BYTE
test_6_byte_struct_return(myRECT r)
{
SIX_BYTE s;
s.a = r.top;
s.b = r.left;
s.c = r.bottom;
s.d = r.right;
s.e = r.top;
s.f = r.left;
return s;
}
SEVEN_BYTE
test_7_byte_struct_return(myRECT r)
{
SEVEN_BYTE s;
s.a = r.top;
s.b = r.left;
s.c = r.bottom;
s.d = r.right;
s.e = r.top;
s.f = r.left;
s.g = r.bottom;
return s;
}
void *
test_fnptr()
{
return (void*)(uintptr_t)test_ansi_len;
}
int32_t
test_closure_cdecl(int8_t i, test_func_ptr f)
{
return f(i);
}
#if defined(_WIN32)
int32_t
test_closure_stdcall(int8_t i, test_func_ptr_stdcall f)
{
return f(i);
}
#endif /* defined(_WIN32) */
template <typename T> struct PromotedTraits {
typedef T type;
};
#define DECL_PROMOTED(FROM, TO) \
template <> struct PromotedTraits<FROM> { \
typedef TO type; \
}
DECL_PROMOTED(bool, int);
DECL_PROMOTED(char, int);
DECL_PROMOTED(short, int);
int32_t
test_sum_va_cdecl(uint8_t n, ...)
{
va_list list;
int32_t sum = 0;
va_start(list, n);
for (uint8_t i = 0; i < n; ++i)
sum += va_arg(list, PromotedTraits<int32_t>::type);
va_end(list);
return sum;
}
uint8_t
test_count_true_va_cdecl(uint8_t n, ...)
{
va_list list;
uint8_t count = 0;
va_start(list, n);
for (uint8_t i = 0; i < n; ++i)
if (va_arg(list, PromotedTraits<bool>::type))
count += 1;
va_end(list);
return count;
}
void
test_add_char_short_int_va_cdecl(uint32_t* result, ...)
{
va_list list;
va_start(list, result);
*result += va_arg(list, PromotedTraits<char>::type);
*result += va_arg(list, PromotedTraits<short>::type);
*result += va_arg(list, PromotedTraits<int>::type);
va_end(list);
}
int32_t*
test_vector_add_va_cdecl(uint8_t num_vecs,
uint8_t vec_len,
int32_t* result, ...)
{
va_list list;
va_start(list, result);
uint8_t i;
for (i = 0; i < vec_len; ++i)
result[i] = 0;
for (i = 0; i < num_vecs; ++i) {
int32_t* vec = va_arg(list, int32_t*);
for (uint8_t j = 0; j < vec_len; ++j)
result[j] += vec[j];
}
va_end(list);
return result;
}
myRECT data_rect = { -1, -2, 3, 4 };
TestClass::TestClass(int32_t a)
{
mInt =a;
}
int32_t
TestClass::Add(int32_t aOther)
{
mInt += aOther;
return mInt;
}

View file

@ -1,197 +0,0 @@
/* -*- 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 jsctypes_test_h
#define jsctypes_test_h
#include "mozilla/Attributes.h"
#include "mozilla/Types.h"
#include "jspubtd.h"
#include "typedefs.h"
#define EXPORT_CDECL(type) MOZ_EXPORT type
#if defined(_WIN32)
#if defined(_WIN64)
#define NS_STDCALL
#else
#define NS_STDCALL __stdcall
#endif
#define EXPORT_STDCALL(type) MOZ_EXPORT type NS_STDCALL
#endif
MOZ_BEGIN_EXTERN_C
EXPORT_CDECL(void) test_void_t_cdecl();
EXPORT_CDECL(void*) get_voidptr_t_cdecl();
EXPORT_CDECL(void*) set_voidptr_t_cdecl(void*);
#define DECLARE_CDECL_FUNCTIONS(name, type, ffiType) \
EXPORT_CDECL(type) get_##name##_cdecl(); \
EXPORT_CDECL(type) set_##name##_cdecl(type); \
EXPORT_CDECL(type) sum_##name##_cdecl(type, type); \
EXPORT_CDECL(type) sum_alignb_##name##_cdecl(char, type, char, type, char); \
EXPORT_CDECL(type) sum_alignf_##name##_cdecl( \
float, type, float, type, float); \
EXPORT_CDECL(type) sum_many_##name##_cdecl( \
type, type, type, type, type, type, type, type, type, \
type, type, type, type, type, type, type, type, type); \
\
EXPORT_CDECL(void) get_##name##_stats(size_t* align, size_t* size, \
size_t* nalign, size_t* nsize, \
size_t offsets[]);
CTYPES_FOR_EACH_TYPE(DECLARE_CDECL_FUNCTIONS)
#undef DECLARE_CDECL_FUNCTIONS
#if defined(_WIN32)
EXPORT_STDCALL(void) test_void_t_stdcall();
EXPORT_STDCALL(void*) get_voidptr_t_stdcall();
EXPORT_STDCALL(void*) set_voidptr_t_stdcall(void*);
#define DECLARE_STDCALL_FUNCTIONS(name, type, ffiType) \
EXPORT_STDCALL(type) get_##name##_stdcall(); \
EXPORT_STDCALL(type) set_##name##_stdcall(type); \
EXPORT_STDCALL(type) sum_##name##_stdcall(type, type); \
EXPORT_STDCALL(type) sum_alignb_##name##_stdcall( \
char, type, char, type, char); \
EXPORT_STDCALL(type) sum_alignf_##name##_stdcall( \
float, type, float, type, float); \
EXPORT_STDCALL(type) sum_many_##name##_stdcall( \
type, type, type, type, type, type, type, type, type, \
type, type, type, type, type, type, type, type, type);
CTYPES_FOR_EACH_TYPE(DECLARE_STDCALL_FUNCTIONS)
#undef DECLARE_STDCALL_FUNCTIONS
#endif /* defined(_WIN32) */
MOZ_EXPORT int32_t test_ansi_len(const char*);
MOZ_EXPORT int32_t test_wide_len(const char16_t*);
MOZ_EXPORT const char* test_ansi_ret();
MOZ_EXPORT const char16_t* test_wide_ret();
MOZ_EXPORT char* test_ansi_echo(const char*);
struct ONE_BYTE {
char a;
};
struct TWO_BYTE {
char a;
char b;
};
struct THREE_BYTE {
char a;
char b;
char c;
};
struct FOUR_BYTE {
char a;
char b;
char c;
char d;
};
struct FIVE_BYTE {
char a;
char b;
char c;
char d;
char e;
};
struct SIX_BYTE {
char a;
char b;
char c;
char d;
char e;
char f;
};
struct SEVEN_BYTE {
char a;
char b;
char c;
char d;
char e;
char f;
char g;
};
struct myPOINT {
int32_t x;
int32_t y;
};
struct myRECT {
int32_t top;
int32_t left;
int32_t bottom;
int32_t right;
};
struct INNER {
uint8_t i1;
int64_t i2;
uint8_t i3;
};
struct NESTED {
int32_t n1;
int16_t n2;
INNER inner;
int64_t n3;
int32_t n4;
};
MOZ_EXPORT int32_t test_pt_in_rect(myRECT, myPOINT);
MOZ_EXPORT void test_init_pt(myPOINT* pt, int32_t x, int32_t y);
MOZ_EXPORT int32_t test_nested_struct(NESTED);
MOZ_EXPORT myPOINT test_struct_return(myRECT);
MOZ_EXPORT myRECT test_large_struct_return(myRECT, myRECT);
MOZ_EXPORT ONE_BYTE test_1_byte_struct_return(myRECT);
MOZ_EXPORT TWO_BYTE test_2_byte_struct_return(myRECT);
MOZ_EXPORT THREE_BYTE test_3_byte_struct_return(myRECT);
MOZ_EXPORT FOUR_BYTE test_4_byte_struct_return(myRECT);
MOZ_EXPORT FIVE_BYTE test_5_byte_struct_return(myRECT);
MOZ_EXPORT SIX_BYTE test_6_byte_struct_return(myRECT);
MOZ_EXPORT SEVEN_BYTE test_7_byte_struct_return(myRECT);
MOZ_EXPORT void * test_fnptr();
typedef int32_t (* test_func_ptr)(int8_t);
MOZ_EXPORT int32_t test_closure_cdecl(int8_t, test_func_ptr);
#if defined(_WIN32)
typedef int32_t (NS_STDCALL * test_func_ptr_stdcall)(int8_t);
MOZ_EXPORT int32_t test_closure_stdcall(int8_t, test_func_ptr_stdcall);
#endif /* defined(_WIN32) */
MOZ_EXPORT int32_t test_callme(int8_t);
MOZ_EXPORT void* test_getfn();
EXPORT_CDECL(int32_t) test_sum_va_cdecl(uint8_t n, ...);
EXPORT_CDECL(uint8_t) test_count_true_va_cdecl(uint8_t n, ...);
EXPORT_CDECL(void) test_add_char_short_int_va_cdecl(uint32_t* result, ...);
EXPORT_CDECL(int32_t*) test_vector_add_va_cdecl(uint8_t num_vecs,
uint8_t vec_len,
int32_t* result, ...);
MOZ_EXPORT extern myRECT data_rect;
MOZ_END_EXTERN_C
class MOZ_EXPORT TestClass final {
public:
explicit TestClass(int32_t);
int32_t Add(int32_t);
private:
int32_t mInt;
};
#endif

View file

@ -1,30 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
DIST_INSTALL = False
XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini']
MOCHITEST_CHROME_MANIFESTS += ['chrome/chrome.ini']
UNIFIED_SOURCES += [
'jsctypes-test-errno.cpp',
'jsctypes-test-finalizer.cpp',
'jsctypes-test.cpp',
]
SharedLibrary('jsctypes-test')
LOCAL_INCLUDES += [
'/js/src/ctypes',
]
# Don't use STL wrappers here (i.e. wrapped <new>); they require mozalloc.
DISABLE_STL_WRAPPING = True
if CONFIG['COMPILE_ENVIRONMENT']:
shared_library = '!%sjsctypes-test%s' % (CONFIG['DLL_PREFIX'], CONFIG['DLL_SUFFIX'])
TEST_HARNESS_FILES.xpcshell.toolkit.components.ctypes.tests.unit += [shared_library]
TEST_HARNESS_FILES.testing.mochitest.chrome.toolkit.components.ctypes.tests.chrome += [shared_library]

View file

@ -1,7 +0,0 @@
"use strict";
module.exports = {
"extends": [
"../../../../../testing/xpcshell/xpcshell.eslintrc.js"
]
};

View file

@ -1,128 +0,0 @@
try {
// We might be running without privileges, in which case it's up to the
// harness to give us the 'ctypes' object.
Components.utils.import("resource://gre/modules/ctypes.jsm");
} catch (e) {
}
function open_ctypes_test_lib()
{
return ctypes.open(do_get_file(ctypes.libraryName("jsctypes-test")).path);
}
/**
* A weak set of CDataFinalizer values that need to be cleaned up before
* proceeding to the next test.
*/
function ResourceCleaner() {
this._map = new WeakMap();
}
ResourceCleaner.prototype = {
add: function ResourceCleaner_add(v) {
this._map.set(v);
return v;
},
cleanup: function ResourceCleaner_cleanup() {
let keys = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(this._map);
keys.forEach((function cleaner(k) {
try {
k.dispose();
} catch (x) {
// This can fail if |forget|/|dispose| has been called manually
// during the test. This is normal.
}
this._map.delete(k);
}).bind(this));
}
};
/**
* Simple wrapper for tests that require cleanup.
*/
function ResourceTester(start, stop) {
this._start = start;
this._stop = stop;
}
ResourceTester.prototype = {
launch: function(size, test, args) {
trigger_gc();
let cleaner = new ResourceCleaner();
this._start(size);
try {
test(size, args, cleaner);
} catch (x) {
cleaner.cleanup();
this._stop();
throw x;
}
trigger_gc();
cleaner.cleanup();
this._stop();
}
};
function structural_check_eq(a, b) {
// 1. If objects can be "toSource()-ed", use this.
let result;
let finished = false;
let asource, bsource;
try {
asource = a.toSource();
bsource = b.toSource();
finished = true;
} catch (x) {
}
if (finished) {
do_check_eq(asource, bsource);
return;
}
// 2. Otherwise, perform slower comparison
try {
structural_check_eq_aux(a, b);
result = true;
} catch (x) {
dump(x);
result = false;
}
do_check_true(result);
}
function structural_check_eq_aux(a, b) {
let ak;
try {
ak = Object.keys(a);
} catch (x) {
if (a != b) {
throw new Error("Distinct values "+a, b);
}
return;
}
ak.forEach(
function(k) {
let av = a[k];
let bv = b[k];
structural_check_eq_aux(av, bv);
}
);
}
function trigger_gc() {
dump("Triggering garbage-collection");
Components.utils.forceGC();
}
function must_throw(f) {
let has_thrown = false;
try {
f();
} catch (x) {
has_thrown = true;
}
do_check_true(has_thrown);
}
function get_os() {
return Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime).OS;
}

View file

@ -1,69 +0,0 @@
Components.utils.import("resource://gre/modules/ctypes.jsm");
// Scope used to relaunch the tests with |ctypes| opened in a limited scope.
var scope = {};
var ctypes = ctypes;
function run_test()
{
// Launch the test with regular loading of ctypes.jsm
main_test();
// Relaunch the test with exotic loading of ctypes.jsm
Components.utils.unload("resource://gre/modules/ctypes.jsm");
Components.utils.import("resource://gre/modules/ctypes.jsm", scope);
ctypes = scope.ctypes;
main_test();
}
function main_test()
{
"use strict";
let library = open_ctypes_test_lib();
let set_errno = library.declare("set_errno", ctypes.default_abi,
ctypes.void_t,
ctypes.int);
let get_errno = library.declare("get_errno", ctypes.default_abi,
ctypes.int);
for (let i = 50; i >= 0; --i) {
set_errno(i);
let status = ctypes.errno;
do_check_eq(status, i);
status = get_errno();
do_check_eq(status, 0);
status = ctypes.errno;
do_check_eq(status, 0);
}
let set_last_error, get_last_error;
try { // The following test is Windows-specific
set_last_error = library.declare("set_last_error", ctypes.default_abi,
ctypes.void_t,
ctypes.int);
get_last_error = library.declare("get_last_error", ctypes.default_abi,
ctypes.int);
} catch (x) {
do_check_eq(ctypes.winLastError, undefined);
}
if (set_last_error) {
do_check_neq(ctypes.winLastError, undefined);
for (let i = 0; i < 50; ++i) {
set_last_error(i);
let status = ctypes.winLastError;
do_check_eq(status, i);
status = get_last_error();
do_check_eq(status, 0);
status = ctypes.winLastError;
do_check_eq(status, 0);
}
}
library.close();
}

View file

@ -1,452 +0,0 @@
var TEST_SIZE = 100;
function run_test()
{
let library = open_ctypes_test_lib();
let start = library.declare("test_finalizer_start", ctypes.default_abi,
ctypes.void_t,
ctypes.size_t);
let stop = library.declare("test_finalizer_stop", ctypes.default_abi,
ctypes.void_t);
let status = library.declare("test_finalizer_resource_is_acquired",
ctypes.default_abi,
ctypes.bool,
ctypes.size_t);
let released = function released(value, witness) {
return witness == undefined;
};
let samples = [];
samples.push(
{
name: "size_t",
acquire: library.declare("test_finalizer_acq_size_t",
ctypes.default_abi,
ctypes.size_t,
ctypes.size_t),
release: library.declare("test_finalizer_rel_size_t",
ctypes.default_abi,
ctypes.void_t,
ctypes.size_t),
compare: library.declare("test_finalizer_cmp_size_t",
ctypes.default_abi,
ctypes.bool,
ctypes.size_t,
ctypes.size_t),
status: status,
released: released
});
samples.push(
{
name: "size_t",
acquire: library.declare("test_finalizer_acq_size_t",
ctypes.default_abi,
ctypes.size_t,
ctypes.size_t),
release: library.declare("test_finalizer_rel_size_t_set_errno",
ctypes.default_abi,
ctypes.void_t,
ctypes.size_t),
compare: library.declare("test_finalizer_cmp_size_t",
ctypes.default_abi,
ctypes.bool,
ctypes.size_t,
ctypes.size_t),
status: status,
released: released
});
samples.push(
{
name: "int32_t",
acquire: library.declare("test_finalizer_acq_int32_t",
ctypes.default_abi,
ctypes.int32_t,
ctypes.size_t),
release: library.declare("test_finalizer_rel_int32_t",
ctypes.default_abi,
ctypes.void_t,
ctypes.int32_t),
compare: library.declare("test_finalizer_cmp_int32_t",
ctypes.default_abi,
ctypes.bool,
ctypes.int32_t,
ctypes.int32_t),
status: status,
released: released
}
);
samples.push(
{
name: "int64_t",
acquire: library.declare("test_finalizer_acq_int64_t",
ctypes.default_abi,
ctypes.int64_t,
ctypes.size_t),
release: library.declare("test_finalizer_rel_int64_t",
ctypes.default_abi,
ctypes.void_t,
ctypes.int64_t),
compare: library.declare("test_finalizer_cmp_int64_t",
ctypes.default_abi,
ctypes.bool,
ctypes.int64_t,
ctypes.int64_t),
status: status,
released: released
}
);
samples.push(
{
name: "ptr",
acquire: library.declare("test_finalizer_acq_ptr_t",
ctypes.default_abi,
ctypes.PointerType(ctypes.void_t),
ctypes.size_t),
release: library.declare("test_finalizer_rel_ptr_t",
ctypes.default_abi,
ctypes.void_t,
ctypes.PointerType(ctypes.void_t)),
compare: library.declare("test_finalizer_cmp_ptr_t",
ctypes.default_abi,
ctypes.bool,
ctypes.void_t.ptr,
ctypes.void_t.ptr),
status: status,
released: released
}
);
samples.push(
{
name: "string",
acquire: library.declare("test_finalizer_acq_string_t",
ctypes.default_abi,
ctypes.char.ptr,
ctypes.int),
release: library.declare("test_finalizer_rel_string_t",
ctypes.default_abi,
ctypes.void_t,
ctypes.char.ptr),
compare: library.declare("test_finalizer_cmp_string_t",
ctypes.default_abi,
ctypes.bool,
ctypes.char.ptr,
ctypes.char.ptr),
status: status,
released: released
}
);
const rect_t = new ctypes.StructType("myRECT",
[{ top : ctypes.int32_t },
{ left : ctypes.int32_t },
{ bottom: ctypes.int32_t },
{ right : ctypes.int32_t }]);
samples.push(
{
name: "struct",
acquire: library.declare("test_finalizer_acq_struct_t",
ctypes.default_abi,
rect_t,
ctypes.int),
release: library.declare("test_finalizer_rel_struct_t",
ctypes.default_abi,
ctypes.void_t,
rect_t),
compare: library.declare("test_finalizer_cmp_struct_t",
ctypes.default_abi,
ctypes.bool,
rect_t,
rect_t),
status: status,
released: released
}
);
samples.push(
{
name: "size_t, release returns size_t",
acquire: library.declare("test_finalizer_acq_size_t",
ctypes.default_abi,
ctypes.size_t,
ctypes.size_t),
release: library.declare("test_finalizer_rel_size_t_return_size_t",
ctypes.default_abi,
ctypes.size_t,
ctypes.size_t),
compare: library.declare("test_finalizer_cmp_size_t",
ctypes.default_abi,
ctypes.bool,
ctypes.size_t,
ctypes.size_t),
status: status,
released: function released_eq(i, witness) {
return i == witness;
}
}
);
samples.push(
{
name: "size_t, release returns myRECT",
acquire: library.declare("test_finalizer_acq_size_t",
ctypes.default_abi,
ctypes.size_t,
ctypes.size_t),
release: library.declare("test_finalizer_rel_size_t_return_struct_t",
ctypes.default_abi,
rect_t,
ctypes.size_t),
compare: library.declare("test_finalizer_cmp_size_t",
ctypes.default_abi,
ctypes.bool,
ctypes.size_t,
ctypes.size_t),
status: status,
released: function released_rect_eq(i, witness) {
return witness.top == i
&& witness.bottom == i
&& witness.left == i
&& witness.right == i;
}
}
);
samples.push(
{
name: "using null",
acquire: library.declare("test_finalizer_acq_null_t",
ctypes.default_abi,
ctypes.PointerType(ctypes.void_t),
ctypes.size_t),
release: library.declare("test_finalizer_rel_null_t",
ctypes.default_abi,
ctypes.void_t,
ctypes.PointerType(ctypes.void_t)),
status: library.declare("test_finalizer_null_resource_is_acquired",
ctypes.default_abi,
ctypes.bool,
ctypes.size_t),
compare: library.declare("test_finalizer_cmp_null_t",
ctypes.default_abi,
ctypes.bool,
ctypes.void_t.ptr,
ctypes.void_t.ptr),
released: released
}
);
let tester = new ResourceTester(start, stop);
samples.forEach(
function run_sample(sample) {
dump("Executing finalization test for data " + sample.name + "\n");
tester.launch(TEST_SIZE, test_executing_finalizers, sample);
tester.launch(TEST_SIZE, test_do_not_execute_finalizers_on_referenced_stuff, sample);
tester.launch(TEST_SIZE, test_executing_dispose, sample);
tester.launch(TEST_SIZE, test_executing_forget, sample);
tester.launch(TEST_SIZE, test_result_dispose, sample);
dump("Successfully completed finalization test for data " + sample.name + "\n");
}
);
/*
* Following test deactivated: Cycle collection never takes place
* (see bug 727371)
tester.launch(TEST_SIZE, test_cycles, samples[0]);
*/
dump("Successfully completed all finalization tests\n");
library.close();
}
// If only I could have Promises to test this :)
// There is only so much we can do at this stage,
// if we want to avoid tests overlapping.
function test_cycles(size, tc) {
// Now, restart this with unreferenced cycles
for (i = 0; i < size/2; ++i) {
let a = {
a: ctypes.CDataFinalizer(tc.acquire(i*2), tc.release),
b: {
b: ctypes.CDataFinalizer(tc.acquire(i*2+1), tc.release)
}
};
a.b.a = a;
}
do_test_pending();
Components.utils.schedulePreciseGC(
function after_gc() {
// Check that _something_ has been finalized
do_check_true(count_finalized(size, tc) > 0);
do_test_finished();
}
);
do_timeout(10000, do_throw);
}
function count_finalized(size, tc) {
let finalizedItems = 0;
for (let i = 0; i < size; ++i) {
if (!tc.status(i)) {
++finalizedItems;
}
}
return finalizedItems;
}
/**
* Test:
* - that (some) finalizers are executed;
* - that no finalizer is executed twice (this is done on the C side).
*/
function test_executing_finalizers(size, tc, cleanup)
{
dump("test_executing_finalizers " + tc.name + "\n");
// Allocate |size| items without references
for (let i = 0; i < size; ++i) {
cleanup.add(ctypes.CDataFinalizer(tc.acquire(i), tc.release));
}
trigger_gc(); // This should trigger some finalizations, hopefully all
// Check that _something_ has been finalized
do_check_true(count_finalized(size, tc) > 0);
}
/**
* Check that
* - |dispose| returns the proper result
*/
function test_result_dispose(size, tc, cleanup) {
dump("test_result_dispose " + tc.name + "\n");
let ref = [];
// Allocate |size| items with references
for (let i = 0; i < size; ++i) {
let value = ctypes.CDataFinalizer(tc.acquire(i), tc.release);
cleanup.add(value);
ref.push(value);
}
do_check_eq(count_finalized(size, tc), 0);
for (i = 0; i < size; ++i) {
let witness = ref[i].dispose();
ref[i] = null;
if (!tc.released(i, witness)) {
do_print("test_result_dispose failure at index "+i);
do_check_true(false);
}
}
do_check_eq(count_finalized(size, tc), size);
}
/**
* Check that
* - |dispose| is executed properly
* - finalizers are not executed after |dispose|
*/
function test_executing_dispose(size, tc, cleanup)
{
dump("test_executing_dispose " + tc.name + "\n");
let ref = [];
// Allocate |size| items with references
for (let i = 0; i < size; ++i) {
let value = ctypes.CDataFinalizer(tc.acquire(i), tc.release);
cleanup.add(value);
ref.push(value);
}
do_check_eq(count_finalized(size, tc), 0);
// Dispose of everything and make sure that everything has been cleaned up
ref.forEach(
function dispose(v) {
v.dispose();
}
);
do_check_eq(count_finalized(size, tc), size);
// Remove references
ref = [];
// Re-acquire data and make sure that everything has been reinialized
for (i = 0; i < size; ++i) {
tc.acquire(i);
}
do_check_eq(count_finalized(size, tc), 0);
// Attempt to trigger finalizations, ensure that they do not take place
trigger_gc();
do_check_eq(count_finalized(size, tc), 0);
}
/**
* Check that
* - |forget| does not dispose
* - |forget| has the right content
* - finalizers are not executed after |forget|
*/
function test_executing_forget(size, tc, cleanup)
{
dump("test_executing_forget " + tc.name + "\n");
let ref = [];
// Allocate |size| items with references
for (let i = 0; i < size; ++i) {
let original = tc.acquire(i);
let finalizer = ctypes.CDataFinalizer(original, tc.release);
ref.push(
{
original: original,
finalizer: finalizer
}
);
cleanup.add(finalizer);
do_check_true(tc.compare(original, finalizer));
}
do_check_eq(count_finalized(size, tc), 0);
// Forget everything, making sure that we recover the original info
ref.forEach(
function compare_original_to_recovered(v) {
let original = v.original;
let recovered = v.finalizer.forget();
// Note: Cannot use do_check_eq on Uint64 et al.
do_check_true(tc.compare(original, recovered));
do_check_eq(original.constructor, recovered.constructor);
}
);
// Also make sure that we have not performed any clean up
do_check_eq(count_finalized(size, tc), 0);
// Remove references
ref = [];
// Attempt to trigger finalizations, ensure that they have no effect
trigger_gc();
do_check_eq(count_finalized(size, tc), 0);
}
/**
* Check that finalizers are not executed
*/
function test_do_not_execute_finalizers_on_referenced_stuff(size, tc, cleanup)
{
dump("test_do_not_execute_finalizers_on_referenced_stuff " + tc.name + "\n");
let ref = [];
// Allocate |size| items without references
for (let i = 0; i < size; ++i) {
let value = ctypes.CDataFinalizer(tc.acquire(i), tc.release);
cleanup.add(value);
ref.push(value);
}
trigger_gc(); // This might trigger some finalizations, but it should not
// Check that _nothing_ has been finalized
do_check_eq(count_finalized(size, tc), 0);
}

View file

@ -1,174 +0,0 @@
try {
// We might be running without privileges, in which case it's up to the
// harness to give us the 'ctypes' object.
Components.utils.import("resource://gre/modules/ctypes.jsm");
} catch (e) {
}
var acquire, dispose, reset_errno, dispose_errno,
acquire_ptr, dispose_ptr,
acquire_void_ptr, dispose_void_ptr,
acquire_string, dispose_string;
function run_test()
{
let library = open_ctypes_test_lib();
let start = library.declare("test_finalizer_start", ctypes.default_abi,
ctypes.void_t,
ctypes.size_t);
let stop = library.declare("test_finalizer_stop", ctypes.default_abi,
ctypes.void_t);
let tester = new ResourceTester(start, stop);
acquire = library.declare("test_finalizer_acq_size_t",
ctypes.default_abi,
ctypes.size_t,
ctypes.size_t);
dispose = library.declare("test_finalizer_rel_size_t",
ctypes.default_abi,
ctypes.void_t,
ctypes.size_t);
reset_errno = library.declare("reset_errno",
ctypes.default_abi,
ctypes.void_t);
dispose_errno = library.declare("test_finalizer_rel_size_t_set_errno",
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);
acquire_string = library.declare("test_finalizer_acq_string_t",
ctypes.default_abi,
ctypes.char.ptr,
ctypes.size_t);
dispose_string = library.declare("test_finalizer_rel_string_t",
ctypes.default_abi,
ctypes.void_t,
ctypes.char.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);
tester.launch(10, test_readstring);
}
/**
* Check that toString succeeds before/after forget/dispose.
*/
function test_to_string()
{
do_print("Starting test_to_string");
let a = ctypes.CDataFinalizer(acquire(0), dispose);
do_check_eq(a.toString(), "0");
a.forget();
do_check_eq(a.toString(), "[CDataFinalizer - empty]");
a = ctypes.CDataFinalizer(acquire(0), dispose);
a.dispose();
do_check_eq(a.toString(), "[CDataFinalizer - empty]");
}
/**
* Check that toSource succeeds before/after forget/dispose.
*/
function test_to_source()
{
do_print("Starting test_to_source");
let value = acquire(0);
let a = ctypes.CDataFinalizer(value, dispose);
do_check_eq(a.toSource(),
"ctypes.CDataFinalizer("
+ ctypes.size_t(value).toSource()
+", "
+dispose.toSource()
+")");
value = null;
a.forget();
do_check_eq(a.toSource(), "ctypes.CDataFinalizer()");
a = ctypes.CDataFinalizer(acquire(0), dispose);
a.dispose();
do_check_eq(a.toSource(), "ctypes.CDataFinalizer()");
}
/**
* Test conversion to int32
*/
function test_to_int()
{
let value = 2;
let wrapped, converted, finalizable;
wrapped = ctypes.int32_t(value);
finalizable = ctypes.CDataFinalizer(acquire(value), dispose);
converted = ctypes.int32_t(finalizable);
structural_check_eq(converted, wrapped);
structural_check_eq(converted, ctypes.int32_t(finalizable.forget()));
finalizable = ctypes.CDataFinalizer(acquire(value), dispose);
wrapped = ctypes.int64_t(value);
converted = ctypes.int64_t(finalizable);
structural_check_eq(converted, wrapped);
finalizable.dispose();
}
/**
* Test that dispose can change errno but finalization cannot
*/
function test_errno(size, tc, cleanup)
{
reset_errno();
do_check_eq(ctypes.errno, 0);
let finalizable = ctypes.CDataFinalizer(acquire(3), dispose_errno);
finalizable.dispose();
do_check_eq(ctypes.errno, 10);
reset_errno();
do_check_eq(ctypes.errno, 0);
for (let i = 0; i < size; ++i) {
finalizable = ctypes.CDataFinalizer(acquire(i), dispose_errno);
cleanup.add(finalizable);
}
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.
}
/**
* Test that readstring can be applied to a finalizer
*/
function test_readstring(size)
{
for (let i = 0; i < size; ++i) {
let acquired = acquire_string(i);
let finalizable = ctypes.CDataFinalizer(acquired,
dispose_string);
do_check_eq(finalizable.readString(), acquired.readString());
finalizable.dispose();
}
}

View file

@ -1,176 +0,0 @@
try {
// We might be running without privileges, in which case it's up to the
// harness to give us the 'ctypes' object.
Components.utils.import("resource://gre/modules/ctypes.jsm");
} catch (e) {
}
var acquire, dispose, null_dispose, compare, dispose_64;
function run_test()
{
let library = open_ctypes_test_lib();
let start = library.declare("test_finalizer_start", ctypes.default_abi,
ctypes.void_t,
ctypes.size_t);
let stop = library.declare("test_finalizer_stop", ctypes.default_abi,
ctypes.void_t);
let tester = new ResourceTester(start, stop);
acquire = library.declare("test_finalizer_acq_size_t",
ctypes.default_abi,
ctypes.size_t,
ctypes.size_t);
dispose = library.declare("test_finalizer_rel_size_t",
ctypes.default_abi,
ctypes.void_t,
ctypes.size_t);
compare = library.declare("test_finalizer_cmp_size_t",
ctypes.default_abi,
ctypes.bool,
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;
let null_dispose_maker =
library.declare("test_finalizer_rel_null_function",
ctypes.default_abi,
type_afun
);
null_dispose = null_dispose_maker();
tester.launch(10, test_double_dispose);
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);
}
/**
* Testing construction of finalizers with wrong arguments.
*/
function test_finalize_bad_construction() {
// First argument does not match second
must_throw(function() { ctypes.CDataFinalizer({}, dispose); });
must_throw(function() { ctypes.CDataFinalizer(dispose, dispose); });
// Not enough arguments
must_throw(function() { ctypes.CDataFinalizer(init(0)); });
// Too many arguments
must_throw(function() { ctypes.CDataFinalizer(init(0), dispose, dispose); });
// Second argument is null
must_throw(function() { ctypes.CDataFinalizer(init(0), null); });
// Second argument is undefined
must_throw(function() {
let a;
ctypes.CDataFinalizer(init(0), a);
});
}
/**
* Test that forget/dispose can only take place once.
*/
function test_double_dispose() {
function test_one_combination(i, a, b) {
let v = ctypes.CDataFinalizer(acquire(i), dispose);
a(v);
must_throw(function() { b(v); } );
}
let call_dispose = function(v) {
v.dispose();
};
let call_forget = function(v) {
v.forget();
};
test_one_combination(0, call_dispose, call_dispose);
test_one_combination(1, call_dispose, call_forget);
test_one_combination(2, call_forget, call_dispose);
test_one_combination(3, call_forget, call_forget);
}
/**
* Test that nothing (too) bad happens when the finalizer is NULL
*/
function test_null_dispose()
{
let exception;
exception = false;
try {
ctypes.CDataFinalizer(acquire(0), null_dispose);
} catch (x) {
exception = true;
}
do_check_true(exception);
}
/**
* Test that conversion of a disposed/forgotten CDataFinalizer to a C
* value fails nicely.
*/
function test_pass_disposed()
{
let exception, v;
exception = false;
v = ctypes.CDataFinalizer(acquire(0), dispose);
do_check_true(compare(v, 0));
v.forget();
try {
compare(v, 0);
} catch (x) {
exception = true;
}
do_check_true(exception);
exception = false;
v = ctypes.CDataFinalizer(acquire(0), dispose);
do_check_true(compare(v, 0));
v.dispose();
try {
compare(v, 0);
} catch (x) {
exception = true;
}
do_check_true(exception);
exception = false;
try {
ctypes.int32_t(ctypes.CDataFinalizer(v, dispose));
} catch (x) {
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");
}

File diff suppressed because it is too large Load diff

View file

@ -1,13 +0,0 @@
[DEFAULT]
head = head.js
tail =
skip-if = toolkit == 'android'
[test_errno.js]
[test_finalizer.js]
[test_finalizer_shouldfail.js]
[test_finalizer_shouldaccept.js]
[test_jsctypes.js]
# Bug 676989: test fails consistently on Android
fail-if = os == "android"