mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 684017 - Implement ctypes.errno and ctypes.winLastError. r=jorendorff
This commit is contained in:
parent
ea3e5e0086
commit
4adff58654
@ -56,6 +56,12 @@
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
#include <errno.h>
|
||||
#elif defined(XP_WIN)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace js {
|
||||
@ -86,6 +92,17 @@ namespace CType {
|
||||
static JSBool ToString(JSContext* cx, unsigned argc, jsval* vp);
|
||||
static JSBool ToSource(JSContext* cx, unsigned argc, jsval* vp);
|
||||
static JSBool HasInstance(JSContext* cx, JSObject* obj, const jsval* v, JSBool* bp);
|
||||
|
||||
|
||||
/**
|
||||
* Get the global "ctypes" object.
|
||||
*
|
||||
* |obj| must be a CType object.
|
||||
*
|
||||
* This function never returns NULL.
|
||||
*/
|
||||
static JSObject* GetGlobalCTypes(JSContext* cx, JSObject* obj);
|
||||
|
||||
}
|
||||
|
||||
namespace PointerType {
|
||||
@ -168,6 +185,14 @@ namespace CData {
|
||||
static JSBool Address(JSContext* cx, unsigned argc, jsval* vp);
|
||||
static JSBool ReadString(JSContext* cx, unsigned argc, jsval* vp);
|
||||
static JSBool ToSource(JSContext* cx, unsigned argc, jsval* vp);
|
||||
|
||||
static JSBool ErrnoGetter(JSContext* cx, JSObject *obj, jsid idval,
|
||||
jsval* vp);
|
||||
|
||||
#if defined(XP_WIN)
|
||||
static JSBool LastErrorGetter(JSContext* cx, JSObject *obj, jsid idval,
|
||||
jsval* vp);
|
||||
#endif // defined(XP_WIN)
|
||||
}
|
||||
|
||||
// Int64Base provides functions common to Int64 and UInt64.
|
||||
@ -442,6 +467,16 @@ static JSFunctionSpec sUInt64Functions[] = {
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
static JSPropertySpec sModuleProps[] = {
|
||||
{ "errno", 0, JSPROP_SHARED | JSPROP_PERMANENT,
|
||||
CData::ErrnoGetter, NULL },
|
||||
#if defined(XP_WIN)
|
||||
{ "winLastError", 0, JSPROP_SHARED | JSPROP_PERMANENT,
|
||||
CData::LastErrorGetter, NULL },
|
||||
#endif // defined(XP_WIN)
|
||||
{ 0, 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static JSFunctionSpec sModuleFunctions[] = {
|
||||
JS_FN("open", Library::Open, 1, CTYPESFN_FLAGS),
|
||||
JS_FN("cast", CData::Cast, 2, CTYPESFN_FLAGS),
|
||||
@ -729,9 +764,9 @@ static void
|
||||
AttachProtos(JSObject* proto, JSObject** protos)
|
||||
{
|
||||
// For a given 'proto' of [[Class]] "CTypeProto", attach each of the 'protos'
|
||||
// to the appropriate CTypeProtoSlot. (SLOT_UINT64PROTO is the last slot
|
||||
// to the appropriate CTypeProtoSlot. (SLOT_CTYPES is the last slot
|
||||
// of [[Class]] "CTypeProto" that we fill in this automated manner.)
|
||||
for (uint32_t i = 0; i <= SLOT_UINT64PROTO; ++i)
|
||||
for (uint32_t i = 0; i <= SLOT_CTYPES; ++i)
|
||||
JS_SetReservedSlot(proto, i, OBJECT_TO_JSVAL(protos[i]));
|
||||
}
|
||||
|
||||
@ -847,6 +882,10 @@ InitTypeClasses(JSContext* cx, JSObject* parent)
|
||||
if (!protos[SLOT_UINT64PROTO])
|
||||
return false;
|
||||
|
||||
// Finally, store a pointer to the global ctypes object.
|
||||
// Note that there is no other reliable manner of locating this object.
|
||||
protos[SLOT_CTYPES] = parent;
|
||||
|
||||
// Attach the prototypes just created to each of ctypes.CType.prototype,
|
||||
// and the special type constructors, so we can access them when constructing
|
||||
// instances of those types.
|
||||
@ -942,8 +981,9 @@ JS_InitCTypesClass(JSContext* cx, JSObject* global)
|
||||
if (!InitTypeClasses(cx, ctypes))
|
||||
return false;
|
||||
|
||||
// attach API functions
|
||||
if (!JS_DefineFunctions(cx, ctypes, sModuleFunctions))
|
||||
// attach API functions and properties
|
||||
if (!JS_DefineFunctions(cx, ctypes, sModuleFunctions) ||
|
||||
!JS_DefineProperties(cx, ctypes, sModuleProps))
|
||||
return false;
|
||||
|
||||
// Seal the ctypes object, to prevent modification.
|
||||
@ -3226,6 +3266,23 @@ CType::HasInstance(JSContext* cx, JSObject* obj, const jsval* v, JSBool* bp)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSObject*
|
||||
CType::GetGlobalCTypes(JSContext* cx, JSObject* obj)
|
||||
{
|
||||
JS_ASSERT(CType::IsCType(obj));
|
||||
|
||||
JSObject *objTypeProto = JS_GetPrototype(obj);
|
||||
if (!objTypeProto) {
|
||||
}
|
||||
JS_ASSERT(objTypeProto);
|
||||
JS_ASSERT(CType::IsCTypeProto(objTypeProto));
|
||||
|
||||
jsval valCTypes = JS_GetReservedSlot(objTypeProto, SLOT_CTYPES);
|
||||
JS_ASSERT(!JSVAL_IS_PRIMITIVE(valCTypes));
|
||||
|
||||
return JSVAL_TO_OBJECT(valCTypes);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
** PointerType implementation
|
||||
*******************************************************************************/
|
||||
@ -5149,13 +5206,45 @@ FunctionType::Call(JSContext* cx,
|
||||
|
||||
uintptr_t fn = *reinterpret_cast<uintptr_t*>(CData::GetData(obj));
|
||||
|
||||
#if defined(XP_WIN)
|
||||
int32_t lastErrorStatus; // The status as defined by |GetLastError|
|
||||
int32_t savedLastError = GetLastError();
|
||||
SetLastError(0);
|
||||
#endif //defined(XP_WIN)
|
||||
int errnoStatus; // The status as defined by |errno|
|
||||
int savedErrno = errno;
|
||||
errno = 0;
|
||||
|
||||
// suspend the request before we call into the function, since the call
|
||||
// may block or otherwise take a long time to return.
|
||||
{
|
||||
JSAutoSuspendRequest suspend(cx);
|
||||
ffi_call(&fninfo->mCIF, FFI_FN(fn), returnValue.mData,
|
||||
reinterpret_cast<void**>(values.begin()));
|
||||
|
||||
// Save error value.
|
||||
// We need to save it before leaving the scope of |suspend| as destructing
|
||||
// |suspend| has the side-effect of clearing |GetLastError|
|
||||
// (see bug 684017).
|
||||
|
||||
errnoStatus = errno;
|
||||
#if defined(XP_WIN)
|
||||
lastErrorStatus = GetLastError();
|
||||
#endif // defined(XP_WIN)
|
||||
}
|
||||
#if defined(XP_WIN)
|
||||
SetLastError(savedLastError);
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
errno = savedErrno;
|
||||
|
||||
// Store the error value for later consultation with |ctypes.getStatus|
|
||||
JSObject *objCTypes = CType::GetGlobalCTypes(cx, typeObj);
|
||||
|
||||
JS_SetReservedSlot(objCTypes, SLOT_ERRNO, INT_TO_JSVAL(errnoStatus));
|
||||
#if defined(XP_WIN)
|
||||
JS_SetReservedSlot(objCTypes, SLOT_LASTERROR, INT_TO_JSVAL(lastErrorStatus));
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
// Small integer types get returned as a word-sized ffi_arg. Coerce it back
|
||||
// into the correct size for ConvertToJS.
|
||||
@ -5976,6 +6065,33 @@ CData::ToSource(JSContext* cx, unsigned argc, jsval* vp)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool
|
||||
CData::ErrnoGetter(JSContext* cx, JSObject* obj, jsid, jsval* vp)
|
||||
{
|
||||
if (!IsCTypesGlobal(obj)) {
|
||||
JS_ReportError(cx, "this is not not global object ctypes");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
*vp = JS_GetReservedSlot(obj, SLOT_ERRNO);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
JSBool
|
||||
CData::LastErrorGetter(JSContext* cx, JSObject* obj, jsid, jsval* vp)
|
||||
{
|
||||
if (!IsCTypesGlobal(obj)) {
|
||||
JS_ReportError(cx, "not global object ctypes");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
*vp = JS_GetReservedSlot(obj, SLOT_LASTERROR);
|
||||
return JS_TRUE;
|
||||
}
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
/*******************************************************************************
|
||||
** Int64 and UInt64 implementation
|
||||
*******************************************************************************/
|
||||
|
@ -369,6 +369,8 @@ JSBool ExplicitConvert(JSContext* cx, jsval val, JSObject* targetType,
|
||||
|
||||
enum CTypesGlobalSlot {
|
||||
SLOT_CALLBACKS = 0, // pointer to JSCTypesCallbacks struct
|
||||
SLOT_ERRNO = 1, // jsval for latest |errno|
|
||||
SLOT_LASTERROR = 2, // jsval for latest |GetLastError|, used only with Windows
|
||||
CTYPESGLOBAL_SLOTS
|
||||
};
|
||||
|
||||
@ -389,8 +391,9 @@ enum CTypeProtoSlot {
|
||||
SLOT_FUNCTIONDATAPROTO = 8, // common ancestor of all CData objects of FunctionType
|
||||
SLOT_INT64PROTO = 9, // ctypes.Int64.prototype object
|
||||
SLOT_UINT64PROTO = 10, // ctypes.UInt64.prototype object
|
||||
SLOT_OURDATAPROTO = 11, // the data prototype corresponding to this object
|
||||
SLOT_CLOSURECX = 12, // JSContext for use with FunctionType closures
|
||||
SLOT_CTYPES = 11, // ctypes object
|
||||
SLOT_OURDATAPROTO = 12, // the data prototype corresponding to this object
|
||||
SLOT_CLOSURECX = 13, // JSContext for use with FunctionType closures
|
||||
CTYPEPROTO_SLOTS
|
||||
};
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
# Contributor(s):
|
||||
# Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
|
||||
# Dan Witte <dwitte@mozilla.com>
|
||||
# David Rajchenbach-Teller <dteller@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -50,7 +51,9 @@ SHORT_LIBNAME = jscttest
|
||||
FORCE_SHARED_LIB = 1
|
||||
NO_DIST_INSTALL = 1
|
||||
|
||||
CPPSRCS = jsctypes-test.cpp
|
||||
CPPSRCS = jsctypes-test.cpp \
|
||||
jsctypes-test-errno.cpp \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(topsrcdir)/js/src/ctypes \
|
||||
|
77
toolkit/components/ctypes/tests/jsctypes-test-errno.cpp
Normal file
77
toolkit/components/ctypes/tests/jsctypes-test-errno.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is js-ctypes.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation <http://www.mozilla.org/>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Fredrik Larsson <nossralf@gmail.com>
|
||||
* Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
|
||||
* Dan Witte <dwitte@mozilla.com>
|
||||
* David Rajchenbach-Teller <dteller@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#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*)NULL)++; \
|
||||
}
|
||||
|
||||
|
||||
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)
|
58
toolkit/components/ctypes/tests/jsctypes-test-errno.h
Normal file
58
toolkit/components/ctypes/tests/jsctypes-test-errno.h
Normal file
@ -0,0 +1,58 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is js-ctypes.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation <http://www.mozilla.org/>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Fredrik Larsson <nossralf@gmail.com>
|
||||
* Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
|
||||
* Dan Witte <dwitte@mozilla.com>
|
||||
* David Rajchenbach-Teller <dteller@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nscore.h"
|
||||
#include "prtypes.h"
|
||||
#include "jsapi.h"
|
||||
|
||||
#define EXPORT_CDECL(type) NS_EXPORT type
|
||||
#define EXPORT_STDCALL(type) NS_EXPORT type NS_STDCALL
|
||||
|
||||
NS_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)
|
||||
}
|
79
toolkit/components/ctypes/tests/unit/head.js
Normal file
79
toolkit/components/ctypes/tests/unit/head.js
Normal file
@ -0,0 +1,79 @@
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple wrapper for tests that require cleanup.
|
||||
*/
|
||||
function ResourceTester(start, stop) {
|
||||
this._start = start;
|
||||
this._stop = stop;
|
||||
}
|
||||
ResourceTester.prototype = {
|
||||
launch: function(size, test, args) {
|
||||
Components.utils.forceGC();
|
||||
this._start(size);
|
||||
try {
|
||||
test(size, args);
|
||||
} catch (x) {
|
||||
this._stop();
|
||||
throw x;
|
||||
}
|
||||
Components.utils.forceGC();
|
||||
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) {
|
||||
return do_check_eq(asource, bsource);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
);
|
||||
}
|
69
toolkit/components/ctypes/tests/unit/test_errno.js
Normal file
69
toolkit/components/ctypes/tests/unit/test_errno.js
Normal file
@ -0,0 +1,69 @@
|
||||
Components.utils.import("resource://gre/modules/ctypes.jsm");
|
||||
|
||||
// Scope used to relaunch the tests with |ctypes| opened in a limited scope.
|
||||
let scope = {};
|
||||
let 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,7 +1,9 @@
|
||||
[DEFAULT]
|
||||
head =
|
||||
head = head.js
|
||||
tail =
|
||||
|
||||
[test_errno.js]
|
||||
|
||||
[test_jsctypes.js]
|
||||
# Bug 676989: test fails consistently on Android
|
||||
fail-if = os == "android"
|
||||
|
Loading…
Reference in New Issue
Block a user