mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-08 08:17:31 +09:00
Issue #439 - Remove tests from toolkit/
This commit is contained in:
parent
3210cc7d95
commit
e5bacc6f6e
2362 changed files with 95 additions and 246993 deletions
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"../../../../../testing/mochitest/chrome.eslintrc.js"
|
||||
]
|
||||
};
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
[DEFAULT]
|
||||
skip-if = os == 'android'
|
||||
support-files =
|
||||
xpcshellTestHarnessAdaptor.js
|
||||
ctypes_worker.js
|
||||
../unit/test_jsctypes.js
|
||||
|
||||
[test_ctypes.xul]
|
||||
|
|
@ -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!");
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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_;
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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]
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"../../../../../testing/xpcshell/xpcshell.eslintrc.js"
|
||||
]
|
||||
};
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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"
|
||||
Loading…
Add table
Add a link
Reference in a new issue