diff --git a/android/Android.mk b/android/Android.mk index 0d5755bd..c3cd7e0d 100644 --- a/android/Android.mk +++ b/android/Android.mk @@ -96,27 +96,6 @@ LOCAL_EXPORT_CPPFLAGS := -D__STDC_LIMIT_MACROS=1 include $(PREBUILT_STATIC_LIBRARY) -#====================================== -include $(CLEAR_VARS) - -LOCAL_MODULE := cocos_mozglue_static -LOCAL_MODULE_FILENAME := mozglue -LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libmozglue.a -include $(PREBUILT_STATIC_LIBRARY) - -#====================================== -include $(CLEAR_VARS) - -LOCAL_MODULE := spidermonkey_static -LOCAL_MODULE_FILENAME := js_static -LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libjs_static.a -LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(TARGET_ARCH_ABI)/include/spidermonkey - -LOCAL_CPPFLAGS := -D__STDC_LIMIT_MACROS=1 -Wno-invalid-offsetof -LOCAL_EXPORT_CPPFLAGS := -D__STDC_LIMIT_MACROS=1 -Wno-invalid-offsetof -LOCAL_STATIC_LIBRARIES += cocos_mozglue_static -include $(PREBUILT_STATIC_LIBRARY) - #====================================== include $(CLEAR_VARS) LOCAL_MODULE := v8_builtins_generators diff --git a/android/arm64-v8a/include/spidermonkey/fdlibm.h b/android/arm64-v8a/include/spidermonkey/fdlibm.h deleted file mode 100644 index 0ad21591..00000000 --- a/android/arm64-v8a/include/spidermonkey/fdlibm.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* - * from: @(#)fdlibm.h 5.1 93/09/24 - * $FreeBSD$ - */ - -#ifndef mozilla_imported_fdlibm_h -#define mozilla_imported_fdlibm_h - -namespace fdlibm { - -double acos(double); -double asin(double); -double atan(double); -double atan2(double, double); - -double cosh(double); -double sinh(double); -double tanh(double); - -double exp(double); -double log(double); -double log10(double); - -double pow(double, double); -double sqrt(double); -double fabs(double); - -double floor(double); -double trunc(double); -double ceil(double); - -double acosh(double); -double asinh(double); -double atanh(double); -double cbrt(double); -double expm1(double); -double hypot(double, double); -double log1p(double); -double log2(double); -double rint(double); -double copysign(double, double); -double nearbyint(double); -double scalbn(double, int); - -float ceilf(float); -float floorf(float); - -float nearbyintf(float); -float rintf(float); -float truncf(float); - -} /* namespace fdlibm */ - -#endif /* mozilla_imported_fdlibm_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js-config.h b/android/arm64-v8a/include/spidermonkey/js-config.h deleted file mode 100644 index 6909f6c7..00000000 --- a/android/arm64-v8a/include/spidermonkey/js-config.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=78: - * - * 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 js_config_h -#define js_config_h - -/* Definitions set at build time that affect SpiderMonkey's public API. - This header file is generated by the SpiderMonkey configure script, - and installed along with jsapi.h. */ - -/* Define to 1 if SpiderMonkey is in debug mode. */ -/* #undef JS_DEBUG */ - -/* - * NB: We have a special case for rust-bindgen, which wants to be able to - * generate both debug and release bindings on a single objdir. - */ -#ifdef JS_DEBUG -#if !defined(DEBUG) && !defined(RUST_BINDGEN) -# error "SpiderMonkey was configured with --enable-debug, so DEBUG must be defined when including this header" -# endif -#else -# if defined(DEBUG) && !defined(RUST_BINDGEN) -# error "SpiderMonkey was configured with --disable-debug, so DEBUG must be not defined when including this header" -# endif -#endif - -/* Define to 1 if SpiderMonkey should not use struct types in debug builds. */ -/* #undef JS_NO_JSVAL_JSID_STRUCT_TYPES */ - -/* Define to 1 if SpiderMonkey should support multi-threaded clients. */ -/* #undef JS_THREADSAFE */ - -/* Define to 1 if SpiderMonkey should include ctypes support. */ -/* #undef JS_HAS_CTYPES */ - -/* Define to 1 if SpiderMonkey should support the ability to perform - entirely too much GC. */ -/* #undef JS_GC_ZEAL */ - -/* Define to 1 if SpiderMonkey should use small chunks. */ -/* #undef JS_GC_SMALL_CHUNK_SIZE */ - -/* Define to 1 to perform extra assertions and heap poisoning. */ -/* #undef JS_CRASH_DIAGNOSTICS */ - -/* Define to 1 if SpiderMonkey is in NUNBOX32 mode. */ -/* #undef JS_NUNBOX32 */ - -/* Define to 1 if SpiderMonkey is in PUNBOX64 mode. */ -#define JS_PUNBOX64 1 - -/* MOZILLA JSAPI version number components */ -#define MOZJS_MAJOR_VERSION 52 -#define MOZJS_MINOR_VERSION 0 - -#endif /* js_config_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js.msg b/android/arm64-v8a/include/spidermonkey/js.msg deleted file mode 100644 index 246e363c..00000000 --- a/android/arm64-v8a/include/spidermonkey/js.msg +++ /dev/null @@ -1,581 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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/. */ - -/* - * This is the JavaScript error message file. - * - * The format for each JS error message is: - * - * MSG_DEF(, , , - * ) - * - * where ; - * is a legal C identifer that will be used in the - * JS engine source. - * - * is an integer literal specifying the total number of - * replaceable arguments in the following format string. - * - * is an exception index from the enum in jsexn.c; - * JSEXN_NONE for none. The given exception index will be raised by the - * engine when the corresponding error occurs. - * - * is a string literal, optionally containing sequences - * {X} where X is an integer representing the argument number that will - * be replaced with a string value when the error is reported. - * - * e.g. - * - * MSG_DEF(JSMSG_NOT_A_SUBSPECIES, 2, JSEXN_NONE, - * "{0} is not a member of the {1} family") - * - * can be used: - * - * JS_ReportErrorNumberASCII(JSMSG_NOT_A_SUBSPECIES, "Rhino", "Monkey"); - * - * to report: - * - * "Rhino is not a member of the Monkey family" - */ - -MSG_DEF(JSMSG_NOT_AN_ERROR, 0, JSEXN_ERR, "") -MSG_DEF(JSMSG_NOT_DEFINED, 1, JSEXN_REFERENCEERR, "{0} is not defined") -MSG_DEF(JSMSG_MORE_ARGS_NEEDED, 3, JSEXN_TYPEERR, "{0} requires more than {1} argument{2}") -MSG_DEF(JSMSG_INCOMPATIBLE_PROTO, 3, JSEXN_TYPEERR, "{0}.prototype.{1} called on incompatible {2}") -MSG_DEF(JSMSG_NO_CONSTRUCTOR, 1, JSEXN_TYPEERR, "{0} has no constructor") -MSG_DEF(JSMSG_BAD_SORT_ARG, 0, JSEXN_TYPEERR, "invalid Array.prototype.sort argument") -MSG_DEF(JSMSG_CANT_WATCH, 1, JSEXN_TYPEERR, "can't watch non-native objects of class {0}") -MSG_DEF(JSMSG_READ_ONLY, 1, JSEXN_TYPEERR, "{0} is read-only") -MSG_DEF(JSMSG_CANT_DELETE, 1, JSEXN_TYPEERR, "property {0} is non-configurable and can't be deleted") -MSG_DEF(JSMSG_CANT_TRUNCATE_ARRAY, 0, JSEXN_TYPEERR, "can't delete non-configurable array element") -MSG_DEF(JSMSG_NOT_FUNCTION, 1, JSEXN_TYPEERR, "{0} is not a function") -MSG_DEF(JSMSG_NOT_CONSTRUCTOR, 1, JSEXN_TYPEERR, "{0} is not a constructor") -MSG_DEF(JSMSG_CANT_CONVERT_TO, 2, JSEXN_TYPEERR, "can't convert {0} to {1}") -MSG_DEF(JSMSG_TOPRIMITIVE_NOT_CALLABLE, 2, JSEXN_TYPEERR, "can't convert {0} to {1}: its [Symbol.toPrimitive] property is not a function") -MSG_DEF(JSMSG_TOPRIMITIVE_RETURNED_OBJECT, 2, JSEXN_TYPEERR, "can't convert {0} to {1}: its [Symbol.toPrimitive] method returned an object") -MSG_DEF(JSMSG_NO_PROPERTIES, 1, JSEXN_TYPEERR, "{0} has no properties") -MSG_DEF(JSMSG_BAD_REGEXP_FLAG, 1, JSEXN_SYNTAXERR, "invalid regular expression flag {0}") -MSG_DEF(JSMSG_ARG_INDEX_OUT_OF_RANGE, 1, JSEXN_RANGEERR, "argument {0} accesses an index that is out of range") -MSG_DEF(JSMSG_SPREAD_TOO_LARGE, 0, JSEXN_RANGEERR, "array too large due to spread operand(s)") -MSG_DEF(JSMSG_BAD_WEAKMAP_KEY, 0, JSEXN_TYPEERR, "cannot use the given object as a weak map key") -MSG_DEF(JSMSG_BAD_GETTER_OR_SETTER, 1, JSEXN_TYPEERR, "invalid {0} usage") -MSG_DEF(JSMSG_BAD_ARRAY_LENGTH, 0, JSEXN_RANGEERR, "invalid array length") -MSG_DEF(JSMSG_REDECLARED_VAR, 2, JSEXN_SYNTAXERR, "redeclaration of {0} {1}") -MSG_DEF(JSMSG_UNDECLARED_VAR, 1, JSEXN_REFERENCEERR, "assignment to undeclared variable {0}") -MSG_DEF(JSMSG_GETTER_ONLY, 0, JSEXN_TYPEERR, "setting a property that has only a getter") -MSG_DEF(JSMSG_OVERWRITING_ACCESSOR, 1, JSEXN_TYPEERR, "can't overwrite accessor property {0}") -MSG_DEF(JSMSG_UNDEFINED_PROP, 1, JSEXN_REFERENCEERR, "reference to undefined property {0}") -MSG_DEF(JSMSG_INVALID_MAP_ITERABLE, 1, JSEXN_TYPEERR, "iterable for {0} should have array-like objects") -MSG_DEF(JSMSG_NESTING_GENERATOR, 0, JSEXN_TYPEERR, "already executing generator") -MSG_DEF(JSMSG_INCOMPATIBLE_METHOD, 3, JSEXN_TYPEERR, "{0} {1} called on incompatible {2}") -MSG_DEF(JSMSG_OBJECT_WATCH_DEPRECATED, 0, JSEXN_WARN, "Object.prototype.watch and unwatch are very slow, non-standard, and deprecated; use a getter/setter instead") -MSG_DEF(JSMSG_ARRAYBUFFER_SLICE_DEPRECATED, 0, JSEXN_WARN, "ArrayBuffer.slice is deprecated; use ArrayBuffer.prototype.slice instead") -MSG_DEF(JSMSG_BAD_SURROGATE_CHAR, 1, JSEXN_TYPEERR, "bad surrogate character {0}") -MSG_DEF(JSMSG_UTF8_CHAR_TOO_LARGE, 1, JSEXN_TYPEERR, "UTF-8 character {0} too large") -MSG_DEF(JSMSG_MALFORMED_UTF8_CHAR, 1, JSEXN_TYPEERR, "malformed UTF-8 character sequence at offset {0}") -MSG_DEF(JSMSG_BUILTIN_CTOR_NO_NEW, 1, JSEXN_TYPEERR, "calling a builtin {0} constructor without new is forbidden") -MSG_DEF(JSMSG_BAD_GENERATOR_YIELD, 1, JSEXN_TYPEERR, "yield from closing generator {0}") -MSG_DEF(JSMSG_EMPTY_ARRAY_REDUCE, 0, JSEXN_TYPEERR, "reduce of empty array with no initial value") -MSG_DEF(JSMSG_UNEXPECTED_TYPE, 2, JSEXN_TYPEERR, "{0} is {1}") -MSG_DEF(JSMSG_MISSING_FUN_ARG, 2, JSEXN_TYPEERR, "missing argument {0} when calling function {1}") -MSG_DEF(JSMSG_NOT_NONNULL_OBJECT, 1, JSEXN_TYPEERR, "{0} is not a non-null object") -MSG_DEF(JSMSG_SET_NON_OBJECT_RECEIVER, 1, JSEXN_TYPEERR, "can't assign to properties of {0}: not an object") -MSG_DEF(JSMSG_INVALID_DESCRIPTOR, 0, JSEXN_TYPEERR, "property descriptors must not specify a value or be writable when a getter or setter has been specified") -MSG_DEF(JSMSG_OBJECT_NOT_EXTENSIBLE, 1, JSEXN_TYPEERR, "{0}: Object is not extensible") -MSG_DEF(JSMSG_CANT_DEFINE_PROP_OBJECT_NOT_EXTENSIBLE, 2, JSEXN_TYPEERR, "can't define property {1}: {0} is not extensible") -MSG_DEF(JSMSG_CANT_REDEFINE_PROP, 1, JSEXN_TYPEERR, "can't redefine non-configurable property {0}") -MSG_DEF(JSMSG_CANT_REDEFINE_ARRAY_LENGTH, 0, JSEXN_TYPEERR, "can't redefine array length") -MSG_DEF(JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH, 0, JSEXN_TYPEERR, "can't define array index property past the end of an array with non-writable length") -MSG_DEF(JSMSG_BAD_GET_SET_FIELD, 1, JSEXN_TYPEERR, "property descriptor's {0} field is neither undefined nor a function") -MSG_DEF(JSMSG_THROW_TYPE_ERROR, 0, JSEXN_TYPEERR, "'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them") -MSG_DEF(JSMSG_NOT_EXPECTED_TYPE, 3, JSEXN_TYPEERR, "{0}: expected {1}, got {2}") -MSG_DEF(JSMSG_NOT_ITERABLE, 1, JSEXN_TYPEERR, "{0} is not iterable") -MSG_DEF(JSMSG_NOT_ITERATOR, 1, JSEXN_TYPEERR, "{0} is not iterator") -MSG_DEF(JSMSG_ALREADY_HAS_PRAGMA, 2, JSEXN_WARN, "{0} is being assigned a {1}, but already has one") -MSG_DEF(JSMSG_GET_ITER_RETURNED_PRIMITIVE, 0, JSEXN_TYPEERR, "[Symbol.iterator]() returned a non-object value") -MSG_DEF(JSMSG_NEXT_RETURNED_PRIMITIVE, 0, JSEXN_TYPEERR, "iterator.next() returned a non-object value") -MSG_DEF(JSMSG_CANT_SET_PROTO, 0, JSEXN_TYPEERR, "can't set prototype of this object") -MSG_DEF(JSMSG_CANT_SET_PROTO_OF, 1, JSEXN_TYPEERR, "can't set prototype of {0}") -MSG_DEF(JSMSG_CANT_SET_PROTO_CYCLE, 0, JSEXN_TYPEERR, "can't set prototype: it would cause a prototype chain cycle") -MSG_DEF(JSMSG_INVALID_ARG_TYPE, 3, JSEXN_TYPEERR, "Invalid type: {0} can't be a{1} {2}") -MSG_DEF(JSMSG_TERMINATED, 1, JSEXN_ERR, "Script terminated by timeout at:\n{0}") -MSG_DEF(JSMSG_PROTO_NOT_OBJORNULL, 1, JSEXN_TYPEERR, "{0}.prototype is not an object or null") -MSG_DEF(JSMSG_CANT_CALL_CLASS_CONSTRUCTOR, 0, JSEXN_TYPEERR, "class constructors must be invoked with |new|") -MSG_DEF(JSMSG_UNINITIALIZED_THIS, 1, JSEXN_REFERENCEERR, "|this| used uninitialized in {0} class constructor") -MSG_DEF(JSMSG_UNINITIALIZED_THIS_ARROW, 0, JSEXN_REFERENCEERR, "|this| used uninitialized in arrow function in class constructor") -MSG_DEF(JSMSG_BAD_DERIVED_RETURN, 1, JSEXN_TYPEERR, "derived class constructor returned invalid value {0}") - -// JSON -MSG_DEF(JSMSG_JSON_BAD_PARSE, 3, JSEXN_SYNTAXERR, "JSON.parse: {0} at line {1} column {2} of the JSON data") -MSG_DEF(JSMSG_JSON_CYCLIC_VALUE, 0, JSEXN_TYPEERR, "cyclic object value") - -// Runtime errors -MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS, 1, JSEXN_TYPEERR, "invalid 'instanceof' operand {0}") -MSG_DEF(JSMSG_BAD_LEFTSIDE_OF_ASS, 0, JSEXN_REFERENCEERR, "invalid assignment left-hand side") -MSG_DEF(JSMSG_BAD_PROTOTYPE, 1, JSEXN_TYPEERR, "'prototype' property of {0} is not an object") -MSG_DEF(JSMSG_IN_NOT_OBJECT, 1, JSEXN_TYPEERR, "invalid 'in' operand {0}") -MSG_DEF(JSMSG_TOO_MANY_CON_SPREADARGS, 0, JSEXN_RANGEERR, "too many constructor arguments") -MSG_DEF(JSMSG_TOO_MANY_FUN_SPREADARGS, 0, JSEXN_RANGEERR, "too many function arguments") -MSG_DEF(JSMSG_UNINITIALIZED_LEXICAL, 1, JSEXN_REFERENCEERR, "can't access lexical declaration `{0}' before initialization") -MSG_DEF(JSMSG_BAD_CONST_ASSIGN, 1, JSEXN_TYPEERR, "invalid assignment to const `{0}'") -MSG_DEF(JSMSG_CANT_DECLARE_GLOBAL_BINDING, 2, JSEXN_TYPEERR, "cannot declare global binding `{0}': {1}") - -// Date -MSG_DEF(JSMSG_INVALID_DATE, 0, JSEXN_RANGEERR, "invalid date") -MSG_DEF(JSMSG_BAD_TOISOSTRING_PROP, 0, JSEXN_TYPEERR, "toISOString property is not callable") - -// String -MSG_DEF(JSMSG_BAD_URI, 0, JSEXN_URIERR, "malformed URI sequence") -MSG_DEF(JSMSG_INVALID_NORMALIZE_FORM, 0, JSEXN_RANGEERR, "form must be one of 'NFC', 'NFD', 'NFKC', or 'NFKD'") -MSG_DEF(JSMSG_NEGATIVE_REPETITION_COUNT, 0, JSEXN_RANGEERR, "repeat count must be non-negative") -MSG_DEF(JSMSG_NOT_A_CODEPOINT, 1, JSEXN_RANGEERR, "{0} is not a valid code point") -MSG_DEF(JSMSG_RESULTING_STRING_TOO_LARGE, 0, JSEXN_RANGEERR, "repeat count must be less than infinity and not overflow maximum string size") - -// Number -MSG_DEF(JSMSG_BAD_RADIX, 0, JSEXN_RANGEERR, "radix must be an integer at least 2 and no greater than 36") -MSG_DEF(JSMSG_PRECISION_RANGE, 1, JSEXN_RANGEERR, "precision {0} out of range") - -// Function -MSG_DEF(JSMSG_BAD_APPLY_ARGS, 1, JSEXN_TYPEERR, "second argument to Function.prototype.{0} must be an array") -MSG_DEF(JSMSG_BAD_FORMAL, 0, JSEXN_SYNTAXERR, "malformed formal parameter") -MSG_DEF(JSMSG_CALLER_IS_STRICT, 0, JSEXN_TYPEERR, "access to strict mode caller function is censored") -MSG_DEF(JSMSG_DEPRECATED_USAGE, 1, JSEXN_REFERENCEERR, "deprecated {0} usage") -MSG_DEF(JSMSG_NOT_SCRIPTED_FUNCTION, 1, JSEXN_TYPEERR, "{0} is not a scripted function") -MSG_DEF(JSMSG_NO_REST_NAME, 0, JSEXN_SYNTAXERR, "no parameter name after ...") -MSG_DEF(JSMSG_PARAMETER_AFTER_REST, 0, JSEXN_SYNTAXERR, "parameter after rest parameter") -MSG_DEF(JSMSG_TOO_MANY_ARGUMENTS, 0, JSEXN_RANGEERR, "too many arguments provided for a function call") - -// CSP -MSG_DEF(JSMSG_CSP_BLOCKED_EVAL, 0, JSEXN_ERR, "call to eval() blocked by CSP") -MSG_DEF(JSMSG_CSP_BLOCKED_FUNCTION, 0, JSEXN_ERR, "call to Function() blocked by CSP") - -// Wrappers -MSG_DEF(JSMSG_ACCESSOR_DEF_DENIED, 1, JSEXN_ERR, "Permission denied to define accessor property {0}") -MSG_DEF(JSMSG_DEAD_OBJECT, 0, JSEXN_TYPEERR, "can't access dead object") -MSG_DEF(JSMSG_UNWRAP_DENIED, 0, JSEXN_ERR, "permission denied to unwrap object") - -// JSAPI-only (Not thrown as JS exceptions) -MSG_DEF(JSMSG_BAD_CLONE_FUNOBJ_SCOPE, 0, JSEXN_TYPEERR, "bad cloned function scope chain") -MSG_DEF(JSMSG_CANT_CLONE_OBJECT, 0, JSEXN_TYPEERR, "can't clone object") -MSG_DEF(JSMSG_CANT_OPEN, 2, JSEXN_ERR, "can't open {0}: {1}") -MSG_DEF(JSMSG_USER_DEFINED_ERROR, 0, JSEXN_ERR, "JS_ReportError was called") - -// Internal errors -MSG_DEF(JSMSG_ALLOC_OVERFLOW, 0, JSEXN_INTERNALERR, "allocation size overflow") -MSG_DEF(JSMSG_BAD_BYTECODE, 1, JSEXN_INTERNALERR, "unimplemented JavaScript bytecode {0}") -MSG_DEF(JSMSG_BUFFER_TOO_SMALL, 0, JSEXN_INTERNALERR, "buffer too small") -MSG_DEF(JSMSG_BUILD_ID_NOT_AVAILABLE, 0, JSEXN_INTERNALERR, "build ID is not available") -MSG_DEF(JSMSG_BYTECODE_TOO_BIG, 2, JSEXN_INTERNALERR, "bytecode {0} too large (limit {1})") -MSG_DEF(JSMSG_ERR_DURING_THROW, 0, JSEXN_INTERNALERR, "an internal error occurred while throwing an exception") -MSG_DEF(JSMSG_NEED_DIET, 1, JSEXN_INTERNALERR, "{0} too large") -MSG_DEF(JSMSG_OUT_OF_MEMORY, 0, JSEXN_INTERNALERR, "out of memory") -MSG_DEF(JSMSG_OVER_RECURSED, 0, JSEXN_INTERNALERR, "too much recursion") -MSG_DEF(JSMSG_TOO_BIG_TO_ENCODE, 0, JSEXN_INTERNALERR, "data are to big to encode") -MSG_DEF(JSMSG_TOO_DEEP, 1, JSEXN_INTERNALERR, "{0} nested too deeply") -MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION, 1, JSEXN_INTERNALERR, "uncaught exception: {0}") -MSG_DEF(JSMSG_UNKNOWN_FORMAT, 1, JSEXN_INTERNALERR, "unknown bytecode format {0}") - -// Frontend -MSG_DEF(JSMSG_ACCESSOR_WRONG_ARGS, 3, JSEXN_SYNTAXERR, "{0} functions must have {1} argument{2}") -MSG_DEF(JSMSG_ARRAY_COMP_LEFTSIDE, 0, JSEXN_SYNTAXERR, "invalid array comprehension left-hand side") -MSG_DEF(JSMSG_ARRAY_INIT_TOO_BIG, 0, JSEXN_INTERNALERR, "array initializer too large") -MSG_DEF(JSMSG_AS_AFTER_IMPORT_STAR, 0, JSEXN_SYNTAXERR, "missing keyword 'as' after import *") -MSG_DEF(JSMSG_AS_AFTER_RESERVED_WORD, 1, JSEXN_SYNTAXERR, "missing keyword 'as' after reserved word '{0}'") -MSG_DEF(JSMSG_ASYNC_GENERATOR, 0, JSEXN_SYNTAXERR, "generator function or method can't be async") -MSG_DEF(JSMSG_AWAIT_IN_DEFAULT, 0, JSEXN_SYNTAXERR, "await can't be used in default expression") -MSG_DEF(JSMSG_BAD_ANON_GENERATOR_RETURN, 0, JSEXN_TYPEERR, "anonymous generator function returns a value") -MSG_DEF(JSMSG_BAD_ARROW_ARGS, 0, JSEXN_SYNTAXERR, "invalid arrow-function arguments (parentheses around the arrow-function may help)") -MSG_DEF(JSMSG_BAD_BINDING, 1, JSEXN_SYNTAXERR, "redefining {0} is deprecated") -MSG_DEF(JSMSG_BAD_CONST_DECL, 0, JSEXN_SYNTAXERR, "missing = in const declaration") -MSG_DEF(JSMSG_BAD_CONTINUE, 0, JSEXN_SYNTAXERR, "continue must be inside loop") -MSG_DEF(JSMSG_BAD_DESTRUCT_ASS, 0, JSEXN_REFERENCEERR, "invalid destructuring assignment operator") -MSG_DEF(JSMSG_BAD_DESTRUCT_TARGET, 0, JSEXN_SYNTAXERR, "invalid destructuring target") -MSG_DEF(JSMSG_BAD_DESTRUCT_PARENS, 0, JSEXN_SYNTAXERR, "destructuring patterns in assignments can't be parenthesized") -MSG_DEF(JSMSG_BAD_DESTRUCT_DECL, 0, JSEXN_SYNTAXERR, "missing = in destructuring declaration") -MSG_DEF(JSMSG_BAD_DUP_ARGS, 0, JSEXN_SYNTAXERR, "duplicate argument names not allowed in this context") -MSG_DEF(JSMSG_BAD_FOR_EACH_LOOP, 0, JSEXN_SYNTAXERR, "invalid for each loop") -MSG_DEF(JSMSG_BAD_FOR_LEFTSIDE, 0, JSEXN_SYNTAXERR, "invalid for-in/of left-hand side") -MSG_DEF(JSMSG_LEXICAL_DECL_DEFINES_LET,0, JSEXN_SYNTAXERR, "a lexical declaration can't define a 'let' binding") -MSG_DEF(JSMSG_LET_STARTING_FOROF_LHS, 0, JSEXN_SYNTAXERR, "an expression X in 'for (X of Y)' must not start with 'let'") -MSG_DEF(JSMSG_BAD_GENERATOR_RETURN, 1, JSEXN_TYPEERR, "generator function {0} returns a value") -MSG_DEF(JSMSG_BAD_GENEXP_BODY, 1, JSEXN_SYNTAXERR, "illegal use of {0} in generator expression") -MSG_DEF(JSMSG_BAD_INCOP_OPERAND, 0, JSEXN_REFERENCEERR, "invalid increment/decrement operand") -MSG_DEF(JSMSG_BAD_METHOD_DEF, 0, JSEXN_SYNTAXERR, "bad method definition") -MSG_DEF(JSMSG_BAD_OCTAL, 1, JSEXN_SYNTAXERR, "{0} is not a legal ECMA-262 octal constant") -MSG_DEF(JSMSG_BAD_OPERAND, 1, JSEXN_SYNTAXERR, "invalid {0} operand") -MSG_DEF(JSMSG_BAD_POW_LEFTSIDE, 0, JSEXN_SYNTAXERR, "unparenthesized unary expression can't appear on the left-hand side of '**'") -MSG_DEF(JSMSG_BAD_PROP_ID, 0, JSEXN_SYNTAXERR, "invalid property id") -MSG_DEF(JSMSG_BAD_RETURN_OR_YIELD, 1, JSEXN_SYNTAXERR, "{0} not in function") -MSG_DEF(JSMSG_BAD_STRICT_ASSIGN, 1, JSEXN_SYNTAXERR, "'{0}' can't be defined or assigned to in strict mode code") -MSG_DEF(JSMSG_BAD_SWITCH, 0, JSEXN_SYNTAXERR, "invalid switch statement") -MSG_DEF(JSMSG_BAD_SUPER, 0, JSEXN_SYNTAXERR, "invalid use of keyword 'super'") -MSG_DEF(JSMSG_BAD_SUPERPROP, 1, JSEXN_SYNTAXERR, "use of super {0} accesses only valid within methods or eval code within methods") -MSG_DEF(JSMSG_BAD_SUPERCALL, 0, JSEXN_SYNTAXERR, "super() is only valid in derived class constructors") -MSG_DEF(JSMSG_BRACKET_AFTER_ARRAY_COMPREHENSION, 0, JSEXN_SYNTAXERR, "missing ] after array comprehension") -MSG_DEF(JSMSG_BRACKET_AFTER_LIST, 0, JSEXN_SYNTAXERR, "missing ] after element list") -MSG_DEF(JSMSG_BRACKET_IN_INDEX, 0, JSEXN_SYNTAXERR, "missing ] in index expression") -MSG_DEF(JSMSG_CATCH_AFTER_GENERAL, 0, JSEXN_SYNTAXERR, "catch after unconditional catch") -MSG_DEF(JSMSG_CATCH_IDENTIFIER, 0, JSEXN_SYNTAXERR, "missing identifier in catch") -MSG_DEF(JSMSG_CATCH_OR_FINALLY, 0, JSEXN_SYNTAXERR, "missing catch or finally after try") -MSG_DEF(JSMSG_CATCH_WITHOUT_TRY, 0, JSEXN_SYNTAXERR, "catch without try") -MSG_DEF(JSMSG_COLON_AFTER_CASE, 0, JSEXN_SYNTAXERR, "missing : after case label") -MSG_DEF(JSMSG_COLON_AFTER_ID, 0, JSEXN_SYNTAXERR, "missing : after property id") -MSG_DEF(JSMSG_COLON_IN_COND, 0, JSEXN_SYNTAXERR, "missing : in conditional expression") -MSG_DEF(JSMSG_COMP_PROP_UNTERM_EXPR, 0, JSEXN_SYNTAXERR, "missing ] in computed property name") -MSG_DEF(JSMSG_CONTRARY_NONDIRECTIVE, 1, JSEXN_SYNTAXERR, "'{0}' statement won't be enforced as a directive because it isn't in directive prologue position") -MSG_DEF(JSMSG_CURLY_AFTER_BODY, 0, JSEXN_SYNTAXERR, "missing } after function body") -MSG_DEF(JSMSG_CURLY_AFTER_CATCH, 0, JSEXN_SYNTAXERR, "missing } after catch block") -MSG_DEF(JSMSG_CURLY_AFTER_FINALLY, 0, JSEXN_SYNTAXERR, "missing } after finally block") -MSG_DEF(JSMSG_CURLY_AFTER_LIST, 0, JSEXN_SYNTAXERR, "missing } after property list") -MSG_DEF(JSMSG_CURLY_AFTER_TRY, 0, JSEXN_SYNTAXERR, "missing } after try block") -MSG_DEF(JSMSG_CURLY_BEFORE_BODY, 0, JSEXN_SYNTAXERR, "missing { before function body") -MSG_DEF(JSMSG_CURLY_BEFORE_CATCH, 0, JSEXN_SYNTAXERR, "missing { before catch block") -MSG_DEF(JSMSG_CURLY_BEFORE_CLASS, 0, JSEXN_SYNTAXERR, "missing { before class body") -MSG_DEF(JSMSG_CURLY_BEFORE_FINALLY, 0, JSEXN_SYNTAXERR, "missing { before finally block") -MSG_DEF(JSMSG_CURLY_BEFORE_SWITCH, 0, JSEXN_SYNTAXERR, "missing { before switch body") -MSG_DEF(JSMSG_CURLY_BEFORE_TRY, 0, JSEXN_SYNTAXERR, "missing { before try block") -MSG_DEF(JSMSG_CURLY_IN_COMPOUND, 0, JSEXN_SYNTAXERR, "missing } in compound statement") -MSG_DEF(JSMSG_DECLARATION_AFTER_EXPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'export' keyword") -MSG_DEF(JSMSG_DECLARATION_AFTER_IMPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'import' keyword") -MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 0, JSEXN_SYNTAXERR, "applying the 'delete' operator to an unqualified name is deprecated") -MSG_DEF(JSMSG_DEPRECATED_EXPR_CLOSURE, 0, JSEXN_WARN, "expression closures are deprecated") -MSG_DEF(JSMSG_DEPRECATED_FOR_EACH, 0, JSEXN_WARN, "JavaScript 1.6's for-each-in loops are deprecated; consider using ES6 for-of instead") -MSG_DEF(JSMSG_DEPRECATED_OCTAL, 0, JSEXN_SYNTAXERR, "\"0\"-prefixed octal literals and octal escape sequences are deprecated; for octal literals use the \"0o\" prefix instead") -MSG_DEF(JSMSG_DEPRECATED_PRAGMA, 1, JSEXN_WARN, "Using //@ to indicate {0} pragmas is deprecated. Use //# instead") -MSG_DEF(JSMSG_DEPRECATED_BLOCK_SCOPE_FUN_REDECL, 1, JSEXN_WARN, "redeclaration of block-scoped function `{0}' is deprecated") -MSG_DEF(JSMSG_DUPLICATE_EXPORT_NAME, 1, JSEXN_SYNTAXERR, "duplicate export name '{0}'") -MSG_DEF(JSMSG_DUPLICATE_FORMAL, 1, JSEXN_SYNTAXERR, "duplicate formal argument {0}") -MSG_DEF(JSMSG_DUPLICATE_LABEL, 0, JSEXN_SYNTAXERR, "duplicate label") -MSG_DEF(JSMSG_DUPLICATE_PROPERTY, 1, JSEXN_SYNTAXERR, "property name {0} appears more than once in object literal") -MSG_DEF(JSMSG_DUPLICATE_PROTO_PROPERTY, 0, JSEXN_SYNTAXERR, "property name __proto__ appears more than once in object literal") -MSG_DEF(JSMSG_EMPTY_CONSEQUENT, 0, JSEXN_SYNTAXERR, "mistyped ; after conditional?") -MSG_DEF(JSMSG_EQUAL_AS_ASSIGN, 0, JSEXN_SYNTAXERR, "test for equality (==) mistyped as assignment (=)?") -MSG_DEF(JSMSG_EXPORT_DECL_AT_TOP_LEVEL,0, JSEXN_SYNTAXERR, "export declarations may only appear at top level of a module") -MSG_DEF(JSMSG_FINALLY_WITHOUT_TRY, 0, JSEXN_SYNTAXERR, "finally without try") -MSG_DEF(JSMSG_FORBIDDEN_AS_STATEMENT, 1, JSEXN_SYNTAXERR, "{0} can't appear in single-statement context") -MSG_DEF(JSMSG_FROM_AFTER_IMPORT_CLAUSE, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after import clause") -MSG_DEF(JSMSG_FROM_AFTER_EXPORT_STAR, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after export *") -MSG_DEF(JSMSG_GARBAGE_AFTER_INPUT, 2, JSEXN_SYNTAXERR, "unexpected garbage after {0}, starting with {1}") -MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER, 0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal") -MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 0, JSEXN_SYNTAXERR, "illegal character") -MSG_DEF(JSMSG_IMPORT_DECL_AT_TOP_LEVEL, 0, JSEXN_SYNTAXERR, "import declarations may only appear at top level of a module") -MSG_DEF(JSMSG_INVALID_FOR_IN_DECL_WITH_INIT,0,JSEXN_SYNTAXERR,"for-in loop head declarations may not have initializers") -MSG_DEF(JSMSG_LABEL_NOT_FOUND, 0, JSEXN_SYNTAXERR, "label not found") -MSG_DEF(JSMSG_LET_COMP_BINDING, 0, JSEXN_SYNTAXERR, "'let' is not a valid name for a comprehension variable") -MSG_DEF(JSMSG_LEXICAL_DECL_NOT_IN_BLOCK, 1, JSEXN_SYNTAXERR, "{0} declaration not directly within block") -MSG_DEF(JSMSG_LEXICAL_DECL_LABEL, 1, JSEXN_SYNTAXERR, "{0} declarations cannot be labelled") -MSG_DEF(JSMSG_GENERATOR_LABEL, 0, JSEXN_SYNTAXERR, "generator functions cannot be labelled") -MSG_DEF(JSMSG_FUNCTION_LABEL, 0, JSEXN_SYNTAXERR, "functions cannot be labelled") -MSG_DEF(JSMSG_SLOPPY_FUNCTION_LABEL, 0, JSEXN_SYNTAXERR, "functions can only be labelled inside blocks") -MSG_DEF(JSMSG_LINE_BREAK_AFTER_THROW, 0, JSEXN_SYNTAXERR, "no line break is allowed between 'throw' and its expression") -MSG_DEF(JSMSG_LINE_BREAK_BEFORE_ARROW, 0, JSEXN_SYNTAXERR, "no line break is allowed before '=>'") -MSG_DEF(JSMSG_MALFORMED_ESCAPE, 1, JSEXN_SYNTAXERR, "malformed {0} character escape sequence") -MSG_DEF(JSMSG_MISSING_BINARY_DIGITS, 0, JSEXN_SYNTAXERR, "missing binary digits after '0b'") -MSG_DEF(JSMSG_MISSING_EXPONENT, 0, JSEXN_SYNTAXERR, "missing exponent") -MSG_DEF(JSMSG_MISSING_EXPR_AFTER_THROW,0, JSEXN_SYNTAXERR, "throw statement is missing an expression") -MSG_DEF(JSMSG_MISSING_FORMAL, 0, JSEXN_SYNTAXERR, "missing formal parameter") -MSG_DEF(JSMSG_MISSING_HEXDIGITS, 0, JSEXN_SYNTAXERR, "missing hexadecimal digits after '0x'") -MSG_DEF(JSMSG_MISSING_OCTAL_DIGITS, 0, JSEXN_SYNTAXERR, "missing octal digits after '0o'") -MSG_DEF(JSMSG_MODULE_SPEC_AFTER_FROM, 0, JSEXN_SYNTAXERR, "missing module specifier after 'from' keyword") -MSG_DEF(JSMSG_NAME_AFTER_DOT, 0, JSEXN_SYNTAXERR, "missing name after . operator") -MSG_DEF(JSMSG_NAMED_IMPORTS_OR_NAMESPACE_IMPORT, 0, JSEXN_SYNTAXERR, "expected named imports or namespace import after comma") -MSG_DEF(JSMSG_NO_BINDING_NAME, 0, JSEXN_SYNTAXERR, "missing binding name") -MSG_DEF(JSMSG_NO_EXPORT_NAME, 0, JSEXN_SYNTAXERR, "missing export name") -MSG_DEF(JSMSG_NO_IMPORT_NAME, 0, JSEXN_SYNTAXERR, "missing import name") -MSG_DEF(JSMSG_NO_VARIABLE_NAME, 0, JSEXN_SYNTAXERR, "missing variable name") -MSG_DEF(JSMSG_OF_AFTER_FOR_NAME, 0, JSEXN_SYNTAXERR, "missing 'of' after for") -MSG_DEF(JSMSG_PAREN_AFTER_ARGS, 0, JSEXN_SYNTAXERR, "missing ) after argument list") -MSG_DEF(JSMSG_PAREN_AFTER_CATCH, 0, JSEXN_SYNTAXERR, "missing ) after catch") -MSG_DEF(JSMSG_PAREN_AFTER_COND, 0, JSEXN_SYNTAXERR, "missing ) after condition") -MSG_DEF(JSMSG_PAREN_AFTER_FOR, 0, JSEXN_SYNTAXERR, "missing ( after for") -MSG_DEF(JSMSG_PAREN_AFTER_FORMAL, 0, JSEXN_SYNTAXERR, "missing ) after formal parameters") -MSG_DEF(JSMSG_PAREN_AFTER_FOR_CTRL, 0, JSEXN_SYNTAXERR, "missing ) after for-loop control") -MSG_DEF(JSMSG_PAREN_AFTER_FOR_OF_ITERABLE, 0, JSEXN_SYNTAXERR, "missing ) after for-of iterable") -MSG_DEF(JSMSG_PAREN_AFTER_SWITCH, 0, JSEXN_SYNTAXERR, "missing ) after switch expression") -MSG_DEF(JSMSG_PAREN_AFTER_WITH, 0, JSEXN_SYNTAXERR, "missing ) after with-statement object") -MSG_DEF(JSMSG_PAREN_BEFORE_CATCH, 0, JSEXN_SYNTAXERR, "missing ( before catch") -MSG_DEF(JSMSG_PAREN_BEFORE_COND, 0, JSEXN_SYNTAXERR, "missing ( before condition") -MSG_DEF(JSMSG_PAREN_BEFORE_FORMAL, 0, JSEXN_SYNTAXERR, "missing ( before formal parameters") -MSG_DEF(JSMSG_PAREN_BEFORE_SWITCH, 0, JSEXN_SYNTAXERR, "missing ( before switch expression") -MSG_DEF(JSMSG_PAREN_BEFORE_WITH, 0, JSEXN_SYNTAXERR, "missing ( before with-statement object") -MSG_DEF(JSMSG_PAREN_IN_PAREN, 0, JSEXN_SYNTAXERR, "missing ) in parenthetical") -MSG_DEF(JSMSG_RC_AFTER_EXPORT_SPEC_LIST, 0, JSEXN_SYNTAXERR, "missing '}' after export specifier list") -MSG_DEF(JSMSG_RC_AFTER_IMPORT_SPEC_LIST, 0, JSEXN_SYNTAXERR, "missing '}' after module specifier list") -MSG_DEF(JSMSG_REDECLARED_CATCH_IDENTIFIER, 1, JSEXN_SYNTAXERR, "redeclaration of identifier '{0}' in catch") -MSG_DEF(JSMSG_RESERVED_ID, 1, JSEXN_SYNTAXERR, "{0} is a reserved identifier") -MSG_DEF(JSMSG_REST_WITH_COMMA, 0, JSEXN_SYNTAXERR, "rest element may not have a trailing comma") -MSG_DEF(JSMSG_REST_WITH_DEFAULT, 0, JSEXN_SYNTAXERR, "rest parameter may not have a default") -MSG_DEF(JSMSG_SELFHOSTED_TOP_LEVEL_LEXICAL, 1, JSEXN_SYNTAXERR, "self-hosted code cannot contain top-level {0} declarations") -MSG_DEF(JSMSG_SELFHOSTED_METHOD_CALL, 0, JSEXN_SYNTAXERR, "self-hosted code may not contain direct method calls. Use callFunction() or callContentFunction()") -MSG_DEF(JSMSG_SELFHOSTED_UNBOUND_NAME, 0, JSEXN_TYPEERR, "self-hosted code may not contain unbound name lookups") -MSG_DEF(JSMSG_SEMI_AFTER_FOR_COND, 0, JSEXN_SYNTAXERR, "missing ; after for-loop condition") -MSG_DEF(JSMSG_SEMI_AFTER_FOR_INIT, 0, JSEXN_SYNTAXERR, "missing ; after for-loop initializer") -MSG_DEF(JSMSG_SEMI_BEFORE_STMNT, 0, JSEXN_SYNTAXERR, "missing ; before statement") -MSG_DEF(JSMSG_SOURCE_TOO_LONG, 0, JSEXN_RANGEERR, "source is too long") -MSG_DEF(JSMSG_STMT_AFTER_RETURN, 0, JSEXN_WARN, "unreachable code after return statement") -MSG_DEF(JSMSG_STRICT_CODE_WITH, 0, JSEXN_SYNTAXERR, "strict mode code may not contain 'with' statements") -MSG_DEF(JSMSG_STRICT_NON_SIMPLE_PARAMS, 1, JSEXN_SYNTAXERR, "\"use strict\" not allowed in function with {0} parameter") -MSG_DEF(JSMSG_TEMPLSTR_UNTERM_EXPR, 0, JSEXN_SYNTAXERR, "missing } in template string") -MSG_DEF(JSMSG_SIMD_NOT_A_VECTOR, 2, JSEXN_TYPEERR, "expecting a SIMD {0} object as argument {1}") -MSG_DEF(JSMSG_TOO_MANY_CASES, 0, JSEXN_INTERNALERR, "too many switch cases") -MSG_DEF(JSMSG_TOO_MANY_CATCH_VARS, 0, JSEXN_SYNTAXERR, "too many catch variables") -MSG_DEF(JSMSG_TOO_MANY_CON_ARGS, 0, JSEXN_SYNTAXERR, "too many constructor arguments") -MSG_DEF(JSMSG_TOO_MANY_DEFAULTS, 0, JSEXN_SYNTAXERR, "more than one switch default") -MSG_DEF(JSMSG_TOO_MANY_FUN_ARGS, 0, JSEXN_SYNTAXERR, "too many function arguments") -MSG_DEF(JSMSG_TOO_MANY_LOCALS, 0, JSEXN_SYNTAXERR, "too many local variables") -MSG_DEF(JSMSG_TOO_MANY_YIELDS, 0, JSEXN_SYNTAXERR, "too many yield expressions") -MSG_DEF(JSMSG_TOUGH_BREAK, 0, JSEXN_SYNTAXERR, "unlabeled break must be inside loop or switch") -MSG_DEF(JSMSG_UNEXPECTED_TOKEN, 2, JSEXN_SYNTAXERR, "expected {0}, got {1}") -MSG_DEF(JSMSG_UNNAMED_CLASS_STMT, 0, JSEXN_SYNTAXERR, "class statement requires a name") -MSG_DEF(JSMSG_UNNAMED_FUNCTION_STMT, 0, JSEXN_SYNTAXERR, "function statement requires a name") -MSG_DEF(JSMSG_UNTERMINATED_COMMENT, 0, JSEXN_SYNTAXERR, "unterminated comment") -MSG_DEF(JSMSG_UNTERMINATED_REGEXP, 0, JSEXN_SYNTAXERR, "unterminated regular expression literal") -MSG_DEF(JSMSG_UNTERMINATED_STRING, 0, JSEXN_SYNTAXERR, "unterminated string literal") -MSG_DEF(JSMSG_USELESS_EXPR, 0, JSEXN_TYPEERR, "useless expression") -MSG_DEF(JSMSG_USE_ASM_DIRECTIVE_FAIL, 0, JSEXN_SYNTAXERR, "\"use asm\" is only meaningful in the Directive Prologue of a function body") -MSG_DEF(JSMSG_VAR_HIDES_ARG, 1, JSEXN_TYPEERR, "variable {0} redeclares argument") -MSG_DEF(JSMSG_WHILE_AFTER_DO, 0, JSEXN_SYNTAXERR, "missing while after do-loop body") -MSG_DEF(JSMSG_YIELD_IN_ARROW, 0, JSEXN_SYNTAXERR, "arrow function may not contain yield") -MSG_DEF(JSMSG_YIELD_IN_DEFAULT, 0, JSEXN_SYNTAXERR, "yield in default expression") -MSG_DEF(JSMSG_YIELD_IN_METHOD, 0, JSEXN_SYNTAXERR, "non-generator method definitions may not contain yield") -MSG_DEF(JSMSG_BAD_COLUMN_NUMBER, 0, JSEXN_RANGEERR, "column number out of range") -MSG_DEF(JSMSG_COMPUTED_NAME_IN_PATTERN,0, JSEXN_SYNTAXERR, "computed property names aren't supported in this destructuring declaration") -MSG_DEF(JSMSG_DEFAULT_IN_PATTERN, 0, JSEXN_SYNTAXERR, "destructuring defaults aren't supported in this destructuring declaration") -MSG_DEF(JSMSG_BAD_NEWTARGET, 0, JSEXN_SYNTAXERR, "new.target only allowed within functions") -MSG_DEF(JSMSG_ESCAPED_KEYWORD, 0, JSEXN_SYNTAXERR, "keywords must be written literally, without embedded escapes") - -// asm.js -MSG_DEF(JSMSG_USE_ASM_TYPE_FAIL, 1, JSEXN_TYPEERR, "asm.js type error: {0}") -MSG_DEF(JSMSG_USE_ASM_LINK_FAIL, 1, JSEXN_TYPEERR, "asm.js link error: {0}") -MSG_DEF(JSMSG_USE_ASM_TYPE_OK, 1, JSEXN_WARN, "Successfully compiled asm.js code ({0})") - -// wasm -MSG_DEF(JSMSG_WASM_COMPILE_ERROR, 1, JSEXN_WASMCOMPILEERROR, "{0}") -MSG_DEF(JSMSG_WASM_IND_CALL_TO_NULL, 0, JSEXN_WASMRUNTIMEERROR, "indirect call to null") -MSG_DEF(JSMSG_WASM_IND_CALL_BAD_SIG, 0, JSEXN_WASMRUNTIMEERROR, "indirect call signature mismatch") -MSG_DEF(JSMSG_WASM_UNREACHABLE, 0, JSEXN_WASMRUNTIMEERROR, "unreachable executed") -MSG_DEF(JSMSG_WASM_INTEGER_OVERFLOW, 0, JSEXN_WASMRUNTIMEERROR, "integer overflow") -MSG_DEF(JSMSG_WASM_INVALID_CONVERSION, 0, JSEXN_WASMRUNTIMEERROR, "invalid conversion to integer") -MSG_DEF(JSMSG_WASM_INT_DIVIDE_BY_ZERO, 0, JSEXN_WASMRUNTIMEERROR, "integer divide by zero") -MSG_DEF(JSMSG_WASM_OUT_OF_BOUNDS, 0, JSEXN_WASMRUNTIMEERROR, "index out of bounds") -MSG_DEF(JSMSG_WASM_UNALIGNED_ACCESS, 0, JSEXN_WASMRUNTIMEERROR, "unaligned memory access") -MSG_DEF(JSMSG_WASM_BAD_UINT32, 2, JSEXN_RANGEERR, "bad {0} {1}") -MSG_DEF(JSMSG_WASM_BAD_GROW, 1, JSEXN_RANGEERR, "failed to grow {0}") -MSG_DEF(JSMSG_WASM_BAD_FIT, 2, JSEXN_RANGEERR, "{0} segment does not fit in {1}") -MSG_DEF(JSMSG_WASM_BAD_BUF_ARG, 0, JSEXN_TYPEERR, "first argument must be an ArrayBuffer or typed array object") -MSG_DEF(JSMSG_WASM_BAD_MOD_ARG, 0, JSEXN_TYPEERR, "first argument must be a WebAssembly.Module") -MSG_DEF(JSMSG_WASM_BAD_BUF_MOD_ARG, 0, JSEXN_TYPEERR, "first argument must be a WebAssembly.Module, ArrayBuffer or typed array object") -MSG_DEF(JSMSG_WASM_BAD_DESC_ARG, 1, JSEXN_TYPEERR, "first argument must be a {0} descriptor") -MSG_DEF(JSMSG_WASM_BAD_IMP_SIZE, 1, JSEXN_TYPEERR, "imported {0} with incompatible size") -MSG_DEF(JSMSG_WASM_BAD_IMP_MAX, 1, JSEXN_TYPEERR, "imported {0} with incompatible maximum size") -MSG_DEF(JSMSG_WASM_BAD_ELEMENT, 0, JSEXN_TYPEERR, "\"element\" property of table descriptor must be \"anyfunc\"") -MSG_DEF(JSMSG_WASM_BAD_IMPORT_ARG, 0, JSEXN_TYPEERR, "second argument must be an object") -MSG_DEF(JSMSG_WASM_BAD_IMPORT_FIELD, 2, JSEXN_TYPEERR, "import object field '{0}' is not {1}") -MSG_DEF(JSMSG_WASM_BAD_IMPORT_SIG, 0, JSEXN_TYPEERR, "imported function signature mismatch") -MSG_DEF(JSMSG_WASM_BAD_TABLE_VALUE, 0, JSEXN_TYPEERR, "can only assign WebAssembly exported functions to Table") -MSG_DEF(JSMSG_WASM_BAD_I64, 0, JSEXN_TYPEERR, "cannot pass i64 to or from JS") -MSG_DEF(JSMSG_WASM_NO_TRANSFER, 0, JSEXN_TYPEERR, "cannot transfer WebAssembly/asm.js ArrayBuffer") -MSG_DEF(JSMSG_WASM_TEXT_FAIL, 1, JSEXN_SYNTAXERR, "wasm text error: {0}") - -// Proxy -MSG_DEF(JSMSG_BAD_TRAP_RETURN_VALUE, 2, JSEXN_TYPEERR,"trap {1} for {0} returned a primitive value") -MSG_DEF(JSMSG_BAD_GETPROTOTYPEOF_TRAP_RETURN,0,JSEXN_TYPEERR,"proxy getPrototypeOf handler returned a non-object, non-null value") -MSG_DEF(JSMSG_INCONSISTENT_GETPROTOTYPEOF_TRAP,0,JSEXN_TYPEERR,"proxy getPrototypeOf handler didn't return the target object's prototype") -MSG_DEF(JSMSG_PROXY_SETPROTOTYPEOF_RETURNED_FALSE, 0, JSEXN_TYPEERR, "proxy setPrototypeOf handler returned false") -MSG_DEF(JSMSG_PROXY_ISEXTENSIBLE_RETURNED_FALSE,0,JSEXN_TYPEERR,"proxy isExtensible handler must return the same extensibility as target") -MSG_DEF(JSMSG_INCONSISTENT_SETPROTOTYPEOF_TRAP,0,JSEXN_TYPEERR,"proxy setPrototypeOf handler returned true, even though the target's prototype is immutable because the target is non-extensible") -MSG_DEF(JSMSG_CANT_CHANGE_EXTENSIBILITY, 0, JSEXN_TYPEERR, "can't change object's extensibility") -MSG_DEF(JSMSG_CANT_DEFINE_INVALID, 0, JSEXN_TYPEERR, "proxy can't define an incompatible property descriptor") -MSG_DEF(JSMSG_CANT_DEFINE_NEW, 0, JSEXN_TYPEERR, "proxy can't define a new property on a non-extensible object") -MSG_DEF(JSMSG_CANT_DEFINE_NE_AS_NC, 0, JSEXN_TYPEERR, "proxy can't define a non-existent property as non-configurable") -MSG_DEF(JSMSG_PROXY_DEFINE_RETURNED_FALSE, 1, JSEXN_TYPEERR, "proxy defineProperty handler returned false for property '{0}'") -MSG_DEF(JSMSG_PROXY_DELETE_RETURNED_FALSE, 1, JSEXN_TYPEERR, "can't delete property '{0}': proxy deleteProperty handler returned false") -MSG_DEF(JSMSG_PROXY_PREVENTEXTENSIONS_RETURNED_FALSE, 0, JSEXN_TYPEERR, "proxy preventExtensions handler returned false") -MSG_DEF(JSMSG_PROXY_SET_RETURNED_FALSE, 1, JSEXN_TYPEERR, "proxy set handler returned false for property '{0}'") -MSG_DEF(JSMSG_CANT_REPORT_AS_NON_EXTENSIBLE, 0, JSEXN_TYPEERR, "proxy can't report an extensible object as non-extensible") -MSG_DEF(JSMSG_CANT_REPORT_C_AS_NC, 0, JSEXN_TYPEERR, "proxy can't report existing configurable property as non-configurable") -MSG_DEF(JSMSG_CANT_REPORT_E_AS_NE, 0, JSEXN_TYPEERR, "proxy can't report an existing own property as non-existent on a non-extensible object") -MSG_DEF(JSMSG_CANT_REPORT_INVALID, 0, JSEXN_TYPEERR, "proxy can't report an incompatible property descriptor") -MSG_DEF(JSMSG_CANT_REPORT_NC_AS_NE, 0, JSEXN_TYPEERR, "proxy can't report a non-configurable own property as non-existent") -MSG_DEF(JSMSG_CANT_REPORT_NEW, 0, JSEXN_TYPEERR, "proxy can't report a new property on a non-extensible object") -MSG_DEF(JSMSG_CANT_REPORT_NE_AS_NC, 0, JSEXN_TYPEERR, "proxy can't report a non-existent property as non-configurable") -MSG_DEF(JSMSG_CANT_SET_NW_NC, 0, JSEXN_TYPEERR, "proxy can't successfully set a non-writable, non-configurable property") -MSG_DEF(JSMSG_CANT_SET_WO_SETTER, 0, JSEXN_TYPEERR, "proxy can't succesfully set an accessor property without a setter") -MSG_DEF(JSMSG_CANT_SKIP_NC, 0, JSEXN_TYPEERR, "proxy can't skip a non-configurable property") -MSG_DEF(JSMSG_ONWKEYS_STR_SYM, 0, JSEXN_TYPEERR, "proxy [[OwnPropertyKeys]] must return an array with only string and symbol elements") -MSG_DEF(JSMSG_MUST_REPORT_SAME_VALUE, 0, JSEXN_TYPEERR, "proxy must report the same value for a non-writable, non-configurable property") -MSG_DEF(JSMSG_MUST_REPORT_UNDEFINED, 0, JSEXN_TYPEERR, "proxy must report undefined for a non-configurable accessor property without a getter") -MSG_DEF(JSMSG_OBJECT_ACCESS_DENIED, 0, JSEXN_ERR, "Permission denied to access object") -MSG_DEF(JSMSG_PROPERTY_ACCESS_DENIED, 1, JSEXN_ERR, "Permission denied to access property {0}") -MSG_DEF(JSMSG_PROXY_CONSTRUCT_OBJECT, 0, JSEXN_TYPEERR, "proxy [[Construct]] must return an object") -MSG_DEF(JSMSG_PROXY_EXTENSIBILITY, 0, JSEXN_TYPEERR, "proxy must report same extensiblitity as target") -MSG_DEF(JSMSG_PROXY_GETOWN_OBJORUNDEF, 0, JSEXN_TYPEERR, "proxy [[GetOwnProperty]] must return an object or undefined") -MSG_DEF(JSMSG_PROXY_REVOKED, 0, JSEXN_TYPEERR, "illegal operation attempted on a revoked proxy") -MSG_DEF(JSMSG_PROXY_ARG_REVOKED, 1, JSEXN_TYPEERR, "argument {0} cannot be a revoked proxy") -MSG_DEF(JSMSG_BAD_TRAP, 1, JSEXN_TYPEERR, "proxy handler's {0} trap wasn't undefined, null, or callable") - -// Structured cloning -MSG_DEF(JSMSG_SC_BAD_CLONE_VERSION, 0, JSEXN_ERR, "unsupported structured clone version") -MSG_DEF(JSMSG_SC_BAD_SERIALIZED_DATA, 1, JSEXN_INTERNALERR, "bad serialized structured data ({0})") -MSG_DEF(JSMSG_SC_DUP_TRANSFERABLE, 0, JSEXN_TYPEERR, "duplicate transferable for structured clone") -MSG_DEF(JSMSG_SC_NOT_TRANSFERABLE, 0, JSEXN_TYPEERR, "invalid transferable array for structured clone") -MSG_DEF(JSMSG_SC_UNSUPPORTED_TYPE, 0, JSEXN_TYPEERR, "unsupported type for structured data") -MSG_DEF(JSMSG_SC_NOT_CLONABLE, 1, JSEXN_TYPEERR, "{0} cannot be cloned in this context") -MSG_DEF(JSMSG_SC_SAB_TRANSFER, 0, JSEXN_WARN, "SharedArrayBuffer must not be in the transfer list") -MSG_DEF(JSMSG_SC_SAB_DISABLED, 0, JSEXN_TYPEERR, "SharedArrayBuffer not cloned - shared memory disabled in receiver") - -// Debugger -MSG_DEF(JSMSG_ASSIGN_FUNCTION_OR_NULL, 1, JSEXN_TYPEERR, "value assigned to {0} must be a function or null") -MSG_DEF(JSMSG_DEBUG_BAD_AWAIT, 0, JSEXN_TYPEERR, "await expression received invalid value") -MSG_DEF(JSMSG_DEBUG_BAD_LINE, 0, JSEXN_TYPEERR, "invalid line number") -MSG_DEF(JSMSG_DEBUG_BAD_OFFSET, 0, JSEXN_TYPEERR, "invalid script offset") -MSG_DEF(JSMSG_DEBUG_BAD_REFERENT, 2, JSEXN_TYPEERR, "{0} does not refer to {1}") -MSG_DEF(JSMSG_DEBUG_BAD_RESUMPTION, 0, JSEXN_TYPEERR, "debugger resumption value must be undefined, {throw: val}, {return: val}, or null") -MSG_DEF(JSMSG_DEBUG_BAD_YIELD, 0, JSEXN_TYPEERR, "generator yielded invalid value") -MSG_DEF(JSMSG_DEBUG_CANT_DEBUG_GLOBAL, 0, JSEXN_TYPEERR, "passing non-debuggable global to addDebuggee") -MSG_DEF(JSMSG_DEBUG_CCW_REQUIRED, 1, JSEXN_TYPEERR, "{0}: argument must be an object from a different compartment") -MSG_DEF(JSMSG_DEBUG_COMPARTMENT_MISMATCH, 2, JSEXN_TYPEERR, "{0}: descriptor .{1} property is an object in a different compartment than the target object") -MSG_DEF(JSMSG_DEBUG_LOOP, 0, JSEXN_TYPEERR, "cannot debug an object in same compartment as debugger or a compartment that is already debugging the debugger") -MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGEE, 2, JSEXN_ERR, "{0} is not a debuggee {1}") -MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGING, 0, JSEXN_ERR, "can't set breakpoint: script global is not a debuggee") -MSG_DEF(JSMSG_DEBUG_NOT_IDLE, 0, JSEXN_ERR, "can't start debugging: a debuggee script is on the stack") -MSG_DEF(JSMSG_DEBUG_NOT_LIVE, 1, JSEXN_ERR, "{0} is not live") -MSG_DEF(JSMSG_DEBUG_NO_ENV_OBJECT, 0, JSEXN_TYPEERR, "declarative Environments don't have binding objects") -MSG_DEF(JSMSG_DEBUG_PROTO, 2, JSEXN_TYPEERR, "{0}.prototype is not a valid {1} instance") -MSG_DEF(JSMSG_DEBUG_WRONG_OWNER, 1, JSEXN_TYPEERR, "{0} belongs to a different Debugger") -MSG_DEF(JSMSG_DEBUG_OPTIMIZED_OUT, 1, JSEXN_ERR, "variable `{0}' has been optimized out") -MSG_DEF(JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED, 0, JSEXN_TYPEERR, "resumption values are disallowed in this hook") -MSG_DEF(JSMSG_DEBUG_VARIABLE_NOT_FOUND,0, JSEXN_TYPEERR, "variable not found in environment") -MSG_DEF(JSMSG_DEBUG_WRAPPER_IN_WAY, 3, JSEXN_TYPEERR, "{0} is {1}{2}a global object, but a direct reference is required") -MSG_DEF(JSMSG_DEBUGGEE_WOULD_RUN, 2, JSEXN_DEBUGGEEWOULDRUN, "debuggee `{0}:{1}' would run") -MSG_DEF(JSMSG_NOT_CALLABLE_OR_UNDEFINED, 0, JSEXN_TYPEERR, "value is not a function or undefined") -MSG_DEF(JSMSG_NOT_TRACKING_ALLOCATIONS, 1, JSEXN_ERR, "Cannot call {0} without setting trackingAllocationSites to true") -MSG_DEF(JSMSG_OBJECT_METADATA_CALLBACK_ALREADY_SET, 0, JSEXN_ERR, "Cannot track object allocation, because other tools are already doing so") -MSG_DEF(JSMSG_QUERY_INNERMOST_WITHOUT_LINE_URL, 0, JSEXN_TYPEERR, "findScripts query object with 'innermost' property must have 'line' and either 'displayURL', 'url', or 'source'") -MSG_DEF(JSMSG_QUERY_LINE_WITHOUT_URL, 0, JSEXN_TYPEERR, "findScripts query object has 'line' property, but no 'displayURL', 'url', or 'source' property") -MSG_DEF(JSMSG_DEBUG_CANT_SET_OPT_ENV, 1, JSEXN_REFERENCEERR, "can't set `{0}' in an optimized-out environment") -MSG_DEF(JSMSG_DEBUG_INVISIBLE_COMPARTMENT, 0, JSEXN_TYPEERR, "object in compartment marked as invisible to Debugger") -MSG_DEF(JSMSG_DEBUG_CENSUS_BREAKDOWN, 1, JSEXN_TYPEERR, "unrecognized 'by' value in takeCensus breakdown: {0}") -MSG_DEF(JSMSG_DEBUG_PROMISE_NOT_RESOLVED, 0, JSEXN_TYPEERR, "Promise hasn't been resolved") -MSG_DEF(JSMSG_DEBUG_PROMISE_NOT_FULFILLED, 0, JSEXN_TYPEERR, "Promise hasn't been fulfilled") -MSG_DEF(JSMSG_DEBUG_PROMISE_NOT_REJECTED, 0, JSEXN_TYPEERR, "Promise hasn't been rejected") - -// Tracelogger -MSG_DEF(JSMSG_TRACELOGGER_ENABLE_FAIL, 1, JSEXN_ERR, "enabling tracelogger failed: {0}") - -// Intl -MSG_DEF(JSMSG_DATE_NOT_FINITE, 0, JSEXN_RANGEERR, "date value is not finite in DateTimeFormat.format()") -MSG_DEF(JSMSG_INTERNAL_INTL_ERROR, 0, JSEXN_ERR, "internal error while computing Intl data") -MSG_DEF(JSMSG_INTL_OBJECT_NOT_INITED, 3, JSEXN_TYPEERR, "Intl.{0}.prototype.{1} called on value that's not an object initialized as a {2}") -MSG_DEF(JSMSG_INTL_OBJECT_REINITED, 0, JSEXN_TYPEERR, "can't initialize object twice as an object of an Intl constructor") -MSG_DEF(JSMSG_INVALID_CURRENCY_CODE, 1, JSEXN_RANGEERR, "invalid currency code in NumberFormat(): {0}") -MSG_DEF(JSMSG_INVALID_DIGITS_VALUE, 1, JSEXN_RANGEERR, "invalid digits value: {0}") -MSG_DEF(JSMSG_INVALID_LANGUAGE_TAG, 1, JSEXN_RANGEERR, "invalid language tag: {0}") -MSG_DEF(JSMSG_INVALID_LOCALES_ELEMENT, 0, JSEXN_TYPEERR, "invalid element in locales argument") -MSG_DEF(JSMSG_INVALID_LOCALE_MATCHER, 1, JSEXN_RANGEERR, "invalid locale matcher in supportedLocalesOf(): {0}") -MSG_DEF(JSMSG_INVALID_OPTION_VALUE, 2, JSEXN_RANGEERR, "invalid value {1} for option {0}") -MSG_DEF(JSMSG_INVALID_TIME_ZONE, 1, JSEXN_RANGEERR, "invalid time zone in DateTimeFormat(): {0}") -MSG_DEF(JSMSG_UNDEFINED_CURRENCY, 0, JSEXN_TYPEERR, "undefined currency in NumberFormat() with currency style") - -// RegExp -MSG_DEF(JSMSG_BACK_REF_OUT_OF_RANGE, 0, JSEXN_SYNTAXERR, "back reference out of range in regular expression") -MSG_DEF(JSMSG_BAD_CLASS_RANGE, 0, JSEXN_SYNTAXERR, "invalid range in character class") -MSG_DEF(JSMSG_ESCAPE_AT_END_OF_REGEXP, 0, JSEXN_SYNTAXERR, "\\ at end of pattern") -MSG_DEF(JSMSG_EXEC_NOT_OBJORNULL, 0, JSEXN_TYPEERR, "RegExp exec method should return object or null") -MSG_DEF(JSMSG_INVALID_DECIMAL_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid decimal escape in regular expression") -MSG_DEF(JSMSG_INVALID_GROUP, 0, JSEXN_SYNTAXERR, "invalid regexp group") -MSG_DEF(JSMSG_INVALID_IDENTITY_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid identity escape in regular expression") -MSG_DEF(JSMSG_INVALID_UNICODE_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid unicode escape in regular expression") -MSG_DEF(JSMSG_MISSING_PAREN, 0, JSEXN_SYNTAXERR, "unterminated parenthetical") -MSG_DEF(JSMSG_NEWREGEXP_FLAGGED, 0, JSEXN_TYPEERR, "can't supply flags when constructing one RegExp from another") -MSG_DEF(JSMSG_NOTHING_TO_REPEAT, 0, JSEXN_SYNTAXERR, "nothing to repeat") -MSG_DEF(JSMSG_NUMBERS_OUT_OF_ORDER, 0, JSEXN_SYNTAXERR, "numbers out of order in {} quantifier.") -MSG_DEF(JSMSG_RANGE_WITH_CLASS_ESCAPE, 0, JSEXN_SYNTAXERR, "character class escape cannot be used in class range in regular expression") -MSG_DEF(JSMSG_RAW_BRACE_IN_REGEP, 0, JSEXN_SYNTAXERR, "raw brace is not allowed in regular expression with unicode flag") -MSG_DEF(JSMSG_RAW_BRACKET_IN_REGEP, 0, JSEXN_SYNTAXERR, "raw bracket is not allowed in regular expression with unicode flag") -MSG_DEF(JSMSG_TOO_MANY_PARENS, 0, JSEXN_INTERNALERR, "too many parentheses in regular expression") -MSG_DEF(JSMSG_UNICODE_OVERFLOW, 0, JSEXN_SYNTAXERR, "unicode codepoint should not be greater than 0x10FFFF in regular expression") -MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN, 0, JSEXN_SYNTAXERR, "unmatched ) in regular expression") -MSG_DEF(JSMSG_UNTERM_CLASS, 0, JSEXN_SYNTAXERR, "unterminated character class") - -// Self-hosting -MSG_DEF(JSMSG_DEFAULT_LOCALE_ERROR, 0, JSEXN_ERR, "internal error getting the default locale") -MSG_DEF(JSMSG_NO_SUCH_SELF_HOSTED_PROP,1, JSEXN_ERR, "No such property on self-hosted object: {0}") - -// Typed object / SIMD -MSG_DEF(JSMSG_INVALID_PROTOTYPE, 0, JSEXN_TYPEERR, "prototype field is not an object") -MSG_DEF(JSMSG_TYPEDOBJECT_BAD_ARGS, 0, JSEXN_TYPEERR, "invalid arguments") -MSG_DEF(JSMSG_TYPEDOBJECT_BINARYARRAY_BAD_INDEX, 0, JSEXN_RANGEERR, "invalid or out-of-range index") -MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED, 0, JSEXN_TYPEERR, "handle unattached") -MSG_DEF(JSMSG_TYPEDOBJECT_STRUCTTYPE_BAD_ARGS, 0, JSEXN_RANGEERR, "invalid field descriptor") -MSG_DEF(JSMSG_TYPEDOBJECT_TOO_BIG, 0, JSEXN_ERR, "Type is too large to allocate") -MSG_DEF(JSMSG_SIMD_FAILED_CONVERSION, 0, JSEXN_RANGEERR, "SIMD conversion loses precision") -MSG_DEF(JSMSG_SIMD_TO_NUMBER, 0, JSEXN_TYPEERR, "can't convert SIMD value to number") - -// Array -MSG_DEF(JSMSG_TOO_LONG_ARRAY, 0, JSEXN_TYPEERR, "Too long array") - -// Typed array -MSG_DEF(JSMSG_BAD_INDEX, 0, JSEXN_RANGEERR, "invalid or out-of-range index") -MSG_DEF(JSMSG_NON_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected ArrayBuffer, but species constructor returned non-ArrayBuffer") -MSG_DEF(JSMSG_SAME_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected different ArrayBuffer, but species constructor returned same ArrayBuffer") -MSG_DEF(JSMSG_SHORT_ARRAY_BUFFER_RETURNED, 2, JSEXN_TYPEERR, "expected ArrayBuffer with at least {0} bytes, but species constructor returns ArrayBuffer with {1} bytes") -MSG_DEF(JSMSG_TYPED_ARRAY_BAD_ARGS, 0, JSEXN_TYPEERR, "invalid arguments") -MSG_DEF(JSMSG_TYPED_ARRAY_NEGATIVE_ARG,1, JSEXN_RANGEERR, "argument {0} must be >= 0") -MSG_DEF(JSMSG_TYPED_ARRAY_DETACHED, 0, JSEXN_TYPEERR, "attempting to access detached ArrayBuffer") -MSG_DEF(JSMSG_TYPED_ARRAY_CONSTRUCT_BOUNDS, 0, JSEXN_RANGEERR, "attempting to construct out-of-bounds TypedArray on ArrayBuffer") -MSG_DEF(JSMSG_TYPED_ARRAY_CALL_OR_CONSTRUCT, 1, JSEXN_TYPEERR, "cannot directly {0} builtin %TypedArray%") -MSG_DEF(JSMSG_NON_TYPED_ARRAY_RETURNED, 0, JSEXN_TYPEERR, "constructor didn't return TypedArray object") -MSG_DEF(JSMSG_SHORT_TYPED_ARRAY_RETURNED, 2, JSEXN_TYPEERR, "expected TypedArray of at least length {0}, but constructor returned TypedArray of length {1}") - -// Shared array buffer -MSG_DEF(JSMSG_SHARED_ARRAY_BAD_LENGTH, 0, JSEXN_RANGEERR, "length argument out of range") -MSG_DEF(JSMSG_NON_SHARED_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected SharedArrayBuffer, but species constructor returned non-SharedArrayBuffer") -MSG_DEF(JSMSG_SAME_SHARED_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected different SharedArrayBuffer, but species constructor returned same SharedArrayBuffer") -MSG_DEF(JSMSG_SHORT_SHARED_ARRAY_BUFFER_RETURNED, 2, JSEXN_TYPEERR, "expected SharedArrayBuffer with at least {0} bytes, but species constructor returns SharedArrayBuffer with {1} bytes") - -// Reflect -MSG_DEF(JSMSG_BAD_PARSE_NODE, 0, JSEXN_INTERNALERR, "bad parse node") - -// Symbol -MSG_DEF(JSMSG_SYMBOL_TO_STRING, 0, JSEXN_TYPEERR, "can't convert symbol to string") -MSG_DEF(JSMSG_SYMBOL_TO_NUMBER, 0, JSEXN_TYPEERR, "can't convert symbol to number") - -// Atomics and futexes -MSG_DEF(JSMSG_ATOMICS_BAD_ARRAY, 0, JSEXN_TYPEERR, "invalid array type for the operation") -MSG_DEF(JSMSG_ATOMICS_TOO_LONG, 0, JSEXN_RANGEERR, "timeout value too large") -MSG_DEF(JSMSG_ATOMICS_WAIT_NOT_ALLOWED, 0, JSEXN_ERR, "waiting is not allowed on this thread") - -// XPConnect wrappers and DOM bindings -MSG_DEF(JSMSG_CANT_SET_INTERPOSED, 1, JSEXN_TYPEERR, "unable to set interposed data property '{0}'") -MSG_DEF(JSMSG_CANT_DEFINE_WINDOW_ELEMENT, 0, JSEXN_TYPEERR, "can't define elements on a Window object") -MSG_DEF(JSMSG_CANT_DELETE_WINDOW_ELEMENT, 0, JSEXN_TYPEERR, "can't delete elements from a Window object") -MSG_DEF(JSMSG_CANT_DELETE_WINDOW_NAMED_PROPERTY, 1, JSEXN_TYPEERR, "can't delete property {0} from window's named properties object") -MSG_DEF(JSMSG_CANT_PREVENT_EXTENSIONS, 0, JSEXN_TYPEERR, "can't prevent extensions on this proxy object") -MSG_DEF(JSMSG_NO_NAMED_SETTER, 2, JSEXN_TYPEERR, "{0} doesn't have a named property setter for '{1}'") -MSG_DEF(JSMSG_NO_INDEXED_SETTER, 2, JSEXN_TYPEERR, "{0} doesn't have an indexed property setter for '{1}'") - -// Super -MSG_DEF(JSMSG_CANT_DELETE_SUPER, 0, JSEXN_REFERENCEERR, "invalid delete involving 'super'") -MSG_DEF(JSMSG_REINIT_THIS, 0, JSEXN_REFERENCEERR, "super() called twice in derived class constructor") - -// Modules -MSG_DEF(JSMSG_BAD_DEFAULT_EXPORT, 0, JSEXN_SYNTAXERR, "default export cannot be provided by export *") -MSG_DEF(JSMSG_MISSING_INDIRECT_EXPORT, 1, JSEXN_SYNTAXERR, "indirect export '{0}' not found") -MSG_DEF(JSMSG_AMBIGUOUS_INDIRECT_EXPORT, 1, JSEXN_SYNTAXERR, "ambiguous indirect export '{0}'") -MSG_DEF(JSMSG_MISSING_IMPORT, 1, JSEXN_SYNTAXERR, "import '{0}' not found") -MSG_DEF(JSMSG_AMBIGUOUS_IMPORT, 1, JSEXN_SYNTAXERR, "ambiguous import '{0}'") -MSG_DEF(JSMSG_MISSING_NAMESPACE_EXPORT, 0, JSEXN_SYNTAXERR, "export not found for namespace") -MSG_DEF(JSMSG_MISSING_EXPORT, 1, JSEXN_SYNTAXERR, "local binding for export '{0}' not found") -MSG_DEF(JSMSG_MODULE_INSTANTIATE_FAILED, 0, JSEXN_INTERNALERR, "attempt to re-instantiate module after failure") -MSG_DEF(JSMSG_BAD_MODULE_STATE, 0, JSEXN_INTERNALERR, "module record in unexpected state") - -// Promise -MSG_DEF(JSMSG_CANNOT_RESOLVE_PROMISE_WITH_ITSELF, 0, JSEXN_TYPEERR, "A promise cannot be resolved with itself.") -MSG_DEF(JSMSG_PROMISE_CAPABILITY_HAS_SOMETHING_ALREADY, 0, JSEXN_TYPEERR, "GetCapabilitiesExecutor function already invoked with non-undefined values.") -MSG_DEF(JSMSG_PROMISE_RESOLVE_FUNCTION_NOT_CALLABLE, 0, JSEXN_TYPEERR, "A Promise subclass passed a non-callable value as the resolve function.") -MSG_DEF(JSMSG_PROMISE_REJECT_FUNCTION_NOT_CALLABLE, 0, JSEXN_TYPEERR, "A Promise subclass passed a non-callable value as the reject function.") -MSG_DEF(JSMSG_PROMISE_ERROR_IN_WRAPPED_REJECTION_REASON,0, JSEXN_INTERNALERR, "Promise rejection value is a non-unwrappable cross-compartment wrapper.") diff --git a/android/arm64-v8a/include/spidermonkey/js/CallArgs.h b/android/arm64-v8a/include/spidermonkey/js/CallArgs.h deleted file mode 100644 index 1e0d909a..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/CallArgs.h +++ /dev/null @@ -1,369 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* - * Helper classes encapsulating access to the callee, |this| value, arguments, - * and argument count for a call/construct operation. - * - * JS::CallArgs encapsulates access to a JSNative's un-abstracted - * |unsigned argc, Value* vp| arguments. The principal way to create a - * JS::CallArgs is using JS::CallArgsFromVp: - * - * // If provided no arguments or a non-numeric first argument, return zero. - * // Otherwise return |this| exactly as given, without boxing. - * static bool - * Func(JSContext* cx, unsigned argc, JS::Value* vp) - * { - * JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - * - * // Guard against no arguments or a non-numeric arg0. - * if (args.length() == 0 || !args[0].isNumber()) { - * args.rval().setInt32(0); - * return true; - * } - * - * // Access to the callee must occur before accessing/setting - * // the return value. - * JSObject& callee = args.callee(); - * args.rval().setObject(callee); - * - * // callee() and calleev() will now assert. - * - * // It's always fine to access thisv(). - * HandleValue thisv = args.thisv(); - * args.rval().set(thisv); - * - * // As the return value was last set to |this|, returns |this|. - * return true; - * } - * - * CallArgs is exposed publicly and used internally. Not all parts of its - * public interface are meant to be used by embedders! See inline comments to - * for details. - * - * It's possible (albeit deprecated) to manually index into |vp| to access the - * callee, |this|, and arguments of a function, and to set its return value. - * It's also possible to use the supported API of JS_CALLEE, JS_THIS, JS_ARGV, - * JS_RVAL, and JS_SET_RVAL to the same ends. - * - * But neither API has the error-handling or moving-GC correctness of CallArgs. - * New code should use CallArgs instead whenever possible. - * - * The eventual plan is to change JSNative to take |const CallArgs&| directly, - * for automatic assertion of correct use and to make calling functions more - * efficient. Embedders should start internally switching away from using - * |argc| and |vp| directly, except to create a |CallArgs|. Then, when an - * eventual release making that change occurs, porting efforts will require - * changing methods' signatures but won't require invasive changes to the - * methods' implementations, potentially under time pressure. - */ - -#ifndef js_CallArgs_h -#define js_CallArgs_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/TypeTraits.h" - -#include "jstypes.h" - -#include "js/RootingAPI.h" -#include "js/Value.h" - -/* Typedef for native functions called by the JS VM. */ -typedef bool -(* JSNative)(JSContext* cx, unsigned argc, JS::Value* vp); - -namespace JS { - -extern JS_PUBLIC_DATA(const HandleValue) UndefinedHandleValue; - -namespace detail { - -/* - * Compute |this| for the |vp| inside a JSNative, either boxing primitives or - * replacing with the global object as necessary. - */ -extern JS_PUBLIC_API(Value) -ComputeThis(JSContext* cx, JS::Value* vp); - -#ifdef JS_DEBUG -extern JS_PUBLIC_API(void) -CheckIsValidConstructible(const Value& v); -#endif - -class MOZ_STACK_CLASS IncludeUsedRval -{ - protected: -#ifdef JS_DEBUG - mutable bool usedRval_; - void setUsedRval() const { usedRval_ = true; } - void clearUsedRval() const { usedRval_ = false; } - void assertUnusedRval() const { MOZ_ASSERT(!usedRval_); } -#else - void setUsedRval() const {} - void clearUsedRval() const {} - void assertUnusedRval() const {} -#endif -}; - -class MOZ_STACK_CLASS NoUsedRval -{ - protected: - void setUsedRval() const {} - void clearUsedRval() const {} - void assertUnusedRval() const {} -}; - -template -class MOZ_STACK_CLASS CallArgsBase : public WantUsedRval -{ - static_assert(mozilla::IsSame::value || - mozilla::IsSame::value, - "WantUsedRval can only be IncludeUsedRval or NoUsedRval"); - - protected: - Value* argv_; - unsigned argc_; - bool constructing_; - - public: - // CALLEE ACCESS - - /* - * Returns the function being called, as a value. Must not be called after - * rval() has been used! - */ - HandleValue calleev() const { - this->assertUnusedRval(); - return HandleValue::fromMarkedLocation(&argv_[-2]); - } - - /* - * Returns the function being called, as an object. Must not be called - * after rval() has been used! - */ - JSObject& callee() const { - return calleev().toObject(); - } - - // CALLING/CONSTRUCTING-DIFFERENTIATIONS - - bool isConstructing() const { - if (!argv_[-1].isMagic()) - return false; - -#ifdef JS_DEBUG - if (!this->usedRval_) - CheckIsValidConstructible(calleev()); -#endif - - return true; - } - - MutableHandleValue newTarget() const { - MOZ_ASSERT(constructing_); - return MutableHandleValue::fromMarkedLocation(&this->argv_[argc_]); - } - - /* - * Returns the |this| value passed to the function. This method must not - * be called when the function is being called as a constructor via |new|. - * The value may or may not be an object: it is the individual function's - * responsibility to box the value if needed. - */ - HandleValue thisv() const { - // Some internal code uses thisv() in constructing cases, so don't do - // this yet. - // MOZ_ASSERT(!argv_[-1].isMagic(JS_IS_CONSTRUCTING)); - return HandleValue::fromMarkedLocation(&argv_[-1]); - } - - Value computeThis(JSContext* cx) const { - if (thisv().isObject()) - return thisv(); - - return ComputeThis(cx, base()); - } - - // ARGUMENTS - - /* Returns the number of arguments. */ - unsigned length() const { return argc_; } - - /* Returns the i-th zero-indexed argument. */ - MutableHandleValue operator[](unsigned i) const { - MOZ_ASSERT(i < argc_); - return MutableHandleValue::fromMarkedLocation(&this->argv_[i]); - } - - /* - * Returns the i-th zero-indexed argument, or |undefined| if there's no - * such argument. - */ - HandleValue get(unsigned i) const { - return i < length() - ? HandleValue::fromMarkedLocation(&this->argv_[i]) - : UndefinedHandleValue; - } - - /* - * Returns true if the i-th zero-indexed argument is present and is not - * |undefined|. - */ - bool hasDefined(unsigned i) const { - return i < argc_ && !this->argv_[i].isUndefined(); - } - - // RETURN VALUE - - /* - * Returns the currently-set return value. The initial contents of this - * value are unspecified. Once this method has been called, callee() and - * calleev() can no longer be used. (If you're compiling against a debug - * build of SpiderMonkey, these methods will assert to aid debugging.) - * - * If the method you're implementing succeeds by returning true, you *must* - * set this. (SpiderMonkey doesn't currently assert this, but it will do - * so eventually.) You don't need to use or change this if your method - * fails. - */ - MutableHandleValue rval() const { - this->setUsedRval(); - return MutableHandleValue::fromMarkedLocation(&argv_[-2]); - } - - public: - // These methods are publicly exposed, but they are *not* to be used when - // implementing a JSNative method and encapsulating access to |vp| within - // it. You probably don't want to use these! - - void setCallee(const Value& aCalleev) const { - this->clearUsedRval(); - argv_[-2] = aCalleev; - } - - void setThis(const Value& aThisv) const { - argv_[-1] = aThisv; - } - - MutableHandleValue mutableThisv() const { - return MutableHandleValue::fromMarkedLocation(&argv_[-1]); - } - - public: - // These methods are publicly exposed, but we're unsure of the interfaces - // (because they're hackish and drop assertions). Avoid using these if you - // can. - - Value* array() const { return argv_; } - Value* end() const { return argv_ + argc_ + constructing_; } - - public: - // These methods are only intended for internal use. Embedders shouldn't - // use them! - - Value* base() const { return argv_ - 2; } - - Value* spAfterCall() const { - this->setUsedRval(); - return argv_ - 1; - } -}; - -} // namespace detail - -class MOZ_STACK_CLASS CallArgs : public detail::CallArgsBase -{ - private: - friend CallArgs CallArgsFromVp(unsigned argc, Value* vp); - friend CallArgs CallArgsFromSp(unsigned stackSlots, Value* sp, bool constructing); - - static CallArgs create(unsigned argc, Value* argv, bool constructing) { - CallArgs args; - args.clearUsedRval(); - args.argv_ = argv; - args.argc_ = argc; - args.constructing_ = constructing; -#ifdef DEBUG - for (unsigned i = 0; i < argc; ++i) - MOZ_ASSERT_IF(argv[i].isMarkable(), !GCThingIsMarkedGray(GCCellPtr(argv[i]))); -#endif - return args; - } - - public: - /* - * Returns true if there are at least |required| arguments passed in. If - * false, it reports an error message on the context. - */ - bool requireAtLeast(JSContext* cx, const char* fnname, unsigned required) const; - -}; - -MOZ_ALWAYS_INLINE CallArgs -CallArgsFromVp(unsigned argc, Value* vp) -{ - return CallArgs::create(argc, vp + 2, vp[1].isMagic(JS_IS_CONSTRUCTING)); -} - -// This method is only intended for internal use in SpiderMonkey. We may -// eventually move it to an internal header. Embedders should use -// JS::CallArgsFromVp! -MOZ_ALWAYS_INLINE CallArgs -CallArgsFromSp(unsigned stackSlots, Value* sp, bool constructing = false) -{ - return CallArgs::create(stackSlots - constructing, sp - stackSlots, constructing); -} - -} // namespace JS - -/* - * Macros to hide interpreter stack layout details from a JSNative using its - * JS::Value* vp parameter. DO NOT USE THESE! Instead use JS::CallArgs and - * friends, above. These macros will be removed when we change JSNative to - * take a const JS::CallArgs&. - */ - -/* - * Return |this| if |this| is an object. Otherwise, return the global object - * if |this| is null or undefined, and finally return a boxed version of any - * other primitive. - * - * Note: if this method returns null, an error has occurred and must be - * propagated or caught. - */ -MOZ_ALWAYS_INLINE JS::Value -JS_THIS(JSContext* cx, JS::Value* vp) -{ - return vp[1].isPrimitive() ? JS::detail::ComputeThis(cx, vp) : vp[1]; -} - -/* - * A note on JS_THIS_OBJECT: no equivalent method is part of the CallArgs - * interface, and we're unlikely to add one (functions shouldn't be implicitly - * exposing the global object to arbitrary callers). Continue using |vp| - * directly for this case, but be aware this API will eventually be replaced - * with a function that operates directly upon |args.thisv()|. - */ -#define JS_THIS_OBJECT(cx,vp) (JS_THIS(cx,vp).toObjectOrNull()) - -/* - * |this| is passed to functions in ES5 without change. Functions themselves - * do any post-processing they desire to box |this|, compute the global object, - * &c. This macro retrieves a function's unboxed |this| value. - * - * This macro must not be used in conjunction with JS_THIS or JS_THIS_OBJECT, - * or vice versa. Either use the provided this value with this macro, or - * compute the boxed |this| value using those. JS_THIS_VALUE must not be used - * if the function is being called as a constructor. - * - * But: DO NOT USE THIS! Instead use JS::CallArgs::thisv(), above. - * - */ -#define JS_THIS_VALUE(cx,vp) ((vp)[1]) - -#endif /* js_CallArgs_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/CallNonGenericMethod.h b/android/arm64-v8a/include/spidermonkey/js/CallNonGenericMethod.h deleted file mode 100644 index 9a1cf010..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/CallNonGenericMethod.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_CallNonGenericMethod_h -#define js_CallNonGenericMethod_h - -#include "jstypes.h" - -#include "js/CallArgs.h" - -namespace JS { - -// Returns true if |v| is considered an acceptable this-value. -typedef bool (*IsAcceptableThis)(HandleValue v); - -// Implements the guts of a method; guaranteed to be provided an acceptable -// this-value, as determined by a corresponding IsAcceptableThis method. -typedef bool (*NativeImpl)(JSContext* cx, const CallArgs& args); - -namespace detail { - -// DON'T CALL THIS DIRECTLY. It's for use only by CallNonGenericMethod! -extern JS_PUBLIC_API(bool) -CallMethodIfWrapped(JSContext* cx, IsAcceptableThis test, NativeImpl impl, const CallArgs& args); - -} // namespace detail - -// Methods usually act upon |this| objects only from a single global object and -// compartment. Sometimes, however, a method must act upon |this| values from -// multiple global objects or compartments. In such cases the |this| value a -// method might see will be wrapped, such that various access to the object -- -// to its class, its private data, its reserved slots, and so on -- will not -// work properly without entering that object's compartment. This method -// implements a solution to this problem. -// -// To implement a method that accepts |this| values from multiple compartments, -// define two functions. The first function matches the IsAcceptableThis type -// and indicates whether the provided value is an acceptable |this| for the -// method; it must be a pure function only of its argument. -// -// static const JSClass AnswerClass = { ... }; -// -// static bool -// IsAnswerObject(const Value& v) -// { -// if (!v.isObject()) -// return false; -// return JS_GetClass(&v.toObject()) == &AnswerClass; -// } -// -// The second function implements the NativeImpl signature and defines the -// behavior of the method when it is provided an acceptable |this| value. -// Aside from some typing niceties -- see the CallArgs interface for details -- -// its interface is the same as that of JSNative. -// -// static bool -// answer_getAnswer_impl(JSContext* cx, JS::CallArgs args) -// { -// args.rval().setInt32(42); -// return true; -// } -// -// The implementation function is guaranteed to be called *only* with a |this| -// value which is considered acceptable. -// -// Now to implement the actual method, write a JSNative that calls the method -// declared below, passing the appropriate template and runtime arguments. -// -// static bool -// answer_getAnswer(JSContext* cx, unsigned argc, JS::Value* vp) -// { -// JS::CallArgs args = JS::CallArgsFromVp(argc, vp); -// return JS::CallNonGenericMethod(cx, args); -// } -// -// Note that, because they are used as template arguments, the predicate -// and implementation functions must have external linkage. (This is -// unfortunate, but GCC wasn't inlining things as one would hope when we -// passed them as function arguments.) -// -// JS::CallNonGenericMethod will test whether |args.thisv()| is acceptable. If -// it is, it will call the provided implementation function, which will return -// a value and indicate success. If it is not, it will attempt to unwrap -// |this| and call the implementation function on the unwrapped |this|. If -// that succeeds, all well and good. If it doesn't succeed, a TypeError will -// be thrown. -// -// Note: JS::CallNonGenericMethod will only work correctly if it's called in -// tail position in a JSNative. Do not call it from any other place. -// -template -MOZ_ALWAYS_INLINE bool -CallNonGenericMethod(JSContext* cx, const CallArgs& args) -{ - HandleValue thisv = args.thisv(); - if (Test(thisv)) - return Impl(cx, args); - - return detail::CallMethodIfWrapped(cx, Test, Impl, args); -} - -MOZ_ALWAYS_INLINE bool -CallNonGenericMethod(JSContext* cx, IsAcceptableThis Test, NativeImpl Impl, const CallArgs& args) -{ - HandleValue thisv = args.thisv(); - if (Test(thisv)) - return Impl(cx, args); - - return detail::CallMethodIfWrapped(cx, Test, Impl, args); -} - -} // namespace JS - -#endif /* js_CallNonGenericMethod_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/CharacterEncoding.h b/android/arm64-v8a/include/spidermonkey/js/CharacterEncoding.h deleted file mode 100644 index fe39a415..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/CharacterEncoding.h +++ /dev/null @@ -1,338 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_CharacterEncoding_h -#define js_CharacterEncoding_h - -#include "mozilla/Range.h" - -#include "js/TypeDecls.h" -#include "js/Utility.h" - -namespace js { -class ExclusiveContext; -} // namespace js - -class JSFlatString; - -namespace JS { - -/* - * By default, all C/C++ 1-byte-per-character strings passed into the JSAPI - * are treated as ISO/IEC 8859-1, also known as Latin-1. That is, each - * byte is treated as a 2-byte character, and there is no way to pass in a - * string containing characters beyond U+00FF. - */ -class Latin1Chars : public mozilla::Range -{ - typedef mozilla::Range Base; - - public: - using CharT = Latin1Char; - - Latin1Chars() : Base() {} - Latin1Chars(char* aBytes, size_t aLength) : Base(reinterpret_cast(aBytes), aLength) {} - Latin1Chars(const Latin1Char* aBytes, size_t aLength) - : Base(const_cast(aBytes), aLength) - {} - Latin1Chars(const char* aBytes, size_t aLength) - : Base(reinterpret_cast(const_cast(aBytes)), aLength) - {} -}; - -/* - * A Latin1Chars, but with \0 termination for C compatibility. - */ -class Latin1CharsZ : public mozilla::RangedPtr -{ - typedef mozilla::RangedPtr Base; - - public: - using CharT = Latin1Char; - - Latin1CharsZ() : Base(nullptr, 0) {} - - Latin1CharsZ(char* aBytes, size_t aLength) - : Base(reinterpret_cast(aBytes), aLength) - { - MOZ_ASSERT(aBytes[aLength] == '\0'); - } - - Latin1CharsZ(Latin1Char* aBytes, size_t aLength) - : Base(aBytes, aLength) - { - MOZ_ASSERT(aBytes[aLength] == '\0'); - } - - using Base::operator=; - - char* c_str() { return reinterpret_cast(get()); } -}; - -class UTF8Chars : public mozilla::Range -{ - typedef mozilla::Range Base; - - public: - using CharT = unsigned char; - - UTF8Chars() : Base() {} - UTF8Chars(char* aBytes, size_t aLength) - : Base(reinterpret_cast(aBytes), aLength) - {} - UTF8Chars(const char* aBytes, size_t aLength) - : Base(reinterpret_cast(const_cast(aBytes)), aLength) - {} -}; - -/* - * SpiderMonkey also deals directly with UTF-8 encoded text in some places. - */ -class UTF8CharsZ : public mozilla::RangedPtr -{ - typedef mozilla::RangedPtr Base; - - public: - using CharT = unsigned char; - - UTF8CharsZ() : Base(nullptr, 0) {} - - UTF8CharsZ(char* aBytes, size_t aLength) - : Base(reinterpret_cast(aBytes), aLength) - { - MOZ_ASSERT(aBytes[aLength] == '\0'); - } - - UTF8CharsZ(unsigned char* aBytes, size_t aLength) - : Base(aBytes, aLength) - { - MOZ_ASSERT(aBytes[aLength] == '\0'); - } - - using Base::operator=; - - char* c_str() { return reinterpret_cast(get()); } -}; - -/* - * A wrapper for a "const char*" that is encoded using UTF-8. - * This class does not manage ownership of the data; that is left - * to others. This differs from UTF8CharsZ in that the chars are - * const and it allows assignment. - */ -class ConstUTF8CharsZ -{ - const char* data_; - - public: - using CharT = unsigned char; - - ConstUTF8CharsZ() : data_(nullptr) - {} - - ConstUTF8CharsZ(const char* aBytes, size_t aLength) - : data_(aBytes) - { - MOZ_ASSERT(aBytes[aLength] == '\0'); -#ifdef DEBUG - validate(aLength); -#endif - } - - const void* get() const { return data_; } - - const char* c_str() const { return data_; } - - explicit operator bool() const { return data_ != nullptr; } - - private: -#ifdef DEBUG - void validate(size_t aLength); -#endif -}; - -/* - * SpiderMonkey uses a 2-byte character representation: it is a - * 2-byte-at-a-time view of a UTF-16 byte stream. This is similar to UCS-2, - * but unlike UCS-2, we do not strip UTF-16 extension bytes. This allows a - * sufficiently dedicated JavaScript program to be fully unicode-aware by - * manually interpreting UTF-16 extension characters embedded in the JS - * string. - */ -class TwoByteChars : public mozilla::Range -{ - typedef mozilla::Range Base; - - public: - using CharT = char16_t; - - TwoByteChars() : Base() {} - TwoByteChars(char16_t* aChars, size_t aLength) : Base(aChars, aLength) {} - TwoByteChars(const char16_t* aChars, size_t aLength) : Base(const_cast(aChars), aLength) {} -}; - -/* - * A TwoByteChars, but \0 terminated for compatibility with JSFlatString. - */ -class TwoByteCharsZ : public mozilla::RangedPtr -{ - typedef mozilla::RangedPtr Base; - - public: - using CharT = char16_t; - - TwoByteCharsZ() : Base(nullptr, 0) {} - - TwoByteCharsZ(char16_t* chars, size_t length) - : Base(chars, length) - { - MOZ_ASSERT(chars[length] == '\0'); - } - - using Base::operator=; -}; - -typedef mozilla::RangedPtr ConstCharPtr; - -/* - * Like TwoByteChars, but the chars are const. - */ -class ConstTwoByteChars : public mozilla::Range -{ - typedef mozilla::Range Base; - - public: - using CharT = char16_t; - - ConstTwoByteChars() : Base() {} - ConstTwoByteChars(const char16_t* aChars, size_t aLength) : Base(aChars, aLength) {} -}; - -/* - * Convert a 2-byte character sequence to "ISO-Latin-1". This works by - * truncating each 2-byte pair in the sequence to a 1-byte pair. If the source - * contains any UTF-16 extension characters, then this may give invalid Latin1 - * output. The returned string is zero terminated. The returned string or the - * returned string's |start()| must be freed with JS_free or js_free, - * respectively. If allocation fails, an OOM error will be set and the method - * will return a nullptr chars (which can be tested for with the ! operator). - * This method cannot trigger GC. - */ -extern Latin1CharsZ -LossyTwoByteCharsToNewLatin1CharsZ(js::ExclusiveContext* cx, - const mozilla::Range tbchars); - -inline Latin1CharsZ -LossyTwoByteCharsToNewLatin1CharsZ(js::ExclusiveContext* cx, const char16_t* begin, size_t length) -{ - const mozilla::Range tbchars(begin, length); - return JS::LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars); -} - -template -extern UTF8CharsZ -CharsToNewUTF8CharsZ(js::ExclusiveContext* maybeCx, const mozilla::Range chars); - -uint32_t -Utf8ToOneUcs4Char(const uint8_t* utf8Buffer, int utf8Length); - -/* - * Inflate bytes in UTF-8 encoding to char16_t. - * - On error, returns an empty TwoByteCharsZ. - * - On success, returns a malloc'd TwoByteCharsZ, and updates |outlen| to hold - * its length; the length value excludes the trailing null. - */ -extern TwoByteCharsZ -UTF8CharsToNewTwoByteCharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen); - -/* - * Like UTF8CharsToNewTwoByteCharsZ, but for ConstUTF8CharsZ. - */ -extern TwoByteCharsZ -UTF8CharsToNewTwoByteCharsZ(JSContext* cx, const ConstUTF8CharsZ& utf8, size_t* outlen); - -/* - * The same as UTF8CharsToNewTwoByteCharsZ(), except that any malformed UTF-8 characters - * will be replaced by \uFFFD. No exception will be thrown for malformed UTF-8 - * input. - */ -extern TwoByteCharsZ -LossyUTF8CharsToNewTwoByteCharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen); - -extern TwoByteCharsZ -LossyUTF8CharsToNewTwoByteCharsZ(JSContext* cx, const ConstUTF8CharsZ& utf8, size_t* outlen); - -/* - * Returns the length of the char buffer required to encode |s| as UTF8. - * Does not include the null-terminator. - */ -JS_PUBLIC_API(size_t) -GetDeflatedUTF8StringLength(JSFlatString* s); - -/* - * Encode |src| as UTF8. The caller must either ensure |dst| has enough space - * to encode the entire string or pass the length of the buffer as |dstlenp|, - * in which case the function will encode characters from the string until - * the buffer is exhausted. Does not write the null terminator. - * - * If |dstlenp| is provided, it will be updated to hold the number of bytes - * written to the buffer. If |numcharsp| is provided, it will be updated to hold - * the number of Unicode characters written to the buffer (which can be less - * than the length of the string, if the buffer is exhausted before the string - * is fully encoded). - */ -JS_PUBLIC_API(void) -DeflateStringToUTF8Buffer(JSFlatString* src, mozilla::RangedPtr dst, - size_t* dstlenp = nullptr, size_t* numcharsp = nullptr); - -/* - * The smallest character encoding capable of fully representing a particular - * string. - */ -enum class SmallestEncoding { - ASCII, - Latin1, - UTF16 -}; - -/* - * Returns the smallest encoding possible for the given string: if all - * codepoints are <128 then ASCII, otherwise if all codepoints are <256 - * Latin-1, else UTF16. - */ -JS_PUBLIC_API(SmallestEncoding) -FindSmallestEncoding(UTF8Chars utf8); - -/* - * Return a null-terminated Latin-1 string copied from the input string, - * storing its length (excluding null terminator) in |*outlen|. Fail and - * report an error if the string contains non-Latin-1 codepoints. Returns - * Latin1CharsZ() on failure. - */ -extern Latin1CharsZ -UTF8CharsToNewLatin1CharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen); - -/* - * Return a null-terminated Latin-1 string copied from the input string, - * storing its length (excluding null terminator) in |*outlen|. Non-Latin-1 - * codepoints are replaced by '?'. Returns Latin1CharsZ() on failure. - */ -extern Latin1CharsZ -LossyUTF8CharsToNewLatin1CharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen); - -/* - * Returns true if all characters in the given null-terminated string are - * ASCII, i.e. < 0x80, false otherwise. - */ -extern bool -StringIsASCII(const char* s); - -} // namespace JS - -inline void JS_free(JS::Latin1CharsZ& ptr) { js_free((void*)ptr.get()); } -inline void JS_free(JS::UTF8CharsZ& ptr) { js_free((void*)ptr.get()); } - -#endif /* js_CharacterEncoding_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/Class.h b/android/arm64-v8a/include/spidermonkey/js/Class.h deleted file mode 100644 index 3b502387..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/Class.h +++ /dev/null @@ -1,995 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* JSClass definition and its component types, plus related interfaces. */ - -#ifndef js_Class_h -#define js_Class_h - -#include "jstypes.h" - -#include "js/CallArgs.h" -#include "js/Id.h" -#include "js/TypeDecls.h" - -/* - * A JSClass acts as a vtable for JS objects that allows JSAPI clients to - * control various aspects of the behavior of an object like property lookup. - * js::Class is an engine-private extension that allows more control over - * object behavior and, e.g., allows custom slow layout. - */ - -struct JSAtomState; -struct JSFreeOp; -struct JSFunctionSpec; - -namespace js { - -struct Class; -class FreeOp; -class Shape; - -// This is equal to JSFunction::class_. Use it in places where you don't want -// to #include jsfun.h. -extern JS_FRIEND_DATA(const js::Class* const) FunctionClassPtr; - -} // namespace js - -namespace JS { - -class AutoIdVector; - -/** - * The answer to a successful query as to whether an object is an Array per - * ES6's internal |IsArray| operation (as exposed by |Array.isArray|). - */ -enum class IsArrayAnswer -{ - Array, - NotArray, - RevokedProxy -}; - -/** - * ES6 7.2.2. - * - * Returns false on failure, otherwise returns true and sets |*isArray| - * indicating whether the object passes ECMAScript's IsArray test. This is the - * same test performed by |Array.isArray|. - * - * This is NOT the same as asking whether |obj| is an Array or a wrapper around - * one. If |obj| is a proxy created by |Proxy.revocable()| and has been - * revoked, or if |obj| is a proxy whose target (at any number of hops) is a - * revoked proxy, this method throws a TypeError and returns false. - */ -extern JS_PUBLIC_API(bool) -IsArray(JSContext* cx, HandleObject obj, bool* isArray); - -/** - * Identical to IsArray above, but the nature of the object (if successfully - * determined) is communicated via |*answer|. In particular this method - * returns true and sets |*answer = IsArrayAnswer::RevokedProxy| when called on - * a revoked proxy. - * - * Most users will want the overload above, not this one. - */ -extern JS_PUBLIC_API(bool) -IsArray(JSContext* cx, HandleObject obj, IsArrayAnswer* answer); - -/** - * Per ES6, the [[DefineOwnProperty]] internal method has three different - * possible outcomes: - * - * - It can throw an exception (which we indicate by returning false). - * - * - It can return true, indicating unvarnished success. - * - * - It can return false, indicating "strict failure". The property could - * not be defined. It's an error, but no exception was thrown. - * - * It's not just [[DefineOwnProperty]]: all the mutating internal methods have - * the same three outcomes. (The other affected internal methods are [[Set]], - * [[Delete]], [[SetPrototypeOf]], and [[PreventExtensions]].) - * - * If you think this design is awful, you're not alone. But as it's the - * standard, we must represent these boolean "success" values somehow. - * ObjectOpSuccess is the class for this. It's like a bool, but when it's false - * it also stores an error code. - * - * Typical usage: - * - * ObjectOpResult result; - * if (!DefineProperty(cx, obj, id, ..., result)) - * return false; - * if (!result) - * return result.reportError(cx, obj, id); - * - * Users don't have to call `result.report()`; another possible ending is: - * - * argv.rval().setBoolean(bool(result)); - * return true; - */ -class ObjectOpResult -{ - private: - /** - * code_ is either one of the special codes OkCode or Uninitialized, or - * an error code. For now the error codes are private to the JS engine; - * they're defined in js/src/js.msg. - * - * code_ is uintptr_t (rather than uint32_t) for the convenience of the - * JITs, which would otherwise have to deal with either padding or stack - * alignment on 64-bit platforms. - */ - uintptr_t code_; - - public: - enum SpecialCodes : uintptr_t { - OkCode = 0, - Uninitialized = uintptr_t(-1) - }; - - ObjectOpResult() : code_(Uninitialized) {} - - /* Return true if succeed() was called. */ - bool ok() const { - MOZ_ASSERT(code_ != Uninitialized); - return code_ == OkCode; - } - - explicit operator bool() const { return ok(); } - - /* Set this ObjectOpResult to true and return true. */ - bool succeed() { - code_ = OkCode; - return true; - } - - /* - * Set this ObjectOpResult to false with an error code. - * - * Always returns true, as a convenience. Typical usage will be: - * - * if (funny condition) - * return result.fail(JSMSG_CANT_DO_THE_THINGS); - * - * The true return value indicates that no exception is pending, and it - * would be OK to ignore the failure and continue. - */ - bool fail(uint32_t msg) { - MOZ_ASSERT(msg != OkCode); - code_ = msg; - return true; - } - - JS_PUBLIC_API(bool) failCantRedefineProp(); - JS_PUBLIC_API(bool) failReadOnly(); - JS_PUBLIC_API(bool) failGetterOnly(); - JS_PUBLIC_API(bool) failCantDelete(); - - JS_PUBLIC_API(bool) failCantSetInterposed(); - JS_PUBLIC_API(bool) failCantDefineWindowElement(); - JS_PUBLIC_API(bool) failCantDeleteWindowElement(); - JS_PUBLIC_API(bool) failCantDeleteWindowNamedProperty(); - JS_PUBLIC_API(bool) failCantPreventExtensions(); - JS_PUBLIC_API(bool) failCantSetProto(); - JS_PUBLIC_API(bool) failNoNamedSetter(); - JS_PUBLIC_API(bool) failNoIndexedSetter(); - - uint32_t failureCode() const { - MOZ_ASSERT(!ok()); - return uint32_t(code_); - } - - /* - * Report an error or warning if necessary; return true to proceed and - * false if an error was reported. Call this when failure should cause - * a warning if extraWarnings are enabled. - * - * The precise rules are like this: - * - * - If ok(), then we succeeded. Do nothing and return true. - * - Otherwise, if |strict| is true, or if cx has both extraWarnings and - * werrorOption enabled, throw a TypeError and return false. - * - Otherwise, if cx has extraWarnings enabled, emit a warning and - * return true. - * - Otherwise, do nothing and return true. - */ - bool checkStrictErrorOrWarning(JSContext* cx, HandleObject obj, HandleId id, bool strict) { - if (ok()) - return true; - return reportStrictErrorOrWarning(cx, obj, id, strict); - } - - /* - * The same as checkStrictErrorOrWarning(cx, id, strict), except the - * operation is not associated with a particular property id. This is - * used for [[PreventExtensions]] and [[SetPrototypeOf]]. failureCode() - * must not be an error that has "{0}" in the error message. - */ - bool checkStrictErrorOrWarning(JSContext* cx, HandleObject obj, bool strict) { - return ok() || reportStrictErrorOrWarning(cx, obj, strict); - } - - /* Throw a TypeError. Call this only if !ok(). */ - bool reportError(JSContext* cx, HandleObject obj, HandleId id) { - return reportStrictErrorOrWarning(cx, obj, id, true); - } - - /* - * The same as reportError(cx, obj, id), except the operation is not - * associated with a particular property id. - */ - bool reportError(JSContext* cx, HandleObject obj) { - return reportStrictErrorOrWarning(cx, obj, true); - } - - /* Helper function for checkStrictErrorOrWarning's slow path. */ - JS_PUBLIC_API(bool) reportStrictErrorOrWarning(JSContext* cx, HandleObject obj, HandleId id, bool strict); - JS_PUBLIC_API(bool) reportStrictErrorOrWarning(JSContext* cx, HandleObject obj, bool strict); - - /* - * Convenience method. Return true if ok() or if strict is false; otherwise - * throw a TypeError and return false. - */ - bool checkStrict(JSContext* cx, HandleObject obj, HandleId id) { - return checkStrictErrorOrWarning(cx, obj, id, true); - } - - /* - * Convenience method. The same as checkStrict(cx, id), except the - * operation is not associated with a particular property id. - */ - bool checkStrict(JSContext* cx, HandleObject obj) { - return checkStrictErrorOrWarning(cx, obj, true); - } -}; - -} // namespace JS - -// JSClass operation signatures. - -/** - * Get a property named by id in obj. Note the jsid id type -- id may - * be a string (Unicode property identifier) or an int (element index). The - * *vp out parameter, on success, is the new property value after the action. - */ -typedef bool -(* JSGetterOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp); - -/** Add a property named by id to obj. */ -typedef bool -(* JSAddPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v); - -/** - * Set a property named by id in obj, treating the assignment as strict - * mode code if strict is true. Note the jsid id type -- id may be a string - * (Unicode property identifier) or an int (element index). The *vp out - * parameter, on success, is the new property value after the - * set. - */ -typedef bool -(* JSSetterOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp, JS::ObjectOpResult& result); - -/** - * Delete a property named by id in obj. - * - * If an error occurred, return false as per normal JSAPI error practice. - * - * If no error occurred, but the deletion attempt wasn't allowed (perhaps - * because the property was non-configurable), call result.fail() and - * return true. This will cause |delete obj[id]| to evaluate to false in - * non-strict mode code, and to throw a TypeError in strict mode code. - * - * If no error occurred and the deletion wasn't disallowed (this is *not* the - * same as saying that a deletion actually occurred -- deleting a non-existent - * property, or an inherited property, is allowed -- it's just pointless), - * call result.succeed() and return true. - */ -typedef bool -(* JSDeletePropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::ObjectOpResult& result); - -/** - * The type of ObjectOps::enumerate. This callback overrides a portion of - * SpiderMonkey's default [[Enumerate]] internal method. When an ordinary object - * is enumerated, that object and each object on its prototype chain is tested - * for an enumerate op, and those ops are called in order. The properties each - * op adds to the 'properties' vector are added to the set of values the for-in - * loop will iterate over. All of this is nonstandard. - * - * An object is "enumerated" when it's the target of a for-in loop or - * JS_Enumerate(). The callback's job is to populate 'properties' with the - * object's property keys. If `enumerableOnly` is true, the callback should only - * add enumerable properties. - */ -typedef bool -(* JSNewEnumerateOp)(JSContext* cx, JS::HandleObject obj, JS::AutoIdVector& properties, - bool enumerableOnly); - -/** - * The old-style JSClass.enumerate op should define all lazy properties not - * yet reflected in obj. - */ -typedef bool -(* JSEnumerateOp)(JSContext* cx, JS::HandleObject obj); - -/** - * The type of ObjectOps::funToString. This callback allows an object to - * provide a custom string to use when Function.prototype.toString is invoked on - * that object. A null return value means OOM. - */ -typedef JSString* -(* JSFunToStringOp)(JSContext* cx, JS::HandleObject obj, unsigned indent); - -/** - * Resolve a lazy property named by id in obj by defining it directly in obj. - * Lazy properties are those reflected from some peer native property space - * (e.g., the DOM attributes for a given node reflected as obj) on demand. - * - * JS looks for a property in an object, and if not found, tries to resolve - * the given id. *resolvedp should be set to true iff the property was defined - * on |obj|. - */ -typedef bool -(* JSResolveOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - bool* resolvedp); - -/** - * A class with a resolve hook can optionally have a mayResolve hook. This hook - * must have no side effects and must return true for a given id if the resolve - * hook may resolve this id. This is useful when we're doing a "pure" lookup: if - * mayResolve returns false, we know we don't have to call the effectful resolve - * hook. - * - * maybeObj, if non-null, is the object on which we're doing the lookup. This - * can be nullptr: during JIT compilation we sometimes know the Class but not - * the object. - */ -typedef bool -(* JSMayResolveOp)(const JSAtomState& names, jsid id, JSObject* maybeObj); - -/** - * Finalize obj, which the garbage collector has determined to be unreachable - * from other live objects or from GC roots. Obviously, finalizers must never - * store a reference to obj. - */ -typedef void -(* JSFinalizeOp)(JSFreeOp* fop, JSObject* obj); - -/** Finalizes external strings created by JS_NewExternalString. */ -struct JSStringFinalizer { - void (*finalize)(JS::Zone* zone, const JSStringFinalizer* fin, char16_t* chars); -}; - -/** - * Check whether v is an instance of obj. Return false on error or exception, - * true on success with true in *bp if v is an instance of obj, false in - * *bp otherwise. - */ -typedef bool -(* JSHasInstanceOp)(JSContext* cx, JS::HandleObject obj, JS::MutableHandleValue vp, - bool* bp); - -/** - * Function type for trace operation of the class called to enumerate all - * traceable things reachable from obj's private data structure. For each such - * thing, a trace implementation must call JS::TraceEdge on the thing's - * location. - * - * JSTraceOp implementation can assume that no other threads mutates object - * state. It must not change state of the object or corresponding native - * structures. The only exception for this rule is the case when the embedding - * needs a tight integration with GC. In that case the embedding can check if - * the traversal is a part of the marking phase through calling - * JS_IsGCMarkingTracer and apply a special code like emptying caches or - * marking its native structures. - */ -typedef void -(* JSTraceOp)(JSTracer* trc, JSObject* obj); - -typedef JSObject* -(* JSWeakmapKeyDelegateOp)(JSObject* obj); - -typedef void -(* JSObjectMovedOp)(JSObject* obj, const JSObject* old); - -/* js::Class operation signatures. */ - -namespace js { - -typedef bool -(* LookupPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleObject objp, JS::MutableHandle propp); -typedef bool -(* DefinePropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::Handle desc, - JS::ObjectOpResult& result); -typedef bool -(* HasPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp); -typedef bool -(* GetPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleValue receiver, JS::HandleId id, - JS::MutableHandleValue vp); -typedef bool -(* SetPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v, - JS::HandleValue receiver, JS::ObjectOpResult& result); -typedef bool -(* GetOwnPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandle desc); -typedef bool -(* DeletePropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::ObjectOpResult& result); - -typedef bool -(* WatchOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable); - -typedef bool -(* UnwatchOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id); - -class JS_FRIEND_API(ElementAdder) -{ - public: - enum GetBehavior { - // Check if the element exists before performing the Get and preserve - // holes. - CheckHasElemPreserveHoles, - - // Perform a Get operation, like obj[index] in JS. - GetElement - }; - - private: - // Only one of these is used. - JS::RootedObject resObj_; - JS::Value* vp_; - - uint32_t index_; -#ifdef DEBUG - uint32_t length_; -#endif - GetBehavior getBehavior_; - - public: - ElementAdder(JSContext* cx, JSObject* obj, uint32_t length, GetBehavior behavior) - : resObj_(cx, obj), vp_(nullptr), index_(0), -#ifdef DEBUG - length_(length), -#endif - getBehavior_(behavior) - {} - ElementAdder(JSContext* cx, JS::Value* vp, uint32_t length, GetBehavior behavior) - : resObj_(cx), vp_(vp), index_(0), -#ifdef DEBUG - length_(length), -#endif - getBehavior_(behavior) - {} - - GetBehavior getBehavior() const { return getBehavior_; } - - bool append(JSContext* cx, JS::HandleValue v); - void appendHole(); -}; - -typedef bool -(* GetElementsOp)(JSContext* cx, JS::HandleObject obj, uint32_t begin, uint32_t end, - ElementAdder* adder); - -typedef void -(* FinalizeOp)(FreeOp* fop, JSObject* obj); - -// The special treatment of |finalize| and |trace| is necessary because if we -// assign either of those hooks to a local variable and then call it -- as is -// done with the other hooks -- the GC hazard analysis gets confused. -#define JS_CLASS_MEMBERS(ClassOpsType, FreeOpType) \ - const char* name; \ - uint32_t flags; \ - const ClassOpsType* cOps; \ - \ - JSAddPropertyOp getAddProperty() const { return cOps ? cOps->addProperty : nullptr; } \ - JSDeletePropertyOp getDelProperty() const { return cOps ? cOps->delProperty : nullptr; } \ - JSGetterOp getGetProperty() const { return cOps ? cOps->getProperty : nullptr; } \ - JSSetterOp getSetProperty() const { return cOps ? cOps->setProperty : nullptr; } \ - JSEnumerateOp getEnumerate() const { return cOps ? cOps->enumerate : nullptr; } \ - JSResolveOp getResolve() const { return cOps ? cOps->resolve : nullptr; } \ - JSMayResolveOp getMayResolve() const { return cOps ? cOps->mayResolve : nullptr; } \ - JSNative getCall() const { return cOps ? cOps->call : nullptr; } \ - JSHasInstanceOp getHasInstance() const { return cOps ? cOps->hasInstance : nullptr; } \ - JSNative getConstruct() const { return cOps ? cOps->construct : nullptr; } \ - \ - bool hasFinalize() const { return cOps && cOps->finalize; } \ - bool hasTrace() const { return cOps && cOps->trace; } \ - \ - bool isTrace(JSTraceOp trace) const { return cOps && cOps->trace == trace; } \ - \ - void doFinalize(FreeOpType* fop, JSObject* obj) const { \ - MOZ_ASSERT(cOps && cOps->finalize); \ - cOps->finalize(fop, obj); \ - } \ - void doTrace(JSTracer* trc, JSObject* obj) const { \ - MOZ_ASSERT(cOps && cOps->trace); \ - cOps->trace(trc, obj); \ - } - -struct ClassOps -{ - /* Function pointer members (may be null). */ - JSAddPropertyOp addProperty; - JSDeletePropertyOp delProperty; - JSGetterOp getProperty; - JSSetterOp setProperty; - JSEnumerateOp enumerate; - JSResolveOp resolve; - JSMayResolveOp mayResolve; - FinalizeOp finalize; - JSNative call; - JSHasInstanceOp hasInstance; - JSNative construct; - JSTraceOp trace; -}; - -/** Callback for the creation of constructor and prototype objects. */ -typedef JSObject* (*ClassObjectCreationOp)(JSContext* cx, JSProtoKey key); - -/** Callback for custom post-processing after class initialization via ClassSpec. */ -typedef bool (*FinishClassInitOp)(JSContext* cx, JS::HandleObject ctor, - JS::HandleObject proto); - -const size_t JSCLASS_CACHED_PROTO_WIDTH = 6; - -struct ClassSpec -{ - // All properties except flags should be accessed through accessor. - ClassObjectCreationOp createConstructor_; - ClassObjectCreationOp createPrototype_; - const JSFunctionSpec* constructorFunctions_; - const JSPropertySpec* constructorProperties_; - const JSFunctionSpec* prototypeFunctions_; - const JSPropertySpec* prototypeProperties_; - FinishClassInitOp finishInit_; - uintptr_t flags; - - static const size_t ProtoKeyWidth = JSCLASS_CACHED_PROTO_WIDTH; - - static const uintptr_t ProtoKeyMask = (1 << ProtoKeyWidth) - 1; - static const uintptr_t DontDefineConstructor = 1 << ProtoKeyWidth; - static const uintptr_t IsDelegated = 1 << (ProtoKeyWidth + 1); - - bool defined() const { return !!createConstructor_; } - - bool delegated() const { - return (flags & IsDelegated); - } - - // The ProtoKey this class inherits from. - JSProtoKey inheritanceProtoKey() const { - MOZ_ASSERT(defined()); - static_assert(JSProto_Null == 0, "zeroed key must be null"); - - // Default: Inherit from Object. - if (!(flags & ProtoKeyMask)) - return JSProto_Object; - - return JSProtoKey(flags & ProtoKeyMask); - } - - bool shouldDefineConstructor() const { - MOZ_ASSERT(defined()); - return !(flags & DontDefineConstructor); - } - - const ClassSpec* delegatedClassSpec() const { - MOZ_ASSERT(delegated()); - return reinterpret_cast(createConstructor_); - } - - ClassObjectCreationOp createConstructorHook() const { - if (delegated()) - return delegatedClassSpec()->createConstructorHook(); - return createConstructor_; - } - ClassObjectCreationOp createPrototypeHook() const { - if (delegated()) - return delegatedClassSpec()->createPrototypeHook(); - return createPrototype_; - } - const JSFunctionSpec* constructorFunctions() const { - if (delegated()) - return delegatedClassSpec()->constructorFunctions(); - return constructorFunctions_; - } - const JSPropertySpec* constructorProperties() const { - if (delegated()) - return delegatedClassSpec()->constructorProperties(); - return constructorProperties_; - } - const JSFunctionSpec* prototypeFunctions() const { - if (delegated()) - return delegatedClassSpec()->prototypeFunctions(); - return prototypeFunctions_; - } - const JSPropertySpec* prototypeProperties() const { - if (delegated()) - return delegatedClassSpec()->prototypeProperties(); - return prototypeProperties_; - } - FinishClassInitOp finishInitHook() const { - if (delegated()) - return delegatedClassSpec()->finishInitHook(); - return finishInit_; - } -}; - -struct ClassExtension -{ - /** - * If an object is used as a key in a weakmap, it may be desirable for the - * garbage collector to keep that object around longer than it otherwise - * would. A common case is when the key is a wrapper around an object in - * another compartment, and we want to avoid collecting the wrapper (and - * removing the weakmap entry) as long as the wrapped object is alive. In - * that case, the wrapped object is returned by the wrapper's - * weakmapKeyDelegateOp hook. As long as the wrapper is used as a weakmap - * key, it will not be collected (and remain in the weakmap) until the - * wrapped object is collected. - */ - JSWeakmapKeyDelegateOp weakmapKeyDelegateOp; - - /** - * Optional hook called when an object is moved by a compacting GC. - * - * There may exist weak pointers to an object that are not traced through - * when the normal trace APIs are used, for example objects in the wrapper - * cache. This hook allows these pointers to be updated. - * - * Note that this hook can be called before JS_NewObject() returns if a GC - * is triggered during construction of the object. This can happen for - * global objects for example. - */ - JSObjectMovedOp objectMovedOp; -}; - -inline ClassObjectCreationOp DELEGATED_CLASSSPEC(const ClassSpec* spec) { - return reinterpret_cast(const_cast(spec)); -} - -#define JS_NULL_CLASS_SPEC nullptr -#define JS_NULL_CLASS_EXT nullptr - -struct ObjectOps -{ - LookupPropertyOp lookupProperty; - DefinePropertyOp defineProperty; - HasPropertyOp hasProperty; - GetPropertyOp getProperty; - SetPropertyOp setProperty; - GetOwnPropertyOp getOwnPropertyDescriptor; - DeletePropertyOp deleteProperty; - WatchOp watch; - UnwatchOp unwatch; - GetElementsOp getElements; - JSNewEnumerateOp enumerate; - JSFunToStringOp funToString; -}; - -#define JS_NULL_OBJECT_OPS nullptr - -} // namespace js - -// Classes, objects, and properties. - -typedef void (*JSClassInternal)(); - -struct JSClassOps -{ - /* Function pointer members (may be null). */ - JSAddPropertyOp addProperty; - JSDeletePropertyOp delProperty; - JSGetterOp getProperty; - JSSetterOp setProperty; - JSEnumerateOp enumerate; - JSResolveOp resolve; - JSMayResolveOp mayResolve; - JSFinalizeOp finalize; - JSNative call; - JSHasInstanceOp hasInstance; - JSNative construct; - JSTraceOp trace; -}; - -#define JS_NULL_CLASS_OPS nullptr - -struct JSClass { - JS_CLASS_MEMBERS(JSClassOps, JSFreeOp); - - void* reserved[3]; -}; - -#define JSCLASS_HAS_PRIVATE (1<<0) // objects have private slot -#define JSCLASS_DELAY_METADATA_BUILDER (1<<1) // class's initialization code - // will call - // SetNewObjectMetadata itself -#define JSCLASS_IS_WRAPPED_NATIVE (1<<2) // class is an XPCWrappedNative. - // WeakMaps use this to override - // the wrapper disposal - // mechanism. -#define JSCLASS_PRIVATE_IS_NSISUPPORTS (1<<3) // private is (nsISupports*) -#define JSCLASS_IS_DOMJSCLASS (1<<4) // objects are DOM -#define JSCLASS_HAS_XRAYED_CONSTRUCTOR (1<<5) // if wrapped by an xray - // wrapper, the builtin - // class's constructor won't - // be unwrapped and invoked. - // Instead, the constructor is - // resolved in the caller's - // compartment and invoked - // with a wrapped newTarget. - // The constructor has to - // detect and handle this - // situation. - // See PromiseConstructor for - // details. -#define JSCLASS_EMULATES_UNDEFINED (1<<6) // objects of this class act - // like the value undefined, - // in some contexts -#define JSCLASS_USERBIT1 (1<<7) // Reserved for embeddings. - -// To reserve slots fetched and stored via JS_Get/SetReservedSlot, bitwise-or -// JSCLASS_HAS_RESERVED_SLOTS(n) into the initializer for JSClass.flags, where -// n is a constant in [1, 255]. Reserved slots are indexed from 0 to n-1. -#define JSCLASS_RESERVED_SLOTS_SHIFT 8 // room for 8 flags below */ -#define JSCLASS_RESERVED_SLOTS_WIDTH 8 // and 16 above this field */ -#define JSCLASS_RESERVED_SLOTS_MASK JS_BITMASK(JSCLASS_RESERVED_SLOTS_WIDTH) -#define JSCLASS_HAS_RESERVED_SLOTS(n) (((n) & JSCLASS_RESERVED_SLOTS_MASK) \ - << JSCLASS_RESERVED_SLOTS_SHIFT) -#define JSCLASS_RESERVED_SLOTS(clasp) (((clasp)->flags \ - >> JSCLASS_RESERVED_SLOTS_SHIFT) \ - & JSCLASS_RESERVED_SLOTS_MASK) - -#define JSCLASS_HIGH_FLAGS_SHIFT (JSCLASS_RESERVED_SLOTS_SHIFT + \ - JSCLASS_RESERVED_SLOTS_WIDTH) - -#define JSCLASS_IS_ANONYMOUS (1<<(JSCLASS_HIGH_FLAGS_SHIFT+0)) -#define JSCLASS_IS_GLOBAL (1<<(JSCLASS_HIGH_FLAGS_SHIFT+1)) -#define JSCLASS_INTERNAL_FLAG2 (1<<(JSCLASS_HIGH_FLAGS_SHIFT+2)) -#define JSCLASS_INTERNAL_FLAG3 (1<<(JSCLASS_HIGH_FLAGS_SHIFT+3)) - -#define JSCLASS_IS_PROXY (1<<(JSCLASS_HIGH_FLAGS_SHIFT+4)) - -#define JSCLASS_SKIP_NURSERY_FINALIZE (1<<(JSCLASS_HIGH_FLAGS_SHIFT+5)) - -// Reserved for embeddings. -#define JSCLASS_USERBIT2 (1<<(JSCLASS_HIGH_FLAGS_SHIFT+6)) -#define JSCLASS_USERBIT3 (1<<(JSCLASS_HIGH_FLAGS_SHIFT+7)) - -#define JSCLASS_BACKGROUND_FINALIZE (1<<(JSCLASS_HIGH_FLAGS_SHIFT+8)) -#define JSCLASS_FOREGROUND_FINALIZE (1<<(JSCLASS_HIGH_FLAGS_SHIFT+9)) - -// Bits 26 through 31 are reserved for the CACHED_PROTO_KEY mechanism, see -// below. - -// ECMA-262 requires that most constructors used internally create objects -// with "the original Foo.prototype value" as their [[Prototype]] (__proto__) -// member initial value. The "original ... value" verbiage is there because -// in ECMA-262, global properties naming class objects are read/write and -// deleteable, for the most part. -// -// Implementing this efficiently requires that global objects have classes -// with the following flags. Failure to use JSCLASS_GLOBAL_FLAGS was -// previously allowed, but is now an ES5 violation and thus unsupported. -// -// JSCLASS_GLOBAL_APPLICATION_SLOTS is the number of slots reserved at -// the beginning of every global object's slots for use by the -// application. -#define JSCLASS_GLOBAL_APPLICATION_SLOTS 5 -#define JSCLASS_GLOBAL_SLOT_COUNT \ - (JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 39) -#define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \ - (JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n))) -#define JSCLASS_GLOBAL_FLAGS \ - JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(0) -#define JSCLASS_HAS_GLOBAL_FLAG_AND_SLOTS(clasp) \ - (((clasp)->flags & JSCLASS_IS_GLOBAL) \ - && JSCLASS_RESERVED_SLOTS(clasp) >= JSCLASS_GLOBAL_SLOT_COUNT) - -// Fast access to the original value of each standard class's prototype. -#define JSCLASS_CACHED_PROTO_SHIFT (JSCLASS_HIGH_FLAGS_SHIFT + 10) -#define JSCLASS_CACHED_PROTO_MASK JS_BITMASK(js::JSCLASS_CACHED_PROTO_WIDTH) -#define JSCLASS_HAS_CACHED_PROTO(key) (uint32_t(key) << JSCLASS_CACHED_PROTO_SHIFT) -#define JSCLASS_CACHED_PROTO_KEY(clasp) ((JSProtoKey) \ - (((clasp)->flags \ - >> JSCLASS_CACHED_PROTO_SHIFT) \ - & JSCLASS_CACHED_PROTO_MASK)) - -// Initializer for unused members of statically initialized JSClass structs. -#define JSCLASS_NO_INTERNAL_MEMBERS {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} -#define JSCLASS_NO_OPTIONAL_MEMBERS 0,0,0,0,0,JSCLASS_NO_INTERNAL_MEMBERS - -namespace js { - -struct Class -{ - JS_CLASS_MEMBERS(js::ClassOps, FreeOp); - const ClassSpec* spec; - const ClassExtension* ext; - const ObjectOps* oOps; - - /* - * Objects of this class aren't native objects. They don't have Shapes that - * describe their properties and layout. Classes using this flag must - * provide their own property behavior, either by being proxy classes (do - * this) or by overriding all the ObjectOps except getElements, watch and - * unwatch (don't do this). - */ - static const uint32_t NON_NATIVE = JSCLASS_INTERNAL_FLAG2; - - bool isNative() const { - return !(flags & NON_NATIVE); - } - - bool hasPrivate() const { - return !!(flags & JSCLASS_HAS_PRIVATE); - } - - bool emulatesUndefined() const { - return flags & JSCLASS_EMULATES_UNDEFINED; - } - - bool isJSFunction() const { - return this == js::FunctionClassPtr; - } - - bool nonProxyCallable() const { - MOZ_ASSERT(!isProxy()); - return isJSFunction() || getCall(); - } - - bool isProxy() const { - return flags & JSCLASS_IS_PROXY; - } - - bool isDOMClass() const { - return flags & JSCLASS_IS_DOMJSCLASS; - } - - bool shouldDelayMetadataBuilder() const { - return flags & JSCLASS_DELAY_METADATA_BUILDER; - } - - bool isWrappedNative() const { - return flags & JSCLASS_IS_WRAPPED_NATIVE; - } - - static size_t offsetOfFlags() { return offsetof(Class, flags); } - - bool specDefined() const { return spec ? spec->defined() : false; } - JSProtoKey specInheritanceProtoKey() - const { return spec ? spec->inheritanceProtoKey() : JSProto_Null; } - bool specShouldDefineConstructor() - const { return spec ? spec->shouldDefineConstructor() : true; } - ClassObjectCreationOp specCreateConstructorHook() - const { return spec ? spec->createConstructorHook() : nullptr; } - ClassObjectCreationOp specCreatePrototypeHook() - const { return spec ? spec->createPrototypeHook() : nullptr; } - const JSFunctionSpec* specConstructorFunctions() - const { return spec ? spec->constructorFunctions() : nullptr; } - const JSPropertySpec* specConstructorProperties() - const { return spec ? spec->constructorProperties() : nullptr; } - const JSFunctionSpec* specPrototypeFunctions() - const { return spec ? spec->prototypeFunctions() : nullptr; } - const JSPropertySpec* specPrototypeProperties() - const { return spec ? spec->prototypeProperties() : nullptr; } - FinishClassInitOp specFinishInitHook() - const { return spec ? spec->finishInitHook() : nullptr; } - - JSWeakmapKeyDelegateOp extWeakmapKeyDelegateOp() - const { return ext ? ext->weakmapKeyDelegateOp : nullptr; } - JSObjectMovedOp extObjectMovedOp() - const { return ext ? ext->objectMovedOp : nullptr; } - - LookupPropertyOp getOpsLookupProperty() const { return oOps ? oOps->lookupProperty : nullptr; } - DefinePropertyOp getOpsDefineProperty() const { return oOps ? oOps->defineProperty : nullptr; } - HasPropertyOp getOpsHasProperty() const { return oOps ? oOps->hasProperty : nullptr; } - GetPropertyOp getOpsGetProperty() const { return oOps ? oOps->getProperty : nullptr; } - SetPropertyOp getOpsSetProperty() const { return oOps ? oOps->setProperty : nullptr; } - GetOwnPropertyOp getOpsGetOwnPropertyDescriptor() - const { return oOps ? oOps->getOwnPropertyDescriptor - : nullptr; } - DeletePropertyOp getOpsDeleteProperty() const { return oOps ? oOps->deleteProperty : nullptr; } - WatchOp getOpsWatch() const { return oOps ? oOps->watch : nullptr; } - UnwatchOp getOpsUnwatch() const { return oOps ? oOps->unwatch : nullptr; } - GetElementsOp getOpsGetElements() const { return oOps ? oOps->getElements : nullptr; } - JSNewEnumerateOp getOpsEnumerate() const { return oOps ? oOps->enumerate : nullptr; } - JSFunToStringOp getOpsFunToString() const { return oOps ? oOps->funToString : nullptr; } -}; - -static_assert(offsetof(JSClassOps, addProperty) == offsetof(ClassOps, addProperty), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, delProperty) == offsetof(ClassOps, delProperty), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, getProperty) == offsetof(ClassOps, getProperty), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, setProperty) == offsetof(ClassOps, setProperty), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, enumerate) == offsetof(ClassOps, enumerate), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, resolve) == offsetof(ClassOps, resolve), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, mayResolve) == offsetof(ClassOps, mayResolve), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, finalize) == offsetof(ClassOps, finalize), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, call) == offsetof(ClassOps, call), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, construct) == offsetof(ClassOps, construct), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, hasInstance) == offsetof(ClassOps, hasInstance), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, trace) == offsetof(ClassOps, trace), - "ClassOps and JSClassOps must be consistent"); -static_assert(sizeof(JSClassOps) == sizeof(ClassOps), - "ClassOps and JSClassOps must be consistent"); - -static_assert(offsetof(JSClass, name) == offsetof(Class, name), - "Class and JSClass must be consistent"); -static_assert(offsetof(JSClass, flags) == offsetof(Class, flags), - "Class and JSClass must be consistent"); -static_assert(offsetof(JSClass, cOps) == offsetof(Class, cOps), - "Class and JSClass must be consistent"); -static_assert(sizeof(JSClass) == sizeof(Class), - "Class and JSClass must be consistent"); - -static MOZ_ALWAYS_INLINE const JSClass* -Jsvalify(const Class* c) -{ - return (const JSClass*)c; -} - -static MOZ_ALWAYS_INLINE const Class* -Valueify(const JSClass* c) -{ - return (const Class*)c; -} - -/** - * Enumeration describing possible values of the [[Class]] internal property - * value of objects. - */ -enum class ESClass { - Object, - Array, - Number, - String, - Boolean, - RegExp, - ArrayBuffer, - SharedArrayBuffer, - Date, - Set, - Map, - Promise, - MapIterator, - SetIterator, - Arguments, - Error, - - /** None of the above. */ - Other -}; - -/* Fills |vp| with the unboxed value for boxed types, or undefined otherwise. */ -bool -Unbox(JSContext* cx, JS::HandleObject obj, JS::MutableHandleValue vp); - -#ifdef DEBUG -JS_FRIEND_API(bool) -HasObjectMovedOp(JSObject* obj); -#endif - -} /* namespace js */ - -#endif /* js_Class_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/Conversions.h b/android/arm64-v8a/include/spidermonkey/js/Conversions.h deleted file mode 100644 index 1cee31c5..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/Conversions.h +++ /dev/null @@ -1,581 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* ECMAScript conversion operations. */ - -#ifndef js_Conversions_h -#define js_Conversions_h - -#include "mozilla/Casting.h" -#include "mozilla/FloatingPoint.h" -#include "mozilla/TypeTraits.h" - -#include - -#include "jspubtd.h" - -#include "js/RootingAPI.h" -#include "js/Value.h" - -struct JSContext; - -namespace js { - -/* DO NOT CALL THIS. Use JS::ToBoolean. */ -extern JS_PUBLIC_API(bool) -ToBooleanSlow(JS::HandleValue v); - -/* DO NOT CALL THIS. Use JS::ToNumber. */ -extern JS_PUBLIC_API(bool) -ToNumberSlow(JSContext* cx, JS::HandleValue v, double* dp); - -/* DO NOT CALL THIS. Use JS::ToInt8. */ -extern JS_PUBLIC_API(bool) -ToInt8Slow(JSContext *cx, JS::HandleValue v, int8_t *out); - -/* DO NOT CALL THIS. Use JS::ToUint8. */ -extern JS_PUBLIC_API(bool) -ToUint8Slow(JSContext *cx, JS::HandleValue v, uint8_t *out); - -/* DO NOT CALL THIS. Use JS::ToInt16. */ -extern JS_PUBLIC_API(bool) -ToInt16Slow(JSContext *cx, JS::HandleValue v, int16_t *out); - -/* DO NOT CALL THIS. Use JS::ToInt32. */ -extern JS_PUBLIC_API(bool) -ToInt32Slow(JSContext* cx, JS::HandleValue v, int32_t* out); - -/* DO NOT CALL THIS. Use JS::ToUint32. */ -extern JS_PUBLIC_API(bool) -ToUint32Slow(JSContext* cx, JS::HandleValue v, uint32_t* out); - -/* DO NOT CALL THIS. Use JS::ToUint16. */ -extern JS_PUBLIC_API(bool) -ToUint16Slow(JSContext* cx, JS::HandleValue v, uint16_t* out); - -/* DO NOT CALL THIS. Use JS::ToInt64. */ -extern JS_PUBLIC_API(bool) -ToInt64Slow(JSContext* cx, JS::HandleValue v, int64_t* out); - -/* DO NOT CALL THIS. Use JS::ToUint64. */ -extern JS_PUBLIC_API(bool) -ToUint64Slow(JSContext* cx, JS::HandleValue v, uint64_t* out); - -/* DO NOT CALL THIS. Use JS::ToString. */ -extern JS_PUBLIC_API(JSString*) -ToStringSlow(JSContext* cx, JS::HandleValue v); - -/* DO NOT CALL THIS. Use JS::ToObject. */ -extern JS_PUBLIC_API(JSObject*) -ToObjectSlow(JSContext* cx, JS::HandleValue v, bool reportScanStack); - -} // namespace js - -namespace JS { - -namespace detail { - -#ifdef JS_DEBUG -/** - * Assert that we're not doing GC on cx, that we're in a request as - * needed, and that the compartments for cx and v are correct. - * Also check that GC would be safe at this point. - */ -extern JS_PUBLIC_API(void) -AssertArgumentsAreSane(JSContext* cx, HandleValue v); -#else -inline void AssertArgumentsAreSane(JSContext* cx, HandleValue v) -{} -#endif /* JS_DEBUG */ - -} // namespace detail - -/** - * ES6 draft 20141224, 7.1.1, second algorithm. - * - * Most users shouldn't call this -- use JS::ToBoolean, ToNumber, or ToString - * instead. This will typically only be called from custom convert hooks that - * wish to fall back to the ES6 default conversion behavior shared by most - * objects in JS, codified as OrdinaryToPrimitive. - */ -extern JS_PUBLIC_API(bool) -OrdinaryToPrimitive(JSContext* cx, HandleObject obj, JSType type, MutableHandleValue vp); - -/* ES6 draft 20141224, 7.1.2. */ -MOZ_ALWAYS_INLINE bool -ToBoolean(HandleValue v) -{ - if (v.isBoolean()) - return v.toBoolean(); - if (v.isInt32()) - return v.toInt32() != 0; - if (v.isNullOrUndefined()) - return false; - if (v.isDouble()) { - double d = v.toDouble(); - return !mozilla::IsNaN(d) && d != 0; - } - if (v.isSymbol()) - return true; - - /* The slow path handles strings and objects. */ - return js::ToBooleanSlow(v); -} - -/* ES6 draft 20141224, 7.1.3. */ -MOZ_ALWAYS_INLINE bool -ToNumber(JSContext* cx, HandleValue v, double* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isNumber()) { - *out = v.toNumber(); - return true; - } - return js::ToNumberSlow(cx, v, out); -} - -/* ES6 draft 20141224, ToInteger (specialized for doubles). */ -inline double -ToInteger(double d) -{ - if (d == 0) - return d; - - if (!mozilla::IsFinite(d)) { - if (mozilla::IsNaN(d)) - return 0; - return d; - } - - return d < 0 ? ceil(d) : floor(d); -} - -/* ES6 draft 20141224, 7.1.5. */ -MOZ_ALWAYS_INLINE bool -ToInt32(JSContext* cx, JS::HandleValue v, int32_t* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = v.toInt32(); - return true; - } - return js::ToInt32Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.6. */ -MOZ_ALWAYS_INLINE bool -ToUint32(JSContext* cx, HandleValue v, uint32_t* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = uint32_t(v.toInt32()); - return true; - } - return js::ToUint32Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.7. */ -MOZ_ALWAYS_INLINE bool -ToInt16(JSContext *cx, JS::HandleValue v, int16_t *out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = int16_t(v.toInt32()); - return true; - } - return js::ToInt16Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.8. */ -MOZ_ALWAYS_INLINE bool -ToUint16(JSContext* cx, HandleValue v, uint16_t* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = uint16_t(v.toInt32()); - return true; - } - return js::ToUint16Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.9 */ -MOZ_ALWAYS_INLINE bool -ToInt8(JSContext *cx, JS::HandleValue v, int8_t *out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = int8_t(v.toInt32()); - return true; - } - return js::ToInt8Slow(cx, v, out); -} - -/* ES6 ECMA-262, 7.1.10 */ -MOZ_ALWAYS_INLINE bool -ToUint8(JSContext *cx, JS::HandleValue v, uint8_t *out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = uint8_t(v.toInt32()); - return true; - } - return js::ToUint8Slow(cx, v, out); -} - -/* - * Non-standard, with behavior similar to that of ToInt32, except in its - * producing an int64_t. - */ -MOZ_ALWAYS_INLINE bool -ToInt64(JSContext* cx, HandleValue v, int64_t* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = int64_t(v.toInt32()); - return true; - } - return js::ToInt64Slow(cx, v, out); -} - -/* - * Non-standard, with behavior similar to that of ToUint32, except in its - * producing a uint64_t. - */ -MOZ_ALWAYS_INLINE bool -ToUint64(JSContext* cx, HandleValue v, uint64_t* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = uint64_t(v.toInt32()); - return true; - } - return js::ToUint64Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.12. */ -MOZ_ALWAYS_INLINE JSString* -ToString(JSContext* cx, HandleValue v) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isString()) - return v.toString(); - return js::ToStringSlow(cx, v); -} - -/* ES6 draft 20141224, 7.1.13. */ -inline JSObject* -ToObject(JSContext* cx, HandleValue v) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isObject()) - return &v.toObject(); - return js::ToObjectSlow(cx, v, false); -} - -namespace detail { - -/* - * Convert a double value to ResultType (an unsigned integral type) using - * ECMAScript-style semantics (that is, in like manner to how ECMAScript's - * ToInt32 converts to int32_t). - * - * If d is infinite or NaN, return 0. - * Otherwise compute d2 = sign(d) * floor(abs(d)), and return the ResultType - * value congruent to d2 mod 2**(bit width of ResultType). - * - * The algorithm below is inspired by that found in - * - * but has been generalized to all integer widths. - */ -template -inline ResultType -ToUintWidth(double d) -{ - static_assert(mozilla::IsUnsigned::value, - "ResultType must be an unsigned type"); - - uint64_t bits = mozilla::BitwiseCast(d); - unsigned DoubleExponentShift = mozilla::FloatingPoint::kExponentShift; - - // Extract the exponent component. (Be careful here! It's not technically - // the exponent in NaN, infinities, and subnormals.) - int_fast16_t exp = - int_fast16_t((bits & mozilla::FloatingPoint::kExponentBits) >> DoubleExponentShift) - - int_fast16_t(mozilla::FloatingPoint::kExponentBias); - - // If the exponent's less than zero, abs(d) < 1, so the result is 0. (This - // also handles subnormals.) - if (exp < 0) - return 0; - - uint_fast16_t exponent = mozilla::AssertedCast(exp); - - // If the exponent is greater than or equal to the bits of precision of a - // double plus ResultType's width, the number is either infinite, NaN, or - // too large to have lower-order bits in the congruent value. (Example: - // 2**84 is exactly representable as a double. The next exact double is - // 2**84 + 2**32. Thus if ResultType is int32_t, an exponent >= 84 implies - // floor(abs(d)) == 0 mod 2**32.) Return 0 in all these cases. - const size_t ResultWidth = CHAR_BIT * sizeof(ResultType); - if (exponent >= DoubleExponentShift + ResultWidth) - return 0; - - // The significand contains the bits that will determine the final result. - // Shift those bits left or right, according to the exponent, to their - // locations in the unsigned binary representation of floor(abs(d)). - static_assert(sizeof(ResultType) <= sizeof(uint64_t), - "Left-shifting below would lose upper bits"); - ResultType result = (exponent > DoubleExponentShift) - ? ResultType(bits << (exponent - DoubleExponentShift)) - : ResultType(bits >> (DoubleExponentShift - exponent)); - - // Two further complications remain. First, |result| may contain bogus - // sign/exponent bits. Second, IEEE-754 numbers' significands (excluding - // subnormals, but we already handled those) have an implicit leading 1 - // which may affect the final result. - // - // It may appear that there's complexity here depending on how ResultWidth - // and DoubleExponentShift relate, but it turns out there's not. - // - // Assume ResultWidth < DoubleExponentShift: - // Only right-shifts leave bogus bits in |result|. For this to happen, - // we must right-shift by > |DoubleExponentShift - ResultWidth|, implying - // |exponent < ResultWidth|. - // The implicit leading bit only matters if it appears in the final - // result -- if |2**exponent mod 2**ResultWidth != 0|. This implies - // |exponent < ResultWidth|. - // Otherwise assume ResultWidth >= DoubleExponentShift: - // Any left-shift less than |ResultWidth - DoubleExponentShift| leaves - // bogus bits in |result|. This implies |exponent < ResultWidth|. Any - // right-shift less than |ResultWidth| does too, which implies - // |DoubleExponentShift - ResultWidth < exponent|. By assumption, then, - // |exponent| is negative, but we excluded that above. So bogus bits - // need only |exponent < ResultWidth|. - // The implicit leading bit matters identically to the other case, so - // again, |exponent < ResultWidth|. - if (exponent < ResultWidth) { - ResultType implicitOne = ResultType(1) << exponent; - result &= implicitOne - 1; // remove bogus bits - result += implicitOne; // add the implicit bit - } - - // Compute the congruent value in the signed range. - return (bits & mozilla::FloatingPoint::kSignBit) ? ~result + 1 : result; -} - -template -inline ResultType -ToIntWidth(double d) -{ - static_assert(mozilla::IsSigned::value, - "ResultType must be a signed type"); - - const ResultType MaxValue = (1ULL << (CHAR_BIT * sizeof(ResultType) - 1)) - 1; - const ResultType MinValue = -MaxValue - 1; - - typedef typename mozilla::MakeUnsigned::Type UnsignedResult; - UnsignedResult u = ToUintWidth(d); - if (u <= UnsignedResult(MaxValue)) - return static_cast(u); - return (MinValue + static_cast(u - MaxValue)) - 1; -} - -} // namespace detail - -/* ES5 9.5 ToInt32 (specialized for doubles). */ -inline int32_t -ToInt32(double d) -{ - // clang crashes compiling this when targeting arm: - // https://llvm.org/bugs/show_bug.cgi?id=22974 -#if defined (__arm__) && defined (__GNUC__) && !defined(__clang__) - int32_t i; - uint32_t tmp0; - uint32_t tmp1; - uint32_t tmp2; - asm ( - // We use a pure integer solution here. In the 'softfp' ABI, the argument - // will start in r0 and r1, and VFP can't do all of the necessary ECMA - // conversions by itself so some integer code will be required anyway. A - // hybrid solution is faster on A9, but this pure integer solution is - // notably faster for A8. - - // %0 is the result register, and may alias either of the %[QR]1 registers. - // %Q4 holds the lower part of the mantissa. - // %R4 holds the sign, exponent, and the upper part of the mantissa. - // %1, %2 and %3 are used as temporary values. - - // Extract the exponent. -" mov %1, %R4, LSR #20\n" -" bic %1, %1, #(1 << 11)\n" // Clear the sign. - - // Set the implicit top bit of the mantissa. This clobbers a bit of the - // exponent, but we have already extracted that. -" orr %R4, %R4, #(1 << 20)\n" - - // Special Cases - // We should return zero in the following special cases: - // - Exponent is 0x000 - 1023: +/-0 or subnormal. - // - Exponent is 0x7ff - 1023: +/-INFINITY or NaN - // - This case is implicitly handled by the standard code path anyway, - // as shifting the mantissa up by the exponent will result in '0'. - // - // The result is composed of the mantissa, prepended with '1' and - // bit-shifted left by the (decoded) exponent. Note that because the r1[20] - // is the bit with value '1', r1 is effectively already shifted (left) by - // 20 bits, and r0 is already shifted by 52 bits. - - // Adjust the exponent to remove the encoding offset. If the decoded - // exponent is negative, quickly bail out with '0' as such values round to - // zero anyway. This also catches +/-0 and subnormals. -" sub %1, %1, #0xff\n" -" subs %1, %1, #0x300\n" -" bmi 8f\n" - - // %1 = (decoded) exponent >= 0 - // %R4 = upper mantissa and sign - - // ---- Lower Mantissa ---- -" subs %3, %1, #52\n" // Calculate exp-52 -" bmi 1f\n" - - // Shift r0 left by exp-52. - // Ensure that we don't overflow ARM's 8-bit shift operand range. - // We need to handle anything up to an 11-bit value here as we know that - // 52 <= exp <= 1024 (0x400). Any shift beyond 31 bits results in zero - // anyway, so as long as we don't touch the bottom 5 bits, we can use - // a logical OR to push long shifts into the 32 <= (exp&0xff) <= 255 range. -" bic %2, %3, #0xff\n" -" orr %3, %3, %2, LSR #3\n" - // We can now perform a straight shift, avoiding the need for any - // conditional instructions or extra branches. -" mov %Q4, %Q4, LSL %3\n" -" b 2f\n" -"1:\n" // Shift r0 right by 52-exp. - // We know that 0 <= exp < 52, and we can shift up to 255 bits so 52-exp - // will always be a valid shift and we can sk%3 the range check for this case. -" rsb %3, %1, #52\n" -" mov %Q4, %Q4, LSR %3\n" - - // %1 = (decoded) exponent - // %R4 = upper mantissa and sign - // %Q4 = partially-converted integer - -"2:\n" - // ---- Upper Mantissa ---- - // This is much the same as the lower mantissa, with a few different - // boundary checks and some masking to hide the exponent & sign bit in the - // upper word. - // Note that the upper mantissa is pre-shifted by 20 in %R4, but we shift - // it left more to remove the sign and exponent so it is effectively - // pre-shifted by 31 bits. -" subs %3, %1, #31\n" // Calculate exp-31 -" mov %1, %R4, LSL #11\n" // Re-use %1 as a temporary register. -" bmi 3f\n" - - // Shift %R4 left by exp-31. - // Avoid overflowing the 8-bit shift range, as before. -" bic %2, %3, #0xff\n" -" orr %3, %3, %2, LSR #3\n" - // Perform the shift. -" mov %2, %1, LSL %3\n" -" b 4f\n" -"3:\n" // Shift r1 right by 31-exp. - // We know that 0 <= exp < 31, and we can shift up to 255 bits so 31-exp - // will always be a valid shift and we can skip the range check for this case. -" rsb %3, %3, #0\n" // Calculate 31-exp from -(exp-31) -" mov %2, %1, LSR %3\n" // Thumb-2 can't do "LSR %3" in "orr". - - // %Q4 = partially-converted integer (lower) - // %R4 = upper mantissa and sign - // %2 = partially-converted integer (upper) - -"4:\n" - // Combine the converted parts. -" orr %Q4, %Q4, %2\n" - // Negate the result if we have to, and move it to %0 in the process. To - // avoid conditionals, we can do this by inverting on %R4[31], then adding - // %R4[31]>>31. -" eor %Q4, %Q4, %R4, ASR #31\n" -" add %0, %Q4, %R4, LSR #31\n" -" b 9f\n" -"8:\n" - // +/-INFINITY, +/-0, subnormals, NaNs, and anything else out-of-range that - // will result in a conversion of '0'. -" mov %0, #0\n" -"9:\n" - : "=r" (i), "=&r" (tmp0), "=&r" (tmp1), "=&r" (tmp2), "=&r" (d) - : "4" (d) - : "cc" - ); - return i; -#else - return detail::ToIntWidth(d); -#endif -} - -/* ES5 9.6 (specialized for doubles). */ -inline uint32_t -ToUint32(double d) -{ - return detail::ToUintWidth(d); -} - -/* WEBIDL 4.2.4 */ -inline int8_t -ToInt8(double d) -{ - return detail::ToIntWidth(d); -} - -/* ECMA-262 7.1.10 ToUInt8() specialized for doubles. */ -inline int8_t -ToUint8(double d) -{ - return detail::ToUintWidth(d); -} - -/* WEBIDL 4.2.6 */ -inline int16_t -ToInt16(double d) -{ - return detail::ToIntWidth(d); -} - -inline uint16_t -ToUint16(double d) -{ - return detail::ToUintWidth(d); -} - -/* WEBIDL 4.2.10 */ -inline int64_t -ToInt64(double d) -{ - return detail::ToIntWidth(d); -} - -/* WEBIDL 4.2.11 */ -inline uint64_t -ToUint64(double d) -{ - return detail::ToUintWidth(d); -} - -} // namespace JS - -#endif /* js_Conversions_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/Date.h b/android/arm64-v8a/include/spidermonkey/js/Date.h deleted file mode 100644 index cba0ea87..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/Date.h +++ /dev/null @@ -1,170 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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/. */ - -/* JavaScript date/time computation and creation functions. */ - -#ifndef js_Date_h -#define js_Date_h - -/* - * Dates in JavaScript are defined by IEEE-754 double precision numbers from - * the set: - * - * { t ∈ ℕ : -8.64e15 ≤ t ≤ +8.64e15 } ∪ { NaN } - * - * The single NaN value represents any invalid-date value. All other values - * represent idealized durations in milliseconds since the UTC epoch. (Leap - * seconds are ignored; leap days are not.) +0 is the only zero in this set. - * The limit represented by 8.64e15 milliseconds is 100 million days either - * side of 00:00 January 1, 1970 UTC. - * - * Dates in the above set are represented by the |ClippedTime| class. The - * double type is a superset of the above set, so it *may* (but need not) - * represent a date. Use ECMAScript's |TimeClip| method to produce a date from - * a double. - * - * Date *objects* are simply wrappers around |TimeClip|'d numbers, with a bunch - * of accessor methods to the various aspects of the represented date. - */ - -#include "mozilla/FloatingPoint.h" -#include "mozilla/MathAlgorithms.h" - -#include "js/Conversions.h" -#include "js/Value.h" - -struct JSContext; - -namespace JS { - -/** - * Re-query the system to determine the current time zone adjustment from UTC, - * including any component due to DST. If the time zone has changed, this will - * cause all Date object non-UTC methods and formatting functions to produce - * appropriately adjusted results. - * - * Left to its own devices, SpiderMonkey itself may occasionally call this - * method to attempt to keep up with system time changes. However, no - * particular frequency of checking is guaranteed. Embedders unable to accept - * occasional inaccuracies should call this method in response to system time - * changes, or immediately before operations requiring instantaneous - * correctness, to guarantee correct behavior. - */ -extern JS_PUBLIC_API(void) -ResetTimeZone(); - -class ClippedTime; -inline ClippedTime TimeClip(double time); - -/* - * |ClippedTime| represents the limited subset of dates/times described above. - * - * An invalid date/time may be created through the |ClippedTime::invalid| - * method. Otherwise, a |ClippedTime| may be created using the |TimeClip| - * method. - * - * In typical use, the user might wish to manipulate a timestamp. The user - * performs a series of operations on it, but the final value might not be a - * date as defined above -- it could have overflowed, acquired a fractional - * component, &c. So as a *final* step, the user passes that value through - * |TimeClip| to produce a number restricted to JavaScript's date range. - * - * APIs that accept a JavaScript date value thus accept a |ClippedTime|, not a - * double. This ensures that date/time APIs will only ever receive acceptable - * JavaScript dates. This also forces users to perform any desired clipping, - * as only the user knows what behavior is desired when clipping occurs. - */ -class ClippedTime -{ - double t; - - explicit ClippedTime(double time) : t(time) {} - friend ClippedTime TimeClip(double time); - - public: - // Create an invalid date. - ClippedTime() : t(mozilla::UnspecifiedNaN()) {} - - // Create an invalid date/time, more explicitly; prefer this to the default - // constructor. - static ClippedTime invalid() { return ClippedTime(); } - - double toDouble() const { return t; } - - bool isValid() const { return !mozilla::IsNaN(t); } -}; - -// ES6 20.3.1.15. -// -// Clip a double to JavaScript's date range (or to an invalid date) using the -// ECMAScript TimeClip algorithm. -inline ClippedTime -TimeClip(double time) -{ - // Steps 1-2. - const double MaxTimeMagnitude = 8.64e15; - if (!mozilla::IsFinite(time) || mozilla::Abs(time) > MaxTimeMagnitude) - return ClippedTime(mozilla::UnspecifiedNaN()); - - // Step 3. - return ClippedTime(ToInteger(time) + (+0.0)); -} - -// Produce a double Value from the given time. Because times may be NaN, -// prefer using this to manual canonicalization. -inline Value -TimeValue(ClippedTime time) -{ - return DoubleValue(JS::CanonicalizeNaN(time.toDouble())); -} - -// Create a new Date object whose [[DateValue]] internal slot contains the -// clipped |time|. (Users who must represent times outside that range must use -// another representation.) -extern JS_PUBLIC_API(JSObject*) -NewDateObject(JSContext* cx, ClippedTime time); - -// Year is a year, month is 0-11, day is 1-based. The return value is a number -// of milliseconds since the epoch. -// -// Consistent with the MakeDate algorithm defined in ECMAScript, this value is -// *not* clipped! Use JS::TimeClip if you need a clipped date. -JS_PUBLIC_API(double) -MakeDate(double year, unsigned month, unsigned day); - -// Takes an integer number of milliseconds since the epoch and returns the -// year. Can return NaN, and will do so if NaN is passed in. -JS_PUBLIC_API(double) -YearFromTime(double time); - -// Takes an integer number of milliseconds since the epoch and returns the -// month (0-11). Can return NaN, and will do so if NaN is passed in. -JS_PUBLIC_API(double) -MonthFromTime(double time); - -// Takes an integer number of milliseconds since the epoch and returns the -// day (1-based). Can return NaN, and will do so if NaN is passed in. -JS_PUBLIC_API(double) -DayFromTime(double time); - -// Takes an integer year and returns the number of days from epoch to the given -// year. -// NOTE: The calculation performed by this function is literally that given in -// the ECMAScript specification. Nonfinite years, years containing fractional -// components, and years outside ECMAScript's date range are not handled with -// any particular intelligence. Garbage in, garbage out. -JS_PUBLIC_API(double) -DayFromYear(double year); - -// Takes an integer number of milliseconds since the epoch and an integer year, -// returns the number of days in that year. If |time| is nonfinite, returns NaN. -// Otherwise |time| *must* correspond to a time within the valid year |year|. -// This should usually be ensured by computing |year| as |JS::DayFromYear(time)|. -JS_PUBLIC_API(double) -DayWithinYear(double time, double year); - -} // namespace JS - -#endif /* js_Date_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/Debug.h b/android/arm64-v8a/include/spidermonkey/js/Debug.h deleted file mode 100644 index 3e4183f0..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/Debug.h +++ /dev/null @@ -1,384 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -// Interfaces by which the embedding can interact with the Debugger API. - -#ifndef js_Debug_h -#define js_Debug_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/MemoryReporting.h" - -#include "jsapi.h" -#include "jspubtd.h" - -#include "js/GCAPI.h" -#include "js/RootingAPI.h" -#include "js/TypeDecls.h" - -namespace js { -class Debugger; -} // namespace js - -namespace JS { -namespace dbg { - -// Helping embedding code build objects for Debugger -// ------------------------------------------------- -// -// Some Debugger API features lean on the embedding application to construct -// their result values. For example, Debugger.Frame.prototype.scriptEntryReason -// calls hooks provided by the embedding to construct values explaining why it -// invoked JavaScript; if F is a frame called from a mouse click event handler, -// F.scriptEntryReason would return an object of the form: -// -// { eventType: "mousedown", event: } -// -// where is a Debugger.Object whose referent is the event being -// dispatched. -// -// However, Debugger implements a trust boundary. Debuggee code may be -// considered untrusted; debugger code needs to be protected from debuggee -// getters, setters, proxies, Object.watch watchpoints, and any other feature -// that might accidentally cause debugger code to set the debuggee running. The -// Debugger API tries to make it easy to write safe debugger code by only -// offering access to debuggee objects via Debugger.Object instances, which -// ensure that only those operations whose explicit purpose is to invoke -// debuggee code do so. But this protective membrane is only helpful if we -// interpose Debugger.Object instances in all the necessary spots. -// -// SpiderMonkey's compartment system also implements a trust boundary. The -// debuggee and debugger are always in different compartments. Inter-compartment -// work requires carefully tracking which compartment each JSObject or JS::Value -// belongs to, and ensuring that is is correctly wrapped for each operation. -// -// It seems precarious to expect the embedding's hooks to implement these trust -// boundaries. Instead, the JS::dbg::Builder API segregates the code which -// constructs trusted objects from that which deals with untrusted objects. -// Trusted objects have an entirely different C++ type, so code that improperly -// mixes trusted and untrusted objects is caught at compile time. -// -// In the structure shown above, there are two trusted objects, and one -// untrusted object: -// -// - The overall object, with the 'eventType' and 'event' properties, is a -// trusted object. We're going to return it to D.F.p.scriptEntryReason's -// caller, which will handle it directly. -// -// - The Debugger.Object instance appearing as the value of the 'event' property -// is a trusted object. It belongs to the same Debugger instance as the -// Debugger.Frame instance whose scriptEntryReason accessor was called, and -// presents a safe reflection-oriented API for inspecting its referent, which -// is: -// -// - The actual event object, an untrusted object, and the referent of the -// Debugger.Object above. (Content can do things like replacing accessors on -// Event.prototype.) -// -// Using JS::dbg::Builder, all objects and values the embedding deals with -// directly are considered untrusted, and are assumed to be debuggee values. The -// only way to construct trusted objects is to use Builder's own methods, which -// return a separate Object type. The only way to set a property on a trusted -// object is through that Object type. The actual trusted object is never -// exposed to the embedding. -// -// So, for example, the embedding might use code like the following to construct -// the object shown above, given a Builder passed to it by Debugger: -// -// bool -// MyScriptEntryReason::explain(JSContext* cx, -// Builder& builder, -// Builder::Object& result) -// { -// JSObject* eventObject = ... obtain debuggee event object somehow ...; -// if (!eventObject) -// return false; -// result = builder.newObject(cx); -// return result && -// result.defineProperty(cx, "eventType", SafelyFetchType(eventObject)) && -// result.defineProperty(cx, "event", eventObject); -// } -// -// -// Object::defineProperty also accepts an Object as the value to store on the -// property. By its type, we know that the value is trusted, so we set it -// directly as the property's value, without interposing a Debugger.Object -// wrapper. This allows the embedding to builted nested structures of trusted -// objects. -// -// The Builder and Builder::Object methods take care of doing whatever -// compartment switching and wrapping are necessary to construct the trusted -// values in the Debugger's compartment. -// -// The Object type is self-rooting. Construction, assignment, and destruction -// all properly root the referent object. - -class BuilderOrigin; - -class Builder { - // The Debugger instance whose client we are building a value for. We build - // objects in this object's compartment. - PersistentRootedObject debuggerObject; - - // debuggerObject's Debugger structure, for convenience. - js::Debugger* debugger; - - // Check that |thing| is in the same compartment as our debuggerObject. Used - // for assertions when constructing BuiltThings. We can overload this as we - // add more instantiations of BuiltThing. -#if DEBUG - void assertBuilt(JSObject* obj); -#else - void assertBuilt(JSObject* obj) { } -#endif - - protected: - // A reference to a trusted object or value. At the moment, we only use it - // with JSObject*. - template - class BuiltThing { - friend class BuilderOrigin; - - protected: - // The Builder to which this trusted thing belongs. - Builder& owner; - - // A rooted reference to our value. - PersistentRooted value; - - BuiltThing(JSContext* cx, Builder& owner_, T value_ = GCPolicy::initial()) - : owner(owner_), value(cx, value_) - { - owner.assertBuilt(value_); - } - - // Forward some things from our owner, for convenience. - js::Debugger* debugger() const { return owner.debugger; } - JSObject* debuggerObject() const { return owner.debuggerObject; } - - public: - BuiltThing(const BuiltThing& rhs) : owner(rhs.owner), value(rhs.value) { } - BuiltThing& operator=(const BuiltThing& rhs) { - MOZ_ASSERT(&owner == &rhs.owner); - owner.assertBuilt(rhs.value); - value = rhs.value; - return *this; - } - - explicit operator bool() const { - // If we ever instantiate BuiltThing, this might not suffice. - return value; - } - - private: - BuiltThing() = delete; - }; - - public: - // A reference to a trusted object, possibly null. Instances of Object are - // always properly rooted. They can be copied and assigned, as if they were - // pointers. - class Object: private BuiltThing { - friend class Builder; // for construction - friend class BuilderOrigin; // for unwrapping - - typedef BuiltThing Base; - - // This is private, because only Builders can create Objects that - // actually point to something (hence the 'friend' declaration). - Object(JSContext* cx, Builder& owner_, HandleObject obj) : Base(cx, owner_, obj.get()) { } - - bool definePropertyToTrusted(JSContext* cx, const char* name, - JS::MutableHandleValue value); - - public: - Object(JSContext* cx, Builder& owner_) : Base(cx, owner_, nullptr) { } - Object(const Object& rhs) : Base(rhs) { } - - // Our automatically-generated assignment operator can see our base - // class's assignment operator, so we don't need to write one out here. - - // Set the property named |name| on this object to |value|. - // - // If |value| is a string or primitive, re-wrap it for the debugger's - // compartment. - // - // If |value| is an object, assume it is a debuggee object and make a - // Debugger.Object instance referring to it. Set that as the propery's - // value. - // - // If |value| is another trusted object, store it directly as the - // property's value. - // - // On error, report the problem on cx and return false. - bool defineProperty(JSContext* cx, const char* name, JS::HandleValue value); - bool defineProperty(JSContext* cx, const char* name, JS::HandleObject value); - bool defineProperty(JSContext* cx, const char* name, Object& value); - - using Base::operator bool; - }; - - // Build an empty object for direct use by debugger code, owned by this - // Builder. If an error occurs, report it on cx and return a false Object. - Object newObject(JSContext* cx); - - protected: - Builder(JSContext* cx, js::Debugger* debugger); -}; - -// Debugger itself instantiates this subclass of Builder, which can unwrap -// BuiltThings that belong to it. -class BuilderOrigin : public Builder { - template - T unwrapAny(const BuiltThing& thing) { - MOZ_ASSERT(&thing.owner == this); - return thing.value.get(); - } - - public: - BuilderOrigin(JSContext* cx, js::Debugger* debugger_) - : Builder(cx, debugger_) - { } - - JSObject* unwrap(Object& object) { return unwrapAny(object); } -}; - - - -// Finding the size of blocks allocated with malloc -// ------------------------------------------------ -// -// Debugger.Memory wants to be able to report how many bytes items in memory are -// consuming. To do this, it needs a function that accepts a pointer to a block, -// and returns the number of bytes allocated to that block. SpiderMonkey itself -// doesn't know which function is appropriate to use, but the embedding does. - -// Tell Debuggers in |cx| to use |mallocSizeOf| to find the size of -// malloc'd blocks. -JS_PUBLIC_API(void) -SetDebuggerMallocSizeOf(JSContext* cx, mozilla::MallocSizeOf mallocSizeOf); - -// Get the MallocSizeOf function that the given context is using to find the -// size of malloc'd blocks. -JS_PUBLIC_API(mozilla::MallocSizeOf) -GetDebuggerMallocSizeOf(JSContext* cx); - - - -// Debugger and Garbage Collection Events -// -------------------------------------- -// -// The Debugger wants to report about its debuggees' GC cycles, however entering -// JS after a GC is troublesome since SpiderMonkey will often do something like -// force a GC and then rely on the nursery being empty. If we call into some -// Debugger's hook after the GC, then JS runs and the nursery won't be -// empty. Instead, we rely on embedders to call back into SpiderMonkey after a -// GC and notify Debuggers to call their onGarbageCollection hook. - - -// For each Debugger that observed a debuggee involved in the given GC event, -// call its `onGarbageCollection` hook. -JS_PUBLIC_API(bool) -FireOnGarbageCollectionHook(JSContext* cx, GarbageCollectionEvent::Ptr&& data); - - - -// Handlers for observing Promises -// ------------------------------- -// -// The Debugger wants to observe behavior of promises, which are implemented by -// Gecko with webidl and which SpiderMonkey knows nothing about. On the other -// hand, Gecko knows nothing about which (if any) debuggers are observing a -// promise's global. The compromise is that Gecko is responsible for calling -// these handlers at the appropriate times, and SpiderMonkey will handle -// notifying any Debugger instances that are observing the given promise's -// global. - -// Notify any Debugger instances observing this promise's global that a new -// promise was allocated. -JS_PUBLIC_API(void) -onNewPromise(JSContext* cx, HandleObject promise); - -// Notify any Debugger instances observing this promise's global that the -// promise has settled (ie, it has either been fulfilled or rejected). Note that -// this is *not* equivalent to the promise resolution (ie, the promise's fate -// getting locked in) because you can resolve a promise with another pending -// promise, in which case neither promise has settled yet. -// -// It is Gecko's responsibility to ensure that this is never called on the same -// promise more than once (because a promise can only make the transition from -// unsettled to settled once). -JS_PUBLIC_API(void) -onPromiseSettled(JSContext* cx, HandleObject promise); - - - -// Return true if the given value is a Debugger object, false otherwise. -JS_PUBLIC_API(bool) -IsDebugger(JSObject& obj); - -// Append each of the debuggee global objects observed by the Debugger object -// |dbgObj| to |vector|. Returns true on success, false on failure. -JS_PUBLIC_API(bool) -GetDebuggeeGlobals(JSContext* cx, JSObject& dbgObj, AutoObjectVector& vector); - - -// Hooks for reporting where JavaScript execution began. -// -// Our performance tools would like to be able to label blocks of JavaScript -// execution with the function name and source location where execution began: -// the event handler, the callback, etc. -// -// Construct an instance of this class on the stack, providing a JSContext -// belonging to the runtime in which execution will occur. Each time we enter -// JavaScript --- specifically, each time we push a JavaScript stack frame that -// has no older JS frames younger than this AutoEntryMonitor --- we will -// call the appropriate |Entry| member function to indicate where we've begun -// execution. - -class MOZ_STACK_CLASS AutoEntryMonitor { - JSRuntime* runtime_; - AutoEntryMonitor* savedMonitor_; - - public: - explicit AutoEntryMonitor(JSContext* cx); - ~AutoEntryMonitor(); - - // SpiderMonkey reports the JavaScript entry points occuring within this - // AutoEntryMonitor's scope to the following member functions, which the - // embedding is expected to override. - // - // It is important to note that |asyncCause| is owned by the caller and its - // lifetime must outlive the lifetime of the AutoEntryMonitor object. It is - // strongly encouraged that |asyncCause| be a string constant or similar - // statically allocated string. - - // We have begun executing |function|. Note that |function| may not be the - // actual closure we are running, but only the canonical function object to - // which the script refers. - virtual void Entry(JSContext* cx, JSFunction* function, - HandleValue asyncStack, - const char* asyncCause) = 0; - - // Execution has begun at the entry point of |script|, which is not a - // function body. (This is probably being executed by 'eval' or some - // JSAPI equivalent.) - virtual void Entry(JSContext* cx, JSScript* script, - HandleValue asyncStack, - const char* asyncCause) = 0; - - // Execution of the function or script has ended. - virtual void Exit(JSContext* cx) { } -}; - - - -} // namespace dbg -} // namespace JS - - -#endif /* js_Debug_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/GCAPI.h b/android/arm64-v8a/include/spidermonkey/js/GCAPI.h deleted file mode 100644 index 7a6675ca..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/GCAPI.h +++ /dev/null @@ -1,723 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_GCAPI_h -#define js_GCAPI_h - -#include "mozilla/Vector.h" - -#include "js/GCAnnotations.h" -#include "js/HeapAPI.h" -#include "js/UniquePtr.h" - -namespace js { -namespace gc { -class GCRuntime; -} // namespace gc -namespace gcstats { -struct Statistics; -} // namespace gcstats -} // namespace js - -typedef enum JSGCMode { - /** Perform only global GCs. */ - JSGC_MODE_GLOBAL = 0, - - /** Perform per-zone GCs until too much garbage has accumulated. */ - JSGC_MODE_ZONE = 1, - - /** - * Collect in short time slices rather than all at once. Implies - * JSGC_MODE_ZONE. - */ - JSGC_MODE_INCREMENTAL = 2 -} JSGCMode; - -/** - * Kinds of js_GC invocation. - */ -typedef enum JSGCInvocationKind { - /* Normal invocation. */ - GC_NORMAL = 0, - - /* Minimize GC triggers and release empty GC chunks right away. */ - GC_SHRINK = 1 -} JSGCInvocationKind; - -namespace JS { - -#define GCREASONS(D) \ - /* Reasons internal to the JS engine */ \ - D(API) \ - D(EAGER_ALLOC_TRIGGER) \ - D(DESTROY_RUNTIME) \ - D(UNUSED0) \ - D(LAST_DITCH) \ - D(TOO_MUCH_MALLOC) \ - D(ALLOC_TRIGGER) \ - D(DEBUG_GC) \ - D(COMPARTMENT_REVIVED) \ - D(RESET) \ - D(OUT_OF_NURSERY) \ - D(EVICT_NURSERY) \ - D(FULL_STORE_BUFFER) \ - D(SHARED_MEMORY_LIMIT) \ - D(UNUSED1) \ - D(INCREMENTAL_TOO_SLOW) \ - D(ABORT_GC) \ - \ - /* These are reserved for future use. */ \ - D(RESERVED0) \ - D(RESERVED1) \ - D(RESERVED2) \ - D(RESERVED3) \ - D(RESERVED4) \ - D(RESERVED5) \ - D(RESERVED6) \ - D(RESERVED7) \ - D(RESERVED8) \ - D(RESERVED9) \ - D(RESERVED10) \ - D(RESERVED11) \ - D(RESERVED12) \ - D(RESERVED13) \ - D(RESERVED14) \ - D(RESERVED15) \ - \ - /* Reasons from Firefox */ \ - D(DOM_WINDOW_UTILS) \ - D(COMPONENT_UTILS) \ - D(MEM_PRESSURE) \ - D(CC_WAITING) \ - D(CC_FORCED) \ - D(LOAD_END) \ - D(POST_COMPARTMENT) \ - D(PAGE_HIDE) \ - D(NSJSCONTEXT_DESTROY) \ - D(SET_NEW_DOCUMENT) \ - D(SET_DOC_SHELL) \ - D(DOM_UTILS) \ - D(DOM_IPC) \ - D(DOM_WORKER) \ - D(INTER_SLICE_GC) \ - D(REFRESH_FRAME) \ - D(FULL_GC_TIMER) \ - D(SHUTDOWN_CC) \ - D(FINISH_LARGE_EVALUATE) \ - D(USER_INACTIVE) \ - D(XPCONNECT_SHUTDOWN) - -namespace gcreason { - -/* GCReasons will end up looking like JSGC_MAYBEGC */ -enum Reason { -#define MAKE_REASON(name) name, - GCREASONS(MAKE_REASON) -#undef MAKE_REASON - NO_REASON, - NUM_REASONS, - - /* - * For telemetry, we want to keep a fixed max bucket size over time so we - * don't have to switch histograms. 100 is conservative; as of this writing - * there are 52. But the cost of extra buckets seems to be low while the - * cost of switching histograms is high. - */ - NUM_TELEMETRY_REASONS = 100 -}; - -/** - * Get a statically allocated C string explaining the given GC reason. - */ -extern JS_PUBLIC_API(const char*) -ExplainReason(JS::gcreason::Reason reason); - -} /* namespace gcreason */ - -/* - * Zone GC: - * - * SpiderMonkey's GC is capable of performing a collection on an arbitrary - * subset of the zones in the system. This allows an embedding to minimize - * collection time by only collecting zones that have run code recently, - * ignoring the parts of the heap that are unlikely to have changed. - * - * When triggering a GC using one of the functions below, it is first necessary - * to select the zones to be collected. To do this, you can call - * PrepareZoneForGC on each zone, or you can call PrepareForFullGC to select - * all zones. Failing to select any zone is an error. - */ - -/** - * Schedule the given zone to be collected as part of the next GC. - */ -extern JS_PUBLIC_API(void) -PrepareZoneForGC(Zone* zone); - -/** - * Schedule all zones to be collected in the next GC. - */ -extern JS_PUBLIC_API(void) -PrepareForFullGC(JSContext* cx); - -/** - * When performing an incremental GC, the zones that were selected for the - * previous incremental slice must be selected in subsequent slices as well. - * This function selects those slices automatically. - */ -extern JS_PUBLIC_API(void) -PrepareForIncrementalGC(JSContext* cx); - -/** - * Returns true if any zone in the system has been scheduled for GC with one of - * the functions above or by the JS engine. - */ -extern JS_PUBLIC_API(bool) -IsGCScheduled(JSContext* cx); - -/** - * Undoes the effect of the Prepare methods above. The given zone will not be - * collected in the next GC. - */ -extern JS_PUBLIC_API(void) -SkipZoneForGC(Zone* zone); - -/* - * Non-Incremental GC: - * - * The following functions perform a non-incremental GC. - */ - -/** - * Performs a non-incremental collection of all selected zones. - * - * If the gckind argument is GC_NORMAL, then some objects that are unreachable - * from the program may still be alive afterwards because of internal - * references; if GC_SHRINK is passed then caches and other temporary references - * to objects will be cleared and all unreferenced objects will be removed from - * the system. - */ -extern JS_PUBLIC_API(void) -GCForReason(JSContext* cx, JSGCInvocationKind gckind, gcreason::Reason reason); - -/* - * Incremental GC: - * - * Incremental GC divides the full mark-and-sweep collection into multiple - * slices, allowing client JavaScript code to run between each slice. This - * allows interactive apps to avoid long collection pauses. Incremental GC does - * not make collection take less time, it merely spreads that time out so that - * the pauses are less noticable. - * - * For a collection to be carried out incrementally the following conditions - * must be met: - * - The collection must be run by calling JS::IncrementalGC() rather than - * JS_GC(). - * - The GC mode must have been set to JSGC_MODE_INCREMENTAL with - * JS_SetGCParameter(). - * - * Note: Even if incremental GC is enabled and working correctly, - * non-incremental collections can still happen when low on memory. - */ - -/** - * Begin an incremental collection and perform one slice worth of work. When - * this function returns, the collection may not be complete. - * IncrementalGCSlice() must be called repeatedly until - * !IsIncrementalGCInProgress(cx). - * - * Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or - * shorter than the requested interval. - */ -extern JS_PUBLIC_API(void) -StartIncrementalGC(JSContext* cx, JSGCInvocationKind gckind, gcreason::Reason reason, - int64_t millis = 0); - -/** - * Perform a slice of an ongoing incremental collection. When this function - * returns, the collection may not be complete. It must be called repeatedly - * until !IsIncrementalGCInProgress(cx). - * - * Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or - * shorter than the requested interval. - */ -extern JS_PUBLIC_API(void) -IncrementalGCSlice(JSContext* cx, gcreason::Reason reason, int64_t millis = 0); - -/** - * If IsIncrementalGCInProgress(cx), this call finishes the ongoing collection - * by performing an arbitrarily long slice. If !IsIncrementalGCInProgress(cx), - * this is equivalent to GCForReason. When this function returns, - * IsIncrementalGCInProgress(cx) will always be false. - */ -extern JS_PUBLIC_API(void) -FinishIncrementalGC(JSContext* cx, gcreason::Reason reason); - -/** - * If IsIncrementalGCInProgress(cx), this call aborts the ongoing collection and - * performs whatever work needs to be done to return the collector to its idle - * state. This may take an arbitrarily long time. When this function returns, - * IsIncrementalGCInProgress(cx) will always be false. - */ -extern JS_PUBLIC_API(void) -AbortIncrementalGC(JSContext* cx); - -namespace dbg { - -// The `JS::dbg::GarbageCollectionEvent` class is essentially a view of the -// `js::gcstats::Statistics` data without the uber implementation-specific bits. -// It should generally be palatable for web developers. -class GarbageCollectionEvent -{ - // The major GC number of the GC cycle this data pertains to. - uint64_t majorGCNumber_; - - // Reference to a non-owned, statically allocated C string. This is a very - // short reason explaining why a GC was triggered. - const char* reason; - - // Reference to a nullable, non-owned, statically allocated C string. If the - // collection was forced to be non-incremental, this is a short reason of - // why the GC could not perform an incremental collection. - const char* nonincrementalReason; - - // Represents a single slice of a possibly multi-slice incremental garbage - // collection. - struct Collection { - double startTimestamp; - double endTimestamp; - }; - - // The set of garbage collection slices that made up this GC cycle. - mozilla::Vector collections; - - GarbageCollectionEvent(const GarbageCollectionEvent& rhs) = delete; - GarbageCollectionEvent& operator=(const GarbageCollectionEvent& rhs) = delete; - - public: - explicit GarbageCollectionEvent(uint64_t majorGCNum) - : majorGCNumber_(majorGCNum) - , reason(nullptr) - , nonincrementalReason(nullptr) - , collections() - { } - - using Ptr = js::UniquePtr; - static Ptr Create(JSRuntime* rt, ::js::gcstats::Statistics& stats, uint64_t majorGCNumber); - - JSObject* toJSObject(JSContext* cx) const; - - uint64_t majorGCNumber() const { return majorGCNumber_; } -}; - -} // namespace dbg - -enum GCProgress { - /* - * During non-incremental GC, the GC is bracketed by JSGC_CYCLE_BEGIN/END - * callbacks. During an incremental GC, the sequence of callbacks is as - * follows: - * JSGC_CYCLE_BEGIN, JSGC_SLICE_END (first slice) - * JSGC_SLICE_BEGIN, JSGC_SLICE_END (second slice) - * ... - * JSGC_SLICE_BEGIN, JSGC_CYCLE_END (last slice) - */ - - GC_CYCLE_BEGIN, - GC_SLICE_BEGIN, - GC_SLICE_END, - GC_CYCLE_END -}; - -struct JS_PUBLIC_API(GCDescription) { - bool isZone_; - JSGCInvocationKind invocationKind_; - gcreason::Reason reason_; - - GCDescription(bool isZone, JSGCInvocationKind kind, gcreason::Reason reason) - : isZone_(isZone), invocationKind_(kind), reason_(reason) {} - - char16_t* formatSliceMessage(JSContext* cx) const; - char16_t* formatSummaryMessage(JSContext* cx) const; - char16_t* formatJSON(JSContext* cx, uint64_t timestamp) const; - - JS::dbg::GarbageCollectionEvent::Ptr toGCEvent(JSContext* cx) const; -}; - -typedef void -(* GCSliceCallback)(JSContext* cx, GCProgress progress, const GCDescription& desc); - -/** - * The GC slice callback is called at the beginning and end of each slice. This - * callback may be used for GC notifications as well as to perform additional - * marking. - */ -extern JS_PUBLIC_API(GCSliceCallback) -SetGCSliceCallback(JSContext* cx, GCSliceCallback callback); - -/** - * Describes the progress of an observed nursery collection. - */ -enum class GCNurseryProgress { - /** - * The nursery collection is starting. - */ - GC_NURSERY_COLLECTION_START, - /** - * The nursery collection is ending. - */ - GC_NURSERY_COLLECTION_END -}; - -/** - * A nursery collection callback receives the progress of the nursery collection - * and the reason for the collection. - */ -using GCNurseryCollectionCallback = void(*)(JSContext* cx, GCNurseryProgress progress, - gcreason::Reason reason); - -/** - * Set the nursery collection callback for the given runtime. When set, it will - * be called at the start and end of every nursery collection. - */ -extern JS_PUBLIC_API(GCNurseryCollectionCallback) -SetGCNurseryCollectionCallback(JSContext* cx, GCNurseryCollectionCallback callback); - -typedef void -(* DoCycleCollectionCallback)(JSContext* cx); - -/** - * The purge gray callback is called after any COMPARTMENT_REVIVED GC in which - * the majority of compartments have been marked gray. - */ -extern JS_PUBLIC_API(DoCycleCollectionCallback) -SetDoCycleCollectionCallback(JSContext* cx, DoCycleCollectionCallback callback); - -/** - * Incremental GC defaults to enabled, but may be disabled for testing or in - * embeddings that have not yet implemented barriers on their native classes. - * There is not currently a way to re-enable incremental GC once it has been - * disabled on the runtime. - */ -extern JS_PUBLIC_API(void) -DisableIncrementalGC(JSContext* cx); - -/** - * Returns true if incremental GC is enabled. Simply having incremental GC - * enabled is not sufficient to ensure incremental collections are happening. - * See the comment "Incremental GC" above for reasons why incremental GC may be - * suppressed. Inspection of the "nonincremental reason" field of the - * GCDescription returned by GCSliceCallback may help narrow down the cause if - * collections are not happening incrementally when expected. - */ -extern JS_PUBLIC_API(bool) -IsIncrementalGCEnabled(JSContext* cx); - -/** - * Returns true while an incremental GC is ongoing, both when actively - * collecting and between slices. - */ -extern JS_PUBLIC_API(bool) -IsIncrementalGCInProgress(JSContext* cx); - -/* - * Returns true when writes to GC things must call an incremental (pre) barrier. - * This is generally only true when running mutator code in-between GC slices. - * At other times, the barrier may be elided for performance. - */ -extern JS_PUBLIC_API(bool) -IsIncrementalBarrierNeeded(JSContext* cx); - -/* - * Notify the GC that a reference to a GC thing is about to be overwritten. - * These methods must be called if IsIncrementalBarrierNeeded. - */ -extern JS_PUBLIC_API(void) -IncrementalReferenceBarrier(GCCellPtr thing); - -extern JS_PUBLIC_API(void) -IncrementalValueBarrier(const Value& v); - -extern JS_PUBLIC_API(void) -IncrementalObjectBarrier(JSObject* obj); - -/** - * Returns true if the most recent GC ran incrementally. - */ -extern JS_PUBLIC_API(bool) -WasIncrementalGC(JSContext* cx); - -/* - * Generational GC: - * - * Note: Generational GC is not yet enabled by default. The following class - * is non-functional unless SpiderMonkey was configured with - * --enable-gcgenerational. - */ - -/** Ensure that generational GC is disabled within some scope. */ -class JS_PUBLIC_API(AutoDisableGenerationalGC) -{ - js::gc::GCRuntime* gc; - - public: - explicit AutoDisableGenerationalGC(JSRuntime* rt); - ~AutoDisableGenerationalGC(); -}; - -/** - * Returns true if generational allocation and collection is currently enabled - * on the given runtime. - */ -extern JS_PUBLIC_API(bool) -IsGenerationalGCEnabled(JSRuntime* rt); - -/** - * Returns the GC's "number". This does not correspond directly to the number - * of GCs that have been run, but is guaranteed to be monotonically increasing - * with GC activity. - */ -extern JS_PUBLIC_API(size_t) -GetGCNumber(); - -/** - * Pass a subclass of this "abstract" class to callees to require that they - * never GC. Subclasses can use assertions or the hazard analysis to ensure no - * GC happens. - */ -class JS_PUBLIC_API(AutoRequireNoGC) -{ - protected: - AutoRequireNoGC() {} - ~AutoRequireNoGC() {} -}; - -/** - * Diagnostic assert (see MOZ_DIAGNOSTIC_ASSERT) that GC cannot occur while this - * class is live. This class does not disable the static rooting hazard - * analysis. - * - * This works by entering a GC unsafe region, which is checked on allocation and - * on GC. - */ -class JS_PUBLIC_API(AutoAssertNoGC) : public AutoRequireNoGC -{ - js::gc::GCRuntime* gc; - size_t gcNumber; - - public: - AutoAssertNoGC(); - explicit AutoAssertNoGC(JSRuntime* rt); - explicit AutoAssertNoGC(JSContext* cx); - ~AutoAssertNoGC(); -}; - -/** - * Assert if an allocation of a GC thing occurs while this class is live. This - * class does not disable the static rooting hazard analysis. - */ -class JS_PUBLIC_API(AutoAssertNoAlloc) -{ -#ifdef JS_DEBUG - js::gc::GCRuntime* gc; - - public: - AutoAssertNoAlloc() : gc(nullptr) {} - explicit AutoAssertNoAlloc(JSContext* cx); - void disallowAlloc(JSRuntime* rt); - ~AutoAssertNoAlloc(); -#else - public: - AutoAssertNoAlloc() {} - explicit AutoAssertNoAlloc(JSContext* cx) {} - void disallowAlloc(JSRuntime* rt) {} -#endif -}; - -/** - * Assert if a GC barrier is invoked while this class is live. This class does - * not disable the static rooting hazard analysis. - */ -class JS_PUBLIC_API(AutoAssertOnBarrier) -{ - JSContext* context; - bool prev; - - public: - explicit AutoAssertOnBarrier(JSContext* cx); - ~AutoAssertOnBarrier(); -}; - -/** - * Disable the static rooting hazard analysis in the live region and assert if - * any allocation that could potentially trigger a GC occurs while this guard - * object is live. This is most useful to help the exact rooting hazard analysis - * in complex regions, since it cannot understand dataflow. - * - * Note: GC behavior is unpredictable even when deterministic and is generally - * non-deterministic in practice. The fact that this guard has not - * asserted is not a guarantee that a GC cannot happen in the guarded - * region. As a rule, anyone performing a GC unsafe action should - * understand the GC properties of all code in that region and ensure - * that the hazard analysis is correct for that code, rather than relying - * on this class. - */ -class JS_PUBLIC_API(AutoSuppressGCAnalysis) : public AutoAssertNoAlloc -{ - public: - AutoSuppressGCAnalysis() : AutoAssertNoAlloc() {} - explicit AutoSuppressGCAnalysis(JSContext* cx) : AutoAssertNoAlloc(cx) {} -} JS_HAZ_GC_SUPPRESSED; - -/** - * Assert that code is only ever called from a GC callback, disable the static - * rooting hazard analysis and assert if any allocation that could potentially - * trigger a GC occurs while this guard object is live. - * - * This is useful to make the static analysis ignore code that runs in GC - * callbacks. - */ -class JS_PUBLIC_API(AutoAssertGCCallback) : public AutoSuppressGCAnalysis -{ - public: - explicit AutoAssertGCCallback(JSObject* obj); -}; - -/** - * Place AutoCheckCannotGC in scopes that you believe can never GC. These - * annotations will be verified both dynamically via AutoAssertNoGC, and - * statically with the rooting hazard analysis (implemented by making the - * analysis consider AutoCheckCannotGC to be a GC pointer, and therefore - * complain if it is live across a GC call.) It is useful when dealing with - * internal pointers to GC things where the GC thing itself may not be present - * for the static analysis: e.g. acquiring inline chars from a JSString* on the - * heap. - * - * We only do the assertion checking in DEBUG builds. - */ -#ifdef DEBUG -class JS_PUBLIC_API(AutoCheckCannotGC) : public AutoAssertNoGC -{ - public: - AutoCheckCannotGC() : AutoAssertNoGC() {} - explicit AutoCheckCannotGC(JSContext* cx) : AutoAssertNoGC(cx) {} -} JS_HAZ_GC_INVALIDATED; -#else -class JS_PUBLIC_API(AutoCheckCannotGC) : public AutoRequireNoGC -{ - public: - AutoCheckCannotGC() {} - explicit AutoCheckCannotGC(JSContext* cx) {} -} JS_HAZ_GC_INVALIDATED; -#endif - -/** - * Unsets the gray bit for anything reachable from |thing|. |kind| should not be - * JS::TraceKind::Shape. |thing| should be non-null. The return value indicates - * if anything was unmarked. - */ -extern JS_FRIEND_API(bool) -UnmarkGrayGCThingRecursively(GCCellPtr thing); - -} /* namespace JS */ - -namespace js { -namespace gc { - -static MOZ_ALWAYS_INLINE void -ExposeGCThingToActiveJS(JS::GCCellPtr thing) -{ - // GC things residing in the nursery cannot be gray: they have no mark bits. - // All live objects in the nursery are moved to tenured at the beginning of - // each GC slice, so the gray marker never sees nursery things. - if (IsInsideNursery(thing.asCell())) - return; - - // There's nothing to do for permanent GC things that might be owned by - // another runtime. - if (thing.mayBeOwnedByOtherRuntime()) - return; - - JS::shadow::Runtime* rt = detail::GetCellRuntime(thing.asCell()); - MOZ_DIAGNOSTIC_ASSERT(rt->allowGCBarriers()); - - if (IsIncrementalBarrierNeededOnTenuredGCThing(rt, thing)) - JS::IncrementalReferenceBarrier(thing); - else if (!thing.mayBeOwnedByOtherRuntime() && js::gc::detail::CellIsMarkedGray(thing.asCell())) - JS::UnmarkGrayGCThingRecursively(thing); -} - -static MOZ_ALWAYS_INLINE void -MarkGCThingAsLive(JSRuntime* aRt, JS::GCCellPtr thing) -{ - // Any object in the nursery will not be freed during any GC running at that - // time. - if (IsInsideNursery(thing.asCell())) - return; - - // There's nothing to do for permanent GC things that might be owned by - // another runtime. - if (thing.mayBeOwnedByOtherRuntime()) - return; - - JS::shadow::Runtime* rt = JS::shadow::Runtime::asShadowRuntime(aRt); - MOZ_DIAGNOSTIC_ASSERT(rt->allowGCBarriers()); - - if (IsIncrementalBarrierNeededOnTenuredGCThing(rt, thing)) - JS::IncrementalReferenceBarrier(thing); -} - -} /* namespace gc */ -} /* namespace js */ - -namespace JS { - -/* - * This should be called when an object that is marked gray is exposed to the JS - * engine (by handing it to running JS code or writing it into live JS - * data). During incremental GC, since the gray bits haven't been computed yet, - * we conservatively mark the object black. - */ -static MOZ_ALWAYS_INLINE void -ExposeObjectToActiveJS(JSObject* obj) -{ - MOZ_ASSERT(obj); - js::gc::ExposeGCThingToActiveJS(GCCellPtr(obj)); -} - -static MOZ_ALWAYS_INLINE void -ExposeScriptToActiveJS(JSScript* script) -{ - js::gc::ExposeGCThingToActiveJS(GCCellPtr(script)); -} - -/* - * If a GC is currently marking, mark the string black. - */ -static MOZ_ALWAYS_INLINE void -MarkStringAsLive(Zone* zone, JSString* string) -{ - JSRuntime* rt = JS::shadow::Zone::asShadowZone(zone)->runtimeFromMainThread(); - js::gc::MarkGCThingAsLive(rt, GCCellPtr(string)); -} - -/* - * Internal to Firefox. - * - * Note: this is not related to the PokeGC in nsJSEnvironment. - */ -extern JS_FRIEND_API(void) -PokeGC(JSContext* cx); - -/* - * Internal to Firefox. - */ -extern JS_FRIEND_API(void) -NotifyDidPaint(JSContext* cx); - -} /* namespace JS */ - -#endif /* js_GCAPI_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/GCAnnotations.h b/android/arm64-v8a/include/spidermonkey/js/GCAnnotations.h deleted file mode 100644 index 366d787b..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/GCAnnotations.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_GCAnnotations_h -#define js_GCAnnotations_h - -// Set of annotations for the rooting hazard analysis, used to categorize types -// and functions. -#ifdef XGILL_PLUGIN - -// Mark a type as being a GC thing (eg js::gc::Cell has this annotation). -# define JS_HAZ_GC_THING __attribute__((tag("GC Thing"))) - -// Mark a type as holding a pointer to a GC thing (eg JS::Value has this -// annotation.) -# define JS_HAZ_GC_POINTER __attribute__((tag("GC Pointer"))) - -// Mark a type as a rooted pointer, suitable for use on the stack (eg all -// Rooted instantiations should have this.) -# define JS_HAZ_ROOTED __attribute__((tag("Rooted Pointer"))) - -// Mark a type as something that should not be held live across a GC, but which -// is not itself a GC pointer. -# define JS_HAZ_GC_INVALIDATED __attribute__((tag("Invalidated by GC"))) - -// Mark a type that would otherwise be considered a GC Pointer (eg because it -// contains a JS::Value field) as a non-GC pointer. It is handled almost the -// same in the analysis as a rooted pointer, except it will not be reported as -// an unnecessary root if used across a GC call. This should rarely be used, -// but makes sense for something like ErrorResult, which only contains a GC -// pointer when it holds an exception (and it does its own rooting, -// conditionally.) -# define JS_HAZ_NON_GC_POINTER __attribute__((tag("Suppressed GC Pointer"))) - -// Mark a function as something that runs a garbage collection, potentially -// invalidating GC pointers. -# define JS_HAZ_GC_CALL __attribute__((tag("GC Call"))) - -// Mark an RAII class as suppressing GC within its scope. -# define JS_HAZ_GC_SUPPRESSED __attribute__((tag("Suppress GC"))) - -#else - -# define JS_HAZ_GC_THING -# define JS_HAZ_GC_POINTER -# define JS_HAZ_ROOTED -# define JS_HAZ_GC_INVALIDATED -# define JS_HAZ_NON_GC_POINTER -# define JS_HAZ_GC_CALL -# define JS_HAZ_GC_SUPPRESSED - -#endif - -#endif /* js_GCAnnotations_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/GCHashTable.h b/android/arm64-v8a/include/spidermonkey/js/GCHashTable.h deleted file mode 100644 index d6c2ce75..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/GCHashTable.h +++ /dev/null @@ -1,399 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 GCHashTable_h -#define GCHashTable_h - -#include "js/GCPolicyAPI.h" -#include "js/HashTable.h" -#include "js/RootingAPI.h" -#include "js/SweepingAPI.h" -#include "js/TracingAPI.h" - -namespace JS { - -// Define a reasonable default GC policy for GC-aware Maps. -template -struct DefaultMapSweepPolicy { - static bool needsSweep(Key* key, Value* value) { - return GCPolicy::needsSweep(key) || GCPolicy::needsSweep(value); - } -}; - -// A GCHashMap is a GC-aware HashMap, meaning that it has additional trace and -// sweep methods that know how to visit all keys and values in the table. -// HashMaps that contain GC pointers will generally want to use this GCHashMap -// specialization instead of HashMap, because this conveniently supports tracing -// keys and values, and cleaning up weak entries. -// -// GCHashMap::trace applies GCPolicy::trace to each entry's key and value. -// Most types of GC pointers already have appropriate specializations of -// GCPolicy, so they should just work as keys and values. Any struct type with a -// default constructor and trace and sweep functions should work as well. If you -// need to define your own GCPolicy specialization, generic helpers can be found -// in js/public/TracingAPI.h. -// -// The MapSweepPolicy template parameter controls how the table drops entries -// when swept. GCHashMap::sweep applies MapSweepPolicy::needsSweep to each table -// entry; if it returns true, the entry is dropped. The default MapSweepPolicy -// drops the entry if either the key or value is about to be finalized, -// according to its GCPolicy::needsSweep method. (This default is almost -// always fine: it's hard to imagine keeping such an entry around anyway.) -// -// Note that this HashMap only knows *how* to trace and sweep, but it does not -// itself cause tracing or sweeping to be invoked. For tracing, it must be used -// with Rooted or PersistentRooted, or barriered and traced manually. For -// sweeping, currently it requires an explicit call to .sweep(). -template , - typename AllocPolicy = js::TempAllocPolicy, - typename MapSweepPolicy = DefaultMapSweepPolicy> -class GCHashMap : public js::HashMap -{ - using Base = js::HashMap; - - public: - explicit GCHashMap(AllocPolicy a = AllocPolicy()) : Base(a) {} - - static void trace(GCHashMap* map, JSTracer* trc) { map->trace(trc); } - void trace(JSTracer* trc) { - if (!this->initialized()) - return; - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - GCPolicy::trace(trc, &e.front().value(), "hashmap value"); - GCPolicy::trace(trc, &e.front().mutableKey(), "hashmap key"); - } - } - - void sweep() { - if (!this->initialized()) - return; - - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - if (MapSweepPolicy::needsSweep(&e.front().mutableKey(), &e.front().value())) - e.removeFront(); - } - } - - // GCHashMap is movable - GCHashMap(GCHashMap&& rhs) : Base(mozilla::Move(rhs)) {} - void operator=(GCHashMap&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - Base::operator=(mozilla::Move(rhs)); - } - - private: - // GCHashMap is not copyable or assignable - GCHashMap(const GCHashMap& hm) = delete; - GCHashMap& operator=(const GCHashMap& hm) = delete; -}; - -} // namespace JS - -namespace js { - -// HashMap that supports rekeying. -// -// If your keys are pointers to something like JSObject that can be tenured or -// compacted, prefer to use GCHashMap with MovableCellHasher, which takes -// advantage of the Zone's stable id table to make rekeying unnecessary. -template , - typename AllocPolicy = TempAllocPolicy, - typename MapSweepPolicy = JS::DefaultMapSweepPolicy> -class GCRekeyableHashMap : public JS::GCHashMap -{ - using Base = JS::GCHashMap; - - public: - explicit GCRekeyableHashMap(AllocPolicy a = AllocPolicy()) : Base(a) {} - - void sweep() { - if (!this->initialized()) - return; - - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - Key key(e.front().key()); - if (MapSweepPolicy::needsSweep(&key, &e.front().value())) - e.removeFront(); - else if (!HashPolicy::match(key, e.front().key())) - e.rekeyFront(key); - } - } - - // GCRekeyableHashMap is movable - GCRekeyableHashMap(GCRekeyableHashMap&& rhs) : Base(mozilla::Move(rhs)) {} - void operator=(GCRekeyableHashMap&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - Base::operator=(mozilla::Move(rhs)); - } -}; - -template -class GCHashMapOperations -{ - using Map = JS::GCHashMap; - using Lookup = typename Map::Lookup; - - const Map& map() const { return static_cast(this)->get(); } - - public: - using AddPtr = typename Map::AddPtr; - using Ptr = typename Map::Ptr; - using Range = typename Map::Range; - - bool initialized() const { return map().initialized(); } - Ptr lookup(const Lookup& l) const { return map().lookup(l); } - AddPtr lookupForAdd(const Lookup& l) const { return map().lookupForAdd(l); } - Range all() const { return map().all(); } - bool empty() const { return map().empty(); } - uint32_t count() const { return map().count(); } - size_t capacity() const { return map().capacity(); } - bool has(const Lookup& l) const { return map().lookup(l).found(); } - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return map().sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + map().sizeOfExcludingThis(mallocSizeOf); - } -}; - -template -class MutableGCHashMapOperations - : public GCHashMapOperations -{ - using Map = JS::GCHashMap; - using Lookup = typename Map::Lookup; - - Map& map() { return static_cast(this)->get(); } - - public: - using AddPtr = typename Map::AddPtr; - struct Enum : public Map::Enum { explicit Enum(Outer& o) : Map::Enum(o.map()) {} }; - using Ptr = typename Map::Ptr; - using Range = typename Map::Range; - - bool init(uint32_t len = 16) { return map().init(len); } - void clear() { map().clear(); } - void finish() { map().finish(); } - void remove(Ptr p) { map().remove(p); } - - template - bool add(AddPtr& p, KeyInput&& k, ValueInput&& v) { - return map().add(p, mozilla::Forward(k), mozilla::Forward(v)); - } - - template - bool add(AddPtr& p, KeyInput&& k) { - return map().add(p, mozilla::Forward(k), Map::Value()); - } - - template - bool relookupOrAdd(AddPtr& p, KeyInput&& k, ValueInput&& v) { - return map().relookupOrAdd(p, k, - mozilla::Forward(k), - mozilla::Forward(v)); - } - - template - bool put(KeyInput&& k, ValueInput&& v) { - return map().put(mozilla::Forward(k), mozilla::Forward(v)); - } - - template - bool putNew(KeyInput&& k, ValueInput&& v) { - return map().putNew(mozilla::Forward(k), mozilla::Forward(v)); - } -}; - -template -class RootedBase> - : public MutableGCHashMapOperations>, A,B,C,D,E> -{}; - -template -class MutableHandleBase> - : public MutableGCHashMapOperations>, A,B,C,D,E> -{}; - -template -class HandleBase> - : public GCHashMapOperations>, A,B,C,D,E> -{}; - -template -class WeakCacheBase> - : public MutableGCHashMapOperations>, A,B,C,D,E> -{}; - -} // namespace js - -namespace JS { - -// A GCHashSet is a HashSet with an additional trace method that knows -// be traced to be kept alive will generally want to use this GCHashSet -// specialization in lieu of HashSet. -// -// Most types of GC pointers can be traced with no extra infrastructure. For -// structs and non-gc-pointer members, ensure that there is a specialization of -// GCPolicy with an appropriate trace method available to handle the custom -// type. Generic helpers can be found in js/public/TracingAPI.h. -// -// Note that although this HashSet's trace will deal correctly with moved -// elements, it does not itself know when to barrier or trace elements. To -// function properly it must either be used with Rooted or barriered and traced -// manually. -template , - typename AllocPolicy = js::TempAllocPolicy> -class GCHashSet : public js::HashSet -{ - using Base = js::HashSet; - - public: - explicit GCHashSet(AllocPolicy a = AllocPolicy()) : Base(a) {} - - static void trace(GCHashSet* set, JSTracer* trc) { set->trace(trc); } - void trace(JSTracer* trc) { - if (!this->initialized()) - return; - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) - GCPolicy::trace(trc, &e.mutableFront(), "hashset element"); - } - - void sweep() { - if (!this->initialized()) - return; - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - if (GCPolicy::needsSweep(&e.mutableFront())) - e.removeFront(); - } - } - - // GCHashSet is movable - GCHashSet(GCHashSet&& rhs) : Base(mozilla::Move(rhs)) {} - void operator=(GCHashSet&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - Base::operator=(mozilla::Move(rhs)); - } - - private: - // GCHashSet is not copyable or assignable - GCHashSet(const GCHashSet& hs) = delete; - GCHashSet& operator=(const GCHashSet& hs) = delete; -}; - -} // namespace JS - -namespace js { - -template -class GCHashSetOperations -{ - using Set = JS::GCHashSet; - using Lookup = typename Set::Lookup; - - const Set& set() const { return static_cast(this)->get(); } - - public: - using AddPtr = typename Set::AddPtr; - using Entry = typename Set::Entry; - using Ptr = typename Set::Ptr; - using Range = typename Set::Range; - - bool initialized() const { return set().initialized(); } - Ptr lookup(const Lookup& l) const { return set().lookup(l); } - AddPtr lookupForAdd(const Lookup& l) const { return set().lookupForAdd(l); } - Range all() const { return set().all(); } - bool empty() const { return set().empty(); } - uint32_t count() const { return set().count(); } - size_t capacity() const { return set().capacity(); } - bool has(const Lookup& l) const { return set().lookup(l).found(); } - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return set().sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + set().sizeOfExcludingThis(mallocSizeOf); - } -}; - -template -class MutableGCHashSetOperations - : public GCHashSetOperations -{ - using Set = JS::GCHashSet; - using Lookup = typename Set::Lookup; - - Set& set() { return static_cast(this)->get(); } - - public: - using AddPtr = typename Set::AddPtr; - using Entry = typename Set::Entry; - struct Enum : public Set::Enum { explicit Enum(Outer& o) : Set::Enum(o.set()) {} }; - using Ptr = typename Set::Ptr; - using Range = typename Set::Range; - - bool init(uint32_t len = 16) { return set().init(len); } - void clear() { set().clear(); } - void finish() { set().finish(); } - void remove(Ptr p) { set().remove(p); } - void remove(const Lookup& l) { set().remove(l); } - - template - bool add(AddPtr& p, TInput&& t) { - return set().add(p, mozilla::Forward(t)); - } - - template - bool relookupOrAdd(AddPtr& p, const Lookup& l, TInput&& t) { - return set().relookupOrAdd(p, l, mozilla::Forward(t)); - } - - template - bool put(TInput&& t) { - return set().put(mozilla::Forward(t)); - } - - template - bool putNew(TInput&& t) { - return set().putNew(mozilla::Forward(t)); - } - - template - bool putNew(const Lookup& l, TInput&& t) { - return set().putNew(l, mozilla::Forward(t)); - } -}; - -template -class RootedBase> - : public MutableGCHashSetOperations>, T, HP, AP> -{ -}; - -template -class MutableHandleBase> - : public MutableGCHashSetOperations>, T, HP, AP> -{ -}; - -template -class HandleBase> - : public GCHashSetOperations>, T, HP, AP> -{ -}; - -template -class WeakCacheBase> - : public MutableGCHashSetOperations>, T, HP, AP> -{ -}; - -} /* namespace js */ - -#endif /* GCHashTable_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/GCPolicyAPI.h b/android/arm64-v8a/include/spidermonkey/js/GCPolicyAPI.h deleted file mode 100644 index 054e397a..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/GCPolicyAPI.h +++ /dev/null @@ -1,164 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -// GC Policy Mechanism - -// A GCPolicy controls how the GC interacts with both direct pointers to GC -// things (e.g. JSObject* or JSString*), tagged and/or optional pointers to GC -// things (e.g. Value or jsid), and C++ container types (e.g. -// JSPropertyDescriptor or GCHashMap). -// -// The GCPolicy provides at a minimum: -// -// static T initial() -// - Construct and return an empty T. -// -// static void trace(JSTracer, T* tp, const char* name) -// - Trace the edge |*tp|, calling the edge |name|. Containers like -// GCHashMap and GCHashSet use this method to trace their children. -// -// static bool needsSweep(T* tp) -// - Return true if |*tp| is about to be finalized. Otherwise, update the -// edge for moving GC, and return false. Containers like GCHashMap and -// GCHashSet use this method to decide when to remove an entry: if this -// function returns true on a key/value/member/etc, its entry is dropped -// from the container. Specializing this method is the standard way to -// get custom weak behavior from a container type. -// -// The default GCPolicy assumes that T has a default constructor and |trace| -// and |needsSweep| methods, and forwards to them. GCPolicy has appropriate -// specializations for pointers to GC things and pointer-like types like -// JS::Heap and mozilla::UniquePtr. -// -// There are some stock structs your specializations can inherit from. -// IgnoreGCPolicy does nothing. StructGCPolicy forwards the methods to the -// referent type T. - -#ifndef GCPolicyAPI_h -#define GCPolicyAPI_h - -#include "mozilla/UniquePtr.h" - -#include "js/TraceKind.h" -#include "js/TracingAPI.h" - -// Expand the given macro D for each public GC pointer. -#define FOR_EACH_PUBLIC_GC_POINTER_TYPE(D) \ - D(JS::Symbol*) \ - D(JSAtom*) \ - D(JSFunction*) \ - D(JSObject*) \ - D(JSScript*) \ - D(JSString*) - -// Expand the given macro D for each public tagged GC pointer type. -#define FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(D) \ - D(JS::Value) \ - D(jsid) - -#define FOR_EACH_PUBLIC_AGGREGATE_GC_POINTER_TYPE(D) \ - D(JSPropertyDescriptor) - -class JSAtom; -class JSFunction; -class JSObject; -class JSScript; -class JSString; -namespace JS { -class Symbol; -} - -namespace JS { - -// Defines a policy for container types with non-GC, i.e. C storage. This -// policy dispatches to the underlying struct for GC interactions. -template -struct StructGCPolicy -{ - static T initial() { - return T(); - } - - static void trace(JSTracer* trc, T* tp, const char* name) { - tp->trace(trc); - } - - static void sweep(T* tp) { - return tp->sweep(); - } - - static bool needsSweep(T* tp) { - return tp->needsSweep(); - } -}; - -// The default GC policy attempts to defer to methods on the underlying type. -// Most C++ structures that contain a default constructor, a trace function and -// a sweep function will work out of the box with Rooted, Handle, GCVector, -// and GCHash{Set,Map}. -template struct GCPolicy : public StructGCPolicy {}; - -// This policy ignores any GC interaction, e.g. for non-GC types. -template -struct IgnoreGCPolicy { - static T initial() { return T(); } - static void trace(JSTracer* trc, T* t, const char* name) {} - static bool needsSweep(T* v) { return false; } -}; -template <> struct GCPolicy : public IgnoreGCPolicy {}; -template <> struct GCPolicy : public IgnoreGCPolicy {}; - -template -struct GCPointerPolicy -{ - static T initial() { return nullptr; } - static void trace(JSTracer* trc, T* vp, const char* name) { - if (*vp) - js::UnsafeTraceManuallyBarrieredEdge(trc, vp, name); - } - static bool needsSweep(T* vp) { - if (*vp) - return js::gc::IsAboutToBeFinalizedUnbarriered(vp); - return false; - } -}; -template <> struct GCPolicy : public GCPointerPolicy {}; -template <> struct GCPolicy : public GCPointerPolicy {}; -template <> struct GCPolicy : public GCPointerPolicy {}; -template <> struct GCPolicy : public GCPointerPolicy {}; -template <> struct GCPolicy : public GCPointerPolicy {}; -template <> struct GCPolicy : public GCPointerPolicy {}; - -template -struct GCPolicy> -{ - static void trace(JSTracer* trc, JS::Heap* thingp, const char* name) { - TraceEdge(trc, thingp, name); - } - static bool needsSweep(JS::Heap* thingp) { - return js::gc::EdgeNeedsSweep(thingp); - } -}; - -// GCPolicy> forwards the contained pointer to GCPolicy. -template -struct GCPolicy> -{ - static mozilla::UniquePtr initial() { return mozilla::UniquePtr(); } - static void trace(JSTracer* trc, mozilla::UniquePtr* tp, const char* name) { - if (tp->get()) - GCPolicy::trace(trc, tp->get(), name); - } - static bool needsSweep(mozilla::UniquePtr* tp) { - if (tp->get()) - return GCPolicy::needsSweep(tp->get()); - return false; - } -}; - -} // namespace JS - -#endif // GCPolicyAPI_h diff --git a/android/arm64-v8a/include/spidermonkey/js/GCVariant.h b/android/arm64-v8a/include/spidermonkey/js/GCVariant.h deleted file mode 100644 index 31ab23f5..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/GCVariant.h +++ /dev/null @@ -1,198 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_GCVariant_h -#define js_GCVariant_h - -#include "mozilla/Variant.h" - -#include "js/GCPolicyAPI.h" -#include "js/RootingAPI.h" -#include "js/TracingAPI.h" - -namespace JS { - -// These template specializations allow Variant to be used inside GC wrappers. -// -// When matching on GC wrappers around Variants, matching should be done on -// the wrapper itself. The matcher class's methods should take Handles or -// MutableHandles. For example, -// -// struct MyMatcher -// { -// using ReturnType = const char*; -// ReturnType match(HandleObject o) { return "object"; } -// ReturnType match(HandleScript s) { return "script"; } -// }; -// -// Rooted> v(cx, someScript); -// MyMatcher mm; -// v.match(mm); -// -// If you get compile errors about inability to upcast subclasses (e.g., from -// NativeObject* to JSObject*) and are inside js/src, be sure to also include -// "gc/Policy.h". - -namespace detail { - -template -struct GCVariantImplementation; - -// The base case. -template -struct GCVariantImplementation -{ - template - static void trace(JSTracer* trc, ConcreteVariant* v, const char* name) { - T& thing = v->template as(); - if (!mozilla::IsPointer::value || thing) - GCPolicy::trace(trc, &thing, name); - } - - template - static typename Matcher::ReturnType - match(Matcher& matcher, Handle v) { - const T& thing = v.get().template as(); - return matcher.match(Handle::fromMarkedLocation(&thing)); - } - - template - static typename Matcher::ReturnType - match(Matcher& matcher, MutableHandle v) { - T& thing = v.get().template as(); - return matcher.match(MutableHandle::fromMarkedLocation(&thing)); - } -}; - -// The inductive case. -template -struct GCVariantImplementation -{ - using Next = GCVariantImplementation; - - template - static void trace(JSTracer* trc, ConcreteVariant* v, const char* name) { - if (v->template is()) { - T& thing = v->template as(); - if (!mozilla::IsPointer::value || thing) - GCPolicy::trace(trc, &thing, name); - } else { - Next::trace(trc, v, name); - } - } - - template - static typename Matcher::ReturnType - match(Matcher& matcher, Handle v) { - if (v.get().template is()) { - const T& thing = v.get().template as(); - return matcher.match(Handle::fromMarkedLocation(&thing)); - } - return Next::match(matcher, v); - } - - template - static typename Matcher::ReturnType - match(Matcher& matcher, MutableHandle v) { - if (v.get().template is()) { - T& thing = v.get().template as(); - return matcher.match(MutableHandle::fromMarkedLocation(&thing)); - } - return Next::match(matcher, v); - } -}; - -} // namespace detail - -template -struct GCPolicy> -{ - using Impl = detail::GCVariantImplementation; - - // Variants do not provide initial(). They do not have a default initial - // value and one must be provided. - - static void trace(JSTracer* trc, mozilla::Variant* v, const char* name) { - Impl::trace(trc, v, name); - } -}; - -} // namespace JS - -namespace js { - -template -class GCVariantOperations -{ - using Impl = JS::detail::GCVariantImplementation; - using Variant = mozilla::Variant; - - const Variant& variant() const { return static_cast(this)->get(); } - - public: - template - bool is() const { - return variant().template is(); - } - - template - JS::Handle as() const { - return Handle::fromMarkedLocation(&variant().template as()); - } - - template - typename Matcher::ReturnType - match(Matcher& matcher) const { - return Impl::match(matcher, JS::Handle::fromMarkedLocation(&variant())); - } -}; - -template -class MutableGCVariantOperations - : public GCVariantOperations -{ - using Impl = JS::detail::GCVariantImplementation; - using Variant = mozilla::Variant; - - const Variant& variant() const { return static_cast(this)->get(); } - Variant& variant() { return static_cast(this)->get(); } - - public: - template - JS::MutableHandle as() { - return JS::MutableHandle::fromMarkedLocation(&variant().template as()); - } - - template - typename Matcher::ReturnType - match(Matcher& matcher) { - return Impl::match(matcher, JS::MutableHandle::fromMarkedLocation(&variant())); - } -}; - -template -class RootedBase> - : public MutableGCVariantOperations>, Ts...> -{ }; - -template -class MutableHandleBase> - : public MutableGCVariantOperations>, Ts...> -{ }; - -template -class HandleBase> - : public GCVariantOperations>, Ts...> -{ }; - -template -class PersistentRootedBase> - : public MutableGCVariantOperations>, Ts...> -{ }; - -} // namespace js - -#endif // js_GCVariant_h diff --git a/android/arm64-v8a/include/spidermonkey/js/GCVector.h b/android/arm64-v8a/include/spidermonkey/js/GCVector.h deleted file mode 100644 index 2668e65b..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/GCVector.h +++ /dev/null @@ -1,249 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_GCVector_h -#define js_GCVector_h - -#include "mozilla/Vector.h" - -#include "js/GCPolicyAPI.h" -#include "js/RootingAPI.h" -#include "js/TracingAPI.h" -#include "js/Vector.h" - -namespace JS { - -// A GCVector is a Vector with an additional trace method that knows how -// to visit all of the items stored in the Vector. For vectors that contain GC -// things, this is usually more convenient than manually iterating and marking -// the contents. -// -// Most types of GC pointers as keys and values can be traced with no extra -// infrastructure. For structs and non-gc-pointer members, ensure that there is -// a specialization of GCPolicy with an appropriate trace method available -// to handle the custom type. Generic helpers can be found in -// js/public/TracingAPI.h. -// -// Note that although this Vector's trace will deal correctly with moved items, -// it does not itself know when to barrier or trace items. To function properly -// it must either be used with Rooted, or barriered and traced manually. -template -class GCVector -{ - mozilla::Vector vector; - - public: - explicit GCVector(AllocPolicy alloc = AllocPolicy()) - : vector(alloc) - {} - - GCVector(GCVector&& vec) - : vector(mozilla::Move(vec.vector)) - {} - - GCVector& operator=(GCVector&& vec) { - vector = mozilla::Move(vec.vector); - return *this; - } - - size_t length() const { return vector.length(); } - bool empty() const { return vector.empty(); } - size_t capacity() const { return vector.capacity(); } - - T* begin() { return vector.begin(); } - const T* begin() const { return vector.begin(); } - - T* end() { return vector.end(); } - const T* end() const { return vector.end(); } - - T& operator[](size_t i) { return vector[i]; } - const T& operator[](size_t i) const { return vector[i]; } - - T& back() { return vector.back(); } - const T& back() const { return vector.back(); } - - bool initCapacity(size_t cap) { return vector.initCapacity(cap); } - bool reserve(size_t req) { return vector.reserve(req); } - void shrinkBy(size_t amount) { return vector.shrinkBy(amount); } - bool growBy(size_t amount) { return vector.growBy(amount); } - bool resize(size_t newLen) { return vector.resize(newLen); } - - void clear() { return vector.clear(); } - - template bool append(U&& item) { return vector.append(mozilla::Forward(item)); } - - template - bool - emplaceBack(Args&&... args) { - return vector.emplaceBack(mozilla::Forward(args)...); - } - - template - void infallibleAppend(U&& aU) { - return vector.infallibleAppend(mozilla::Forward(aU)); - } - void infallibleAppendN(const T& aT, size_t aN) { - return vector.infallibleAppendN(aT, aN); - } - template void - infallibleAppend(const U* aBegin, const U* aEnd) { - return vector.infallibleAppend(aBegin, aEnd); - } - template void infallibleAppend(const U* aBegin, size_t aLength) { - return vector.infallibleAppend(aBegin, aLength); - } - - template - bool appendAll(const mozilla::Vector& aU) { return vector.appendAll(aU); } - template - bool appendAll(const GCVector& aU) { return vector.append(aU.begin(), aU.length()); } - - bool appendN(const T& val, size_t count) { return vector.appendN(val, count); } - - template bool append(const U* aBegin, const U* aEnd) { - return vector.append(aBegin, aEnd); - } - template bool append(const U* aBegin, size_t aLength) { - return vector.append(aBegin, aLength); - } - - void popBack() { return vector.popBack(); } - T popCopy() { return vector.popCopy(); } - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return vector.sizeOfExcludingThis(mallocSizeOf); - } - - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return vector.sizeOfIncludingThis(mallocSizeOf); - } - - static void trace(GCVector* vec, JSTracer* trc) { vec->trace(trc); } - - void trace(JSTracer* trc) { - for (auto& elem : vector) - GCPolicy::trace(trc, &elem, "vector element"); - } -}; - -} // namespace JS - -namespace js { - -template -class GCVectorOperations -{ - using Vec = JS::GCVector; - const Vec& vec() const { return static_cast(this)->get(); } - - public: - const AllocPolicy& allocPolicy() const { return vec().allocPolicy(); } - size_t length() const { return vec().length(); } - bool empty() const { return vec().empty(); } - size_t capacity() const { return vec().capacity(); } - const T* begin() const { return vec().begin(); } - const T* end() const { return vec().end(); } - const T& back() const { return vec().back(); } - - JS::Handle operator[](size_t aIndex) const { - return JS::Handle::fromMarkedLocation(&vec().operator[](aIndex)); - } -}; - -template -class MutableGCVectorOperations - : public GCVectorOperations -{ - using Vec = JS::GCVector; - const Vec& vec() const { return static_cast(this)->get(); } - Vec& vec() { return static_cast(this)->get(); } - - public: - const AllocPolicy& allocPolicy() const { return vec().allocPolicy(); } - AllocPolicy& allocPolicy() { return vec().allocPolicy(); } - const T* begin() const { return vec().begin(); } - T* begin() { return vec().begin(); } - const T* end() const { return vec().end(); } - T* end() { return vec().end(); } - const T& back() const { return vec().back(); } - T& back() { return vec().back(); } - - JS::Handle operator[](size_t aIndex) const { - return JS::Handle::fromMarkedLocation(&vec().operator[](aIndex)); - } - JS::MutableHandle operator[](size_t aIndex) { - return JS::MutableHandle::fromMarkedLocation(&vec().operator[](aIndex)); - } - - bool initCapacity(size_t aRequest) { return vec().initCapacity(aRequest); } - bool reserve(size_t aRequest) { return vec().reserve(aRequest); } - void shrinkBy(size_t aIncr) { vec().shrinkBy(aIncr); } - bool growBy(size_t aIncr) { return vec().growBy(aIncr); } - bool resize(size_t aNewLength) { return vec().resize(aNewLength); } - bool growByUninitialized(size_t aIncr) { return vec().growByUninitialized(aIncr); } - void infallibleGrowByUninitialized(size_t aIncr) { vec().infallibleGrowByUninitialized(aIncr); } - bool resizeUninitialized(size_t aNewLength) { return vec().resizeUninitialized(aNewLength); } - void clear() { vec().clear(); } - void clearAndFree() { vec().clearAndFree(); } - template bool append(U&& aU) { return vec().append(mozilla::Forward(aU)); } - template bool emplaceBack(Args&&... aArgs) { - return vec().emplaceBack(mozilla::Forward(aArgs...)); - } - template - bool appendAll(const mozilla::Vector& aU) { return vec().appendAll(aU); } - template - bool appendAll(const JS::GCVector& aU) { return vec().appendAll(aU); } - bool appendN(const T& aT, size_t aN) { return vec().appendN(aT, aN); } - template bool append(const U* aBegin, const U* aEnd) { - return vec().append(aBegin, aEnd); - } - template bool append(const U* aBegin, size_t aLength) { - return vec().append(aBegin, aLength); - } - template void infallibleAppend(U&& aU) { - vec().infallibleAppend(mozilla::Forward(aU)); - } - void infallibleAppendN(const T& aT, size_t aN) { vec().infallibleAppendN(aT, aN); } - template void infallibleAppend(const U* aBegin, const U* aEnd) { - vec().infallibleAppend(aBegin, aEnd); - } - template void infallibleAppend(const U* aBegin, size_t aLength) { - vec().infallibleAppend(aBegin, aLength); - } - void popBack() { vec().popBack(); } - T popCopy() { return vec().popCopy(); } - template T* insert(T* aP, U&& aVal) { - return vec().insert(aP, mozilla::Forward(aVal)); - } - void erase(T* aT) { vec().erase(aT); } - void erase(T* aBegin, T* aEnd) { vec().erase(aBegin, aEnd); } -}; - -template -class RootedBase> - : public MutableGCVectorOperations>, T,N,AP> -{}; - -template -class MutableHandleBase> - : public MutableGCVectorOperations>, T,N,AP> -{}; - -template -class HandleBase> - : public GCVectorOperations>, T,N,AP> -{}; - -template -class PersistentRootedBase> - : public MutableGCVectorOperations>, T,N,AP> -{}; - -} // namespace js - -#endif // js_GCVector_h diff --git a/android/arm64-v8a/include/spidermonkey/js/HashTable.h b/android/arm64-v8a/include/spidermonkey/js/HashTable.h deleted file mode 100644 index 5d4c0665..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/HashTable.h +++ /dev/null @@ -1,1880 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_HashTable_h -#define js_HashTable_h - -#include "mozilla/Alignment.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Casting.h" -#include "mozilla/HashFunctions.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" -#include "mozilla/Opaque.h" -#include "mozilla/PodOperations.h" -#include "mozilla/ReentrancyGuard.h" -#include "mozilla/TemplateLib.h" -#include "mozilla/TypeTraits.h" -#include "mozilla/UniquePtr.h" - -#include "js/Utility.h" - -namespace js { - -class TempAllocPolicy; -template struct DefaultHasher; -template class HashMapEntry; -namespace detail { - template class HashTableEntry; - template class HashTable; -} // namespace detail - -/*****************************************************************************/ - -// The "generation" of a hash table is an opaque value indicating the state of -// modification of the hash table through its lifetime. If the generation of -// a hash table compares equal at times T1 and T2, then lookups in the hash -// table, pointers to (or into) hash table entries, etc. at time T1 are valid -// at time T2. If the generation compares unequal, these computations are all -// invalid and must be performed again to be used. -// -// Generations are meaningfully comparable only with respect to a single hash -// table. It's always nonsensical to compare the generation of distinct hash -// tables H1 and H2. -using Generation = mozilla::Opaque; - -// A JS-friendly, STL-like container providing a hash-based map from keys to -// values. In particular, HashMap calls constructors and destructors of all -// objects added so non-PODs may be used safely. -// -// Key/Value requirements: -// - movable, destructible, assignable -// HashPolicy requirements: -// - see Hash Policy section below -// AllocPolicy: -// - see jsalloc.h -// -// Note: -// - HashMap is not reentrant: Key/Value/HashPolicy/AllocPolicy members -// called by HashMap must not call back into the same HashMap object. -// - Due to the lack of exception handling, the user must call |init()|. -template , - class AllocPolicy = TempAllocPolicy> -class HashMap -{ - typedef HashMapEntry TableEntry; - - struct MapHashPolicy : HashPolicy - { - using Base = HashPolicy; - typedef Key KeyType; - static const Key& getKey(TableEntry& e) { return e.key(); } - static void setKey(TableEntry& e, Key& k) { HashPolicy::rekey(e.mutableKey(), k); } - }; - - typedef detail::HashTable Impl; - Impl impl; - - public: - typedef typename HashPolicy::Lookup Lookup; - typedef TableEntry Entry; - - // HashMap construction is fallible (due to OOM); thus the user must call - // init after constructing a HashMap and check the return value. - explicit HashMap(AllocPolicy a = AllocPolicy()) : impl(a) {} - MOZ_MUST_USE bool init(uint32_t len = 16) { return impl.init(len); } - bool initialized() const { return impl.initialized(); } - - // Return whether the given lookup value is present in the map. E.g.: - // - // typedef HashMap HM; - // HM h; - // if (HM::Ptr p = h.lookup(3)) { - // const HM::Entry& e = *p; // p acts like a pointer to Entry - // assert(p->key == 3); // Entry contains the key - // char val = p->value; // and value - // } - // - // Also see the definition of Ptr in HashTable above (with T = Entry). - typedef typename Impl::Ptr Ptr; - Ptr lookup(const Lookup& l) const { return impl.lookup(l); } - - // Like lookup, but does not assert if two threads call lookup at the same - // time. Only use this method when none of the threads will modify the map. - Ptr readonlyThreadsafeLookup(const Lookup& l) const { return impl.readonlyThreadsafeLookup(l); } - - // Assuming |p.found()|, remove |*p|. - void remove(Ptr p) { impl.remove(p); } - - // Like |lookup(l)|, but on miss, |p = lookupForAdd(l)| allows efficient - // insertion of Key |k| (where |HashPolicy::match(k,l) == true|) using - // |add(p,k,v)|. After |add(p,k,v)|, |p| points to the new Entry. E.g.: - // - // typedef HashMap HM; - // HM h; - // HM::AddPtr p = h.lookupForAdd(3); - // if (!p) { - // if (!h.add(p, 3, 'a')) - // return false; - // } - // const HM::Entry& e = *p; // p acts like a pointer to Entry - // assert(p->key == 3); // Entry contains the key - // char val = p->value; // and value - // - // Also see the definition of AddPtr in HashTable above (with T = Entry). - // - // N.B. The caller must ensure that no mutating hash table operations - // occur between a pair of |lookupForAdd| and |add| calls. To avoid - // looking up the key a second time, the caller may use the more efficient - // relookupOrAdd method. This method reuses part of the hashing computation - // to more efficiently insert the key if it has not been added. For - // example, a mutation-handling version of the previous example: - // - // HM::AddPtr p = h.lookupForAdd(3); - // if (!p) { - // call_that_may_mutate_h(); - // if (!h.relookupOrAdd(p, 3, 'a')) - // return false; - // } - // const HM::Entry& e = *p; - // assert(p->key == 3); - // char val = p->value; - typedef typename Impl::AddPtr AddPtr; - AddPtr lookupForAdd(const Lookup& l) const { - return impl.lookupForAdd(l); - } - - template - MOZ_MUST_USE bool add(AddPtr& p, KeyInput&& k, ValueInput&& v) { - return impl.add(p, - mozilla::Forward(k), - mozilla::Forward(v)); - } - - template - MOZ_MUST_USE bool add(AddPtr& p, KeyInput&& k) { - return impl.add(p, mozilla::Forward(k), Value()); - } - - template - MOZ_MUST_USE bool relookupOrAdd(AddPtr& p, KeyInput&& k, ValueInput&& v) { - return impl.relookupOrAdd(p, k, - mozilla::Forward(k), - mozilla::Forward(v)); - } - - // |all()| returns a Range containing |count()| elements. E.g.: - // - // typedef HashMap HM; - // HM h; - // for (HM::Range r = h.all(); !r.empty(); r.popFront()) - // char c = r.front().value(); - // - // Also see the definition of Range in HashTable above (with T = Entry). - typedef typename Impl::Range Range; - Range all() const { return impl.all(); } - - // Typedef for the enumeration class. An Enum may be used to examine and - // remove table entries: - // - // typedef HashMap HM; - // HM s; - // for (HM::Enum e(s); !e.empty(); e.popFront()) - // if (e.front().value() == 'l') - // e.removeFront(); - // - // Table resize may occur in Enum's destructor. Also see the definition of - // Enum in HashTable above (with T = Entry). - typedef typename Impl::Enum Enum; - - // Remove all entries. This does not shrink the table. For that consider - // using the finish() method. - void clear() { impl.clear(); } - - // Remove all the entries and release all internal buffers. The map must - // be initialized again before any use. - void finish() { impl.finish(); } - - // Does the table contain any entries? - bool empty() const { return impl.empty(); } - - // Number of live elements in the map. - uint32_t count() const { return impl.count(); } - - // Total number of allocation in the dynamic table. Note: resize will - // happen well before count() == capacity(). - size_t capacity() const { return impl.capacity(); } - - // Don't just call |impl.sizeOfExcludingThis()| because there's no - // guarantee that |impl| is the first field in HashMap. - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return impl.sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + impl.sizeOfExcludingThis(mallocSizeOf); - } - - Generation generation() const { - return impl.generation(); - } - - /************************************************** Shorthand operations */ - - bool has(const Lookup& l) const { - return impl.lookup(l).found(); - } - - // Overwrite existing value with v. Return false on oom. - template - MOZ_MUST_USE bool put(KeyInput&& k, ValueInput&& v) { - AddPtr p = lookupForAdd(k); - if (p) { - p->value() = mozilla::Forward(v); - return true; - } - return add(p, mozilla::Forward(k), mozilla::Forward(v)); - } - - // Like put, but assert that the given key is not already present. - template - MOZ_MUST_USE bool putNew(KeyInput&& k, ValueInput&& v) { - return impl.putNew(k, mozilla::Forward(k), mozilla::Forward(v)); - } - - // Only call this to populate an empty map after reserving space with init(). - template - void putNewInfallible(KeyInput&& k, ValueInput&& v) { - impl.putNewInfallible(k, mozilla::Forward(k), mozilla::Forward(v)); - } - - // Add (k,defaultValue) if |k| is not found. Return a false-y Ptr on oom. - Ptr lookupWithDefault(const Key& k, const Value& defaultValue) { - AddPtr p = lookupForAdd(k); - if (p) - return p; - bool ok = add(p, k, defaultValue); - MOZ_ASSERT_IF(!ok, !p); // p is left false-y on oom. - (void)ok; - return p; - } - - // Remove if present. - void remove(const Lookup& l) { - if (Ptr p = lookup(l)) - remove(p); - } - - // Infallibly rekey one entry, if necessary. - // Requires template parameters Key and HashPolicy::Lookup to be the same type. - void rekeyIfMoved(const Key& old_key, const Key& new_key) { - if (old_key != new_key) - rekeyAs(old_key, new_key, new_key); - } - - // Infallibly rekey one entry if present, and return whether that happened. - bool rekeyAs(const Lookup& old_lookup, const Lookup& new_lookup, const Key& new_key) { - if (Ptr p = lookup(old_lookup)) { - impl.rekeyAndMaybeRehash(p, new_lookup, new_key); - return true; - } - return false; - } - - // HashMap is movable - HashMap(HashMap&& rhs) : impl(mozilla::Move(rhs.impl)) {} - void operator=(HashMap&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - impl = mozilla::Move(rhs.impl); - } - - private: - // HashMap is not copyable or assignable - HashMap(const HashMap& hm) = delete; - HashMap& operator=(const HashMap& hm) = delete; - - friend class Impl::Enum; -}; - -/*****************************************************************************/ - -// A JS-friendly, STL-like container providing a hash-based set of values. In -// particular, HashSet calls constructors and destructors of all objects added -// so non-PODs may be used safely. -// -// T requirements: -// - movable, destructible, assignable -// HashPolicy requirements: -// - see Hash Policy section below -// AllocPolicy: -// - see jsalloc.h -// -// Note: -// - HashSet is not reentrant: T/HashPolicy/AllocPolicy members called by -// HashSet must not call back into the same HashSet object. -// - Due to the lack of exception handling, the user must call |init()|. -template , - class AllocPolicy = TempAllocPolicy> -class HashSet -{ - struct SetOps : HashPolicy - { - using Base = HashPolicy; - typedef T KeyType; - static const KeyType& getKey(const T& t) { return t; } - static void setKey(T& t, KeyType& k) { HashPolicy::rekey(t, k); } - }; - - typedef detail::HashTable Impl; - Impl impl; - - public: - typedef typename HashPolicy::Lookup Lookup; - typedef T Entry; - - // HashSet construction is fallible (due to OOM); thus the user must call - // init after constructing a HashSet and check the return value. - explicit HashSet(AllocPolicy a = AllocPolicy()) : impl(a) {} - MOZ_MUST_USE bool init(uint32_t len = 16) { return impl.init(len); } - bool initialized() const { return impl.initialized(); } - - // Return whether the given lookup value is present in the map. E.g.: - // - // typedef HashSet HS; - // HS h; - // if (HS::Ptr p = h.lookup(3)) { - // assert(*p == 3); // p acts like a pointer to int - // } - // - // Also see the definition of Ptr in HashTable above. - typedef typename Impl::Ptr Ptr; - Ptr lookup(const Lookup& l) const { return impl.lookup(l); } - - // Like lookup, but does not assert if two threads call lookup at the same - // time. Only use this method when none of the threads will modify the map. - Ptr readonlyThreadsafeLookup(const Lookup& l) const { return impl.readonlyThreadsafeLookup(l); } - - // Assuming |p.found()|, remove |*p|. - void remove(Ptr p) { impl.remove(p); } - - // Like |lookup(l)|, but on miss, |p = lookupForAdd(l)| allows efficient - // insertion of T value |t| (where |HashPolicy::match(t,l) == true|) using - // |add(p,t)|. After |add(p,t)|, |p| points to the new element. E.g.: - // - // typedef HashSet HS; - // HS h; - // HS::AddPtr p = h.lookupForAdd(3); - // if (!p) { - // if (!h.add(p, 3)) - // return false; - // } - // assert(*p == 3); // p acts like a pointer to int - // - // Also see the definition of AddPtr in HashTable above. - // - // N.B. The caller must ensure that no mutating hash table operations - // occur between a pair of |lookupForAdd| and |add| calls. To avoid - // looking up the key a second time, the caller may use the more efficient - // relookupOrAdd method. This method reuses part of the hashing computation - // to more efficiently insert the key if it has not been added. For - // example, a mutation-handling version of the previous example: - // - // HS::AddPtr p = h.lookupForAdd(3); - // if (!p) { - // call_that_may_mutate_h(); - // if (!h.relookupOrAdd(p, 3, 3)) - // return false; - // } - // assert(*p == 3); - // - // Note that relookupOrAdd(p,l,t) performs Lookup using |l| and adds the - // entry |t|, where the caller ensures match(l,t). - typedef typename Impl::AddPtr AddPtr; - AddPtr lookupForAdd(const Lookup& l) const { return impl.lookupForAdd(l); } - - template - MOZ_MUST_USE bool add(AddPtr& p, U&& u) { - return impl.add(p, mozilla::Forward(u)); - } - - template - MOZ_MUST_USE bool relookupOrAdd(AddPtr& p, const Lookup& l, U&& u) { - return impl.relookupOrAdd(p, l, mozilla::Forward(u)); - } - - // |all()| returns a Range containing |count()| elements: - // - // typedef HashSet HS; - // HS h; - // for (HS::Range r = h.all(); !r.empty(); r.popFront()) - // int i = r.front(); - // - // Also see the definition of Range in HashTable above. - typedef typename Impl::Range Range; - Range all() const { return impl.all(); } - - // Typedef for the enumeration class. An Enum may be used to examine and - // remove table entries: - // - // typedef HashSet HS; - // HS s; - // for (HS::Enum e(s); !e.empty(); e.popFront()) - // if (e.front() == 42) - // e.removeFront(); - // - // Table resize may occur in Enum's destructor. Also see the definition of - // Enum in HashTable above. - typedef typename Impl::Enum Enum; - - // Remove all entries. This does not shrink the table. For that consider - // using the finish() method. - void clear() { impl.clear(); } - - // Remove all the entries and release all internal buffers. The set must - // be initialized again before any use. - void finish() { impl.finish(); } - - // Does the table contain any entries? - bool empty() const { return impl.empty(); } - - // Number of live elements in the map. - uint32_t count() const { return impl.count(); } - - // Total number of allocation in the dynamic table. Note: resize will - // happen well before count() == capacity(). - size_t capacity() const { return impl.capacity(); } - - // Don't just call |impl.sizeOfExcludingThis()| because there's no - // guarantee that |impl| is the first field in HashSet. - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return impl.sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + impl.sizeOfExcludingThis(mallocSizeOf); - } - - Generation generation() const { - return impl.generation(); - } - - /************************************************** Shorthand operations */ - - bool has(const Lookup& l) const { - return impl.lookup(l).found(); - } - - // Add |u| if it is not present already. Return false on oom. - template - MOZ_MUST_USE bool put(U&& u) { - AddPtr p = lookupForAdd(u); - return p ? true : add(p, mozilla::Forward(u)); - } - - // Like put, but assert that the given key is not already present. - template - MOZ_MUST_USE bool putNew(U&& u) { - return impl.putNew(u, mozilla::Forward(u)); - } - - template - MOZ_MUST_USE bool putNew(const Lookup& l, U&& u) { - return impl.putNew(l, mozilla::Forward(u)); - } - - // Only call this to populate an empty set after reserving space with init(). - template - void putNewInfallible(const Lookup& l, U&& u) { - impl.putNewInfallible(l, mozilla::Forward(u)); - } - - void remove(const Lookup& l) { - if (Ptr p = lookup(l)) - remove(p); - } - - // Infallibly rekey one entry, if present. - // Requires template parameters T and HashPolicy::Lookup to be the same type. - void rekeyIfMoved(const Lookup& old_value, const T& new_value) { - if (old_value != new_value) - rekeyAs(old_value, new_value, new_value); - } - - // Infallibly rekey one entry if present, and return whether that happened. - bool rekeyAs(const Lookup& old_lookup, const Lookup& new_lookup, const T& new_value) { - if (Ptr p = lookup(old_lookup)) { - impl.rekeyAndMaybeRehash(p, new_lookup, new_value); - return true; - } - return false; - } - - // Infallibly replace the current key at |p| with an equivalent key. - // Specifically, both HashPolicy::hash and HashPolicy::match must return - // identical results for the new and old key when applied against all - // possible matching values. - void replaceKey(Ptr p, const T& new_value) { - MOZ_ASSERT(p.found()); - MOZ_ASSERT(*p != new_value); - MOZ_ASSERT(HashPolicy::hash(*p) == HashPolicy::hash(new_value)); - MOZ_ASSERT(HashPolicy::match(*p, new_value)); - const_cast(*p) = new_value; - } - - // HashSet is movable - HashSet(HashSet&& rhs) : impl(mozilla::Move(rhs.impl)) {} - void operator=(HashSet&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - impl = mozilla::Move(rhs.impl); - } - - private: - // HashSet is not copyable or assignable - HashSet(const HashSet& hs) = delete; - HashSet& operator=(const HashSet& hs) = delete; - - friend class Impl::Enum; -}; - -/*****************************************************************************/ - -// Hash Policy -// -// A hash policy P for a hash table with key-type Key must provide: -// - a type |P::Lookup| to use to lookup table entries; -// - a static member function |P::hash| with signature -// -// static js::HashNumber hash(Lookup) -// -// to use to hash the lookup type; and -// - a static member function |P::match| with signature -// -// static bool match(Key, Lookup) -// -// to use to test equality of key and lookup values. -// -// Normally, Lookup = Key. In general, though, different values and types of -// values can be used to lookup and store. If a Lookup value |l| is != to the -// added Key value |k|, the user must ensure that |P::match(k,l)|. E.g.: -// -// js::HashSet::AddPtr p = h.lookup(l); -// if (!p) { -// assert(P::match(k, l)); // must hold -// h.add(p, k); -// } - -// Pointer hashing policy that strips the lowest zeroBits when calculating the -// hash to improve key distribution. -template -struct PointerHasher -{ - typedef Key Lookup; - static HashNumber hash(const Lookup& l) { - size_t word = reinterpret_cast(l) >> zeroBits; - static_assert(sizeof(HashNumber) == 4, - "subsequent code assumes a four-byte hash"); -#if JS_BITS_PER_WORD == 32 - return HashNumber(word); -#else - static_assert(sizeof(word) == 8, - "unexpected word size, new hashing strategy required to " - "properly incorporate all bits"); - return HashNumber((word >> 32) ^ word); -#endif - } - static bool match(const Key& k, const Lookup& l) { - return k == l; - } - static void rekey(Key& k, const Key& newKey) { - k = newKey; - } -}; - -// Default hash policy: just use the 'lookup' value. This of course only -// works if the lookup value is integral. HashTable applies ScrambleHashCode to -// the result of the 'hash' which means that it is 'ok' if the lookup value is -// not well distributed over the HashNumber domain. -template -struct DefaultHasher -{ - typedef Key Lookup; - static HashNumber hash(const Lookup& l) { - // Hash if can implicitly cast to hash number type. - return l; - } - static bool match(const Key& k, const Lookup& l) { - // Use builtin or overloaded operator==. - return k == l; - } - static void rekey(Key& k, const Key& newKey) { - k = newKey; - } -}; - -// Specialize hashing policy for pointer types. It assumes that the type is -// at least word-aligned. For types with smaller size use PointerHasher. -template -struct DefaultHasher : PointerHasher::value> -{}; - -// Specialize hashing policy for mozilla::UniquePtr to proxy the UniquePtr's -// raw pointer to PointerHasher. -template -struct DefaultHasher> -{ - using Lookup = mozilla::UniquePtr; - using PtrHasher = PointerHasher::value>; - - static HashNumber hash(const Lookup& l) { - return PtrHasher::hash(l.get()); - } - static bool match(const mozilla::UniquePtr& k, const Lookup& l) { - return PtrHasher::match(k.get(), l.get()); - } - static void rekey(mozilla::UniquePtr& k, mozilla::UniquePtr&& newKey) { - k = mozilla::Move(newKey); - } -}; - -// For doubles, we can xor the two uint32s. -template <> -struct DefaultHasher -{ - typedef double Lookup; - static HashNumber hash(double d) { - static_assert(sizeof(HashNumber) == 4, - "subsequent code assumes a four-byte hash"); - uint64_t u = mozilla::BitwiseCast(d); - return HashNumber(u ^ (u >> 32)); - } - static bool match(double lhs, double rhs) { - return mozilla::BitwiseCast(lhs) == mozilla::BitwiseCast(rhs); - } -}; - -template <> -struct DefaultHasher -{ - typedef float Lookup; - static HashNumber hash(float f) { - static_assert(sizeof(HashNumber) == 4, - "subsequent code assumes a four-byte hash"); - return HashNumber(mozilla::BitwiseCast(f)); - } - static bool match(float lhs, float rhs) { - return mozilla::BitwiseCast(lhs) == mozilla::BitwiseCast(rhs); - } -}; - -// A hash policy that compares C strings. -struct CStringHasher -{ - typedef const char* Lookup; - static js::HashNumber hash(Lookup l) { - return mozilla::HashString(l); - } - static bool match(const char* key, Lookup lookup) { - return strcmp(key, lookup) == 0; - } -}; - -// Fallible hashing interface. -// -// Most of the time generating a hash code is infallible so this class provides -// default methods that always succeed. Specialize this class for your own hash -// policy to provide fallible hashing. -// -// This is used by MovableCellHasher to handle the fact that generating a unique -// ID for cell pointer may fail due to OOM. -template -struct FallibleHashMethods -{ - // Return true if a hashcode is already available for its argument. Once - // this returns true for a specific argument it must continue to do so. - template static bool hasHash(Lookup&& l) { return true; } - - // Fallible method to ensure a hashcode exists for its argument and create - // one if not. Returns false on error, e.g. out of memory. - template static bool ensureHash(Lookup&& l) { return true; } -}; - -template -static bool -HasHash(Lookup&& l) { - return FallibleHashMethods::hasHash(mozilla::Forward(l)); -} - -template -static bool -EnsureHash(Lookup&& l) { - return FallibleHashMethods::ensureHash(mozilla::Forward(l)); -} - -/*****************************************************************************/ - -// Both HashMap and HashSet are implemented by a single HashTable that is even -// more heavily parameterized than the other two. This leaves HashTable gnarly -// and extremely coupled to HashMap and HashSet; thus code should not use -// HashTable directly. - -template -class HashMapEntry -{ - Key key_; - Value value_; - - template friend class detail::HashTable; - template friend class detail::HashTableEntry; - template friend class HashMap; - - public: - template - HashMapEntry(KeyInput&& k, ValueInput&& v) - : key_(mozilla::Forward(k)), - value_(mozilla::Forward(v)) - {} - - HashMapEntry(HashMapEntry&& rhs) - : key_(mozilla::Move(rhs.key_)), - value_(mozilla::Move(rhs.value_)) - {} - - void operator=(HashMapEntry&& rhs) { - key_ = mozilla::Move(rhs.key_); - value_ = mozilla::Move(rhs.value_); - } - - typedef Key KeyType; - typedef Value ValueType; - - const Key& key() const { return key_; } - Key& mutableKey() { return key_; } - const Value& value() const { return value_; } - Value& value() { return value_; } - - private: - HashMapEntry(const HashMapEntry&) = delete; - void operator=(const HashMapEntry&) = delete; -}; - -} // namespace js - -namespace mozilla { - -template -struct IsPod > : IsPod {}; - -template -struct IsPod > - : IntegralConstant::value && IsPod::value> -{}; - -} // namespace mozilla - -namespace js { - -namespace detail { - -template -class HashTable; - -template -class HashTableEntry -{ - template friend class HashTable; - typedef typename mozilla::RemoveConst::Type NonConstT; - - HashNumber keyHash; - mozilla::AlignedStorage2 mem; - - static const HashNumber sFreeKey = 0; - static const HashNumber sRemovedKey = 1; - static const HashNumber sCollisionBit = 1; - - static bool isLiveHash(HashNumber hash) - { - return hash > sRemovedKey; - } - - HashTableEntry(const HashTableEntry&) = delete; - void operator=(const HashTableEntry&) = delete; - ~HashTableEntry() = delete; - - public: - // NB: HashTableEntry is treated as a POD: no constructor or destructor calls. - - void destroyIfLive() { - if (isLive()) - mem.addr()->~T(); - } - - void destroy() { - MOZ_ASSERT(isLive()); - mem.addr()->~T(); - } - - void swap(HashTableEntry* other) { - if (this == other) - return; - MOZ_ASSERT(isLive()); - if (other->isLive()) { - mozilla::Swap(*mem.addr(), *other->mem.addr()); - } else { - *other->mem.addr() = mozilla::Move(*mem.addr()); - destroy(); - } - mozilla::Swap(keyHash, other->keyHash); - } - - T& get() { MOZ_ASSERT(isLive()); return *mem.addr(); } - NonConstT& getMutable() { MOZ_ASSERT(isLive()); return *mem.addr(); } - - bool isFree() const { return keyHash == sFreeKey; } - void clearLive() { MOZ_ASSERT(isLive()); keyHash = sFreeKey; mem.addr()->~T(); } - void clear() { if (isLive()) mem.addr()->~T(); keyHash = sFreeKey; } - bool isRemoved() const { return keyHash == sRemovedKey; } - void removeLive() { MOZ_ASSERT(isLive()); keyHash = sRemovedKey; mem.addr()->~T(); } - bool isLive() const { return isLiveHash(keyHash); } - void setCollision() { MOZ_ASSERT(isLive()); keyHash |= sCollisionBit; } - void unsetCollision() { keyHash &= ~sCollisionBit; } - bool hasCollision() const { return keyHash & sCollisionBit; } - bool matchHash(HashNumber hn) { return (keyHash & ~sCollisionBit) == hn; } - HashNumber getKeyHash() const { return keyHash & ~sCollisionBit; } - - template - void setLive(HashNumber hn, Args&&... args) - { - MOZ_ASSERT(!isLive()); - keyHash = hn; - new(mem.addr()) T(mozilla::Forward(args)...); - MOZ_ASSERT(isLive()); - } -}; - -template -class HashTable : private AllocPolicy -{ - friend class mozilla::ReentrancyGuard; - - typedef typename mozilla::RemoveConst::Type NonConstT; - typedef typename HashPolicy::KeyType Key; - typedef typename HashPolicy::Lookup Lookup; - - public: - typedef HashTableEntry Entry; - - // A nullable pointer to a hash table element. A Ptr |p| can be tested - // either explicitly |if (p.found()) p->...| or using boolean conversion - // |if (p) p->...|. Ptr objects must not be used after any mutating hash - // table operations unless |generation()| is tested. - class Ptr - { - friend class HashTable; - - Entry* entry_; -#ifdef JS_DEBUG - const HashTable* table_; - Generation generation; -#endif - - protected: - Ptr(Entry& entry, const HashTable& tableArg) - : entry_(&entry) -#ifdef JS_DEBUG - , table_(&tableArg) - , generation(tableArg.generation()) -#endif - {} - - public: - Ptr() - : entry_(nullptr) -#ifdef JS_DEBUG - , table_(nullptr) - , generation(0) -#endif - {} - - bool isValid() const { - return !entry_; - } - - bool found() const { - if (isValid()) - return false; -#ifdef JS_DEBUG - MOZ_ASSERT(generation == table_->generation()); -#endif - return entry_->isLive(); - } - - explicit operator bool() const { - return found(); - } - - bool operator==(const Ptr& rhs) const { - MOZ_ASSERT(found() && rhs.found()); - return entry_ == rhs.entry_; - } - - bool operator!=(const Ptr& rhs) const { -#ifdef JS_DEBUG - MOZ_ASSERT(generation == table_->generation()); -#endif - return !(*this == rhs); - } - - T& operator*() const { -#ifdef JS_DEBUG - MOZ_ASSERT(found()); - MOZ_ASSERT(generation == table_->generation()); -#endif - return entry_->get(); - } - - T* operator->() const { -#ifdef JS_DEBUG - MOZ_ASSERT(found()); - MOZ_ASSERT(generation == table_->generation()); -#endif - return &entry_->get(); - } - }; - - // A Ptr that can be used to add a key after a failed lookup. - class AddPtr : public Ptr - { - friend class HashTable; - HashNumber keyHash; -#ifdef JS_DEBUG - uint64_t mutationCount; -#endif - - AddPtr(Entry& entry, const HashTable& tableArg, HashNumber hn) - : Ptr(entry, tableArg) - , keyHash(hn) -#ifdef JS_DEBUG - , mutationCount(tableArg.mutationCount) -#endif - {} - - public: - AddPtr() : keyHash(0) {} - }; - - // A collection of hash table entries. The collection is enumerated by - // calling |front()| followed by |popFront()| as long as |!empty()|. As - // with Ptr/AddPtr, Range objects must not be used after any mutating hash - // table operation unless the |generation()| is tested. - class Range - { - protected: - friend class HashTable; - - Range(const HashTable& tableArg, Entry* c, Entry* e) - : cur(c) - , end(e) -#ifdef JS_DEBUG - , table_(&tableArg) - , mutationCount(tableArg.mutationCount) - , generation(tableArg.generation()) - , validEntry(true) -#endif - { - while (cur < end && !cur->isLive()) - ++cur; - } - - Entry* cur; - Entry* end; -#ifdef JS_DEBUG - const HashTable* table_; - uint64_t mutationCount; - Generation generation; - bool validEntry; -#endif - - public: - Range() - : cur(nullptr) - , end(nullptr) -#ifdef JS_DEBUG - , table_(nullptr) - , mutationCount(0) - , generation(0) - , validEntry(false) -#endif - {} - - bool empty() const { -#ifdef JS_DEBUG - MOZ_ASSERT(generation == table_->generation()); - MOZ_ASSERT(mutationCount == table_->mutationCount); -#endif - return cur == end; - } - - T& front() const { - MOZ_ASSERT(!empty()); -#ifdef JS_DEBUG - MOZ_ASSERT(validEntry); - MOZ_ASSERT(generation == table_->generation()); - MOZ_ASSERT(mutationCount == table_->mutationCount); -#endif - return cur->get(); - } - - void popFront() { - MOZ_ASSERT(!empty()); -#ifdef JS_DEBUG - MOZ_ASSERT(generation == table_->generation()); - MOZ_ASSERT(mutationCount == table_->mutationCount); -#endif - while (++cur < end && !cur->isLive()) - continue; -#ifdef JS_DEBUG - validEntry = true; -#endif - } - }; - - // A Range whose lifetime delimits a mutating enumeration of a hash table. - // Since rehashing when elements were removed during enumeration would be - // bad, it is postponed until the Enum is destructed. Since the Enum's - // destructor touches the hash table, the user must ensure that the hash - // table is still alive when the destructor runs. - class Enum : public Range - { - friend class HashTable; - - HashTable& table_; - bool rekeyed; - bool removed; - - /* Not copyable. */ - Enum(const Enum&) = delete; - void operator=(const Enum&) = delete; - - public: - template explicit - Enum(Map& map) : Range(map.all()), table_(map.impl), rekeyed(false), removed(false) {} - - // Removes the |front()| element from the table, leaving |front()| - // invalid until the next call to |popFront()|. For example: - // - // HashSet s; - // for (HashSet::Enum e(s); !e.empty(); e.popFront()) - // if (e.front() == 42) - // e.removeFront(); - void removeFront() { - table_.remove(*this->cur); - removed = true; -#ifdef JS_DEBUG - this->validEntry = false; - this->mutationCount = table_.mutationCount; -#endif - } - - NonConstT& mutableFront() { - MOZ_ASSERT(!this->empty()); -#ifdef JS_DEBUG - MOZ_ASSERT(this->validEntry); - MOZ_ASSERT(this->generation == this->Range::table_->generation()); - MOZ_ASSERT(this->mutationCount == this->Range::table_->mutationCount); -#endif - return this->cur->getMutable(); - } - - // Removes the |front()| element and re-inserts it into the table with - // a new key at the new Lookup position. |front()| is invalid after - // this operation until the next call to |popFront()|. - void rekeyFront(const Lookup& l, const Key& k) { - MOZ_ASSERT(&k != &HashPolicy::getKey(this->cur->get())); - Ptr p(*this->cur, table_); - table_.rekeyWithoutRehash(p, l, k); - rekeyed = true; -#ifdef JS_DEBUG - this->validEntry = false; - this->mutationCount = table_.mutationCount; -#endif - } - - void rekeyFront(const Key& k) { - rekeyFront(k, k); - } - - // Potentially rehashes the table. - ~Enum() { - if (rekeyed) { - table_.gen++; - table_.checkOverRemoved(); - } - - if (removed) - table_.compactIfUnderloaded(); - } - }; - - // HashTable is movable - HashTable(HashTable&& rhs) - : AllocPolicy(rhs) - { - mozilla::PodAssign(this, &rhs); - rhs.table = nullptr; - } - void operator=(HashTable&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - if (table) - destroyTable(*this, table, capacity()); - mozilla::PodAssign(this, &rhs); - rhs.table = nullptr; - } - - private: - // HashTable is not copyable or assignable - HashTable(const HashTable&) = delete; - void operator=(const HashTable&) = delete; - - private: - static const size_t CAP_BITS = 30; - - public: - uint64_t gen:56; // entry storage generation number - uint64_t hashShift:8; // multiplicative hash shift - Entry* table; // entry storage - uint32_t entryCount; // number of entries in table - uint32_t removedCount; // removed entry sentinels in table - -#ifdef JS_DEBUG - uint64_t mutationCount; - mutable bool mEntered; - // Note that some updates to these stats are not thread-safe. See the - // comment on the three-argument overloading of HashTable::lookup(). - mutable struct Stats - { - uint32_t searches; // total number of table searches - uint32_t steps; // hash chain links traversed - uint32_t hits; // searches that found key - uint32_t misses; // searches that didn't find key - uint32_t addOverRemoved; // adds that recycled a removed entry - uint32_t removes; // calls to remove - uint32_t removeFrees; // calls to remove that freed the entry - uint32_t grows; // table expansions - uint32_t shrinks; // table contractions - uint32_t compresses; // table compressions - uint32_t rehashes; // tombstone decontaminations - } stats; -# define METER(x) x -#else -# define METER(x) -#endif - - // The default initial capacity is 32 (enough to hold 16 elements), but it - // can be as low as 4. - static const unsigned sMinCapacityLog2 = 2; - static const unsigned sMinCapacity = 1 << sMinCapacityLog2; - static const unsigned sMaxInit = JS_BIT(CAP_BITS - 1); - static const unsigned sMaxCapacity = JS_BIT(CAP_BITS); - static const unsigned sHashBits = mozilla::tl::BitSize::value; - - // Hash-table alpha is conceptually a fraction, but to avoid floating-point - // math we implement it as a ratio of integers. - static const uint8_t sAlphaDenominator = 4; - static const uint8_t sMinAlphaNumerator = 1; // min alpha: 1/4 - static const uint8_t sMaxAlphaNumerator = 3; // max alpha: 3/4 - - static const HashNumber sFreeKey = Entry::sFreeKey; - static const HashNumber sRemovedKey = Entry::sRemovedKey; - static const HashNumber sCollisionBit = Entry::sCollisionBit; - - void setTableSizeLog2(unsigned sizeLog2) - { - hashShift = sHashBits - sizeLog2; - } - - static bool isLiveHash(HashNumber hash) - { - return Entry::isLiveHash(hash); - } - - static HashNumber prepareHash(const Lookup& l) - { - HashNumber keyHash = ScrambleHashCode(HashPolicy::hash(l)); - - // Avoid reserved hash codes. - if (!isLiveHash(keyHash)) - keyHash -= (sRemovedKey + 1); - return keyHash & ~sCollisionBit; - } - - enum FailureBehavior { DontReportFailure = false, ReportFailure = true }; - - static Entry* createTable(AllocPolicy& alloc, uint32_t capacity, - FailureBehavior reportFailure = ReportFailure) - { - static_assert(sFreeKey == 0, - "newly-calloc'd tables have to be considered empty"); - if (reportFailure) - return alloc.template pod_calloc(capacity); - - return alloc.template maybe_pod_calloc(capacity); - } - - static Entry* maybeCreateTable(AllocPolicy& alloc, uint32_t capacity) - { - static_assert(sFreeKey == 0, - "newly-calloc'd tables have to be considered empty"); - return alloc.template maybe_pod_calloc(capacity); - } - - static void destroyTable(AllocPolicy& alloc, Entry* oldTable, uint32_t capacity) - { - Entry* end = oldTable + capacity; - for (Entry* e = oldTable; e < end; ++e) - e->destroyIfLive(); - alloc.free_(oldTable); - } - - public: - explicit HashTable(AllocPolicy ap) - : AllocPolicy(ap) - , gen(0) - , hashShift(sHashBits) - , table(nullptr) - , entryCount(0) - , removedCount(0) -#ifdef JS_DEBUG - , mutationCount(0) - , mEntered(false) -#endif - {} - - MOZ_MUST_USE bool init(uint32_t length) - { - MOZ_ASSERT(!initialized()); - - // Reject all lengths whose initial computed capacity would exceed - // sMaxCapacity. Round that maximum length down to the nearest power - // of two for speedier code. - if (MOZ_UNLIKELY(length > sMaxInit)) { - this->reportAllocOverflow(); - return false; - } - - static_assert((sMaxInit * sAlphaDenominator) / sAlphaDenominator == sMaxInit, - "multiplication in numerator below could overflow"); - static_assert(sMaxInit * sAlphaDenominator <= UINT32_MAX - sMaxAlphaNumerator, - "numerator calculation below could potentially overflow"); - - // Compute the smallest capacity allowing |length| elements to be - // inserted without rehashing: ceil(length / max-alpha). (Ceiling - // integral division: .) - uint32_t newCapacity = - (length * sAlphaDenominator + sMaxAlphaNumerator - 1) / sMaxAlphaNumerator; - if (newCapacity < sMinCapacity) - newCapacity = sMinCapacity; - - // FIXME: use JS_CEILING_LOG2 when PGO stops crashing (bug 543034). - uint32_t roundUp = sMinCapacity, roundUpLog2 = sMinCapacityLog2; - while (roundUp < newCapacity) { - roundUp <<= 1; - ++roundUpLog2; - } - - newCapacity = roundUp; - MOZ_ASSERT(newCapacity >= length); - MOZ_ASSERT(newCapacity <= sMaxCapacity); - - table = createTable(*this, newCapacity); - if (!table) - return false; - - setTableSizeLog2(roundUpLog2); - METER(memset(&stats, 0, sizeof(stats))); - return true; - } - - bool initialized() const - { - return !!table; - } - - ~HashTable() - { - if (table) - destroyTable(*this, table, capacity()); - } - - private: - HashNumber hash1(HashNumber hash0) const - { - return hash0 >> hashShift; - } - - struct DoubleHash - { - HashNumber h2; - HashNumber sizeMask; - }; - - DoubleHash hash2(HashNumber curKeyHash) const - { - unsigned sizeLog2 = sHashBits - hashShift; - DoubleHash dh = { - ((curKeyHash << sizeLog2) >> hashShift) | 1, - (HashNumber(1) << sizeLog2) - 1 - }; - return dh; - } - - static HashNumber applyDoubleHash(HashNumber h1, const DoubleHash& dh) - { - return (h1 - dh.h2) & dh.sizeMask; - } - - bool overloaded() - { - static_assert(sMaxCapacity <= UINT32_MAX / sMaxAlphaNumerator, - "multiplication below could overflow"); - return entryCount + removedCount >= - capacity() * sMaxAlphaNumerator / sAlphaDenominator; - } - - // Would the table be underloaded if it had the given capacity and entryCount? - static bool wouldBeUnderloaded(uint32_t capacity, uint32_t entryCount) - { - static_assert(sMaxCapacity <= UINT32_MAX / sMinAlphaNumerator, - "multiplication below could overflow"); - return capacity > sMinCapacity && - entryCount <= capacity * sMinAlphaNumerator / sAlphaDenominator; - } - - bool underloaded() - { - return wouldBeUnderloaded(capacity(), entryCount); - } - - static bool match(Entry& e, const Lookup& l) - { - return HashPolicy::match(HashPolicy::getKey(e.get()), l); - } - - // Warning: in order for readonlyThreadsafeLookup() to be safe this - // function must not modify the table in any way when |collisionBit| is 0. - // (The use of the METER() macro to increment stats violates this - // restriction but we will live with that for now because it's enabled so - // rarely.) - Entry& lookup(const Lookup& l, HashNumber keyHash, unsigned collisionBit) const - { - MOZ_ASSERT(isLiveHash(keyHash)); - MOZ_ASSERT(!(keyHash & sCollisionBit)); - MOZ_ASSERT(collisionBit == 0 || collisionBit == sCollisionBit); - MOZ_ASSERT(table); - METER(stats.searches++); - - // Compute the primary hash address. - HashNumber h1 = hash1(keyHash); - Entry* entry = &table[h1]; - - // Miss: return space for a new entry. - if (entry->isFree()) { - METER(stats.misses++); - return *entry; - } - - // Hit: return entry. - if (entry->matchHash(keyHash) && match(*entry, l)) { - METER(stats.hits++); - return *entry; - } - - // Collision: double hash. - DoubleHash dh = hash2(keyHash); - - // Save the first removed entry pointer so we can recycle later. - Entry* firstRemoved = nullptr; - - while (true) { - if (MOZ_UNLIKELY(entry->isRemoved())) { - if (!firstRemoved) - firstRemoved = entry; - } else { - if (collisionBit == sCollisionBit) - entry->setCollision(); - } - - METER(stats.steps++); - h1 = applyDoubleHash(h1, dh); - - entry = &table[h1]; - if (entry->isFree()) { - METER(stats.misses++); - return firstRemoved ? *firstRemoved : *entry; - } - - if (entry->matchHash(keyHash) && match(*entry, l)) { - METER(stats.hits++); - return *entry; - } - } - } - - // This is a copy of lookup hardcoded to the assumptions: - // 1. the lookup is a lookupForAdd - // 2. the key, whose |keyHash| has been passed is not in the table, - // 3. no entries have been removed from the table. - // This specialized search avoids the need for recovering lookup values - // from entries, which allows more flexible Lookup/Key types. - Entry& findFreeEntry(HashNumber keyHash) - { - MOZ_ASSERT(!(keyHash & sCollisionBit)); - MOZ_ASSERT(table); - METER(stats.searches++); - - // We assume 'keyHash' has already been distributed. - - // Compute the primary hash address. - HashNumber h1 = hash1(keyHash); - Entry* entry = &table[h1]; - - // Miss: return space for a new entry. - if (!entry->isLive()) { - METER(stats.misses++); - return *entry; - } - - // Collision: double hash. - DoubleHash dh = hash2(keyHash); - - while (true) { - MOZ_ASSERT(!entry->isRemoved()); - entry->setCollision(); - - METER(stats.steps++); - h1 = applyDoubleHash(h1, dh); - - entry = &table[h1]; - if (!entry->isLive()) { - METER(stats.misses++); - return *entry; - } - } - } - - enum RebuildStatus { NotOverloaded, Rehashed, RehashFailed }; - - RebuildStatus changeTableSize(int deltaLog2, FailureBehavior reportFailure = ReportFailure) - { - // Look, but don't touch, until we succeed in getting new entry store. - Entry* oldTable = table; - uint32_t oldCap = capacity(); - uint32_t newLog2 = sHashBits - hashShift + deltaLog2; - uint32_t newCapacity = JS_BIT(newLog2); - if (MOZ_UNLIKELY(newCapacity > sMaxCapacity)) { - if (reportFailure) - this->reportAllocOverflow(); - return RehashFailed; - } - - Entry* newTable = createTable(*this, newCapacity, reportFailure); - if (!newTable) - return RehashFailed; - - // We can't fail from here on, so update table parameters. - setTableSizeLog2(newLog2); - removedCount = 0; - gen++; - table = newTable; - - // Copy only live entries, leaving removed ones behind. - Entry* end = oldTable + oldCap; - for (Entry* src = oldTable; src < end; ++src) { - if (src->isLive()) { - HashNumber hn = src->getKeyHash(); - findFreeEntry(hn).setLive( - hn, mozilla::Move(const_cast(src->get()))); - src->destroy(); - } - } - - // All entries have been destroyed, no need to destroyTable. - this->free_(oldTable); - return Rehashed; - } - - bool shouldCompressTable() - { - // Compress if a quarter or more of all entries are removed. - return removedCount >= (capacity() >> 2); - } - - RebuildStatus checkOverloaded(FailureBehavior reportFailure = ReportFailure) - { - if (!overloaded()) - return NotOverloaded; - - int deltaLog2; - if (shouldCompressTable()) { - METER(stats.compresses++); - deltaLog2 = 0; - } else { - METER(stats.grows++); - deltaLog2 = 1; - } - - return changeTableSize(deltaLog2, reportFailure); - } - - // Infallibly rehash the table if we are overloaded with removals. - void checkOverRemoved() - { - if (overloaded()) { - if (checkOverloaded(DontReportFailure) == RehashFailed) - rehashTableInPlace(); - } - } - - void remove(Entry& e) - { - MOZ_ASSERT(table); - METER(stats.removes++); - - if (e.hasCollision()) { - e.removeLive(); - removedCount++; - } else { - METER(stats.removeFrees++); - e.clearLive(); - } - entryCount--; -#ifdef JS_DEBUG - mutationCount++; -#endif - } - - void checkUnderloaded() - { - if (underloaded()) { - METER(stats.shrinks++); - (void) changeTableSize(-1, DontReportFailure); - } - } - - // Resize the table down to the largest capacity which doesn't underload the - // table. Since we call checkUnderloaded() on every remove, you only need - // to call this after a bulk removal of items done without calling remove(). - void compactIfUnderloaded() - { - int32_t resizeLog2 = 0; - uint32_t newCapacity = capacity(); - while (wouldBeUnderloaded(newCapacity, entryCount)) { - newCapacity = newCapacity >> 1; - resizeLog2--; - } - - if (resizeLog2 != 0) - (void) changeTableSize(resizeLog2, DontReportFailure); - } - - // This is identical to changeTableSize(currentSize), but without requiring - // a second table. We do this by recycling the collision bits to tell us if - // the element is already inserted or still waiting to be inserted. Since - // already-inserted elements win any conflicts, we get the same table as we - // would have gotten through random insertion order. - void rehashTableInPlace() - { - METER(stats.rehashes++); - removedCount = 0; - for (size_t i = 0; i < capacity(); ++i) - table[i].unsetCollision(); - - for (size_t i = 0; i < capacity();) { - Entry* src = &table[i]; - - if (!src->isLive() || src->hasCollision()) { - ++i; - continue; - } - - HashNumber keyHash = src->getKeyHash(); - HashNumber h1 = hash1(keyHash); - DoubleHash dh = hash2(keyHash); - Entry* tgt = &table[h1]; - while (true) { - if (!tgt->hasCollision()) { - src->swap(tgt); - tgt->setCollision(); - break; - } - - h1 = applyDoubleHash(h1, dh); - tgt = &table[h1]; - } - } - - // TODO: this algorithm leaves collision bits on *all* elements, even if - // they are on no collision path. We have the option of setting the - // collision bits correctly on a subsequent pass or skipping the rehash - // unless we are totally filled with tombstones: benchmark to find out - // which approach is best. - } - - // Note: |l| may be a reference to a piece of |u|, so this function - // must take care not to use |l| after moving |u|. - // - // Prefer to use putNewInfallible; this function does not check - // invariants. - template - void putNewInfallibleInternal(const Lookup& l, Args&&... args) - { - MOZ_ASSERT(table); - - HashNumber keyHash = prepareHash(l); - Entry* entry = &findFreeEntry(keyHash); - MOZ_ASSERT(entry); - - if (entry->isRemoved()) { - METER(stats.addOverRemoved++); - removedCount--; - keyHash |= sCollisionBit; - } - - entry->setLive(keyHash, mozilla::Forward(args)...); - entryCount++; -#ifdef JS_DEBUG - mutationCount++; -#endif - } - - public: - void clear() - { - if (mozilla::IsPod::value) { - memset(table, 0, sizeof(*table) * capacity()); - } else { - uint32_t tableCapacity = capacity(); - Entry* end = table + tableCapacity; - for (Entry* e = table; e < end; ++e) - e->clear(); - } - removedCount = 0; - entryCount = 0; -#ifdef JS_DEBUG - mutationCount++; -#endif - } - - void finish() - { -#ifdef JS_DEBUG - MOZ_ASSERT(!mEntered); -#endif - if (!table) - return; - - destroyTable(*this, table, capacity()); - table = nullptr; - gen++; - entryCount = 0; - removedCount = 0; -#ifdef JS_DEBUG - mutationCount++; -#endif - } - - Range all() const - { - MOZ_ASSERT(table); - return Range(*this, table, table + capacity()); - } - - bool empty() const - { - MOZ_ASSERT(table); - return !entryCount; - } - - uint32_t count() const - { - MOZ_ASSERT(table); - return entryCount; - } - - uint32_t capacity() const - { - MOZ_ASSERT(table); - return JS_BIT(sHashBits - hashShift); - } - - Generation generation() const - { - MOZ_ASSERT(table); - return Generation(gen); - } - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const - { - return mallocSizeOf(table); - } - - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const - { - return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf); - } - - Ptr lookup(const Lookup& l) const - { - mozilla::ReentrancyGuard g(*this); - if (!HasHash(l)) - return Ptr(); - HashNumber keyHash = prepareHash(l); - return Ptr(lookup(l, keyHash, 0), *this); - } - - Ptr readonlyThreadsafeLookup(const Lookup& l) const - { - if (!HasHash(l)) - return Ptr(); - HashNumber keyHash = prepareHash(l); - return Ptr(lookup(l, keyHash, 0), *this); - } - - AddPtr lookupForAdd(const Lookup& l) const - { - mozilla::ReentrancyGuard g(*this); - if (!EnsureHash(l)) - return AddPtr(); - HashNumber keyHash = prepareHash(l); - Entry& entry = lookup(l, keyHash, sCollisionBit); - AddPtr p(entry, *this, keyHash); - return p; - } - - template - MOZ_MUST_USE bool add(AddPtr& p, Args&&... args) - { - mozilla::ReentrancyGuard g(*this); - MOZ_ASSERT(table); - MOZ_ASSERT(!p.found()); - MOZ_ASSERT(!(p.keyHash & sCollisionBit)); - - // Check for error from ensureHash() here. - if (p.isValid()) - return false; - - // Changing an entry from removed to live does not affect whether we - // are overloaded and can be handled separately. - if (p.entry_->isRemoved()) { - if (!this->checkSimulatedOOM()) - return false; - METER(stats.addOverRemoved++); - removedCount--; - p.keyHash |= sCollisionBit; - } else { - // Preserve the validity of |p.entry_|. - RebuildStatus status = checkOverloaded(); - if (status == RehashFailed) - return false; - if (status == NotOverloaded && !this->checkSimulatedOOM()) - return false; - if (status == Rehashed) - p.entry_ = &findFreeEntry(p.keyHash); - } - - p.entry_->setLive(p.keyHash, mozilla::Forward(args)...); - entryCount++; -#ifdef JS_DEBUG - mutationCount++; - p.generation = generation(); - p.mutationCount = mutationCount; -#endif - return true; - } - - // Note: |l| may be a reference to a piece of |u|, so this function - // must take care not to use |l| after moving |u|. - template - void putNewInfallible(const Lookup& l, Args&&... args) - { - MOZ_ASSERT(!lookup(l).found()); - mozilla::ReentrancyGuard g(*this); - putNewInfallibleInternal(l, mozilla::Forward(args)...); - } - - // Note: |l| may be alias arguments in |args|, so this function must take - // care not to use |l| after moving |args|. - template - MOZ_MUST_USE bool putNew(const Lookup& l, Args&&... args) - { - if (!this->checkSimulatedOOM()) - return false; - - if (!EnsureHash(l)) - return false; - - if (checkOverloaded() == RehashFailed) - return false; - - putNewInfallible(l, mozilla::Forward(args)...); - return true; - } - - // Note: |l| may be a reference to a piece of |u|, so this function - // must take care not to use |l| after moving |u|. - template - MOZ_MUST_USE bool relookupOrAdd(AddPtr& p, const Lookup& l, Args&&... args) - { - // Check for error from ensureHash() here. - if (p.isValid()) - return false; - -#ifdef JS_DEBUG - p.generation = generation(); - p.mutationCount = mutationCount; -#endif - { - mozilla::ReentrancyGuard g(*this); - MOZ_ASSERT(prepareHash(l) == p.keyHash); // l has not been destroyed - p.entry_ = &lookup(l, p.keyHash, sCollisionBit); - } - return p.found() || add(p, mozilla::Forward(args)...); - } - - void remove(Ptr p) - { - MOZ_ASSERT(table); - mozilla::ReentrancyGuard g(*this); - MOZ_ASSERT(p.found()); - remove(*p.entry_); - checkUnderloaded(); - } - - void rekeyWithoutRehash(Ptr p, const Lookup& l, const Key& k) - { - MOZ_ASSERT(table); - mozilla::ReentrancyGuard g(*this); - MOZ_ASSERT(p.found()); - typename HashTableEntry::NonConstT t(mozilla::Move(*p)); - HashPolicy::setKey(t, const_cast(k)); - remove(*p.entry_); - putNewInfallibleInternal(l, mozilla::Move(t)); - } - - void rekeyAndMaybeRehash(Ptr p, const Lookup& l, const Key& k) - { - rekeyWithoutRehash(p, l, k); - checkOverRemoved(); - } - -#undef METER -}; - -} // namespace detail -} // namespace js - -#endif /* js_HashTable_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/HeapAPI.h b/android/arm64-v8a/include/spidermonkey/js/HeapAPI.h deleted file mode 100644 index e37d13e9..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/HeapAPI.h +++ /dev/null @@ -1,406 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_HeapAPI_h -#define js_HeapAPI_h - -#include - -#include "jspubtd.h" - -#include "js/TraceKind.h" -#include "js/Utility.h" - -/* These values are private to the JS engine. */ -namespace js { - -JS_FRIEND_API(bool) -CurrentThreadCanAccessZone(JS::Zone* zone); - -namespace gc { - -struct Cell; - -const size_t ArenaShift = 12; -const size_t ArenaSize = size_t(1) << ArenaShift; -const size_t ArenaMask = ArenaSize - 1; - -#ifdef JS_GC_SMALL_CHUNK_SIZE -const size_t ChunkShift = 18; -#else -const size_t ChunkShift = 20; -#endif -const size_t ChunkSize = size_t(1) << ChunkShift; -const size_t ChunkMask = ChunkSize - 1; - -const size_t CellShift = 3; -const size_t CellSize = size_t(1) << CellShift; -const size_t CellMask = CellSize - 1; - -/* These are magic constants derived from actual offsets in gc/Heap.h. */ -#ifdef JS_GC_SMALL_CHUNK_SIZE -const size_t ChunkMarkBitmapOffset = 258104; -const size_t ChunkMarkBitmapBits = 31744; -#else -const size_t ChunkMarkBitmapOffset = 1032352; -const size_t ChunkMarkBitmapBits = 129024; -#endif -const size_t ChunkRuntimeOffset = ChunkSize - sizeof(void*); -const size_t ChunkTrailerSize = 2 * sizeof(uintptr_t) + sizeof(uint64_t); -const size_t ChunkLocationOffset = ChunkSize - ChunkTrailerSize; -const size_t ArenaZoneOffset = sizeof(size_t); -const size_t ArenaHeaderSize = sizeof(size_t) + 2 * sizeof(uintptr_t) + - sizeof(size_t) + sizeof(uintptr_t); - -/* - * Live objects are marked black. How many other additional colors are available - * depends on the size of the GCThing. Objects marked gray are eligible for - * cycle collection. - */ -static const uint32_t BLACK = 0; -static const uint32_t GRAY = 1; - -/* - * The "location" field in the Chunk trailer is a enum indicating various roles - * of the chunk. - */ -enum class ChunkLocation : uint32_t -{ - Invalid = 0, - Nursery = 1, - TenuredHeap = 2 -}; - -#ifdef JS_DEBUG -/* When downcasting, ensure we are actually the right type. */ -extern JS_FRIEND_API(void) -AssertGCThingHasType(js::gc::Cell* cell, JS::TraceKind kind); -#else -inline void -AssertGCThingHasType(js::gc::Cell* cell, JS::TraceKind kind) {} -#endif - -MOZ_ALWAYS_INLINE bool IsInsideNursery(const js::gc::Cell* cell); - -} /* namespace gc */ -} /* namespace js */ - -namespace JS { -struct Zone; - -/* Default size for the generational nursery in bytes. */ -const uint32_t DefaultNurseryBytes = 16 * js::gc::ChunkSize; - -/* Default maximum heap size in bytes to pass to JS_NewRuntime(). */ -const uint32_t DefaultHeapMaxBytes = 32 * 1024 * 1024; - -namespace shadow { - -struct Zone -{ - protected: - JSRuntime* const runtime_; - JSTracer* const barrierTracer_; // A pointer to the JSRuntime's |gcMarker|. - - public: - // Stack GC roots for Rooted GC pointers. - js::RootedListHeads stackRoots_; - template friend class JS::Rooted; - - bool needsIncrementalBarrier_; - - Zone(JSRuntime* runtime, JSTracer* barrierTracerArg) - : runtime_(runtime), - barrierTracer_(barrierTracerArg), - needsIncrementalBarrier_(false) - { - for (auto& stackRootPtr : stackRoots_) - stackRootPtr = nullptr; - } - - bool needsIncrementalBarrier() const { - return needsIncrementalBarrier_; - } - - JSTracer* barrierTracer() { - MOZ_ASSERT(needsIncrementalBarrier_); - MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_)); - return barrierTracer_; - } - - JSRuntime* runtimeFromMainThread() const { - MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_)); - return runtime_; - } - - // Note: Unrestricted access to the zone's runtime from an arbitrary - // thread can easily lead to races. Use this method very carefully. - JSRuntime* runtimeFromAnyThread() const { - return runtime_; - } - - static MOZ_ALWAYS_INLINE JS::shadow::Zone* asShadowZone(JS::Zone* zone) { - return reinterpret_cast(zone); - } -}; - -} /* namespace shadow */ - -/** - * A GC pointer, tagged with the trace kind. - * - * In general, a GC pointer should be stored with an exact type. This class - * is for use when that is not possible because a single pointer must point - * to several kinds of GC thing. - */ -class JS_FRIEND_API(GCCellPtr) -{ - public: - // Construction from a void* and trace kind. - GCCellPtr(void* gcthing, JS::TraceKind traceKind) : ptr(checkedCast(gcthing, traceKind)) {} - - // Automatically construct a null GCCellPtr from nullptr. - MOZ_IMPLICIT GCCellPtr(decltype(nullptr)) : ptr(checkedCast(nullptr, JS::TraceKind::Null)) {} - - // Construction from an explicit type. - template - explicit GCCellPtr(T* p) : ptr(checkedCast(p, JS::MapTypeToTraceKind::kind)) { } - explicit GCCellPtr(JSFunction* p) : ptr(checkedCast(p, JS::TraceKind::Object)) { } - explicit GCCellPtr(JSFlatString* str) : ptr(checkedCast(str, JS::TraceKind::String)) { } - explicit GCCellPtr(const Value& v); - - JS::TraceKind kind() const { - JS::TraceKind traceKind = JS::TraceKind(ptr & OutOfLineTraceKindMask); - if (uintptr_t(traceKind) != OutOfLineTraceKindMask) - return traceKind; - return outOfLineKind(); - } - - // Allow GCCellPtr to be used in a boolean context. - explicit operator bool() const { - MOZ_ASSERT(bool(asCell()) == (kind() != JS::TraceKind::Null)); - return asCell(); - } - - // Simplify checks to the kind. - template - bool is() const { return kind() == JS::MapTypeToTraceKind::kind; } - - // Conversions to more specific types must match the kind. Access to - // further refined types is not allowed directly from a GCCellPtr. - template - T& as() const { - MOZ_ASSERT(kind() == JS::MapTypeToTraceKind::kind); - // We can't use static_cast here, because the fact that JSObject - // inherits from js::gc::Cell is not part of the public API. - return *reinterpret_cast(asCell()); - } - - // Return a pointer to the cell this |GCCellPtr| refers to, or |nullptr|. - // (It would be more symmetrical with |to| for this to return a |Cell&|, but - // the result can be |nullptr|, and null references are undefined behavior.) - js::gc::Cell* asCell() const { - return reinterpret_cast(ptr & ~OutOfLineTraceKindMask); - } - - // The CC's trace logger needs an identity that is XPIDL serializable. - uint64_t unsafeAsInteger() const { - return static_cast(unsafeAsUIntPtr()); - } - // Inline mark bitmap access requires direct pointer arithmetic. - uintptr_t unsafeAsUIntPtr() const { - MOZ_ASSERT(asCell()); - MOZ_ASSERT(!js::gc::IsInsideNursery(asCell())); - return reinterpret_cast(asCell()); - } - - bool mayBeOwnedByOtherRuntime() const; - - private: - static uintptr_t checkedCast(void* p, JS::TraceKind traceKind) { - js::gc::Cell* cell = static_cast(p); - MOZ_ASSERT((uintptr_t(p) & OutOfLineTraceKindMask) == 0); - AssertGCThingHasType(cell, traceKind); - // Note: the OutOfLineTraceKindMask bits are set on all out-of-line kinds - // so that we can mask instead of branching. - MOZ_ASSERT_IF(uintptr_t(traceKind) >= OutOfLineTraceKindMask, - (uintptr_t(traceKind) & OutOfLineTraceKindMask) == OutOfLineTraceKindMask); - return uintptr_t(p) | (uintptr_t(traceKind) & OutOfLineTraceKindMask); - } - - JS::TraceKind outOfLineKind() const; - - uintptr_t ptr; -}; - -inline bool -operator==(const GCCellPtr& ptr1, const GCCellPtr& ptr2) -{ - return ptr1.asCell() == ptr2.asCell(); -} - -inline bool -operator!=(const GCCellPtr& ptr1, const GCCellPtr& ptr2) -{ - return !(ptr1 == ptr2); -} - -// Unwraps the given GCCellPtr and calls the given functor with a template -// argument of the actual type of the pointer. -template -auto -DispatchTyped(F f, GCCellPtr thing, Args&&... args) - -> decltype(f(static_cast(nullptr), mozilla::Forward(args)...)) -{ - switch (thing.kind()) { -#define JS_EXPAND_DEF(name, type, _) \ - case JS::TraceKind::name: \ - return f(&thing.as(), mozilla::Forward(args)...); - JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF); -#undef JS_EXPAND_DEF - default: - MOZ_CRASH("Invalid trace kind in DispatchTyped for GCCellPtr."); - } -} - -} /* namespace JS */ - -namespace js { -namespace gc { -namespace detail { - -static MOZ_ALWAYS_INLINE uintptr_t* -GetGCThingMarkBitmap(const uintptr_t addr) -{ - MOZ_ASSERT(addr); - const uintptr_t bmap_addr = (addr & ~ChunkMask) | ChunkMarkBitmapOffset; - return reinterpret_cast(bmap_addr); -} - -static MOZ_ALWAYS_INLINE void -GetGCThingMarkWordAndMask(const uintptr_t addr, uint32_t color, - uintptr_t** wordp, uintptr_t* maskp) -{ - MOZ_ASSERT(addr); - const size_t bit = (addr & js::gc::ChunkMask) / js::gc::CellSize + color; - MOZ_ASSERT(bit < js::gc::ChunkMarkBitmapBits); - uintptr_t* bitmap = GetGCThingMarkBitmap(addr); - const uintptr_t nbits = sizeof(*bitmap) * CHAR_BIT; - *maskp = uintptr_t(1) << (bit % nbits); - *wordp = &bitmap[bit / nbits]; -} - -static MOZ_ALWAYS_INLINE JS::Zone* -GetGCThingZone(const uintptr_t addr) -{ - MOZ_ASSERT(addr); - const uintptr_t zone_addr = (addr & ~ArenaMask) | ArenaZoneOffset; - return *reinterpret_cast(zone_addr); - -} - -static MOZ_ALWAYS_INLINE JS::shadow::Runtime* -GetCellRuntime(const Cell* cell) -{ - MOZ_ASSERT(cell); - const uintptr_t addr = uintptr_t(cell); - const uintptr_t rt_addr = (addr & ~ChunkMask) | ChunkRuntimeOffset; - return *reinterpret_cast(rt_addr); -} - -static MOZ_ALWAYS_INLINE bool -CellIsMarkedGray(const Cell* cell) -{ - MOZ_ASSERT(cell); - if (js::gc::IsInsideNursery(cell)) - return false; - - uintptr_t* word, mask; - js::gc::detail::GetGCThingMarkWordAndMask(uintptr_t(cell), js::gc::GRAY, &word, &mask); - return *word & mask; -} - -extern JS_PUBLIC_API(bool) -CellIsMarkedGrayIfKnown(const Cell* cell); - -} /* namespace detail */ - -MOZ_ALWAYS_INLINE bool -IsInsideNursery(const js::gc::Cell* cell) -{ - if (!cell) - return false; - uintptr_t addr = uintptr_t(cell); - addr &= ~js::gc::ChunkMask; - addr |= js::gc::ChunkLocationOffset; - auto location = *reinterpret_cast(addr); - MOZ_ASSERT(location == ChunkLocation::Nursery || location == ChunkLocation::TenuredHeap); - return location == ChunkLocation::Nursery; -} - -} /* namespace gc */ -} /* namespace js */ - -namespace JS { - -static MOZ_ALWAYS_INLINE Zone* -GetTenuredGCThingZone(GCCellPtr thing) -{ - MOZ_ASSERT(!js::gc::IsInsideNursery(thing.asCell())); - return js::gc::detail::GetGCThingZone(thing.unsafeAsUIntPtr()); -} - -static MOZ_ALWAYS_INLINE Zone* -GetStringZone(JSString* str) -{ - return js::gc::detail::GetGCThingZone(uintptr_t(str)); -} - -extern JS_PUBLIC_API(Zone*) -GetObjectZone(JSObject* obj); - -static MOZ_ALWAYS_INLINE bool -GCThingIsMarkedGray(GCCellPtr thing) -{ - if (thing.mayBeOwnedByOtherRuntime()) - return false; - return js::gc::detail::CellIsMarkedGrayIfKnown(thing.asCell()); -} - -extern JS_PUBLIC_API(JS::TraceKind) -GCThingTraceKind(void* thing); - -} /* namespace JS */ - -namespace js { -namespace gc { - -static MOZ_ALWAYS_INLINE bool -IsIncrementalBarrierNeededOnTenuredGCThing(JS::shadow::Runtime* rt, const JS::GCCellPtr thing) -{ - MOZ_ASSERT(thing); - MOZ_ASSERT(!js::gc::IsInsideNursery(thing.asCell())); - - // TODO: I'd like to assert !isHeapBusy() here but this gets called while we - // are tracing the heap, e.g. during memory reporting (see bug 1313318). - MOZ_ASSERT(!rt->isHeapCollecting()); - - JS::Zone* zone = JS::GetTenuredGCThingZone(thing); - return JS::shadow::Zone::asShadowZone(zone)->needsIncrementalBarrier(); -} - -/** - * Create an object providing access to the garbage collector's internal notion - * of the current state of memory (both GC heap memory and GCthing-controlled - * malloc memory. - */ -extern JS_PUBLIC_API(JSObject*) -NewMemoryInfoObject(JSContext* cx); - -} /* namespace gc */ -} /* namespace js */ - -#endif /* js_HeapAPI_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/Id.h b/android/arm64-v8a/include/spidermonkey/js/Id.h deleted file mode 100644 index d474e784..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/Id.h +++ /dev/null @@ -1,207 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_Id_h -#define js_Id_h - -// A jsid is an identifier for a property or method of an object which is -// either a 31-bit unsigned integer, interned string or symbol. -// -// Also, there is an additional jsid value, JSID_VOID, which does not occur in -// JS scripts but may be used to indicate the absence of a valid jsid. A void -// jsid is not a valid id and only arises as an exceptional API return value, -// such as in JS_NextProperty. Embeddings must not pass JSID_VOID into JSAPI -// entry points expecting a jsid and do not need to handle JSID_VOID in hooks -// receiving a jsid except when explicitly noted in the API contract. -// -// A jsid is not implicitly convertible to or from a Value; JS_ValueToId or -// JS_IdToValue must be used instead. - -#include "jstypes.h" - -#include "js/HeapAPI.h" -#include "js/RootingAPI.h" -#include "js/TypeDecls.h" -#include "js/Utility.h" - -struct jsid -{ - size_t asBits; - bool operator==(const jsid& rhs) const { return asBits == rhs.asBits; } - bool operator!=(const jsid& rhs) const { return asBits != rhs.asBits; } -} JS_HAZ_GC_POINTER; -#define JSID_BITS(id) (id.asBits) - -#define JSID_TYPE_STRING 0x0 -#define JSID_TYPE_INT 0x1 -#define JSID_TYPE_VOID 0x2 -#define JSID_TYPE_SYMBOL 0x4 -#define JSID_TYPE_MASK 0x7 - -// Avoid using canonical 'id' for jsid parameters since this is a magic word in -// Objective-C++ which, apparently, wants to be able to #include jsapi.h. -#define id iden - -static MOZ_ALWAYS_INLINE bool -JSID_IS_STRING(jsid id) -{ - return (JSID_BITS(id) & JSID_TYPE_MASK) == 0; -} - -static MOZ_ALWAYS_INLINE JSString* -JSID_TO_STRING(jsid id) -{ - MOZ_ASSERT(JSID_IS_STRING(id)); - return (JSString*)JSID_BITS(id); -} - -/** - * Only JSStrings that have been interned via the JSAPI can be turned into - * jsids by API clients. - * - * N.B. if a jsid is backed by a string which has not been interned, that - * string must be appropriately rooted to avoid being collected by the GC. - */ -JS_PUBLIC_API(jsid) -INTERNED_STRING_TO_JSID(JSContext* cx, JSString* str); - -static MOZ_ALWAYS_INLINE bool -JSID_IS_INT(jsid id) -{ - return !!(JSID_BITS(id) & JSID_TYPE_INT); -} - -static MOZ_ALWAYS_INLINE int32_t -JSID_TO_INT(jsid id) -{ - MOZ_ASSERT(JSID_IS_INT(id)); - return ((uint32_t)JSID_BITS(id)) >> 1; -} - -#define JSID_INT_MIN 0 -#define JSID_INT_MAX INT32_MAX - -static MOZ_ALWAYS_INLINE bool -INT_FITS_IN_JSID(int32_t i) -{ - return i >= 0; -} - -static MOZ_ALWAYS_INLINE jsid -INT_TO_JSID(int32_t i) -{ - jsid id; - MOZ_ASSERT(INT_FITS_IN_JSID(i)); - JSID_BITS(id) = ((i << 1) | JSID_TYPE_INT); - return id; -} - -static MOZ_ALWAYS_INLINE bool -JSID_IS_SYMBOL(jsid id) -{ - return (JSID_BITS(id) & JSID_TYPE_MASK) == JSID_TYPE_SYMBOL && - JSID_BITS(id) != JSID_TYPE_SYMBOL; -} - -static MOZ_ALWAYS_INLINE JS::Symbol* -JSID_TO_SYMBOL(jsid id) -{ - MOZ_ASSERT(JSID_IS_SYMBOL(id)); - return (JS::Symbol*)(JSID_BITS(id) & ~(size_t)JSID_TYPE_MASK); -} - -static MOZ_ALWAYS_INLINE jsid -SYMBOL_TO_JSID(JS::Symbol* sym) -{ - jsid id; - MOZ_ASSERT(sym != nullptr); - MOZ_ASSERT((size_t(sym) & JSID_TYPE_MASK) == 0); - MOZ_ASSERT(!js::gc::IsInsideNursery(reinterpret_cast(sym))); - JSID_BITS(id) = (size_t(sym) | JSID_TYPE_SYMBOL); - return id; -} - -static MOZ_ALWAYS_INLINE bool -JSID_IS_GCTHING(jsid id) -{ - return JSID_IS_STRING(id) || JSID_IS_SYMBOL(id); -} - -static MOZ_ALWAYS_INLINE JS::GCCellPtr -JSID_TO_GCTHING(jsid id) -{ - void* thing = (void*)(JSID_BITS(id) & ~(size_t)JSID_TYPE_MASK); - if (JSID_IS_STRING(id)) - return JS::GCCellPtr(thing, JS::TraceKind::String); - MOZ_ASSERT(JSID_IS_SYMBOL(id)); - return JS::GCCellPtr(thing, JS::TraceKind::Symbol); -} - -static MOZ_ALWAYS_INLINE bool -JSID_IS_VOID(const jsid id) -{ - MOZ_ASSERT_IF(((size_t)JSID_BITS(id) & JSID_TYPE_MASK) == JSID_TYPE_VOID, - JSID_BITS(id) == JSID_TYPE_VOID); - return (size_t)JSID_BITS(id) == JSID_TYPE_VOID; -} - -static MOZ_ALWAYS_INLINE bool -JSID_IS_EMPTY(const jsid id) -{ - return (size_t)JSID_BITS(id) == JSID_TYPE_SYMBOL; -} - -extern JS_PUBLIC_DATA(const jsid) JSID_VOID; -extern JS_PUBLIC_DATA(const jsid) JSID_EMPTY; - -extern JS_PUBLIC_DATA(const JS::HandleId) JSID_VOIDHANDLE; -extern JS_PUBLIC_DATA(const JS::HandleId) JSID_EMPTYHANDLE; - -namespace JS { - -template <> -struct GCPolicy -{ - static jsid initial() { return JSID_VOID; } - static void trace(JSTracer* trc, jsid* idp, const char* name) { - js::UnsafeTraceManuallyBarrieredEdge(trc, idp, name); - } -}; - -} // namespace JS - -namespace js { - -template <> -struct BarrierMethods -{ - static void postBarrier(jsid* idp, jsid prev, jsid next) {} - static void exposeToJS(jsid id) { - if (JSID_IS_GCTHING(id)) - js::gc::ExposeGCThingToActiveJS(JSID_TO_GCTHING(id)); - } -}; - -// If the jsid is a GC pointer type, convert to that type and call |f| with -// the pointer. If the jsid is not a GC type, calls F::defaultValue. -template -auto -DispatchTyped(F f, const jsid& id, Args&&... args) - -> decltype(f(static_cast(nullptr), mozilla::Forward(args)...)) -{ - if (JSID_IS_STRING(id)) - return f(JSID_TO_STRING(id), mozilla::Forward(args)...); - if (JSID_IS_SYMBOL(id)) - return f(JSID_TO_SYMBOL(id), mozilla::Forward(args)...); - MOZ_ASSERT(!JSID_IS_GCTHING(id)); - return F::defaultValue(id); -} - -#undef id - -} // namespace js - -#endif /* js_Id_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/Initialization.h b/android/arm64-v8a/include/spidermonkey/js/Initialization.h deleted file mode 100644 index 8a1cf910..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/Initialization.h +++ /dev/null @@ -1,125 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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/. */ - -/* SpiderMonkey initialization and shutdown APIs. */ - -#ifndef js_Initialization_h -#define js_Initialization_h - -#include "jstypes.h" - -namespace JS { -namespace detail { - -enum class InitState { Uninitialized = 0, Running, ShutDown }; - -/** - * SpiderMonkey's initialization status is tracked here, and it controls things - * that should happen only once across all runtimes. It's an API requirement - * that JS_Init (and JS_ShutDown, if called) be called in a thread-aware - * manner, so this (internal -- embedders, don't use!) variable doesn't need to - * be atomic. - */ -extern JS_PUBLIC_DATA(InitState) -libraryInitState; - -extern JS_PUBLIC_API(const char*) -InitWithFailureDiagnostic(bool isDebugBuild); - -} // namespace detail -} // namespace JS - -// These are equivalent to ICU's |UMemAllocFn|, |UMemReallocFn|, and -// |UMemFreeFn| types. The first argument (called |context| in the ICU docs) -// will always be nullptr and should be ignored. -typedef void* (*JS_ICUAllocFn)(const void*, size_t size); -typedef void* (*JS_ICUReallocFn)(const void*, void* p, size_t size); -typedef void (*JS_ICUFreeFn)(const void*, void* p); - -/** - * This function can be used to track memory used by ICU. If it is called, it - * *must* be called before JS_Init. Don't use it unless you know what you're - * doing! - */ -extern JS_PUBLIC_API(bool) -JS_SetICUMemoryFunctions(JS_ICUAllocFn allocFn, - JS_ICUReallocFn reallocFn, - JS_ICUFreeFn freeFn); - -/** - * Initialize SpiderMonkey, returning true only if initialization succeeded. - * Once this method has succeeded, it is safe to call JS_NewRuntime and other - * JSAPI methods. - * - * This method must be called before any other JSAPI method is used on any - * thread. Once it has been used, it is safe to call any JSAPI method, and it - * remains safe to do so until JS_ShutDown is correctly called. - * - * It is currently not possible to initialize SpiderMonkey multiple times (that - * is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so - * again). This restriction may eventually be lifted. - */ -inline bool -JS_Init(void) -{ -#ifdef DEBUG - return !JS::detail::InitWithFailureDiagnostic(true); -#else - return !JS::detail::InitWithFailureDiagnostic(false); -#endif -} - -/** - * A variant of JS_Init. On success it returns nullptr. On failure it returns a - * pointer to a string literal that describes how initialization failed, which - * can be useful for debugging purposes. - */ -inline const char* -JS_InitWithFailureDiagnostic(void) -{ -#ifdef DEBUG - return JS::detail::InitWithFailureDiagnostic(true); -#else - return JS::detail::InitWithFailureDiagnostic(false); -#endif -} - -/* - * Returns true if SpiderMonkey has been initialized successfully, even if it has - * possibly been shut down. - * - * Note that it is the responsibility of the embedder to call JS_Init() and - * JS_ShutDown() at the correct times, and therefore this API should ideally not - * be necessary to use. This is only intended to be used in cases where the - * embedder isn't in full control of deciding whether to initialize SpiderMonkey - * or hand off the task to another consumer. - */ -inline bool -JS_IsInitialized(void) -{ - return JS::detail::libraryInitState != JS::detail::InitState::Uninitialized; -} - -/** - * Destroy free-standing resources allocated by SpiderMonkey, not associated - * with any runtime, context, or other structure. - * - * This method should be called after all other JSAPI data has been properly - * cleaned up: every new runtime must have been destroyed, every new context - * must have been destroyed, and so on. Calling this method before all other - * resources have been destroyed has undefined behavior. - * - * Failure to call this method, at present, has no adverse effects other than - * leaking memory. This may not always be the case; it's recommended that all - * embedders call this method when all other JSAPI operations have completed. - * - * It is currently not possible to initialize SpiderMonkey multiple times (that - * is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so - * again). This restriction may eventually be lifted. - */ -extern JS_PUBLIC_API(void) -JS_ShutDown(void); - -#endif /* js_Initialization_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/LegacyIntTypes.h b/android/arm64-v8a/include/spidermonkey/js/LegacyIntTypes.h deleted file mode 100644 index 2c8498c8..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/LegacyIntTypes.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* - * This section typedefs the old 'native' types to the new types. - * These redefinitions are provided solely to allow JSAPI users to more easily - * transition to types. They are not to be used in the JSAPI, and - * new JSAPI user code should not use them. This mapping file may eventually - * be removed from SpiderMonkey, so don't depend on it in the long run. - */ - -/* - * BEWARE: Comity with other implementers of these types is not guaranteed. - * Indeed, if you use this header and third-party code defining these - * types, *expect* to encounter either compile errors or link errors, - * depending how these types are used and on the order of inclusion. - * It is safest to use only the types. - */ -#ifndef js_LegacyIntTypes_h -#define js_LegacyIntTypes_h - -#include - -#include "js-config.h" - -typedef uint8_t uint8; -typedef uint16_t uint16; -typedef uint32_t uint32; -typedef uint64_t uint64; - -/* - * On AIX 4.3, sys/inttypes.h (which is included by sys/types.h, a very - * common header file) defines the types int8, int16, int32, and int64. - * So we don't define these four types here to avoid conflicts in case - * the code also includes sys/types.h. - */ -#if defined(AIX) && defined(HAVE_SYS_INTTYPES_H) -#include -#else -typedef int8_t int8; -typedef int16_t int16; -typedef int32_t int32; -typedef int64_t int64; -#endif /* AIX && HAVE_SYS_INTTYPES_H */ - -typedef uint8_t JSUint8; -typedef uint16_t JSUint16; -typedef uint32_t JSUint32; -typedef uint64_t JSUint64; - -typedef int8_t JSInt8; -typedef int16_t JSInt16; -typedef int32_t JSInt32; -typedef int64_t JSInt64; - -#endif /* js_LegacyIntTypes_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/MemoryMetrics.h b/android/arm64-v8a/include/spidermonkey/js/MemoryMetrics.h deleted file mode 100644 index 9b5caa24..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/MemoryMetrics.h +++ /dev/null @@ -1,971 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_MemoryMetrics_h -#define js_MemoryMetrics_h - -// These declarations are highly likely to change in the future. Depend on them -// at your own risk. - -#include "mozilla/MemoryReporting.h" -#include "mozilla/PodOperations.h" -#include "mozilla/TypeTraits.h" - -#include - -#include "jsalloc.h" -#include "jspubtd.h" - -#include "js/HashTable.h" -#include "js/TracingAPI.h" -#include "js/Utility.h" -#include "js/Vector.h" - -class nsISupports; // Needed for ObjectPrivateVisitor. - -namespace JS { - -struct TabSizes -{ - enum Kind { - Objects, - Strings, - Private, - Other - }; - - TabSizes() { mozilla::PodZero(this); } - - void add(Kind kind, size_t n) { - switch (kind) { - case Objects: objects += n; break; - case Strings: strings += n; break; - case Private: private_ += n; break; - case Other: other += n; break; - default: MOZ_CRASH("bad TabSizes kind"); - } - } - - size_t objects; - size_t strings; - size_t private_; - size_t other; -}; - -/** These are the measurements used by Servo. */ -struct ServoSizes -{ - enum Kind { - GCHeapUsed, - GCHeapUnused, - GCHeapAdmin, - GCHeapDecommitted, - MallocHeap, - NonHeap, - Ignore - }; - - ServoSizes() { mozilla::PodZero(this); } - - void add(Kind kind, size_t n) { - switch (kind) { - case GCHeapUsed: gcHeapUsed += n; break; - case GCHeapUnused: gcHeapUnused += n; break; - case GCHeapAdmin: gcHeapAdmin += n; break; - case GCHeapDecommitted: gcHeapDecommitted += n; break; - case MallocHeap: mallocHeap += n; break; - case NonHeap: nonHeap += n; break; - case Ignore: /* do nothing */ break; - default: MOZ_CRASH("bad ServoSizes kind"); - } - } - - size_t gcHeapUsed; - size_t gcHeapUnused; - size_t gcHeapAdmin; - size_t gcHeapDecommitted; - size_t mallocHeap; - size_t nonHeap; -}; - -} // namespace JS - -namespace js { - -/** - * In memory reporting, we have concept of "sundries", line items which are too - * small to be worth reporting individually. Under some circumstances, a memory - * reporter gets tossed into the sundries bucket if it's smaller than - * MemoryReportingSundriesThreshold() bytes. - * - * We need to define this value here, rather than in the code which actually - * generates the memory reports, because NotableStringInfo uses this value. - */ -JS_FRIEND_API(size_t) MemoryReportingSundriesThreshold(); - -/** - * This hash policy avoids flattening ropes (which perturbs the site being - * measured and requires a JSContext) at the expense of doing a FULL ROPE COPY - * on every hash and match! Beware. - */ -struct InefficientNonFlatteningStringHashPolicy -{ - typedef JSString* Lookup; - static HashNumber hash(const Lookup& l); - static bool match(const JSString* const& k, const Lookup& l); -}; - -struct CStringHashPolicy -{ - typedef const char* Lookup; - static HashNumber hash(const Lookup& l); - static bool match(const char* const& k, const Lookup& l); -}; - -// This file features many classes with numerous size_t fields, and each such -// class has one or more methods that need to operate on all of these fields. -// Writing these individually is error-prone -- it's easy to add a new field -// without updating all the required methods. So we define a single macro list -// in each class to name the fields (and notable characteristics of them), and -// then use the following macros to transform those lists into the required -// methods. -// -// - The |tabKind| value is used when measuring TabSizes. -// -// - The |servoKind| value is used when measuring ServoSizes and also for -// the various sizeOfLiveGCThings() methods. -// -// In some classes, one or more of the macro arguments aren't used. We use '_' -// for those. -// -#define DECL_SIZE(tabKind, servoKind, mSize) size_t mSize; -#define ZERO_SIZE(tabKind, servoKind, mSize) mSize(0), -#define COPY_OTHER_SIZE(tabKind, servoKind, mSize) mSize(other.mSize), -#define ADD_OTHER_SIZE(tabKind, servoKind, mSize) mSize += other.mSize; -#define SUB_OTHER_SIZE(tabKind, servoKind, mSize) \ - MOZ_ASSERT(mSize >= other.mSize); \ - mSize -= other.mSize; -#define ADD_SIZE_TO_N(tabKind, servoKind, mSize) n += mSize; -#define ADD_SIZE_TO_N_IF_LIVE_GC_THING(tabKind, servoKind, mSize) \ - /* Avoid self-comparison warnings by comparing enums indirectly. */ \ - n += (mozilla::IsSame::value) \ - ? mSize \ - : 0; -#define ADD_TO_TAB_SIZES(tabKind, servoKind, mSize) sizes->add(JS::TabSizes::tabKind, mSize); -#define ADD_TO_SERVO_SIZES(tabKind, servoKind, mSize) sizes->add(JS::ServoSizes::servoKind, mSize); - -} // namespace js - -namespace JS { - -struct ClassInfo -{ -#define FOR_EACH_SIZE(macro) \ - macro(Objects, GCHeapUsed, objectsGCHeap) \ - macro(Objects, MallocHeap, objectsMallocHeapSlots) \ - macro(Objects, MallocHeap, objectsMallocHeapElementsNormal) \ - macro(Objects, MallocHeap, objectsMallocHeapElementsAsmJS) \ - macro(Objects, MallocHeap, objectsMallocHeapMisc) \ - macro(Objects, NonHeap, objectsNonHeapElementsNormal) \ - macro(Objects, NonHeap, objectsNonHeapElementsShared) \ - macro(Objects, NonHeap, objectsNonHeapElementsWasm) \ - macro(Objects, NonHeap, objectsNonHeapCodeWasm) - - ClassInfo() - : FOR_EACH_SIZE(ZERO_SIZE) - wasmGuardPages(0) - {} - - void add(const ClassInfo& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE) - } - - void subtract(const ClassInfo& other) { - FOR_EACH_SIZE(SUB_OTHER_SIZE) - } - - size_t sizeOfAllThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N) - return n; - } - - bool isNotable() const { - static const size_t NotabilityThreshold = 16 * 1024; - return sizeOfAllThings() >= NotabilityThreshold; - } - - size_t sizeOfLiveGCThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) - return n; - } - - void addToTabSizes(TabSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_TAB_SIZES) - } - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - size_t wasmGuardPages; - -#undef FOR_EACH_SIZE -}; - -struct ShapeInfo -{ -#define FOR_EACH_SIZE(macro) \ - macro(Other, GCHeapUsed, shapesGCHeapTree) \ - macro(Other, GCHeapUsed, shapesGCHeapDict) \ - macro(Other, GCHeapUsed, shapesGCHeapBase) \ - macro(Other, MallocHeap, shapesMallocHeapTreeTables) \ - macro(Other, MallocHeap, shapesMallocHeapDictTables) \ - macro(Other, MallocHeap, shapesMallocHeapTreeKids) - - ShapeInfo() - : FOR_EACH_SIZE(ZERO_SIZE) - dummy() - {} - - void add(const ShapeInfo& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE) - } - - void subtract(const ShapeInfo& other) { - FOR_EACH_SIZE(SUB_OTHER_SIZE) - } - - size_t sizeOfAllThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N) - return n; - } - - size_t sizeOfLiveGCThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) - return n; - } - - void addToTabSizes(TabSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_TAB_SIZES) - } - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE) - -#undef FOR_EACH_SIZE -}; - -/** - * Holds data about a notable class (one whose combined object and shape - * instances use more than a certain amount of memory) so we can report it - * individually. - * - * The only difference between this class and ClassInfo is that this class - * holds a copy of the filename. - */ -struct NotableClassInfo : public ClassInfo -{ - NotableClassInfo(); - NotableClassInfo(const char* className, const ClassInfo& info); - NotableClassInfo(NotableClassInfo&& info); - NotableClassInfo& operator=(NotableClassInfo&& info); - - ~NotableClassInfo() { - js_free(className_); - } - - char* className_; - - private: - NotableClassInfo(const NotableClassInfo& info) = delete; -}; - -/** Data for tracking JIT-code memory usage. */ -struct CodeSizes -{ -#define FOR_EACH_SIZE(macro) \ - macro(_, NonHeap, ion) \ - macro(_, NonHeap, baseline) \ - macro(_, NonHeap, regexp) \ - macro(_, NonHeap, other) \ - macro(_, NonHeap, unused) - - CodeSizes() - : FOR_EACH_SIZE(ZERO_SIZE) - dummy() - {} - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE) - -#undef FOR_EACH_SIZE -}; - -/** Data for tracking GC memory usage. */ -struct GCSizes -{ - // |nurseryDecommitted| is marked as NonHeap rather than GCHeapDecommitted - // because we don't consider the nursery to be part of the GC heap. -#define FOR_EACH_SIZE(macro) \ - macro(_, MallocHeap, marker) \ - macro(_, NonHeap, nurseryCommitted) \ - macro(_, MallocHeap, nurseryMallocedBuffers) \ - macro(_, MallocHeap, storeBufferVals) \ - macro(_, MallocHeap, storeBufferCells) \ - macro(_, MallocHeap, storeBufferSlots) \ - macro(_, MallocHeap, storeBufferWholeCells) \ - macro(_, MallocHeap, storeBufferGenerics) - - GCSizes() - : FOR_EACH_SIZE(ZERO_SIZE) - dummy() - {} - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE) - -#undef FOR_EACH_SIZE -}; - -/** - * This class holds information about the memory taken up by identical copies of - * a particular string. Multiple JSStrings may have their sizes aggregated - * together into one StringInfo object. Note that two strings with identical - * chars will not be aggregated together if one is a short string and the other - * is not. - */ -struct StringInfo -{ -#define FOR_EACH_SIZE(macro) \ - macro(Strings, GCHeapUsed, gcHeapLatin1) \ - macro(Strings, GCHeapUsed, gcHeapTwoByte) \ - macro(Strings, MallocHeap, mallocHeapLatin1) \ - macro(Strings, MallocHeap, mallocHeapTwoByte) - - StringInfo() - : FOR_EACH_SIZE(ZERO_SIZE) - numCopies(0) - {} - - void add(const StringInfo& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE); - numCopies++; - } - - void subtract(const StringInfo& other) { - FOR_EACH_SIZE(SUB_OTHER_SIZE); - numCopies--; - } - - bool isNotable() const { - static const size_t NotabilityThreshold = 16 * 1024; - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N) - return n >= NotabilityThreshold; - } - - size_t sizeOfLiveGCThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) - return n; - } - - void addToTabSizes(TabSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_TAB_SIZES) - } - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - uint32_t numCopies; // How many copies of the string have we seen? - -#undef FOR_EACH_SIZE -}; - -/** - * Holds data about a notable string (one which, counting all duplicates, uses - * more than a certain amount of memory) so we can report it individually. - * - * The only difference between this class and StringInfo is that - * NotableStringInfo holds a copy of some or all of the string's chars. - */ -struct NotableStringInfo : public StringInfo -{ - static const size_t MAX_SAVED_CHARS = 1024; - - NotableStringInfo(); - NotableStringInfo(JSString* str, const StringInfo& info); - NotableStringInfo(NotableStringInfo&& info); - NotableStringInfo& operator=(NotableStringInfo&& info); - - ~NotableStringInfo() { - js_free(buffer); - } - - char* buffer; - size_t length; - - private: - NotableStringInfo(const NotableStringInfo& info) = delete; -}; - -/** - * This class holds information about the memory taken up by script sources - * from a particular file. - */ -struct ScriptSourceInfo -{ -#define FOR_EACH_SIZE(macro) \ - macro(_, MallocHeap, misc) - - ScriptSourceInfo() - : FOR_EACH_SIZE(ZERO_SIZE) - numScripts(0) - {} - - void add(const ScriptSourceInfo& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE) - numScripts++; - } - - void subtract(const ScriptSourceInfo& other) { - FOR_EACH_SIZE(SUB_OTHER_SIZE) - numScripts--; - } - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - bool isNotable() const { - static const size_t NotabilityThreshold = 16 * 1024; - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N) - return n >= NotabilityThreshold; - } - - FOR_EACH_SIZE(DECL_SIZE) - uint32_t numScripts; // How many ScriptSources come from this file? (It - // can be more than one in XML files that have - // multiple scripts in CDATA sections.) -#undef FOR_EACH_SIZE -}; - -/** - * Holds data about a notable script source file (one whose combined - * script sources use more than a certain amount of memory) so we can report it - * individually. - * - * The only difference between this class and ScriptSourceInfo is that this - * class holds a copy of the filename. - */ -struct NotableScriptSourceInfo : public ScriptSourceInfo -{ - NotableScriptSourceInfo(); - NotableScriptSourceInfo(const char* filename, const ScriptSourceInfo& info); - NotableScriptSourceInfo(NotableScriptSourceInfo&& info); - NotableScriptSourceInfo& operator=(NotableScriptSourceInfo&& info); - - ~NotableScriptSourceInfo() { - js_free(filename_); - } - - char* filename_; - - private: - NotableScriptSourceInfo(const NotableScriptSourceInfo& info) = delete; -}; - -/** - * These measurements relate directly to the JSRuntime, and not to zones and - * compartments within it. - */ -struct RuntimeSizes -{ -#define FOR_EACH_SIZE(macro) \ - macro(_, MallocHeap, object) \ - macro(_, MallocHeap, atomsTable) \ - macro(_, MallocHeap, contexts) \ - macro(_, MallocHeap, temporary) \ - macro(_, MallocHeap, interpreterStack) \ - macro(_, MallocHeap, mathCache) \ - macro(_, MallocHeap, sharedImmutableStringsCache) \ - macro(_, MallocHeap, sharedIntlData) \ - macro(_, MallocHeap, uncompressedSourceCache) \ - macro(_, MallocHeap, scriptData) - - RuntimeSizes() - : FOR_EACH_SIZE(ZERO_SIZE) - scriptSourceInfo(), - code(), - gc(), - notableScriptSources() - { - allScriptSources = js_new(); - if (!allScriptSources || !allScriptSources->init()) - MOZ_CRASH("oom"); - } - - ~RuntimeSizes() { - // |allScriptSources| is usually deleted and set to nullptr before this - // destructor runs. But there are failure cases due to OOMs that may - // prevent that, so it doesn't hurt to try again here. - js_delete(allScriptSources); - } - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - scriptSourceInfo.addToServoSizes(sizes); - code.addToServoSizes(sizes); - gc.addToServoSizes(sizes); - } - - // The script source measurements in |scriptSourceInfo| are initially for - // all script sources. At the end, if the measurement granularity is - // FineGrained, we subtract the measurements of the notable script sources - // and move them into |notableScriptSources|. - FOR_EACH_SIZE(DECL_SIZE) - ScriptSourceInfo scriptSourceInfo; - CodeSizes code; - GCSizes gc; - - typedef js::HashMap ScriptSourcesHashMap; - - // |allScriptSources| is only used transiently. During the reporting phase - // it is filled with info about every script source in the runtime. It's - // then used to fill in |notableScriptSources| (which actually gets - // reported), and immediately discarded afterwards. - ScriptSourcesHashMap* allScriptSources; - js::Vector notableScriptSources; - -#undef FOR_EACH_SIZE -}; - -struct UnusedGCThingSizes -{ -#define FOR_EACH_SIZE(macro) \ - macro(Other, GCHeapUnused, object) \ - macro(Other, GCHeapUnused, script) \ - macro(Other, GCHeapUnused, lazyScript) \ - macro(Other, GCHeapUnused, shape) \ - macro(Other, GCHeapUnused, baseShape) \ - macro(Other, GCHeapUnused, objectGroup) \ - macro(Other, GCHeapUnused, string) \ - macro(Other, GCHeapUnused, symbol) \ - macro(Other, GCHeapUnused, jitcode) \ - macro(Other, GCHeapUnused, scope) - - UnusedGCThingSizes() - : FOR_EACH_SIZE(ZERO_SIZE) - dummy() - {} - - UnusedGCThingSizes(UnusedGCThingSizes&& other) - : FOR_EACH_SIZE(COPY_OTHER_SIZE) - dummy() - {} - - void addToKind(JS::TraceKind kind, intptr_t n) { - switch (kind) { - case JS::TraceKind::Object: object += n; break; - case JS::TraceKind::String: string += n; break; - case JS::TraceKind::Symbol: symbol += n; break; - case JS::TraceKind::Script: script += n; break; - case JS::TraceKind::Shape: shape += n; break; - case JS::TraceKind::BaseShape: baseShape += n; break; - case JS::TraceKind::JitCode: jitcode += n; break; - case JS::TraceKind::LazyScript: lazyScript += n; break; - case JS::TraceKind::ObjectGroup: objectGroup += n; break; - case JS::TraceKind::Scope: scope += n; break; - default: - MOZ_CRASH("Bad trace kind for UnusedGCThingSizes"); - } - } - - void addSizes(const UnusedGCThingSizes& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE) - } - - size_t totalSize() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N) - return n; - } - - void addToTabSizes(JS::TabSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_TAB_SIZES) - } - - void addToServoSizes(JS::ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE) - -#undef FOR_EACH_SIZE -}; - -struct ZoneStats -{ -#define FOR_EACH_SIZE(macro) \ - macro(Other, GCHeapUsed, symbolsGCHeap) \ - macro(Other, GCHeapAdmin, gcHeapArenaAdmin) \ - macro(Other, GCHeapUsed, lazyScriptsGCHeap) \ - macro(Other, MallocHeap, lazyScriptsMallocHeap) \ - macro(Other, GCHeapUsed, jitCodesGCHeap) \ - macro(Other, GCHeapUsed, objectGroupsGCHeap) \ - macro(Other, MallocHeap, objectGroupsMallocHeap) \ - macro(Other, GCHeapUsed, scopesGCHeap) \ - macro(Other, MallocHeap, scopesMallocHeap) \ - macro(Other, MallocHeap, typePool) \ - macro(Other, MallocHeap, baselineStubsOptimized) \ - macro(Other, MallocHeap, uniqueIdMap) \ - macro(Other, MallocHeap, shapeTables) - - ZoneStats() - : FOR_EACH_SIZE(ZERO_SIZE) - unusedGCThings(), - stringInfo(), - shapeInfo(), - extra(), - allStrings(nullptr), - notableStrings(), - isTotals(true) - {} - - ZoneStats(ZoneStats&& other) - : FOR_EACH_SIZE(COPY_OTHER_SIZE) - unusedGCThings(mozilla::Move(other.unusedGCThings)), - stringInfo(mozilla::Move(other.stringInfo)), - shapeInfo(mozilla::Move(other.shapeInfo)), - extra(other.extra), - allStrings(other.allStrings), - notableStrings(mozilla::Move(other.notableStrings)), - isTotals(other.isTotals) - { - other.allStrings = nullptr; - MOZ_ASSERT(!other.isTotals); - } - - ~ZoneStats() { - // |allStrings| is usually deleted and set to nullptr before this - // destructor runs. But there are failure cases due to OOMs that may - // prevent that, so it doesn't hurt to try again here. - js_delete(allStrings); - } - - bool initStrings(JSRuntime* rt); - - void addSizes(const ZoneStats& other) { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_OTHER_SIZE) - unusedGCThings.addSizes(other.unusedGCThings); - stringInfo.add(other.stringInfo); - shapeInfo.add(other.shapeInfo); - } - - size_t sizeOfLiveGCThings() const { - MOZ_ASSERT(isTotals); - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) - n += stringInfo.sizeOfLiveGCThings(); - n += shapeInfo.sizeOfLiveGCThings(); - return n; - } - - void addToTabSizes(JS::TabSizes* sizes) const { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_TO_TAB_SIZES) - unusedGCThings.addToTabSizes(sizes); - stringInfo.addToTabSizes(sizes); - shapeInfo.addToTabSizes(sizes); - } - - void addToServoSizes(JS::ServoSizes *sizes) const { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - unusedGCThings.addToServoSizes(sizes); - stringInfo.addToServoSizes(sizes); - shapeInfo.addToServoSizes(sizes); - } - - // These string measurements are initially for all strings. At the end, - // if the measurement granularity is FineGrained, we subtract the - // measurements of the notable script sources and move them into - // |notableStrings|. - FOR_EACH_SIZE(DECL_SIZE) - UnusedGCThingSizes unusedGCThings; - StringInfo stringInfo; - ShapeInfo shapeInfo; - void* extra; // This field can be used by embedders. - - typedef js::HashMap StringsHashMap; - - // |allStrings| is only used transiently. During the zone traversal it is - // filled with info about every string in the zone. It's then used to fill - // in |notableStrings| (which actually gets reported), and immediately - // discarded afterwards. - StringsHashMap* allStrings; - js::Vector notableStrings; - bool isTotals; - -#undef FOR_EACH_SIZE -}; - -struct CompartmentStats -{ - // We assume that |objectsPrivate| is on the malloc heap, but it's not - // actually guaranteed. But for Servo, at least, it's a moot point because - // it doesn't provide an ObjectPrivateVisitor so the value will always be - // zero. -#define FOR_EACH_SIZE(macro) \ - macro(Private, MallocHeap, objectsPrivate) \ - macro(Other, GCHeapUsed, scriptsGCHeap) \ - macro(Other, MallocHeap, scriptsMallocHeapData) \ - macro(Other, MallocHeap, baselineData) \ - macro(Other, MallocHeap, baselineStubsFallback) \ - macro(Other, MallocHeap, ionData) \ - macro(Other, MallocHeap, typeInferenceTypeScripts) \ - macro(Other, MallocHeap, typeInferenceAllocationSiteTables) \ - macro(Other, MallocHeap, typeInferenceArrayTypeTables) \ - macro(Other, MallocHeap, typeInferenceObjectTypeTables) \ - macro(Other, MallocHeap, compartmentObject) \ - macro(Other, MallocHeap, compartmentTables) \ - macro(Other, MallocHeap, innerViewsTable) \ - macro(Other, MallocHeap, lazyArrayBuffersTable) \ - macro(Other, MallocHeap, objectMetadataTable) \ - macro(Other, MallocHeap, crossCompartmentWrappersTable) \ - macro(Other, MallocHeap, regexpCompartment) \ - macro(Other, MallocHeap, savedStacksSet) \ - macro(Other, MallocHeap, varNamesSet) \ - macro(Other, MallocHeap, nonSyntacticLexicalScopesTable) \ - macro(Other, MallocHeap, jitCompartment) \ - macro(Other, MallocHeap, privateData) - - CompartmentStats() - : FOR_EACH_SIZE(ZERO_SIZE) - classInfo(), - extra(), - allClasses(nullptr), - notableClasses(), - isTotals(true) - {} - - CompartmentStats(CompartmentStats&& other) - : FOR_EACH_SIZE(COPY_OTHER_SIZE) - classInfo(mozilla::Move(other.classInfo)), - extra(other.extra), - allClasses(other.allClasses), - notableClasses(mozilla::Move(other.notableClasses)), - isTotals(other.isTotals) - { - other.allClasses = nullptr; - MOZ_ASSERT(!other.isTotals); - } - - CompartmentStats(const CompartmentStats&) = delete; // disallow copying - - ~CompartmentStats() { - // |allClasses| is usually deleted and set to nullptr before this - // destructor runs. But there are failure cases due to OOMs that may - // prevent that, so it doesn't hurt to try again here. - js_delete(allClasses); - } - - bool initClasses(JSRuntime* rt); - - void addSizes(const CompartmentStats& other) { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_OTHER_SIZE) - classInfo.add(other.classInfo); - } - - size_t sizeOfLiveGCThings() const { - MOZ_ASSERT(isTotals); - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) - n += classInfo.sizeOfLiveGCThings(); - return n; - } - - void addToTabSizes(TabSizes* sizes) const { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_TO_TAB_SIZES); - classInfo.addToTabSizes(sizes); - } - - void addToServoSizes(ServoSizes *sizes) const { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES); - classInfo.addToServoSizes(sizes); - } - - // The class measurements in |classInfo| are initially for all classes. At - // the end, if the measurement granularity is FineGrained, we subtract the - // measurements of the notable classes and move them into |notableClasses|. - FOR_EACH_SIZE(DECL_SIZE) - ClassInfo classInfo; - void* extra; // This field can be used by embedders. - - typedef js::HashMap ClassesHashMap; - - // These are similar to |allStrings| and |notableStrings| in ZoneStats. - ClassesHashMap* allClasses; - js::Vector notableClasses; - bool isTotals; - -#undef FOR_EACH_SIZE -}; - -typedef js::Vector CompartmentStatsVector; -typedef js::Vector ZoneStatsVector; - -struct RuntimeStats -{ - // |gcHeapChunkTotal| is ignored because it's the sum of all the other - // values. |gcHeapGCThings| is ignored because it's the sum of some of the - // values from the zones and compartments. Both of those values are not - // reported directly, but are just present for sanity-checking other - // values. -#define FOR_EACH_SIZE(macro) \ - macro(_, Ignore, gcHeapChunkTotal) \ - macro(_, GCHeapDecommitted, gcHeapDecommittedArenas) \ - macro(_, GCHeapUnused, gcHeapUnusedChunks) \ - macro(_, GCHeapUnused, gcHeapUnusedArenas) \ - macro(_, GCHeapAdmin, gcHeapChunkAdmin) \ - macro(_, Ignore, gcHeapGCThings) - - explicit RuntimeStats(mozilla::MallocSizeOf mallocSizeOf) - : FOR_EACH_SIZE(ZERO_SIZE) - runtime(), - cTotals(), - zTotals(), - compartmentStatsVector(), - zoneStatsVector(), - currZoneStats(nullptr), - mallocSizeOf_(mallocSizeOf) - {} - - // Here's a useful breakdown of the GC heap. - // - // - rtStats.gcHeapChunkTotal - // - decommitted bytes - // - rtStats.gcHeapDecommittedArenas (decommitted arenas in non-empty chunks) - // - unused bytes - // - rtStats.gcHeapUnusedChunks (empty chunks) - // - rtStats.gcHeapUnusedArenas (empty arenas within non-empty chunks) - // - rtStats.zTotals.unusedGCThings.totalSize() (empty GC thing slots within non-empty arenas) - // - used bytes - // - rtStats.gcHeapChunkAdmin - // - rtStats.zTotals.gcHeapArenaAdmin - // - rtStats.gcHeapGCThings (in-use GC things) - // == rtStats.zTotals.sizeOfLiveGCThings() + rtStats.cTotals.sizeOfLiveGCThings() - // - // It's possible that some arenas in empty chunks may be decommitted, but - // we don't count those under rtStats.gcHeapDecommittedArenas because (a) - // it's rare, and (b) this means that rtStats.gcHeapUnusedChunks is a - // multiple of the chunk size, which is good. - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - runtime.addToServoSizes(sizes); - } - - FOR_EACH_SIZE(DECL_SIZE) - - RuntimeSizes runtime; - - CompartmentStats cTotals; // The sum of this runtime's compartments' measurements. - ZoneStats zTotals; // The sum of this runtime's zones' measurements. - - CompartmentStatsVector compartmentStatsVector; - ZoneStatsVector zoneStatsVector; - - ZoneStats* currZoneStats; - - mozilla::MallocSizeOf mallocSizeOf_; - - virtual void initExtraCompartmentStats(JSCompartment* c, CompartmentStats* cstats) = 0; - virtual void initExtraZoneStats(JS::Zone* zone, ZoneStats* zstats) = 0; - -#undef FOR_EACH_SIZE -}; - -class ObjectPrivateVisitor -{ - public: - // Within CollectRuntimeStats, this method is called for each JS object - // that has an nsISupports pointer. - virtual size_t sizeOfIncludingThis(nsISupports* aSupports) = 0; - - // A callback that gets a JSObject's nsISupports pointer, if it has one. - // Note: this function does *not* addref |iface|. - typedef bool(*GetISupportsFun)(JSObject* obj, nsISupports** iface); - GetISupportsFun getISupports_; - - explicit ObjectPrivateVisitor(GetISupportsFun getISupports) - : getISupports_(getISupports) - {} -}; - -extern JS_PUBLIC_API(bool) -CollectRuntimeStats(JSContext* cx, RuntimeStats* rtStats, ObjectPrivateVisitor* opv, bool anonymize); - -extern JS_PUBLIC_API(size_t) -SystemCompartmentCount(JSContext* cx); - -extern JS_PUBLIC_API(size_t) -UserCompartmentCount(JSContext* cx); - -extern JS_PUBLIC_API(size_t) -PeakSizeOfTemporary(const JSContext* cx); - -extern JS_PUBLIC_API(bool) -AddSizeOfTab(JSContext* cx, JS::HandleObject obj, mozilla::MallocSizeOf mallocSizeOf, - ObjectPrivateVisitor* opv, TabSizes* sizes); - -extern JS_PUBLIC_API(bool) -AddServoSizeOf(JSContext* cx, mozilla::MallocSizeOf mallocSizeOf, - ObjectPrivateVisitor *opv, ServoSizes *sizes); - -} // namespace JS - -#undef DECL_SIZE -#undef ZERO_SIZE -#undef COPY_OTHER_SIZE -#undef ADD_OTHER_SIZE -#undef SUB_OTHER_SIZE -#undef ADD_SIZE_TO_N -#undef ADD_SIZE_TO_N_IF_LIVE_GC_THING -#undef ADD_TO_TAB_SIZES - -#endif /* js_MemoryMetrics_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/Principals.h b/android/arm64-v8a/include/spidermonkey/js/Principals.h deleted file mode 100644 index cf6c813a..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/Principals.h +++ /dev/null @@ -1,132 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* JSPrincipals and related interfaces. */ - -#ifndef js_Principals_h -#define js_Principals_h - -#include "mozilla/Atomics.h" - -#include - -#include "jspubtd.h" - -#include "js/StructuredClone.h" - -namespace js { - struct PerformanceGroup; -} // namespace js - -struct JSPrincipals { - /* Don't call "destroy"; use reference counting macros below. */ - mozilla::Atomic refcount; - -#ifdef JS_DEBUG - /* A helper to facilitate principals debugging. */ - uint32_t debugToken; -#endif - - JSPrincipals() : refcount(0) {} - - void setDebugToken(uint32_t token) { -# ifdef JS_DEBUG - debugToken = token; -# endif - } - - /* - * Write the principals with the given |writer|. Return false on failure, - * true on success. - */ - virtual bool write(JSContext* cx, JSStructuredCloneWriter* writer) = 0; - - /* - * This is not defined by the JS engine but should be provided by the - * embedding. - */ - JS_PUBLIC_API(void) dump(); -}; - -extern JS_PUBLIC_API(void) -JS_HoldPrincipals(JSPrincipals* principals); - -extern JS_PUBLIC_API(void) -JS_DropPrincipals(JSContext* cx, JSPrincipals* principals); - -// Return whether the first principal subsumes the second. The exact meaning of -// 'subsumes' is left up to the browser. Subsumption is checked inside the JS -// engine when determining, e.g., which stack frames to display in a backtrace. -typedef bool -(* JSSubsumesOp)(JSPrincipals* first, JSPrincipals* second); - -/* - * Used to check if a CSP instance wants to disable eval() and friends. - * See js_CheckCSPPermitsJSAction() in jsobj. - */ -typedef bool -(* JSCSPEvalChecker)(JSContext* cx); - -struct JSSecurityCallbacks { - JSCSPEvalChecker contentSecurityPolicyAllows; - JSSubsumesOp subsumes; -}; - -extern JS_PUBLIC_API(void) -JS_SetSecurityCallbacks(JSContext* cx, const JSSecurityCallbacks* callbacks); - -extern JS_PUBLIC_API(const JSSecurityCallbacks*) -JS_GetSecurityCallbacks(JSContext* cx); - -/* - * Code running with "trusted" principals will be given a deeper stack - * allocation than ordinary scripts. This allows trusted script to run after - * untrusted script has exhausted the stack. This function sets the - * runtime-wide trusted principal. - * - * This principals is not held (via JS_HoldPrincipals/JS_DropPrincipals). - * Instead, the caller must ensure that the given principals stays valid for as - * long as 'cx' may point to it. If the principals would be destroyed before - * 'cx', JS_SetTrustedPrincipals must be called again, passing nullptr for - * 'prin'. - */ -extern JS_PUBLIC_API(void) -JS_SetTrustedPrincipals(JSContext* cx, JSPrincipals* prin); - -typedef void -(* JSDestroyPrincipalsOp)(JSPrincipals* principals); - -/* - * Initialize the callback that is called to destroy JSPrincipals instance - * when its reference counter drops to zero. The initialization can be done - * only once per JS runtime. - */ -extern JS_PUBLIC_API(void) -JS_InitDestroyPrincipalsCallback(JSContext* cx, JSDestroyPrincipalsOp destroyPrincipals); - -/* - * Read a JSPrincipals instance from the given |reader| and initialize the out - * paratemer |outPrincipals| to the JSPrincipals instance read. - * - * Return false on failure, true on success. The |outPrincipals| parameter - * should not be modified if false is returned. - * - * The caller is not responsible for calling JS_HoldPrincipals on the resulting - * JSPrincipals instance, the JSReadPrincipalsOp must increment the refcount of - * the resulting JSPrincipals on behalf of the caller. - */ -using JSReadPrincipalsOp = bool (*)(JSContext* cx, JSStructuredCloneReader* reader, - JSPrincipals** outPrincipals); - -/* - * Initialize the callback that is called to read JSPrincipals instances from a - * buffer. The initialization can be done only once per JS runtime. - */ -extern JS_PUBLIC_API(void) -JS_InitReadPrincipalsCallback(JSContext* cx, JSReadPrincipalsOp read); - - -#endif /* js_Principals_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/ProfilingFrameIterator.h b/android/arm64-v8a/include/spidermonkey/js/ProfilingFrameIterator.h deleted file mode 100644 index d082213d..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/ProfilingFrameIterator.h +++ /dev/null @@ -1,203 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_ProfilingFrameIterator_h -#define js_ProfilingFrameIterator_h - -#include "mozilla/Alignment.h" -#include "mozilla/Maybe.h" - -#include "jsbytecode.h" -#include "js/GCAPI.h" -#include "js/TypeDecls.h" -#include "js/Utility.h" - -struct JSContext; -struct JSRuntime; -class JSScript; - -namespace js { - class Activation; - namespace jit { - class JitActivation; - class JitProfilingFrameIterator; - class JitcodeGlobalEntry; - } // namespace jit - namespace wasm { - class ProfilingFrameIterator; - } // namespace wasm -} // namespace js - -namespace JS { - -struct ForEachTrackedOptimizationAttemptOp; -struct ForEachTrackedOptimizationTypeInfoOp; - -// This iterator can be used to walk the stack of a thread suspended at an -// arbitrary pc. To provide acurate results, profiling must have been enabled -// (via EnableRuntimeProfilingStack) before executing the callstack being -// unwound. -// -// Note that the caller must not do anything that could cause GC to happen while -// the iterator is alive, since this could invalidate Ion code and cause its -// contents to become out of date. -class JS_PUBLIC_API(ProfilingFrameIterator) -{ - JSRuntime* rt_; - uint32_t sampleBufferGen_; - js::Activation* activation_; - - // When moving past a JitActivation, we need to save the prevJitTop - // from it to use as the exit-frame pointer when the next caller jit - // activation (if any) comes around. - void* savedPrevJitTop_; - - JS::AutoCheckCannotGC nogc_; - - static const unsigned StorageSpace = 8 * sizeof(void*); - mozilla::AlignedStorage storage_; - js::wasm::ProfilingFrameIterator& wasmIter() { - MOZ_ASSERT(!done()); - MOZ_ASSERT(isWasm()); - return *reinterpret_cast(storage_.addr()); - } - const js::wasm::ProfilingFrameIterator& wasmIter() const { - MOZ_ASSERT(!done()); - MOZ_ASSERT(isWasm()); - return *reinterpret_cast(storage_.addr()); - } - - js::jit::JitProfilingFrameIterator& jitIter() { - MOZ_ASSERT(!done()); - MOZ_ASSERT(isJit()); - return *reinterpret_cast(storage_.addr()); - } - - const js::jit::JitProfilingFrameIterator& jitIter() const { - MOZ_ASSERT(!done()); - MOZ_ASSERT(isJit()); - return *reinterpret_cast(storage_.addr()); - } - - void settle(); - - bool hasSampleBufferGen() const { - return sampleBufferGen_ != UINT32_MAX; - } - - public: - struct RegisterState - { - RegisterState() : pc(nullptr), sp(nullptr), lr(nullptr) {} - void* pc; - void* sp; - void* lr; - }; - - ProfilingFrameIterator(JSContext* cx, const RegisterState& state, - uint32_t sampleBufferGen = UINT32_MAX); - ~ProfilingFrameIterator(); - void operator++(); - bool done() const { return !activation_; } - - // Assuming the stack grows down (we do), the return value: - // - always points into the stack - // - is weakly monotonically increasing (may be equal for successive frames) - // - will compare greater than newer native and psuedo-stack frame addresses - // and less than older native and psuedo-stack frame addresses - void* stackAddress() const; - - enum FrameKind - { - Frame_Baseline, - Frame_Ion, - Frame_Wasm - }; - - struct Frame - { - FrameKind kind; - void* stackAddress; - void* returnAddress; - void* activation; - UniqueChars label; - }; - - bool isWasm() const; - bool isJit() const; - - uint32_t extractStack(Frame* frames, uint32_t offset, uint32_t end) const; - - mozilla::Maybe getPhysicalFrameWithoutLabel() const; - - private: - mozilla::Maybe getPhysicalFrameAndEntry(js::jit::JitcodeGlobalEntry* entry) const; - - void iteratorConstruct(const RegisterState& state); - void iteratorConstruct(); - void iteratorDestroy(); - bool iteratorDone(); -}; - -JS_FRIEND_API(bool) -IsProfilingEnabledForContext(JSContext* cx); - -/** - * After each sample run, this method should be called with the latest sample - * buffer generation, and the lapCount. It will update corresponding fields on - * JSRuntime. - * - * See fields |profilerSampleBufferGen|, |profilerSampleBufferLapCount| on - * JSRuntime for documentation about what these values are used for. - */ -JS_FRIEND_API(void) -UpdateJSContextProfilerSampleBufferGen(JSContext* cx, uint32_t generation, - uint32_t lapCount); - -struct ForEachProfiledFrameOp -{ - // A handle to the underlying JitcodeGlobalEntry, so as to avoid repeated - // lookups on JitcodeGlobalTable. - class MOZ_STACK_CLASS FrameHandle - { - friend JS_PUBLIC_API(void) ForEachProfiledFrame(JSContext* cx, void* addr, - ForEachProfiledFrameOp& op); - - JSRuntime* rt_; - js::jit::JitcodeGlobalEntry& entry_; - void* addr_; - void* canonicalAddr_; - const char* label_; - uint32_t depth_; - mozilla::Maybe optsIndex_; - - FrameHandle(JSRuntime* rt, js::jit::JitcodeGlobalEntry& entry, void* addr, - const char* label, uint32_t depth); - - void updateHasTrackedOptimizations(); - - public: - const char* label() const { return label_; } - uint32_t depth() const { return depth_; } - bool hasTrackedOptimizations() const { return optsIndex_.isSome(); } - void* canonicalAddress() const { return canonicalAddr_; } - - ProfilingFrameIterator::FrameKind frameKind() const; - void forEachOptimizationAttempt(ForEachTrackedOptimizationAttemptOp& op, - JSScript** scriptOut, jsbytecode** pcOut) const; - void forEachOptimizationTypeInfo(ForEachTrackedOptimizationTypeInfoOp& op) const; - }; - - // Called once per frame. - virtual void operator()(const FrameHandle& frame) = 0; -}; - -JS_PUBLIC_API(void) -ForEachProfiledFrame(JSContext* cx, void* addr, ForEachProfiledFrameOp& op); - -} // namespace JS - -#endif /* js_ProfilingFrameIterator_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/ProfilingStack.h b/android/arm64-v8a/include/spidermonkey/js/ProfilingStack.h deleted file mode 100644 index 6b6c9701..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/ProfilingStack.h +++ /dev/null @@ -1,208 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_ProfilingStack_h -#define js_ProfilingStack_h - -#include "jsbytecode.h" -#include "jstypes.h" -#include "js/TypeDecls.h" - -#include "js/Utility.h" - -struct JSRuntime; -class JSTracer; - -namespace js { - -// A call stack can be specified to the JS engine such that all JS entry/exits -// to functions push/pop an entry to/from the specified stack. -// -// For more detailed information, see vm/SPSProfiler.h. -// -class ProfileEntry -{ - // All fields are marked volatile to prevent the compiler from re-ordering - // instructions. Namely this sequence: - // - // entry[size] = ...; - // size++; - // - // If the size modification were somehow reordered before the stores, then - // if a sample were taken it would be examining bogus information. - // - // A ProfileEntry represents both a C++ profile entry and a JS one. - - // Descriptive string of this entry. - const char * volatile string; - - // Stack pointer for non-JS entries, the script pointer otherwise. - void * volatile spOrScript; - - // Line number for non-JS entries, the bytecode offset otherwise. - int32_t volatile lineOrPcOffset; - - // General purpose storage describing this frame. - uint32_t volatile flags_; - - public: - // These traits are bit masks. Make sure they're powers of 2. - enum Flags : uint32_t { - // Indicate whether a profile entry represents a CPP frame. If not set, - // a JS frame is assumed by default. You're not allowed to publicly - // change the frame type. Instead, initialize the ProfileEntry as either - // a JS or CPP frame with `initJsFrame` or `initCppFrame` respectively. - IS_CPP_ENTRY = 0x01, - - // Indicate that copying the frame label is not necessary when taking a - // sample of the pseudostack. - FRAME_LABEL_COPY = 0x02, - - // This ProfileEntry is a dummy entry indicating the start of a run - // of JS pseudostack entries. - BEGIN_PSEUDO_JS = 0x04, - - // This flag is used to indicate that an interpreter JS entry has OSR-ed - // into baseline. - OSR = 0x08, - - // Union of all flags. - ALL = IS_CPP_ENTRY|FRAME_LABEL_COPY|BEGIN_PSEUDO_JS|OSR, - - // Mask for removing all flags except the category information. - CATEGORY_MASK = ~ALL - }; - - // Keep these in sync with devtools/client/performance/modules/categories.js - enum class Category : uint32_t { - OTHER = 0x10, - CSS = 0x20, - JS = 0x40, - GC = 0x80, - CC = 0x100, - NETWORK = 0x200, - GRAPHICS = 0x400, - STORAGE = 0x800, - EVENTS = 0x1000, - - FIRST = OTHER, - LAST = EVENTS - }; - - static_assert((static_cast(Category::FIRST) & Flags::ALL) == 0, - "The category bitflags should not intersect with the other flags!"); - - // All of these methods are marked with the 'volatile' keyword because SPS's - // representation of the stack is stored such that all ProfileEntry - // instances are volatile. These methods would not be available unless they - // were marked as volatile as well. - - bool isCpp() const volatile { return hasFlag(IS_CPP_ENTRY); } - bool isJs() const volatile { return !isCpp(); } - - bool isCopyLabel() const volatile { return hasFlag(FRAME_LABEL_COPY); } - - void setLabel(const char* aString) volatile { string = aString; } - const char* label() const volatile { return string; } - - void initJsFrame(JSScript* aScript, jsbytecode* aPc) volatile { - flags_ = 0; - spOrScript = aScript; - setPC(aPc); - } - void initCppFrame(void* aSp, uint32_t aLine) volatile { - flags_ = IS_CPP_ENTRY; - spOrScript = aSp; - lineOrPcOffset = static_cast(aLine); - } - - void setFlag(uint32_t flag) volatile { - MOZ_ASSERT(flag != IS_CPP_ENTRY); - flags_ |= flag; - } - void unsetFlag(uint32_t flag) volatile { - MOZ_ASSERT(flag != IS_CPP_ENTRY); - flags_ &= ~flag; - } - bool hasFlag(uint32_t flag) const volatile { - return bool(flags_ & flag); - } - - uint32_t flags() const volatile { - return flags_; - } - - uint32_t category() const volatile { - return flags_ & CATEGORY_MASK; - } - void setCategory(Category c) volatile { - MOZ_ASSERT(c >= Category::FIRST); - MOZ_ASSERT(c <= Category::LAST); - flags_ &= ~CATEGORY_MASK; - setFlag(static_cast(c)); - } - - void setOSR() volatile { - MOZ_ASSERT(isJs()); - setFlag(OSR); - } - void unsetOSR() volatile { - MOZ_ASSERT(isJs()); - unsetFlag(OSR); - } - bool isOSR() const volatile { - return hasFlag(OSR); - } - - void* stackAddress() const volatile { - MOZ_ASSERT(!isJs()); - return spOrScript; - } - JSScript* script() const volatile; - uint32_t line() const volatile { - MOZ_ASSERT(!isJs()); - return static_cast(lineOrPcOffset); - } - - // Note that the pointer returned might be invalid. - JSScript* rawScript() const volatile { - MOZ_ASSERT(isJs()); - return (JSScript*)spOrScript; - } - - // We can't know the layout of JSScript, so look in vm/SPSProfiler.cpp. - JS_FRIEND_API(jsbytecode*) pc() const volatile; - JS_FRIEND_API(void) setPC(jsbytecode* pc) volatile; - - void trace(JSTracer* trc); - - // The offset of a pc into a script's code can actually be 0, so to - // signify a nullptr pc, use a -1 index. This is checked against in - // pc() and setPC() to set/get the right pc. - static const int32_t NullPCOffset = -1; - - static size_t offsetOfLabel() { return offsetof(ProfileEntry, string); } - static size_t offsetOfSpOrScript() { return offsetof(ProfileEntry, spOrScript); } - static size_t offsetOfLineOrPcOffset() { return offsetof(ProfileEntry, lineOrPcOffset); } - static size_t offsetOfFlags() { return offsetof(ProfileEntry, flags_); } -}; - -JS_FRIEND_API(void) -SetContextProfilingStack(JSContext* cx, ProfileEntry* stack, uint32_t* size, - uint32_t max); - -JS_FRIEND_API(void) -EnableContextProfilingStack(JSContext* cx, bool enabled); - -JS_FRIEND_API(void) -RegisterContextProfilingEventMarker(JSContext* cx, void (*fn)(const char*)); - -JS_FRIEND_API(jsbytecode*) -ProfilingGetPC(JSContext* cx, JSScript* script, void* ip); - -} // namespace js - -#endif /* js_ProfilingStack_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/Proxy.h b/android/arm64-v8a/include/spidermonkey/js/Proxy.h deleted file mode 100644 index 3e95538d..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/Proxy.h +++ /dev/null @@ -1,632 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_Proxy_h -#define js_Proxy_h - -#include "mozilla/Maybe.h" - -#include "jsfriendapi.h" - -#include "js/CallNonGenericMethod.h" -#include "js/Class.h" - -namespace js { - -using JS::AutoIdVector; -using JS::CallArgs; -using JS::Handle; -using JS::HandleId; -using JS::HandleObject; -using JS::HandleValue; -using JS::IsAcceptableThis; -using JS::MutableHandle; -using JS::MutableHandleObject; -using JS::MutableHandleValue; -using JS::NativeImpl; -using JS::ObjectOpResult; -using JS::PrivateValue; -using JS::PropertyDescriptor; -using JS::Value; - -class RegExpGuard; -class JS_FRIEND_API(Wrapper); - -/* - * A proxy is a JSObject with highly customizable behavior. ES6 specifies a - * single kind of proxy, but the customization mechanisms we use to implement - * ES6 Proxy objects are also useful wherever an object with weird behavior is - * wanted. Proxies are used to implement: - * - * - the scope objects used by the Debugger's frame.eval() method - * (see js::GetDebugScopeForFunction) - * - * - the khuey hack, whereby a whole compartment can be blown away - * even if other compartments hold references to objects in it - * (see js::NukeCrossCompartmentWrappers) - * - * - XPConnect security wrappers, which protect chrome from malicious content - * (js/xpconnect/wrappers) - * - * - DOM objects with special property behavior, like named getters - * (dom/bindings/Codegen.py generates these proxies from WebIDL) - * - * - semi-transparent use of objects that live in other processes - * (CPOWs, implemented in js/ipc) - * - * ### Proxies and internal methods - * - * ES2016 specifies 13 internal methods. The runtime semantics of just - * about everything a script can do to an object is specified in terms - * of these internal methods. For example: - * - * JS code ES6 internal method that gets called - * --------------------------- -------------------------------- - * obj.prop obj.[[Get]](obj, "prop") - * "prop" in obj obj.[[HasProperty]]("prop") - * new obj() obj.[[Construct]]() - * - * With regard to the implementation of these internal methods, there are three - * very different kinds of object in SpiderMonkey. - * - * 1. Native objects' internal methods are implemented in vm/NativeObject.cpp, - * with duplicate (but functionally identical) implementations scattered - * through the ICs and JITs. - * - * 2. Certain non-native objects have internal methods that are implemented as - * magical js::ObjectOps hooks. We're trying to get rid of these. - * - * 3. All other objects are proxies. A proxy's internal methods are - * implemented in C++, as the virtual methods of a C++ object stored on the - * proxy, known as its handler. - * - * This means that just about anything you do to a proxy will end up going - * through a C++ virtual method call. Possibly several. There's no reason the - * JITs and ICs can't specialize for particular proxies, based on the handler; - * but currently we don't do much of this, so the virtual method overhead - * typically is actually incurred. - * - * ### The proxy handler hierarchy - * - * A major use case for proxies is to forward each internal method call to - * another object, known as its target. The target can be an arbitrary JS - * object. Not every proxy has the notion of a target, however. - * - * To minimize code duplication, a set of abstract proxy handler classes is - * provided, from which other handlers may inherit. These abstract classes are - * organized in the following hierarchy: - * - * BaseProxyHandler - * | - * Wrapper // has a target, can be unwrapped to reveal - * | // target (see js::CheckedUnwrap) - * | - * CrossCompartmentWrapper // target is in another compartment; - * // implements membrane between compartments - * - * Example: Some DOM objects (including all the arraylike DOM objects) are - * implemented as proxies. Since these objects don't need to forward operations - * to any underlying JS object, DOMJSProxyHandler directly subclasses - * BaseProxyHandler. - * - * Gecko's security wrappers are examples of cross-compartment wrappers. - * - * ### Proxy prototype chains - * - * In addition to the normal methods, there are two models for proxy prototype - * chains. - * - * 1. Proxies can use the standard prototype mechanism used throughout the - * engine. To do so, simply pass a prototype to NewProxyObject() at - * creation time. All prototype accesses will then "just work" to treat the - * proxy as a "normal" object. - * - * 2. A proxy can implement more complicated prototype semantics (if, for - * example, it wants to delegate the prototype lookup to a wrapped object) - * by passing Proxy::LazyProto as the prototype at create time. This - * guarantees that the getPrototype() handler method will be called every - * time the object's prototype chain is accessed. - * - * This system is implemented with two methods: {get,set}Prototype. The - * default implementation of setPrototype throws a TypeError. Since it is - * not possible to create an object without a sense of prototype chain, - * handlers must implement getPrototype if opting in to the dynamic - * prototype system. - */ - -/* - * BaseProxyHandler is the most generic kind of proxy handler. It does not make - * any assumptions about the target. Consequently, it does not provide any - * default implementation for most methods. As a convenience, a few high-level - * methods, like get() and set(), are given default implementations that work by - * calling the low-level methods, like getOwnPropertyDescriptor(). - * - * Important: If you add a method here, you should probably also add a - * Proxy::foo entry point with an AutoEnterPolicy. If you don't, you need an - * explicit override for the method in SecurityWrapper. See bug 945826 comment 0. - */ -class JS_FRIEND_API(BaseProxyHandler) -{ - /* - * Sometimes it's desirable to designate groups of proxy handlers as "similar". - * For this, we use the notion of a "family": A consumer-provided opaque pointer - * that designates the larger group to which this proxy belongs. - * - * If it will never be important to differentiate this proxy from others as - * part of a distinct group, nullptr may be used instead. - */ - const void* mFamily; - - /* - * Proxy handlers can use mHasPrototype to request the following special - * treatment from the JS engine: - * - * - When mHasPrototype is true, the engine never calls these methods: - * getPropertyDescriptor, has, set, enumerate, iterate. Instead, for - * these operations, it calls the "own" methods like - * getOwnPropertyDescriptor, hasOwn, defineProperty, - * getOwnEnumerablePropertyKeys, etc., and consults the prototype chain - * if needed. - * - * - When mHasPrototype is true, the engine calls handler->get() only if - * handler->hasOwn() says an own property exists on the proxy. If not, - * it consults the prototype chain. - * - * This is useful because it frees the ProxyHandler from having to implement - * any behavior having to do with the prototype chain. - */ - bool mHasPrototype; - - /* - * All proxies indicate whether they have any sort of interesting security - * policy that might prevent the caller from doing something it wants to - * the object. In the case of wrappers, this distinction is used to - * determine whether the caller may strip off the wrapper if it so desires. - */ - bool mHasSecurityPolicy; - - public: - explicit constexpr BaseProxyHandler(const void* aFamily, bool aHasPrototype = false, - bool aHasSecurityPolicy = false) - : mFamily(aFamily), - mHasPrototype(aHasPrototype), - mHasSecurityPolicy(aHasSecurityPolicy) - { } - - bool hasPrototype() const { - return mHasPrototype; - } - - bool hasSecurityPolicy() const { - return mHasSecurityPolicy; - } - - inline const void* family() const { - return mFamily; - } - static size_t offsetOfFamily() { - return offsetof(BaseProxyHandler, mFamily); - } - - virtual bool finalizeInBackground(const Value& priv) const { - /* - * Called on creation of a proxy to determine whether its finalize - * method can be finalized on the background thread. - */ - return true; - } - - virtual bool canNurseryAllocate() const { - /* - * Nursery allocation is allowed if and only if it is safe to not - * run |finalize| when the ProxyObject dies. - */ - return false; - } - - /* Policy enforcement methods. - * - * enter() allows the policy to specify whether the caller may perform |act| - * on the proxy's |id| property. In the case when |act| is CALL, |id| is - * generally JSID_VOID. - * - * The |act| parameter to enter() specifies the action being performed. - * If |bp| is false, the method suggests that the caller throw (though it - * may still decide to squelch the error). - * - * We make these OR-able so that assertEnteredPolicy can pass a union of them. - * For example, get{,Own}PropertyDescriptor is invoked by calls to ::get() - * ::set(), in addition to being invoked on its own, so there are several - * valid Actions that could have been entered. - */ - typedef uint32_t Action; - enum { - NONE = 0x00, - GET = 0x01, - SET = 0x02, - CALL = 0x04, - ENUMERATE = 0x08, - GET_PROPERTY_DESCRIPTOR = 0x10 - }; - - virtual bool enter(JSContext* cx, HandleObject wrapper, HandleId id, Action act, - bool* bp) const; - - /* Standard internal methods. */ - virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id, - MutableHandle desc) const = 0; - virtual bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id, - Handle desc, - ObjectOpResult& result) const = 0; - virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy, - AutoIdVector& props) const = 0; - virtual bool delete_(JSContext* cx, HandleObject proxy, HandleId id, - ObjectOpResult& result) const = 0; - - /* - * These methods are standard, but the engine does not normally call them. - * They're opt-in. See "Proxy prototype chains" above. - * - * getPrototype() crashes if called. setPrototype() throws a TypeError. - */ - virtual bool getPrototype(JSContext* cx, HandleObject proxy, MutableHandleObject protop) const; - virtual bool setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto, - ObjectOpResult& result) const; - - /* Non-standard but conceptual kin to {g,s}etPrototype, so these live here. */ - virtual bool getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy, bool* isOrdinary, - MutableHandleObject protop) const = 0; - virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy, bool* succeeded) const; - - virtual bool preventExtensions(JSContext* cx, HandleObject proxy, - ObjectOpResult& result) const = 0; - virtual bool isExtensible(JSContext* cx, HandleObject proxy, bool* extensible) const = 0; - - /* - * These standard internal methods are implemented, as a convenience, so - * that ProxyHandler subclasses don't have to provide every single method. - * - * The base-class implementations work by calling getPropertyDescriptor(). - * They do not follow any standard. When in doubt, override them. - */ - virtual bool has(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const; - virtual bool get(JSContext* cx, HandleObject proxy, HandleValue receiver, - HandleId id, MutableHandleValue vp) const; - virtual bool set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v, - HandleValue receiver, ObjectOpResult& result) const; - - /* - * [[Call]] and [[Construct]] are standard internal methods but according - * to the spec, they are not present on every object. - * - * SpiderMonkey never calls a proxy's call()/construct() internal method - * unless isCallable()/isConstructor() returns true for that proxy. - * - * BaseProxyHandler::isCallable()/isConstructor() always return false, and - * BaseProxyHandler::call()/construct() crash if called. So if you're - * creating a kind of that is never callable, you don't have to override - * anything, but otherwise you probably want to override all four. - */ - virtual bool call(JSContext* cx, HandleObject proxy, const CallArgs& args) const; - virtual bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const; - - /* SpiderMonkey extensions. */ - virtual bool enumerate(JSContext* cx, HandleObject proxy, MutableHandleObject objp) const; - virtual bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id, - MutableHandle desc) const; - virtual bool hasOwn(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const; - virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject proxy, - AutoIdVector& props) const; - virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl, - const CallArgs& args) const; - virtual bool hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v, bool* bp) const; - virtual bool getBuiltinClass(JSContext* cx, HandleObject proxy, - ESClass* cls) const; - virtual bool isArray(JSContext* cx, HandleObject proxy, JS::IsArrayAnswer* answer) const; - virtual const char* className(JSContext* cx, HandleObject proxy) const; - virtual JSString* fun_toString(JSContext* cx, HandleObject proxy, unsigned indent) const; - virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const; - virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const; - virtual void trace(JSTracer* trc, JSObject* proxy) const; - virtual void finalize(JSFreeOp* fop, JSObject* proxy) const; - virtual void objectMoved(JSObject* proxy, const JSObject* old) const; - - // Allow proxies, wrappers in particular, to specify callability at runtime. - // Note: These do not take const JSObject*, but they do in spirit. - // We are not prepared to do this, as there's little const correctness - // in the external APIs that handle proxies. - virtual bool isCallable(JSObject* obj) const; - virtual bool isConstructor(JSObject* obj) const; - - // These two hooks must be overridden, or not overridden, in tandem -- no - // overriding just one! - virtual bool watch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, - JS::HandleObject callable) const; - virtual bool unwatch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id) const; - - virtual bool getElements(JSContext* cx, HandleObject proxy, uint32_t begin, uint32_t end, - ElementAdder* adder) const; - - /* See comment for weakmapKeyDelegateOp in js/Class.h. */ - virtual JSObject* weakmapKeyDelegate(JSObject* proxy) const; - virtual bool isScripted() const { return false; } -}; - -extern JS_FRIEND_DATA(const js::Class* const) ProxyClassPtr; - -inline bool IsProxy(const JSObject* obj) -{ - return GetObjectClass(obj)->isProxy(); -} - -namespace detail { -const uint32_t PROXY_EXTRA_SLOTS = 2; - -// Layout of the values stored by a proxy. Note that API clients require the -// private slot to be the first slot in the proxy's values, so that the private -// slot can be accessed in the same fashion as the first reserved slot, via -// {Get,Set}ReservedOrProxyPrivateSlot. - -struct ProxyValueArray -{ - Value privateSlot; - Value extraSlots[PROXY_EXTRA_SLOTS]; - - ProxyValueArray() - : privateSlot(JS::UndefinedValue()) - { - for (size_t i = 0; i < PROXY_EXTRA_SLOTS; i++) - extraSlots[i] = JS::UndefinedValue(); - } -}; - -// All proxies share the same data layout. Following the object's shape and -// type, the proxy has a ProxyDataLayout structure with a pointer to an array -// of values and the proxy's handler. This is designed both so that proxies can -// be easily swapped with other objects (via RemapWrapper) and to mimic the -// layout of other objects (proxies and other objects have the same size) so -// that common code can access either type of object. -// -// See GetReservedOrProxyPrivateSlot below. -struct ProxyDataLayout -{ - ProxyValueArray* values; - const BaseProxyHandler* handler; -}; - -const uint32_t ProxyDataOffset = 2 * sizeof(void*); - -inline ProxyDataLayout* -GetProxyDataLayout(JSObject* obj) -{ - MOZ_ASSERT(IsProxy(obj)); - return reinterpret_cast(reinterpret_cast(obj) + ProxyDataOffset); -} - -inline const ProxyDataLayout* -GetProxyDataLayout(const JSObject* obj) -{ - MOZ_ASSERT(IsProxy(obj)); - return reinterpret_cast(reinterpret_cast(obj) + - ProxyDataOffset); -} -} // namespace detail - -inline const BaseProxyHandler* -GetProxyHandler(const JSObject* obj) -{ - return detail::GetProxyDataLayout(obj)->handler; -} - -inline const Value& -GetProxyPrivate(const JSObject* obj) -{ - return detail::GetProxyDataLayout(obj)->values->privateSlot; -} - -inline JSObject* -GetProxyTargetObject(JSObject* obj) -{ - return GetProxyPrivate(obj).toObjectOrNull(); -} - -inline const Value& -GetProxyExtra(const JSObject* obj, size_t n) -{ - MOZ_ASSERT(n < detail::PROXY_EXTRA_SLOTS); - return detail::GetProxyDataLayout(obj)->values->extraSlots[n]; -} - -inline void -SetProxyHandler(JSObject* obj, const BaseProxyHandler* handler) -{ - detail::GetProxyDataLayout(obj)->handler = handler; -} - -JS_FRIEND_API(void) -SetValueInProxy(Value* slot, const Value& value); - -inline void -SetProxyExtra(JSObject* obj, size_t n, const Value& extra) -{ - MOZ_ASSERT(n < detail::PROXY_EXTRA_SLOTS); - Value* vp = &detail::GetProxyDataLayout(obj)->values->extraSlots[n]; - - // Trigger a barrier before writing the slot. - if (vp->isMarkable() || extra.isMarkable()) - SetValueInProxy(vp, extra); - else - *vp = extra; -} - -inline bool -IsScriptedProxy(const JSObject* obj) -{ - return IsProxy(obj) && GetProxyHandler(obj)->isScripted(); -} - -inline const Value& -GetReservedOrProxyPrivateSlot(const JSObject* obj, size_t slot) -{ - MOZ_ASSERT(slot == 0); - MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj)) || IsProxy(obj)); - return reinterpret_cast(obj)->slotRef(slot); -} - -inline void -SetReservedOrProxyPrivateSlot(JSObject* obj, size_t slot, const Value& value) -{ - MOZ_ASSERT(slot == 0); - MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj)) || IsProxy(obj)); - shadow::Object* sobj = reinterpret_cast(obj); - if (sobj->slotRef(slot).isMarkable() || value.isMarkable()) - SetReservedOrProxyPrivateSlotWithBarrier(obj, slot, value); - else - sobj->slotRef(slot) = value; -} - -class MOZ_STACK_CLASS ProxyOptions { - protected: - /* protected constructor for subclass */ - explicit ProxyOptions(bool singletonArg, bool lazyProtoArg = false) - : singleton_(singletonArg), - lazyProto_(lazyProtoArg), - clasp_(ProxyClassPtr) - {} - - public: - ProxyOptions() : singleton_(false), - lazyProto_(false), - clasp_(ProxyClassPtr) - {} - - bool singleton() const { return singleton_; } - ProxyOptions& setSingleton(bool flag) { - singleton_ = flag; - return *this; - } - - bool lazyProto() const { return lazyProto_; } - ProxyOptions& setLazyProto(bool flag) { - lazyProto_ = flag; - return *this; - } - - const Class* clasp() const { - return clasp_; - } - ProxyOptions& setClass(const Class* claspArg) { - clasp_ = claspArg; - return *this; - } - - private: - bool singleton_; - bool lazyProto_; - const Class* clasp_; -}; - -JS_FRIEND_API(JSObject*) -NewProxyObject(JSContext* cx, const BaseProxyHandler* handler, HandleValue priv, - JSObject* proto, const ProxyOptions& options = ProxyOptions()); - -JSObject* -RenewProxyObject(JSContext* cx, JSObject* obj, BaseProxyHandler* handler, const Value& priv); - -class JS_FRIEND_API(AutoEnterPolicy) -{ - public: - typedef BaseProxyHandler::Action Action; - AutoEnterPolicy(JSContext* cx, const BaseProxyHandler* handler, - HandleObject wrapper, HandleId id, Action act, bool mayThrow) -#ifdef JS_DEBUG - : context(nullptr) -#endif - { - allow = handler->hasSecurityPolicy() ? handler->enter(cx, wrapper, id, act, &rv) - : true; - recordEnter(cx, wrapper, id, act); - // We want to throw an exception if all of the following are true: - // * The policy disallowed access. - // * The policy set rv to false, indicating that we should throw. - // * The caller did not instruct us to ignore exceptions. - // * The policy did not throw itself. - if (!allow && !rv && mayThrow) - reportErrorIfExceptionIsNotPending(cx, id); - } - - virtual ~AutoEnterPolicy() { recordLeave(); } - inline bool allowed() { return allow; } - inline bool returnValue() { MOZ_ASSERT(!allowed()); return rv; } - - protected: - // no-op constructor for subclass - AutoEnterPolicy() -#ifdef JS_DEBUG - : context(nullptr) - , enteredAction(BaseProxyHandler::NONE) -#endif - {} - void reportErrorIfExceptionIsNotPending(JSContext* cx, jsid id); - bool allow; - bool rv; - -#ifdef JS_DEBUG - JSContext* context; - mozilla::Maybe enteredProxy; - mozilla::Maybe enteredId; - Action enteredAction; - - // NB: We explicitly don't track the entered action here, because sometimes - // set() methods do an implicit get() during their implementation, leading - // to spurious assertions. - AutoEnterPolicy* prev; - void recordEnter(JSContext* cx, HandleObject proxy, HandleId id, Action act); - void recordLeave(); - - friend JS_FRIEND_API(void) assertEnteredPolicy(JSContext* cx, JSObject* proxy, jsid id, Action act); -#else - inline void recordEnter(JSContext* cx, JSObject* proxy, jsid id, Action act) {} - inline void recordLeave() {} -#endif - -}; - -#ifdef JS_DEBUG -class JS_FRIEND_API(AutoWaivePolicy) : public AutoEnterPolicy { -public: - AutoWaivePolicy(JSContext* cx, HandleObject proxy, HandleId id, - BaseProxyHandler::Action act) - { - allow = true; - recordEnter(cx, proxy, id, act); - } -}; -#else -class JS_FRIEND_API(AutoWaivePolicy) { - public: - AutoWaivePolicy(JSContext* cx, HandleObject proxy, HandleId id, - BaseProxyHandler::Action act) - {} -}; -#endif - -#ifdef JS_DEBUG -extern JS_FRIEND_API(void) -assertEnteredPolicy(JSContext* cx, JSObject* obj, jsid id, - BaseProxyHandler::Action act); -#else -inline void assertEnteredPolicy(JSContext* cx, JSObject* obj, jsid id, - BaseProxyHandler::Action act) -{} -#endif - -extern JS_FRIEND_API(JSObject*) -InitProxyClass(JSContext* cx, JS::HandleObject obj); - -} /* namespace js */ - -#endif /* js_Proxy_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/Realm.h b/android/arm64-v8a/include/spidermonkey/js/Realm.h deleted file mode 100644 index 13a22c70..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/Realm.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* - * Ways to get various per-Realm objects. All the getters declared in this - * header operate on the Realm corresponding to the current compartment on the - * JSContext. - */ - -#ifndef js_Realm_h -#define js_Realm_h - -#include "jstypes.h" - -struct JSContext; -class JSObject; - -namespace JS { - -extern JS_PUBLIC_API(JSObject*) -GetRealmObjectPrototype(JSContext* cx); - -extern JS_PUBLIC_API(JSObject*) -GetRealmFunctionPrototype(JSContext* cx); - -extern JS_PUBLIC_API(JSObject*) -GetRealmArrayPrototype(JSContext* cx); - -extern JS_PUBLIC_API(JSObject*) -GetRealmErrorPrototype(JSContext* cx); - -extern JS_PUBLIC_API(JSObject*) -GetRealmIteratorPrototype(JSContext* cx); - -} // namespace JS - -#endif // js_Realm_h - - diff --git a/android/arm64-v8a/include/spidermonkey/js/RequiredDefines.h b/android/arm64-v8a/include/spidermonkey/js/RequiredDefines.h deleted file mode 100644 index 308fd7d6..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/RequiredDefines.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* - * Various #defines required to build SpiderMonkey. Embedders should add this - * file to the start of the command line via -include or a similar mechanism, - * or SpiderMonkey public headers may not work correctly. - */ - -#ifndef js_RequiredDefines_h -#define js_RequiredDefines_h - -/* - * The c99 defining the limit macros (UINT32_MAX for example), says: - * - * C++ implementations should define these macros only when - * __STDC_LIMIT_MACROS is defined before is included. - * - * The same also occurs with __STDC_CONSTANT_MACROS for the constant macros - * (INT8_C for example) used to specify a literal constant of the proper type, - * and with __STDC_FORMAT_MACROS for the format macros (PRId32 for example) used - * with the fprintf function family. - */ -#define __STDC_LIMIT_MACROS -#define __STDC_CONSTANT_MACROS -#define __STDC_FORMAT_MACROS - -/* Also define a char16_t type if not provided by the compiler. */ -#include "mozilla/Char16.h" - -#endif /* js_RequiredDefines_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/RootingAPI.h b/android/arm64-v8a/include/spidermonkey/js/RootingAPI.h deleted file mode 100644 index a99ac4ec..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/RootingAPI.h +++ /dev/null @@ -1,1308 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_RootingAPI_h -#define js_RootingAPI_h - -#include "mozilla/Attributes.h" -#include "mozilla/DebugOnly.h" -#include "mozilla/GuardObjects.h" -#include "mozilla/LinkedList.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -#include - -#include "jspubtd.h" - -#include "js/GCAnnotations.h" -#include "js/GCAPI.h" -#include "js/GCPolicyAPI.h" -#include "js/HeapAPI.h" -#include "js/TypeDecls.h" -#include "js/UniquePtr.h" -#include "js/Utility.h" - -/* - * Moving GC Stack Rooting - * - * A moving GC may change the physical location of GC allocated things, even - * when they are rooted, updating all pointers to the thing to refer to its new - * location. The GC must therefore know about all live pointers to a thing, - * not just one of them, in order to behave correctly. - * - * The |Rooted| and |Handle| classes below are used to root stack locations - * whose value may be held live across a call that can trigger GC. For a - * code fragment such as: - * - * JSObject* obj = NewObject(cx); - * DoSomething(cx); - * ... = obj->lastProperty(); - * - * If |DoSomething()| can trigger a GC, the stack location of |obj| must be - * rooted to ensure that the GC does not move the JSObject referred to by - * |obj| without updating |obj|'s location itself. This rooting must happen - * regardless of whether there are other roots which ensure that the object - * itself will not be collected. - * - * If |DoSomething()| cannot trigger a GC, and the same holds for all other - * calls made between |obj|'s definitions and its last uses, then no rooting - * is required. - * - * SpiderMonkey can trigger a GC at almost any time and in ways that are not - * always clear. For example, the following innocuous-looking actions can - * cause a GC: allocation of any new GC thing; JSObject::hasProperty; - * JS_ReportError and friends; and ToNumber, among many others. The following - * dangerous-looking actions cannot trigger a GC: js_malloc, cx->malloc_, - * rt->malloc_, and friends and JS_ReportOutOfMemory. - * - * The following family of three classes will exactly root a stack location. - * Incorrect usage of these classes will result in a compile error in almost - * all cases. Therefore, it is very hard to be incorrectly rooted if you use - * these classes exclusively. These classes are all templated on the type T of - * the value being rooted. - * - * - Rooted declares a variable of type T, whose value is always rooted. - * Rooted may be automatically coerced to a Handle, below. Rooted - * should be used whenever a local variable's value may be held live across a - * call which can trigger a GC. - * - * - Handle is a const reference to a Rooted. Functions which take GC - * things or values as arguments and need to root those arguments should - * generally use handles for those arguments and avoid any explicit rooting. - * This has two benefits. First, when several such functions call each other - * then redundant rooting of multiple copies of the GC thing can be avoided. - * Second, if the caller does not pass a rooted value a compile error will be - * generated, which is quicker and easier to fix than when relying on a - * separate rooting analysis. - * - * - MutableHandle is a non-const reference to Rooted. It is used in the - * same way as Handle and includes a |set(const T& v)| method to allow - * updating the value of the referenced Rooted. A MutableHandle can be - * created with an implicit cast from a Rooted*. - * - * In some cases the small performance overhead of exact rooting (measured to - * be a few nanoseconds on desktop) is too much. In these cases, try the - * following: - * - * - Move all Rooted above inner loops: this allows you to re-use the root - * on each iteration of the loop. - * - * - Pass Handle through your hot call stack to avoid re-rooting costs at - * every invocation. - * - * The following diagram explains the list of supported, implicit type - * conversions between classes of this family: - * - * Rooted ----> Handle - * | ^ - * | | - * | | - * +---> MutableHandle - * (via &) - * - * All of these types have an implicit conversion to raw pointers. - */ - -namespace js { - -template -struct BarrierMethods { -}; - -template -class RootedBase {}; - -template -class HandleBase {}; - -template -class MutableHandleBase {}; - -template -class HeapBase {}; - -// Cannot use FOR_EACH_HEAP_ABLE_GC_POINTER_TYPE, as this would import too many macros into scope -template struct IsHeapConstructibleType { static constexpr bool value = false; }; -#define DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE(T) \ - template <> struct IsHeapConstructibleType { static constexpr bool value = true; }; -FOR_EACH_PUBLIC_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE) -FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE) -#undef DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE - -template -class PersistentRootedBase {}; - -static void* const ConstNullValue = nullptr; - -namespace gc { -struct Cell; -template -struct PersistentRootedMarker; -} /* namespace gc */ - -#define DECLARE_POINTER_COMPARISON_OPS(T) \ - bool operator==(const T& other) const { return get() == other; } \ - bool operator!=(const T& other) const { return get() != other; } - -// Important: Return a reference so passing a Rooted, etc. to -// something that takes a |const T&| is not a GC hazard. -#define DECLARE_POINTER_CONSTREF_OPS(T) \ - operator const T&() const { return get(); } \ - const T& operator->() const { return get(); } - -// Assignment operators on a base class are hidden by the implicitly defined -// operator= on the derived class. Thus, define the operator= directly on the -// class as we would need to manually pass it through anyway. -#define DECLARE_POINTER_ASSIGN_OPS(Wrapper, T) \ - Wrapper& operator=(const T& p) { \ - set(p); \ - return *this; \ - } \ - Wrapper& operator=(const Wrapper& other) { \ - set(other.get()); \ - return *this; \ - } \ - -#define DELETE_ASSIGNMENT_OPS(Wrapper, T) \ - template Wrapper& operator=(S) = delete; \ - Wrapper& operator=(const Wrapper&) = delete; - -#define DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr) \ - const T* address() const { return &(ptr); } \ - const T& get() const { return (ptr); } \ - -#define DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr) \ - T* address() { return &(ptr); } \ - T& get() { return (ptr); } \ - -} /* namespace js */ - -namespace JS { - -template class Rooted; -template class PersistentRooted; - -/* This is exposing internal state of the GC for inlining purposes. */ -JS_FRIEND_API(bool) isGCEnabled(); - -JS_FRIEND_API(void) HeapObjectPostBarrier(JSObject** objp, JSObject* prev, JSObject* next); - -#ifdef JS_DEBUG -/** - * For generational GC, assert that an object is in the tenured generation as - * opposed to being in the nursery. - */ -extern JS_FRIEND_API(void) -AssertGCThingMustBeTenured(JSObject* obj); -extern JS_FRIEND_API(void) -AssertGCThingIsNotAnObjectSubclass(js::gc::Cell* cell); -#else -inline void -AssertGCThingMustBeTenured(JSObject* obj) {} -inline void -AssertGCThingIsNotAnObjectSubclass(js::gc::Cell* cell) {} -#endif - -/** - * The Heap class is a heap-stored reference to a JS GC thing. All members of - * heap classes that refer to GC things should use Heap (or possibly - * TenuredHeap, described below). - * - * Heap is an abstraction that hides some of the complexity required to - * maintain GC invariants for the contained reference. It uses operator - * overloading to provide a normal pointer interface, but notifies the GC every - * time the value it contains is updated. This is necessary for generational GC, - * which keeps track of all pointers into the nursery. - * - * Heap instances must be traced when their containing object is traced to - * keep the pointed-to GC thing alive. - * - * Heap objects should only be used on the heap. GC references stored on the - * C/C++ stack must use Rooted/Handle/MutableHandle instead. - * - * Type T must be a public GC pointer type. - */ -template -class Heap : public js::HeapBase -{ - // Please note: this can actually also be used by nsXBLMaybeCompiled, for legacy reasons. - static_assert(js::IsHeapConstructibleType::value, - "Type T must be a public GC pointer type"); - public: - Heap() { - static_assert(sizeof(T) == sizeof(Heap), - "Heap must be binary compatible with T."); - init(GCPolicy::initial()); - } - explicit Heap(const T& p) { init(p); } - - /* - * For Heap, move semantics are equivalent to copy semantics. In C++, a - * copy constructor taking const-ref is the way to get a single function - * that will be used for both lvalue and rvalue copies, so we can simply - * omit the rvalue variant. - */ - explicit Heap(const Heap& p) { init(p.ptr); } - - ~Heap() { - post(ptr, GCPolicy::initial()); - } - - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_POINTER_ASSIGN_OPS(Heap, T); - - const T* address() const { return &ptr; } - - void exposeToActiveJS() const { - js::BarrierMethods::exposeToJS(ptr); - } - const T& get() const { - exposeToActiveJS(); - return ptr; - } - const T& unbarrieredGet() const { - return ptr; - } - - T* unsafeGet() { return &ptr; } - - explicit operator bool() const { - return bool(js::BarrierMethods::asGCThingOrNull(ptr)); - } - explicit operator bool() { - return bool(js::BarrierMethods::asGCThingOrNull(ptr)); - } - - private: - void init(const T& newPtr) { - ptr = newPtr; - post(GCPolicy::initial(), ptr); - } - - void set(const T& newPtr) { - T tmp = ptr; - ptr = newPtr; - post(tmp, ptr); - } - - void post(const T& prev, const T& next) { - js::BarrierMethods::postBarrier(&ptr, prev, next); - } - - T ptr; -}; - -static MOZ_ALWAYS_INLINE bool -ObjectIsTenured(JSObject* obj) -{ - return !js::gc::IsInsideNursery(reinterpret_cast(obj)); -} - -static MOZ_ALWAYS_INLINE bool -ObjectIsTenured(const Heap& obj) -{ - return ObjectIsTenured(obj.unbarrieredGet()); -} - -static MOZ_ALWAYS_INLINE bool -ObjectIsMarkedGray(JSObject* obj) -{ - auto cell = reinterpret_cast(obj); - return js::gc::detail::CellIsMarkedGrayIfKnown(cell); -} - -static MOZ_ALWAYS_INLINE bool -ObjectIsMarkedGray(const JS::Heap& obj) -{ - return ObjectIsMarkedGray(obj.unbarrieredGet()); -} - -static MOZ_ALWAYS_INLINE bool -ScriptIsMarkedGray(JSScript* script) -{ - auto cell = reinterpret_cast(script); - return js::gc::detail::CellIsMarkedGrayIfKnown(cell); -} - -static MOZ_ALWAYS_INLINE bool -ScriptIsMarkedGray(const Heap& script) -{ - return ScriptIsMarkedGray(script.unbarrieredGet()); -} - -/** - * The TenuredHeap class is similar to the Heap class above in that it - * encapsulates the GC concerns of an on-heap reference to a JS object. However, - * it has two important differences: - * - * 1) Pointers which are statically known to only reference "tenured" objects - * can avoid the extra overhead of SpiderMonkey's write barriers. - * - * 2) Objects in the "tenured" heap have stronger alignment restrictions than - * those in the "nursery", so it is possible to store flags in the lower - * bits of pointers known to be tenured. TenuredHeap wraps a normal tagged - * pointer with a nice API for accessing the flag bits and adds various - * assertions to ensure that it is not mis-used. - * - * GC things are said to be "tenured" when they are located in the long-lived - * heap: e.g. they have gained tenure as an object by surviving past at least - * one GC. For performance, SpiderMonkey allocates some things which are known - * to normally be long lived directly into the tenured generation; for example, - * global objects. Additionally, SpiderMonkey does not visit individual objects - * when deleting non-tenured objects, so object with finalizers are also always - * tenured; for instance, this includes most DOM objects. - * - * The considerations to keep in mind when using a TenuredHeap vs a normal - * Heap are: - * - * - It is invalid for a TenuredHeap to refer to a non-tenured thing. - * - It is however valid for a Heap to refer to a tenured thing. - * - It is not possible to store flag bits in a Heap. - */ -template -class TenuredHeap : public js::HeapBase -{ - public: - TenuredHeap() : bits(0) { - static_assert(sizeof(T) == sizeof(TenuredHeap), - "TenuredHeap must be binary compatible with T."); - } - explicit TenuredHeap(T p) : bits(0) { setPtr(p); } - explicit TenuredHeap(const TenuredHeap& p) : bits(0) { setPtr(p.getPtr()); } - - bool operator==(const TenuredHeap& other) { return bits == other.bits; } - bool operator!=(const TenuredHeap& other) { return bits != other.bits; } - - void setPtr(T newPtr) { - MOZ_ASSERT((reinterpret_cast(newPtr) & flagsMask) == 0); - if (newPtr) - AssertGCThingMustBeTenured(newPtr); - bits = (bits & flagsMask) | reinterpret_cast(newPtr); - } - - void setFlags(uintptr_t flagsToSet) { - MOZ_ASSERT((flagsToSet & ~flagsMask) == 0); - bits |= flagsToSet; - } - - void unsetFlags(uintptr_t flagsToUnset) { - MOZ_ASSERT((flagsToUnset & ~flagsMask) == 0); - bits &= ~flagsToUnset; - } - - bool hasFlag(uintptr_t flag) const { - MOZ_ASSERT((flag & ~flagsMask) == 0); - return (bits & flag) != 0; - } - - T unbarrieredGetPtr() const { return reinterpret_cast(bits & ~flagsMask); } - uintptr_t getFlags() const { return bits & flagsMask; } - - void exposeToActiveJS() const { - js::BarrierMethods::exposeToJS(unbarrieredGetPtr()); - } - T getPtr() const { - exposeToActiveJS(); - return unbarrieredGetPtr(); - } - - operator T() const { return getPtr(); } - T operator->() const { return getPtr(); } - - explicit operator bool() const { - return bool(js::BarrierMethods::asGCThingOrNull(unbarrieredGetPtr())); - } - explicit operator bool() { - return bool(js::BarrierMethods::asGCThingOrNull(unbarrieredGetPtr())); - } - - TenuredHeap& operator=(T p) { - setPtr(p); - return *this; - } - - TenuredHeap& operator=(const TenuredHeap& other) { - bits = other.bits; - return *this; - } - - private: - enum { - maskBits = 3, - flagsMask = (1 << maskBits) - 1, - }; - - uintptr_t bits; -}; - -/** - * Reference to a T that has been rooted elsewhere. This is most useful - * as a parameter type, which guarantees that the T lvalue is properly - * rooted. See "Move GC Stack Rooting" above. - * - * If you want to add additional methods to Handle for a specific - * specialization, define a HandleBase specialization containing them. - */ -template -class MOZ_NONHEAP_CLASS Handle : public js::HandleBase -{ - friend class JS::MutableHandle; - - public: - /* Creates a handle from a handle of a type convertible to T. */ - template - MOZ_IMPLICIT Handle(Handle handle, - typename mozilla::EnableIf::value, int>::Type dummy = 0) - { - static_assert(sizeof(Handle) == sizeof(T*), - "Handle must be binary compatible with T*."); - ptr = reinterpret_cast(handle.address()); - } - - MOZ_IMPLICIT Handle(decltype(nullptr)) { - static_assert(mozilla::IsPointer::value, - "nullptr_t overload not valid for non-pointer types"); - ptr = reinterpret_cast(&js::ConstNullValue); - } - - MOZ_IMPLICIT Handle(MutableHandle handle) { - ptr = handle.address(); - } - - /* - * Take care when calling this method! - * - * This creates a Handle from the raw location of a T. - * - * It should be called only if the following conditions hold: - * - * 1) the location of the T is guaranteed to be marked (for some reason - * other than being a Rooted), e.g., if it is guaranteed to be reachable - * from an implicit root. - * - * 2) the contents of the location are immutable, or at least cannot change - * for the lifetime of the handle, as its users may not expect its value - * to change underneath them. - */ - static constexpr Handle fromMarkedLocation(const T* p) { - return Handle(p, DeliberatelyChoosingThisOverload, - ImUsingThisOnlyInFromFromMarkedLocation); - } - - /* - * Construct a handle from an explicitly rooted location. This is the - * normal way to create a handle, and normally happens implicitly. - */ - template - inline - MOZ_IMPLICIT Handle(const Rooted& root, - typename mozilla::EnableIf::value, int>::Type dummy = 0); - - template - inline - MOZ_IMPLICIT Handle(const PersistentRooted& root, - typename mozilla::EnableIf::value, int>::Type dummy = 0); - - /* Construct a read only handle from a mutable handle. */ - template - inline - MOZ_IMPLICIT Handle(MutableHandle& root, - typename mozilla::EnableIf::value, int>::Type dummy = 0); - - DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr); - - private: - Handle() {} - DELETE_ASSIGNMENT_OPS(Handle, T); - - enum Disambiguator { DeliberatelyChoosingThisOverload = 42 }; - enum CallerIdentity { ImUsingThisOnlyInFromFromMarkedLocation = 17 }; - constexpr Handle(const T* p, Disambiguator, CallerIdentity) : ptr(p) {} - - const T* ptr; -}; - -/** - * Similar to a handle, but the underlying storage can be changed. This is - * useful for outparams. - * - * If you want to add additional methods to MutableHandle for a specific - * specialization, define a MutableHandleBase specialization containing - * them. - */ -template -class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase -{ - public: - inline MOZ_IMPLICIT MutableHandle(Rooted* root); - inline MOZ_IMPLICIT MutableHandle(PersistentRooted* root); - - private: - // Disallow nullptr for overloading purposes. - MutableHandle(decltype(nullptr)) = delete; - - public: - void set(const T& v) { - *ptr = v; - } - - /* - * This may be called only if the location of the T is guaranteed - * to be marked (for some reason other than being a Rooted), - * e.g., if it is guaranteed to be reachable from an implicit root. - * - * Create a MutableHandle from a raw location of a T. - */ - static MutableHandle fromMarkedLocation(T* p) { - MutableHandle h; - h.ptr = p; - return h; - } - - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr); - DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(*ptr); - - private: - MutableHandle() {} - DELETE_ASSIGNMENT_OPS(MutableHandle, T); - - T* ptr; -}; - -} /* namespace JS */ - -namespace js { - -template -struct BarrierMethods -{ - static T* initial() { return nullptr; } - static gc::Cell* asGCThingOrNull(T* v) { - if (!v) - return nullptr; - MOZ_ASSERT(uintptr_t(v) > 32); - return reinterpret_cast(v); - } - static void postBarrier(T** vp, T* prev, T* next) { - if (next) - JS::AssertGCThingIsNotAnObjectSubclass(reinterpret_cast(next)); - } - static void exposeToJS(T* t) { - if (t) - js::gc::ExposeGCThingToActiveJS(JS::GCCellPtr(t)); - } -}; - -template <> -struct BarrierMethods -{ - static JSObject* initial() { return nullptr; } - static gc::Cell* asGCThingOrNull(JSObject* v) { - if (!v) - return nullptr; - MOZ_ASSERT(uintptr_t(v) > 32); - return reinterpret_cast(v); - } - static void postBarrier(JSObject** vp, JSObject* prev, JSObject* next) { - JS::HeapObjectPostBarrier(vp, prev, next); - } - static void exposeToJS(JSObject* obj) { - if (obj) - JS::ExposeObjectToActiveJS(obj); - } -}; - -template <> -struct BarrierMethods -{ - static JSFunction* initial() { return nullptr; } - static gc::Cell* asGCThingOrNull(JSFunction* v) { - if (!v) - return nullptr; - MOZ_ASSERT(uintptr_t(v) > 32); - return reinterpret_cast(v); - } - static void postBarrier(JSFunction** vp, JSFunction* prev, JSFunction* next) { - JS::HeapObjectPostBarrier(reinterpret_cast(vp), - reinterpret_cast(prev), - reinterpret_cast(next)); - } - static void exposeToJS(JSFunction* fun) { - if (fun) - JS::ExposeObjectToActiveJS(reinterpret_cast(fun)); - } -}; - -// Provide hash codes for Cell kinds that may be relocated and, thus, not have -// a stable address to use as the base for a hash code. Instead of the address, -// this hasher uses Cell::getUniqueId to provide exact matches and as a base -// for generating hash codes. -// -// Note: this hasher, like PointerHasher can "hash" a nullptr. While a nullptr -// would not likely be a useful key, there are some cases where being able to -// hash a nullptr is useful, either on purpose or because of bugs: -// (1) existence checks where the key may happen to be null and (2) some -// aggregate Lookup kinds embed a JSObject* that is frequently null and do not -// null test before dispatching to the hasher. -template -struct JS_PUBLIC_API(MovableCellHasher) -{ - using Key = T; - using Lookup = T; - - static bool hasHash(const Lookup& l); - static bool ensureHash(const Lookup& l); - static HashNumber hash(const Lookup& l); - static bool match(const Key& k, const Lookup& l); - static void rekey(Key& k, const Key& newKey) { k = newKey; } -}; - -template -struct JS_PUBLIC_API(MovableCellHasher>) -{ - using Key = JS::Heap; - using Lookup = T; - - static bool hasHash(const Lookup& l) { return MovableCellHasher::hasHash(l); } - static bool ensureHash(const Lookup& l) { return MovableCellHasher::ensureHash(l); } - static HashNumber hash(const Lookup& l) { return MovableCellHasher::hash(l); } - static bool match(const Key& k, const Lookup& l) { - return MovableCellHasher::match(k.unbarrieredGet(), l); - } - static void rekey(Key& k, const Key& newKey) { k.unsafeSet(newKey); } -}; - -template -struct FallibleHashMethods> -{ - template static bool hasHash(Lookup&& l) { - return MovableCellHasher::hasHash(mozilla::Forward(l)); - } - template static bool ensureHash(Lookup&& l) { - return MovableCellHasher::ensureHash(mozilla::Forward(l)); - } -}; - -} /* namespace js */ - -namespace js { - -// The alignment must be set because the Rooted and PersistentRooted ptr fields -// may be accessed through reinterpret_cast*>, and -// the compiler may choose a different alignment for the ptr field when it -// knows the actual type stored in DispatchWrapper. -// -// It would make more sense to align only those specific fields of type -// DispatchWrapper, rather than DispatchWrapper itself, but that causes MSVC to -// fail when Rooted is used in an IsConvertible test. -template -class alignas(8) DispatchWrapper -{ - static_assert(JS::MapTypeToRootKind::kind == JS::RootKind::Traceable, - "DispatchWrapper is intended only for usage with a Traceable"); - - using TraceFn = void (*)(JSTracer*, T*, const char*); - TraceFn tracer; - alignas(gc::CellSize) T storage; - - public: - template - MOZ_IMPLICIT DispatchWrapper(U&& initial) - : tracer(&JS::GCPolicy::trace), - storage(mozilla::Forward(initial)) - { } - - // Mimic a pointer type, so that we can drop into Rooted. - T* operator &() { return &storage; } - const T* operator &() const { return &storage; } - operator T&() { return storage; } - operator const T&() const { return storage; } - - // Trace the contained storage (of unknown type) using the trace function - // we set aside when we did know the type. - static void TraceWrapped(JSTracer* trc, T* thingp, const char* name) { - auto wrapper = reinterpret_cast( - uintptr_t(thingp) - offsetof(DispatchWrapper, storage)); - wrapper->tracer(trc, &wrapper->storage, name); - } -}; - -} /* namespace js */ - -namespace JS { - -/** - * Local variable of type T whose value is always rooted. This is typically - * used for local variables, or for non-rooted values being passed to a - * function that requires a handle, e.g. Foo(Root(cx, x)). - * - * If you want to add additional methods to Rooted for a specific - * specialization, define a RootedBase specialization containing them. - */ -template -class MOZ_RAII Rooted : public js::RootedBase -{ - inline void registerWithRootLists(js::RootedListHeads& roots) { - this->stack = &roots[JS::MapTypeToRootKind::kind]; - this->prev = *stack; - *stack = reinterpret_cast*>(this); - } - - inline js::RootedListHeads& rootLists(JS::RootingContext* cx) { - return rootLists(static_cast(cx)); - } - inline js::RootedListHeads& rootLists(js::ContextFriendFields* cx) { - if (JS::Zone* zone = cx->zone_) - return JS::shadow::Zone::asShadowZone(zone)->stackRoots_; - MOZ_ASSERT(cx->isJSContext); - return cx->roots.stackRoots_; - } - inline js::RootedListHeads& rootLists(JSContext* cx) { - return rootLists(js::ContextFriendFields::get(cx)); - } - - public: - template - explicit Rooted(const RootingContext& cx) - : ptr(GCPolicy::initial()) - { - registerWithRootLists(rootLists(cx)); - } - - template - Rooted(const RootingContext& cx, S&& initial) - : ptr(mozilla::Forward(initial)) - { - registerWithRootLists(rootLists(cx)); - } - - ~Rooted() { - MOZ_ASSERT(*stack == reinterpret_cast*>(this)); - *stack = prev; - } - - Rooted* previous() { return reinterpret_cast*>(prev); } - - /* - * This method is public for Rooted so that Codegen.py can use a Rooted - * interchangeably with a MutableHandleValue. - */ - void set(const T& value) { - ptr = value; - } - - DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_POINTER_ASSIGN_OPS(Rooted, T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr); - DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr); - - private: - /* - * These need to be templated on void* to avoid aliasing issues between, for - * example, Rooted and Rooted, which use the same - * stack head pointer for different classes. - */ - Rooted** stack; - Rooted* prev; - - /* - * For pointer types, the TraceKind for tracing is based on the list it is - * in (selected via MapTypeToRootKind), so no additional storage is - * required here. Non-pointer types, however, share the same list, so the - * function to call for tracing is stored adjacent to the struct. Since C++ - * cannot templatize on storage class, this is implemented via the wrapper - * class DispatchWrapper. - */ - using MaybeWrapped = typename mozilla::Conditional< - MapTypeToRootKind::kind == JS::RootKind::Traceable, - js::DispatchWrapper, - T>::Type; - MaybeWrapped ptr; - - Rooted(const Rooted&) = delete; -} JS_HAZ_ROOTED; - -} /* namespace JS */ - -namespace js { - -/** - * Augment the generic Rooted interface when T = JSObject* with - * class-querying and downcasting operations. - * - * Given a Rooted obj, one can view - * Handle h = obj.as(); - * as an optimization of - * Rooted rooted(cx, &obj->as()); - * Handle h = rooted; - */ -template <> -class RootedBase -{ - public: - template - JS::Handle as() const; -}; - -/** - * Augment the generic Handle interface when T = JSObject* with - * downcasting operations. - * - * Given a Handle obj, one can view - * Handle h = obj.as(); - * as an optimization of - * Rooted rooted(cx, &obj->as()); - * Handle h = rooted; - */ -template <> -class HandleBase -{ - public: - template - JS::Handle as() const; -}; - -/** Interface substitute for Rooted which does not root the variable's memory. */ -template -class MOZ_RAII FakeRooted : public RootedBase -{ - public: - template - explicit FakeRooted(CX* cx) : ptr(JS::GCPolicy::initial()) {} - - template - FakeRooted(CX* cx, T initial) : ptr(initial) {} - - DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_POINTER_ASSIGN_OPS(FakeRooted, T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr); - DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr); - - private: - T ptr; - - void set(const T& value) { - ptr = value; - } - - FakeRooted(const FakeRooted&) = delete; -}; - -/** Interface substitute for MutableHandle which is not required to point to rooted memory. */ -template -class FakeMutableHandle : public js::MutableHandleBase -{ - public: - MOZ_IMPLICIT FakeMutableHandle(T* t) { - ptr = t; - } - - MOZ_IMPLICIT FakeMutableHandle(FakeRooted* root) { - ptr = root->address(); - } - - void set(const T& v) { - *ptr = v; - } - - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr); - DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(*ptr); - - private: - FakeMutableHandle() {} - DELETE_ASSIGNMENT_OPS(FakeMutableHandle, T); - - T* ptr; -}; - -/** - * Types for a variable that either should or shouldn't be rooted, depending on - * the template parameter allowGC. Used for implementing functions that can - * operate on either rooted or unrooted data. - * - * The toHandle() and toMutableHandle() functions are for calling functions - * which require handle types and are only called in the CanGC case. These - * allow the calling code to type check. - */ -enum AllowGC { - NoGC = 0, - CanGC = 1 -}; -template -class MaybeRooted -{ -}; - -template class MaybeRooted -{ - public: - typedef JS::Handle HandleType; - typedef JS::Rooted RootType; - typedef JS::MutableHandle MutableHandleType; - - static inline JS::Handle toHandle(HandleType v) { - return v; - } - - static inline JS::MutableHandle toMutableHandle(MutableHandleType v) { - return v; - } - - template - static inline JS::Handle downcastHandle(HandleType v) { - return v.template as(); - } -}; - -template class MaybeRooted -{ - public: - typedef const T& HandleType; - typedef FakeRooted RootType; - typedef FakeMutableHandle MutableHandleType; - - static JS::Handle toHandle(HandleType v) { - MOZ_CRASH("Bad conversion"); - } - - static JS::MutableHandle toMutableHandle(MutableHandleType v) { - MOZ_CRASH("Bad conversion"); - } - - template - static inline T2* downcastHandle(HandleType v) { - return &v->template as(); - } -}; - -} /* namespace js */ - -namespace JS { - -template template -inline -Handle::Handle(const Rooted& root, - typename mozilla::EnableIf::value, int>::Type dummy) -{ - ptr = reinterpret_cast(root.address()); -} - -template template -inline -Handle::Handle(const PersistentRooted& root, - typename mozilla::EnableIf::value, int>::Type dummy) -{ - ptr = reinterpret_cast(root.address()); -} - -template template -inline -Handle::Handle(MutableHandle& root, - typename mozilla::EnableIf::value, int>::Type dummy) -{ - ptr = reinterpret_cast(root.address()); -} - -template -inline -MutableHandle::MutableHandle(Rooted* root) -{ - static_assert(sizeof(MutableHandle) == sizeof(T*), - "MutableHandle must be binary compatible with T*."); - ptr = root->address(); -} - -template -inline -MutableHandle::MutableHandle(PersistentRooted* root) -{ - static_assert(sizeof(MutableHandle) == sizeof(T*), - "MutableHandle must be binary compatible with T*."); - ptr = root->address(); -} - -/** - * A copyable, assignable global GC root type with arbitrary lifetime, an - * infallible constructor, and automatic unrooting on destruction. - * - * These roots can be used in heap-allocated data structures, so they are not - * associated with any particular JSContext or stack. They are registered with - * the JSRuntime itself, without locking, so they require a full JSContext to be - * initialized, not one of its more restricted superclasses. Initialization may - * take place on construction, or in two phases if the no-argument constructor - * is called followed by init(). - * - * Note that you must not use an PersistentRooted in an object owned by a JS - * object: - * - * Whenever one object whose lifetime is decided by the GC refers to another - * such object, that edge must be traced only if the owning JS object is traced. - * This applies not only to JS objects (which obviously are managed by the GC) - * but also to C++ objects owned by JS objects. - * - * If you put a PersistentRooted in such a C++ object, that is almost certainly - * a leak. When a GC begins, the referent of the PersistentRooted is treated as - * live, unconditionally (because a PersistentRooted is a *root*), even if the - * JS object that owns it is unreachable. If there is any path from that - * referent back to the JS object, then the C++ object containing the - * PersistentRooted will not be destructed, and the whole blob of objects will - * not be freed, even if there are no references to them from the outside. - * - * In the context of Firefox, this is a severe restriction: almost everything in - * Firefox is owned by some JS object or another, so using PersistentRooted in - * such objects would introduce leaks. For these kinds of edges, Heap or - * TenuredHeap would be better types. It's up to the implementor of the type - * containing Heap or TenuredHeap members to make sure their referents get - * marked when the object itself is marked. - */ -template -class PersistentRooted : public js::PersistentRootedBase, - private mozilla::LinkedListElement> -{ - using ListBase = mozilla::LinkedListElement>; - - friend class mozilla::LinkedList; - friend class mozilla::LinkedListElement; - - void registerWithRootLists(js::RootLists& roots) { - MOZ_ASSERT(!initialized()); - JS::RootKind kind = JS::MapTypeToRootKind::kind; - roots.heapRoots_[kind].insertBack(reinterpret_cast*>(this)); - } - - js::RootLists& rootLists(JSContext* cx) { - return rootLists(JS::RootingContext::get(cx)); - } - js::RootLists& rootLists(JS::RootingContext* cx) { - MOZ_ASSERT(cx->isJSContext); - return cx->roots; - } - - // Disallow ExclusiveContext*. - js::RootLists& rootLists(js::ContextFriendFields* cx) = delete; - - public: - PersistentRooted() : ptr(GCPolicy::initial()) {} - - template - explicit PersistentRooted(const RootingContext& cx) - : ptr(GCPolicy::initial()) - { - registerWithRootLists(rootLists(cx)); - } - - template - PersistentRooted(const RootingContext& cx, U&& initial) - : ptr(mozilla::Forward(initial)) - { - registerWithRootLists(rootLists(cx)); - } - - PersistentRooted(const PersistentRooted& rhs) - : mozilla::LinkedListElement>(), - ptr(rhs.ptr) - { - /* - * Copy construction takes advantage of the fact that the original - * is already inserted, and simply adds itself to whatever list the - * original was on - no JSRuntime pointer needed. - * - * This requires mutating rhs's links, but those should be 'mutable' - * anyway. C++ doesn't let us declare mutable base classes. - */ - const_cast(rhs).setNext(this); - } - - bool initialized() { - return ListBase::isInList(); - } - - template - void init(const RootingContext& cx) { - init(cx, GCPolicy::initial()); - } - - template - void init(const RootingContext& cx, U&& initial) { - ptr = mozilla::Forward(initial); - registerWithRootLists(rootLists(cx)); - } - - void reset() { - if (initialized()) { - set(GCPolicy::initial()); - ListBase::remove(); - } - } - - DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_POINTER_ASSIGN_OPS(PersistentRooted, T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr); - - // These are the same as DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS, except - // they check that |this| is initialized in case the caller later stores - // something in |ptr|. - T* address() { - MOZ_ASSERT(initialized()); - return &ptr; - } - T& get() { - MOZ_ASSERT(initialized()); - return ptr; - } - - private: - template - void set(U&& value) { - MOZ_ASSERT(initialized()); - ptr = mozilla::Forward(value); - } - - // See the comment above Rooted::ptr. - using MaybeWrapped = typename mozilla::Conditional< - MapTypeToRootKind::kind == JS::RootKind::Traceable, - js::DispatchWrapper, - T>::Type; - MaybeWrapped ptr; -} JS_HAZ_ROOTED; - -class JS_PUBLIC_API(ObjectPtr) -{ - Heap value; - - public: - ObjectPtr() : value(nullptr) {} - - explicit ObjectPtr(JSObject* obj) : value(obj) {} - - /* Always call finalize before the destructor. */ - ~ObjectPtr() { MOZ_ASSERT(!value); } - - void finalize(JSRuntime* rt); - void finalize(JSContext* cx); - - void init(JSObject* obj) { value = obj; } - - JSObject* get() const { return value; } - JSObject* unbarrieredGet() const { return value.unbarrieredGet(); } - - void writeBarrierPre(JSContext* cx) { - IncrementalObjectBarrier(value); - } - - void updateWeakPointerAfterGC(); - - ObjectPtr& operator=(JSObject* obj) { - IncrementalObjectBarrier(value); - value = obj; - return *this; - } - - void trace(JSTracer* trc, const char* name); - - JSObject& operator*() const { return *value; } - JSObject* operator->() const { return value; } - operator JSObject*() const { return value; } - - explicit operator bool() const { return value.unbarrieredGet(); } - explicit operator bool() { return value.unbarrieredGet(); } -}; - -} /* namespace JS */ - -namespace js { - -template -class UniquePtrOperations -{ - const UniquePtr& uniquePtr() const { return static_cast(this)->get(); } - - public: - explicit operator bool() const { return !!uniquePtr(); } -}; - -template -class MutableUniquePtrOperations : public UniquePtrOperations -{ - UniquePtr& uniquePtr() { return static_cast(this)->get(); } - - public: - MOZ_MUST_USE typename UniquePtr::Pointer release() { return uniquePtr().release(); } -}; - -template -class RootedBase> - : public MutableUniquePtrOperations>, T, D> -{ }; - -template -class MutableHandleBase> - : public MutableUniquePtrOperations>, T, D> -{ }; - -template -class HandleBase> - : public UniquePtrOperations>, T, D> -{ }; - -template -class PersistentRootedBase> - : public MutableUniquePtrOperations>, T, D> -{ }; - -namespace gc { - -template -void -CallTraceCallbackOnNonHeap(T* v, const TraceCallbacks& aCallbacks, const char* aName, void* aClosure) -{ - static_assert(sizeof(T) == sizeof(JS::Heap), "T and Heap must be compatible."); - MOZ_ASSERT(v); - mozilla::DebugOnly cell = BarrierMethods::asGCThingOrNull(*v); - MOZ_ASSERT(cell); - MOZ_ASSERT(!IsInsideNursery(cell)); - JS::Heap* asHeapT = reinterpret_cast*>(v); - aCallbacks.Trace(asHeapT, aName, aClosure); -} - -} /* namespace gc */ -} /* namespace js */ - -// mozilla::Swap uses a stack temporary, which prevents classes like Heap -// from being declared MOZ_HEAP_CLASS. -namespace mozilla { - -template -inline void -Swap(JS::Heap& aX, JS::Heap& aY) -{ - T tmp = aX; - aX = aY; - aY = tmp; -} - -template -inline void -Swap(JS::TenuredHeap& aX, JS::TenuredHeap& aY) -{ - T tmp = aX; - aX = aY; - aY = tmp; -} - -} /* namespace mozilla */ - -#undef DELETE_ASSIGNMENT_OPS - -#endif /* js_RootingAPI_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/SliceBudget.h b/android/arm64-v8a/include/spidermonkey/js/SliceBudget.h deleted file mode 100644 index 78982df0..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/SliceBudget.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_SliceBudget_h -#define js_SliceBudget_h - -#include - -namespace js { - -struct JS_PUBLIC_API(TimeBudget) -{ - int64_t budget; - - explicit TimeBudget(int64_t milliseconds) { budget = milliseconds; } -}; - -struct JS_PUBLIC_API(WorkBudget) -{ - int64_t budget; - - explicit WorkBudget(int64_t work) { budget = work; } -}; - -/* - * This class records how much work has been done in a given collection slice, - * so that we can return before pausing for too long. Some slices are allowed - * to run for unlimited time, and others are bounded. To reduce the number of - * gettimeofday calls, we only check the time every 1000 operations. - */ -class JS_PUBLIC_API(SliceBudget) -{ - static const int64_t unlimitedDeadline = INT64_MAX; - static const intptr_t unlimitedStartCounter = INTPTR_MAX; - - bool checkOverBudget(); - - SliceBudget(); - - public: - // Memory of the originally requested budget. If isUnlimited, neither of - // these are in use. If deadline==0, then workBudget is valid. Otherwise - // timeBudget is valid. - TimeBudget timeBudget; - WorkBudget workBudget; - - int64_t deadline; /* in microseconds */ - intptr_t counter; - - static const intptr_t CounterReset = 1000; - - static const int64_t UnlimitedTimeBudget = -1; - static const int64_t UnlimitedWorkBudget = -1; - - /* Use to create an unlimited budget. */ - static SliceBudget unlimited() { return SliceBudget(); } - - /* Instantiate as SliceBudget(TimeBudget(n)). */ - explicit SliceBudget(TimeBudget time); - - /* Instantiate as SliceBudget(WorkBudget(n)). */ - explicit SliceBudget(WorkBudget work); - - void makeUnlimited() { - deadline = unlimitedDeadline; - counter = unlimitedStartCounter; - } - - void step(intptr_t amt = 1) { - counter -= amt; - } - - bool isOverBudget() { - if (counter > 0) - return false; - return checkOverBudget(); - } - - bool isWorkBudget() const { return deadline == 0; } - bool isTimeBudget() const { return deadline > 0 && !isUnlimited(); } - bool isUnlimited() const { return deadline == unlimitedDeadline; } - - int describe(char* buffer, size_t maxlen) const; -}; - -} // namespace js - -#endif /* js_SliceBudget_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/StructuredClone.h b/android/arm64-v8a/include/spidermonkey/js/StructuredClone.h deleted file mode 100644 index e10a3073..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/StructuredClone.h +++ /dev/null @@ -1,358 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_StructuredClone_h -#define js_StructuredClone_h - -#include "mozilla/Attributes.h" -#include "mozilla/BufferList.h" - -#include - -#include "jstypes.h" - -#include "js/RootingAPI.h" -#include "js/TypeDecls.h" -#include "js/Value.h" - -struct JSRuntime; -struct JSStructuredCloneReader; -struct JSStructuredCloneWriter; - -// API for the HTML5 internal structured cloning algorithm. - -namespace JS { - -enum class StructuredCloneScope : uint32_t { - SameProcessSameThread, - SameProcessDifferentThread, - DifferentProcess -}; - -enum TransferableOwnership { - /** Transferable data has not been filled in yet */ - SCTAG_TMO_UNFILLED = 0, - - /** Structured clone buffer does not yet own the data */ - SCTAG_TMO_UNOWNED = 1, - - /** All values at least this large are owned by the clone buffer */ - SCTAG_TMO_FIRST_OWNED = 2, - - /** Data is a pointer that can be freed */ - SCTAG_TMO_ALLOC_DATA = 2, - - /** Data is a memory mapped pointer */ - SCTAG_TMO_MAPPED_DATA = 3, - - /** - * Data is embedding-specific. The engine can free it by calling the - * freeTransfer op. The embedding can also use SCTAG_TMO_USER_MIN and - * greater, up to 32 bits, to distinguish specific ownership variants. - */ - SCTAG_TMO_CUSTOM = 4, - - SCTAG_TMO_USER_MIN -}; - -class CloneDataPolicy -{ - bool sharedArrayBuffer_; - - public: - // The default is to allow all policy-controlled aspects. - - CloneDataPolicy() : - sharedArrayBuffer_(true) - {} - - // In the JS engine, SharedArrayBuffers can only be cloned intra-process - // because the shared memory areas are allocated in process-private memory. - // Clients should therefore deny SharedArrayBuffers when cloning data that - // are to be transmitted inter-process. - // - // Clients should also deny SharedArrayBuffers when cloning data that are to - // be transmitted intra-process if policy needs dictate such denial. - - CloneDataPolicy& denySharedArrayBuffer() { - sharedArrayBuffer_ = false; - return *this; - } - - bool isSharedArrayBufferAllowed() const { - return sharedArrayBuffer_; - } -}; - -} /* namespace JS */ - -/** - * Read structured data from the reader r. This hook is used to read a value - * previously serialized by a call to the WriteStructuredCloneOp hook. - * - * tag and data are the pair of uint32_t values from the header. The callback - * may use the JS_Read* APIs to read any other relevant parts of the object - * from the reader r. closure is any value passed to the JS_ReadStructuredClone - * function. Return the new object on success, nullptr on error/exception. - */ -typedef JSObject* (*ReadStructuredCloneOp)(JSContext* cx, JSStructuredCloneReader* r, - uint32_t tag, uint32_t data, void* closure); - -/** - * Structured data serialization hook. The engine can write primitive values, - * Objects, Arrays, Dates, RegExps, TypedArrays, ArrayBuffers, Sets, Maps, - * and SharedTypedArrays. Any other type of object requires application support. - * This callback must first use the JS_WriteUint32Pair API to write an object - * header, passing a value greater than JS_SCTAG_USER to the tag parameter. - * Then it can use the JS_Write* APIs to write any other relevant parts of - * the value v to the writer w. closure is any value passed to the - * JS_WriteStructuredClone function. - * - * Return true on success, false on error/exception. - */ -typedef bool (*WriteStructuredCloneOp)(JSContext* cx, JSStructuredCloneWriter* w, - JS::HandleObject obj, void* closure); - -/** - * This is called when JS_WriteStructuredClone is given an invalid transferable. - * To follow HTML5, the application must throw a DATA_CLONE_ERR DOMException - * with error set to one of the JS_SCERR_* values. - */ -typedef void (*StructuredCloneErrorOp)(JSContext* cx, uint32_t errorid); - -/** - * This is called when JS_ReadStructuredClone receives a transferable object - * not known to the engine. If this hook does not exist or returns false, the - * JS engine calls the reportError op if set, otherwise it throws a - * DATA_CLONE_ERR DOM Exception. This method is called before any other - * callback and must return a non-null object in returnObject on success. - */ -typedef bool (*ReadTransferStructuredCloneOp)(JSContext* cx, JSStructuredCloneReader* r, - uint32_t tag, void* content, uint64_t extraData, - void* closure, - JS::MutableHandleObject returnObject); - -/** - * Called when JS_WriteStructuredClone receives a transferable object not - * handled by the engine. If this hook does not exist or returns false, the JS - * engine will call the reportError hook or fall back to throwing a - * DATA_CLONE_ERR DOM Exception. This method is called before any other - * callback. - * - * tag: indicates what type of transferable this is. Must be greater than - * 0xFFFF0201 (value of the internal SCTAG_TRANSFER_MAP_PENDING_ENTRY) - * - * ownership: see TransferableOwnership, above. Used to communicate any needed - * ownership info to the FreeTransferStructuredCloneOp. - * - * content, extraData: what the ReadTransferStructuredCloneOp will receive - */ -typedef bool (*TransferStructuredCloneOp)(JSContext* cx, - JS::Handle obj, - void* closure, - // Output: - uint32_t* tag, - JS::TransferableOwnership* ownership, - void** content, - uint64_t* extraData); - -/** - * Called when freeing an unknown transferable object. Note that it - * should never trigger a garbage collection (and will assert in a - * debug build if it does.) - */ -typedef void (*FreeTransferStructuredCloneOp)(uint32_t tag, JS::TransferableOwnership ownership, - void* content, uint64_t extraData, void* closure); - -// The maximum supported structured-clone serialization format version. -// Increment this when anything at all changes in the serialization format. -// (Note that this does not need to be bumped for Transferable-only changes, -// since they are never saved to persistent storage.) -#define JS_STRUCTURED_CLONE_VERSION 8 - -struct JSStructuredCloneCallbacks { - ReadStructuredCloneOp read; - WriteStructuredCloneOp write; - StructuredCloneErrorOp reportError; - ReadTransferStructuredCloneOp readTransfer; - TransferStructuredCloneOp writeTransfer; - FreeTransferStructuredCloneOp freeTransfer; -}; - -enum OwnTransferablePolicy { - OwnsTransferablesIfAny, - IgnoreTransferablesIfAny, - NoTransferables -}; - -class MOZ_NON_MEMMOVABLE JSStructuredCloneData : public mozilla::BufferList -{ - typedef js::SystemAllocPolicy AllocPolicy; - typedef mozilla::BufferList BufferList; - - static const size_t kInitialSize = 0; - static const size_t kInitialCapacity = 4096; - static const size_t kStandardCapacity = 4096; - - const JSStructuredCloneCallbacks* callbacks_; - void* closure_; - OwnTransferablePolicy ownTransferables_; - - void setOptionalCallbacks(const JSStructuredCloneCallbacks* callbacks, - void* closure, - OwnTransferablePolicy policy) { - callbacks_ = callbacks; - closure_ = closure; - ownTransferables_ = policy; - } - - friend struct JSStructuredCloneWriter; - friend class JS_PUBLIC_API(JSAutoStructuredCloneBuffer); - -public: - explicit JSStructuredCloneData(AllocPolicy aAP = AllocPolicy()) - : BufferList(kInitialSize, kInitialCapacity, kStandardCapacity, aAP) - , callbacks_(nullptr) - , closure_(nullptr) - , ownTransferables_(OwnTransferablePolicy::NoTransferables) - {} - MOZ_IMPLICIT JSStructuredCloneData(BufferList&& buffers) - : BufferList(Move(buffers)) - , callbacks_(nullptr) - , closure_(nullptr) - , ownTransferables_(OwnTransferablePolicy::NoTransferables) - {} - JSStructuredCloneData(JSStructuredCloneData&& other) = default; - JSStructuredCloneData& operator=(JSStructuredCloneData&& other) = default; - ~JSStructuredCloneData(); - - using BufferList::BufferList; -}; - -/** Note: if the *data contains transferable objects, it can be read only once. */ -JS_PUBLIC_API(bool) -JS_ReadStructuredClone(JSContext* cx, JSStructuredCloneData& data, uint32_t version, - JS::StructuredCloneScope scope, - JS::MutableHandleValue vp, - const JSStructuredCloneCallbacks* optionalCallbacks, void* closure); - -JS_PUBLIC_API(bool) -JS_WriteStructuredClone(JSContext* cx, JS::HandleValue v, JSStructuredCloneData* data, - JS::StructuredCloneScope scope, - JS::CloneDataPolicy cloneDataPolicy, - const JSStructuredCloneCallbacks* optionalCallbacks, - void* closure, JS::HandleValue transferable); - -JS_PUBLIC_API(bool) -JS_StructuredCloneHasTransferables(JSStructuredCloneData& data, bool* hasTransferable); - -JS_PUBLIC_API(bool) -JS_StructuredClone(JSContext* cx, JS::HandleValue v, JS::MutableHandleValue vp, - const JSStructuredCloneCallbacks* optionalCallbacks, void* closure); - -/** RAII sugar for JS_WriteStructuredClone. */ -class JS_PUBLIC_API(JSAutoStructuredCloneBuffer) { - const JS::StructuredCloneScope scope_; - JSStructuredCloneData data_; - uint32_t version_; - - public: - JSAutoStructuredCloneBuffer(JS::StructuredCloneScope scope, - const JSStructuredCloneCallbacks* callbacks, void* closure) - : scope_(scope), version_(JS_STRUCTURED_CLONE_VERSION) - { - data_.setOptionalCallbacks(callbacks, closure, OwnTransferablePolicy::NoTransferables); - } - - JSAutoStructuredCloneBuffer(JSAutoStructuredCloneBuffer&& other); - JSAutoStructuredCloneBuffer& operator=(JSAutoStructuredCloneBuffer&& other); - - ~JSAutoStructuredCloneBuffer() { clear(); } - - JSStructuredCloneData& data() { return data_; } - bool empty() const { return !data_.Size(); } - - void clear(const JSStructuredCloneCallbacks* optionalCallbacks=nullptr, void* closure=nullptr); - - /** Copy some memory. It will be automatically freed by the destructor. */ - bool copy(const JSStructuredCloneData& data, uint32_t version=JS_STRUCTURED_CLONE_VERSION, - const JSStructuredCloneCallbacks* callbacks=nullptr, void* closure=nullptr); - - /** - * Adopt some memory. It will be automatically freed by the destructor. - * data must have been allocated by the JS engine (e.g., extracted via - * JSAutoStructuredCloneBuffer::steal). - */ - void adopt(JSStructuredCloneData&& data, uint32_t version=JS_STRUCTURED_CLONE_VERSION, - const JSStructuredCloneCallbacks* callbacks=nullptr, void* closure=nullptr); - - /** - * Release the buffer and transfer ownership to the caller. - */ - void steal(JSStructuredCloneData* data, uint32_t* versionp=nullptr, - const JSStructuredCloneCallbacks** callbacks=nullptr, void** closure=nullptr); - - /** - * Abandon ownership of any transferable objects stored in the buffer, - * without freeing the buffer itself. Useful when copying the data out into - * an external container, though note that you will need to use adopt() to - * properly release that data eventually. - */ - void abandon() { data_.ownTransferables_ = OwnTransferablePolicy::IgnoreTransferablesIfAny; } - - bool read(JSContext* cx, JS::MutableHandleValue vp, - const JSStructuredCloneCallbacks* optionalCallbacks=nullptr, void* closure=nullptr); - - bool write(JSContext* cx, JS::HandleValue v, - const JSStructuredCloneCallbacks* optionalCallbacks=nullptr, void* closure=nullptr); - - bool write(JSContext* cx, JS::HandleValue v, JS::HandleValue transferable, - JS::CloneDataPolicy cloneDataPolicy, - const JSStructuredCloneCallbacks* optionalCallbacks=nullptr, void* closure=nullptr); - - private: - // Copy and assignment are not supported. - JSAutoStructuredCloneBuffer(const JSAutoStructuredCloneBuffer& other) = delete; - JSAutoStructuredCloneBuffer& operator=(const JSAutoStructuredCloneBuffer& other) = delete; -}; - -// The range of tag values the application may use for its own custom object types. -#define JS_SCTAG_USER_MIN ((uint32_t) 0xFFFF8000) -#define JS_SCTAG_USER_MAX ((uint32_t) 0xFFFFFFFF) - -#define JS_SCERR_RECURSION 0 -#define JS_SCERR_TRANSFERABLE 1 -#define JS_SCERR_DUP_TRANSFERABLE 2 -#define JS_SCERR_UNSUPPORTED_TYPE 3 - -JS_PUBLIC_API(bool) -JS_ReadUint32Pair(JSStructuredCloneReader* r, uint32_t* p1, uint32_t* p2); - -JS_PUBLIC_API(bool) -JS_ReadBytes(JSStructuredCloneReader* r, void* p, size_t len); - -JS_PUBLIC_API(bool) -JS_ReadTypedArray(JSStructuredCloneReader* r, JS::MutableHandleValue vp); - -JS_PUBLIC_API(bool) -JS_WriteUint32Pair(JSStructuredCloneWriter* w, uint32_t tag, uint32_t data); - -JS_PUBLIC_API(bool) -JS_WriteBytes(JSStructuredCloneWriter* w, const void* p, size_t len); - -JS_PUBLIC_API(bool) -JS_WriteString(JSStructuredCloneWriter* w, JS::HandleString str); - -JS_PUBLIC_API(bool) -JS_WriteTypedArray(JSStructuredCloneWriter* w, JS::HandleValue v); - -JS_PUBLIC_API(bool) -JS_ObjectNotWritten(JSStructuredCloneWriter* w, JS::HandleObject obj); - -JS_PUBLIC_API(JS::StructuredCloneScope) -JS_GetStructuredCloneScope(JSStructuredCloneWriter* w); - -#endif /* js_StructuredClone_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/SweepingAPI.h b/android/arm64-v8a/include/spidermonkey/js/SweepingAPI.h deleted file mode 100644 index 0eb29ae4..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/SweepingAPI.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_SweepingAPI_h -#define js_SweepingAPI_h - -#include "js/HeapAPI.h" - -namespace js { -template -class WeakCacheBase {}; -} // namespace js - -namespace JS { -template class WeakCache; - -namespace shadow { -JS_PUBLIC_API(void) -RegisterWeakCache(JS::Zone* zone, JS::WeakCache* cachep); -} // namespace shadow - -// A WeakCache stores the given Sweepable container and links itself into a -// list of such caches that are swept during each GC. -template -class WeakCache : public js::WeakCacheBase, - private mozilla::LinkedListElement> -{ - friend class mozilla::LinkedListElement>; - friend class mozilla::LinkedList>; - - WeakCache() = delete; - WeakCache(const WeakCache&) = delete; - - using SweepFn = void (*)(T*); - SweepFn sweeper; - T cache; - - public: - using Type = T; - - template - WeakCache(Zone* zone, U&& initial) - : cache(mozilla::Forward(initial)) - { - sweeper = GCPolicy::sweep; - shadow::RegisterWeakCache(zone, reinterpret_cast*>(this)); - } - WeakCache(WeakCache&& other) - : sweeper(other.sweeper), - cache(mozilla::Move(other.cache)) - { - } - - const T& get() const { return cache; } - T& get() { return cache; } - - void sweep() { sweeper(&cache); } -}; - -} // namespace JS - -#endif // js_SweepingAPI_h diff --git a/android/arm64-v8a/include/spidermonkey/js/TraceKind.h b/android/arm64-v8a/include/spidermonkey/js/TraceKind.h deleted file mode 100644 index 2eda9cb2..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/TraceKind.h +++ /dev/null @@ -1,212 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_TraceKind_h -#define js_TraceKind_h - -#include "mozilla/UniquePtr.h" - -#include "js/TypeDecls.h" - -// Forward declarations of all the types a TraceKind can denote. -namespace js { -class BaseShape; -class LazyScript; -class ObjectGroup; -class Shape; -class Scope; -namespace jit { -class JitCode; -} // namespace jit -} // namespace js - -namespace JS { - -// When tracing a thing, the GC needs to know about the layout of the object it -// is looking at. There are a fixed number of different layouts that the GC -// knows about. The "trace kind" is a static map which tells which layout a GC -// thing has. -// -// Although this map is public, the details are completely hidden. Not all of -// the matching C++ types are exposed, and those that are, are opaque. -// -// See Value::gcKind() and JSTraceCallback in Tracer.h for more details. -enum class TraceKind -{ - // These trace kinds have a publicly exposed, although opaque, C++ type. - // Note: The order here is determined by our Value packing. Other users - // should sort alphabetically, for consistency. - Object = 0x00, - String = 0x01, - Symbol = 0x02, - Script = 0x03, - - // Shape details are exposed through JS_TraceShapeCycleCollectorChildren. - Shape = 0x04, - - // ObjectGroup details are exposed through JS_TraceObjectGroupCycleCollectorChildren. - ObjectGroup = 0x05, - - // The kind associated with a nullptr. - Null = 0x06, - - // The following kinds do not have an exposed C++ idiom. - BaseShape = 0x0F, - JitCode = 0x1F, - LazyScript = 0x2F, - Scope = 0x3F -}; -const static uintptr_t OutOfLineTraceKindMask = 0x07; -static_assert(uintptr_t(JS::TraceKind::BaseShape) & OutOfLineTraceKindMask, "mask bits are set"); -static_assert(uintptr_t(JS::TraceKind::JitCode) & OutOfLineTraceKindMask, "mask bits are set"); -static_assert(uintptr_t(JS::TraceKind::LazyScript) & OutOfLineTraceKindMask, "mask bits are set"); -static_assert(uintptr_t(JS::TraceKind::Scope) & OutOfLineTraceKindMask, "mask bits are set"); - -// When this header is imported inside SpiderMonkey, the class definitions are -// available and we can query those definitions to find the correct kind -// directly from the class hierarchy. -template -struct MapTypeToTraceKind { - static const JS::TraceKind kind = T::TraceKind; -}; - -// When this header is used outside SpiderMonkey, the class definitions are not -// available, so the following table containing all public GC types is used. -#define JS_FOR_EACH_TRACEKIND(D) \ - /* PrettyName TypeName AddToCCKind */ \ - D(BaseShape, js::BaseShape, true) \ - D(JitCode, js::jit::JitCode, true) \ - D(LazyScript, js::LazyScript, true) \ - D(Scope, js::Scope, true) \ - D(Object, JSObject, true) \ - D(ObjectGroup, js::ObjectGroup, true) \ - D(Script, JSScript, true) \ - D(Shape, js::Shape, true) \ - D(String, JSString, false) \ - D(Symbol, JS::Symbol, false) - -// Map from all public types to their trace kind. -#define JS_EXPAND_DEF(name, type, _) \ - template <> struct MapTypeToTraceKind { \ - static const JS::TraceKind kind = JS::TraceKind::name; \ - }; -JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF); -#undef JS_EXPAND_DEF - -// RootKind is closely related to TraceKind. Whereas TraceKind's indices are -// laid out for convenient embedding as a pointer tag, the indicies of RootKind -// are designed for use as array keys via EnumeratedArray. -enum class RootKind : int8_t -{ - // These map 1:1 with trace kinds. -#define EXPAND_ROOT_KIND(name, _0, _1) \ - name, -JS_FOR_EACH_TRACEKIND(EXPAND_ROOT_KIND) -#undef EXPAND_ROOT_KIND - - // These tagged pointers are special-cased for performance. - Id, - Value, - - // Everything else. - Traceable, - - Limit -}; - -// Most RootKind correspond directly to a trace kind. -template struct MapTraceKindToRootKind {}; -#define JS_EXPAND_DEF(name, _0, _1) \ - template <> struct MapTraceKindToRootKind { \ - static const JS::RootKind kind = JS::RootKind::name; \ - }; -JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF) -#undef JS_EXPAND_DEF - -// Specify the RootKind for all types. Value and jsid map to special cases; -// pointer types we can derive directly from the TraceKind; everything else -// should go in the Traceable list and use GCPolicy::trace for tracing. -template -struct MapTypeToRootKind { - static const JS::RootKind kind = JS::RootKind::Traceable; -}; -template -struct MapTypeToRootKind { - static const JS::RootKind kind = - JS::MapTraceKindToRootKind::kind>::kind; -}; -template -struct MapTypeToRootKind> { - static const JS::RootKind kind = JS::MapTypeToRootKind::kind; -}; -template <> struct MapTypeToRootKind { - static const JS::RootKind kind = JS::RootKind::Value; -}; -template <> struct MapTypeToRootKind { - static const JS::RootKind kind = JS::RootKind::Id; -}; -template <> struct MapTypeToRootKind : public MapTypeToRootKind {}; - -// Fortunately, few places in the system need to deal with fully abstract -// cells. In those places that do, we generally want to move to a layout -// templated function as soon as possible. This template wraps the upcast -// for that dispatch. -// -// Given a call: -// -// DispatchTraceKindTyped(f, thing, traceKind, ... args) -// -// Downcast the |void *thing| to the specific type designated by |traceKind|, -// and pass it to the functor |f| along with |... args|, forwarded. Pass the -// type designated by |traceKind| as the functor's template argument. The -// |thing| parameter is optional; without it, we simply pass through |... args|. - -// GCC and Clang require an explicit template declaration in front of the -// specialization of operator() because it is a dependent template. MSVC, on -// the other hand, gets very confused if we have a |template| token there. -// The clang-cl front end defines _MSC_VER, but still requires the explicit -// template declaration, so we must test for __clang__ here as well. -#if defined(_MSC_VER) && !defined(__clang__) -# define JS_DEPENDENT_TEMPLATE_HINT -#else -# define JS_DEPENDENT_TEMPLATE_HINT template -#endif -template -auto -DispatchTraceKindTyped(F f, JS::TraceKind traceKind, Args&&... args) - -> decltype(f. JS_DEPENDENT_TEMPLATE_HINT operator()(mozilla::Forward(args)...)) -{ - switch (traceKind) { -#define JS_EXPAND_DEF(name, type, _) \ - case JS::TraceKind::name: \ - return f. JS_DEPENDENT_TEMPLATE_HINT operator()(mozilla::Forward(args)...); - JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF); -#undef JS_EXPAND_DEF - default: - MOZ_CRASH("Invalid trace kind in DispatchTraceKindTyped."); - } -} -#undef JS_DEPENDENT_TEMPLATE_HINT - -template -auto -DispatchTraceKindTyped(F f, void* thing, JS::TraceKind traceKind, Args&&... args) - -> decltype(f(static_cast(nullptr), mozilla::Forward(args)...)) -{ - switch (traceKind) { -#define JS_EXPAND_DEF(name, type, _) \ - case JS::TraceKind::name: \ - return f(static_cast(thing), mozilla::Forward(args)...); - JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF); -#undef JS_EXPAND_DEF - default: - MOZ_CRASH("Invalid trace kind in DispatchTraceKindTyped."); - } -} - -} // namespace JS - -#endif // js_TraceKind_h diff --git a/android/arm64-v8a/include/spidermonkey/js/TracingAPI.h b/android/arm64-v8a/include/spidermonkey/js/TracingAPI.h deleted file mode 100644 index 37c69aca..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/TracingAPI.h +++ /dev/null @@ -1,403 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_TracingAPI_h -#define js_TracingAPI_h - -#include "jsalloc.h" - -#include "js/HashTable.h" -#include "js/HeapAPI.h" -#include "js/TraceKind.h" - -class JS_PUBLIC_API(JSTracer); - -namespace JS { -class JS_PUBLIC_API(CallbackTracer); -template class Heap; -template class TenuredHeap; - -/** Returns a static string equivalent of |kind|. */ -JS_FRIEND_API(const char*) -GCTraceKindToAscii(JS::TraceKind kind); - -} // namespace JS - -enum WeakMapTraceKind { - /** - * Do not trace into weak map keys or values during traversal. Users must - * handle weak maps manually. - */ - DoNotTraceWeakMaps, - - /** - * Do true ephemeron marking with a weak key lookup marking phase. This is - * the default for GCMarker. - */ - ExpandWeakMaps, - - /** - * Trace through to all values, irrespective of whether the keys are live - * or not. Used for non-marking tracers. - */ - TraceWeakMapValues, - - /** - * Trace through to all keys and values, irrespective of whether the keys - * are live or not. Used for non-marking tracers. - */ - TraceWeakMapKeysValues -}; - -class JS_PUBLIC_API(JSTracer) -{ - public: - // Return the runtime set on the tracer. - JSRuntime* runtime() const { return runtime_; } - - // Return the weak map tracing behavior currently set on this tracer. - WeakMapTraceKind weakMapAction() const { return weakMapAction_; } - - enum class TracerKindTag { - // Marking path: a tracer used only for marking liveness of cells, not - // for moving them. The kind will transition to WeakMarking after - // everything reachable by regular edges has been marked. - Marking, - - // Same as Marking, except we have now moved on to the "weak marking - // phase", in which every marked obj/script is immediately looked up to - // see if it is a weak map key (and therefore might require marking its - // weak map value). - WeakMarking, - - // A tracer that traverses the graph for the purposes of moving objects - // from the nursery to the tenured area. - Tenuring, - - // General-purpose traversal that invokes a callback on each cell. - // Traversing children is the responsibility of the callback. - Callback - }; - bool isMarkingTracer() const { return tag_ == TracerKindTag::Marking || tag_ == TracerKindTag::WeakMarking; } - bool isWeakMarkingTracer() const { return tag_ == TracerKindTag::WeakMarking; } - bool isTenuringTracer() const { return tag_ == TracerKindTag::Tenuring; } - bool isCallbackTracer() const { return tag_ == TracerKindTag::Callback; } - inline JS::CallbackTracer* asCallbackTracer(); -#ifdef DEBUG - bool checkEdges() { return checkEdges_; } -#endif - - protected: - JSTracer(JSRuntime* rt, TracerKindTag tag, - WeakMapTraceKind weakTraceKind = TraceWeakMapValues) - : runtime_(rt) - , weakMapAction_(weakTraceKind) -#ifdef DEBUG - , checkEdges_(true) -#endif - , tag_(tag) - {} - -#ifdef DEBUG - // Set whether to check edges are valid in debug builds. - void setCheckEdges(bool check) { - checkEdges_ = check; - } -#endif - - private: - JSRuntime* runtime_; - WeakMapTraceKind weakMapAction_; -#ifdef DEBUG - bool checkEdges_; -#endif - - protected: - TracerKindTag tag_; -}; - -namespace JS { - -class AutoTracingName; -class AutoTracingIndex; -class AutoTracingCallback; - -class JS_PUBLIC_API(CallbackTracer) : public JSTracer -{ - public: - CallbackTracer(JSRuntime* rt, WeakMapTraceKind weakTraceKind = TraceWeakMapValues) - : JSTracer(rt, JSTracer::TracerKindTag::Callback, weakTraceKind), - contextName_(nullptr), contextIndex_(InvalidIndex), contextFunctor_(nullptr) - {} - CallbackTracer(JSContext* cx, WeakMapTraceKind weakTraceKind = TraceWeakMapValues); - - // Override these methods to receive notification when an edge is visited - // with the type contained in the callback. The default implementation - // dispatches to the fully-generic onChild implementation, so for cases that - // do not care about boxing overhead and do not need the actual edges, - // just override the generic onChild. - virtual void onObjectEdge(JSObject** objp) { onChild(JS::GCCellPtr(*objp)); } - virtual void onStringEdge(JSString** strp) { onChild(JS::GCCellPtr(*strp)); } - virtual void onSymbolEdge(JS::Symbol** symp) { onChild(JS::GCCellPtr(*symp)); } - virtual void onScriptEdge(JSScript** scriptp) { onChild(JS::GCCellPtr(*scriptp)); } - virtual void onShapeEdge(js::Shape** shapep) { - onChild(JS::GCCellPtr(*shapep, JS::TraceKind::Shape)); - } - virtual void onObjectGroupEdge(js::ObjectGroup** groupp) { - onChild(JS::GCCellPtr(*groupp, JS::TraceKind::ObjectGroup)); - } - virtual void onBaseShapeEdge(js::BaseShape** basep) { - onChild(JS::GCCellPtr(*basep, JS::TraceKind::BaseShape)); - } - virtual void onJitCodeEdge(js::jit::JitCode** codep) { - onChild(JS::GCCellPtr(*codep, JS::TraceKind::JitCode)); - } - virtual void onLazyScriptEdge(js::LazyScript** lazyp) { - onChild(JS::GCCellPtr(*lazyp, JS::TraceKind::LazyScript)); - } - virtual void onScopeEdge(js::Scope** scopep) { - onChild(JS::GCCellPtr(*scopep, JS::TraceKind::Scope)); - } - - // Override this method to receive notification when a node in the GC - // heap graph is visited. - virtual void onChild(const JS::GCCellPtr& thing) = 0; - - // Access to the tracing context: - // When tracing with a JS::CallbackTracer, we invoke the callback with the - // edge location and the type of target. This is useful for operating on - // the edge in the abstract or on the target thing, satisfying most common - // use cases. However, some tracers need additional detail about the - // specific edge that is being traced in order to be useful. Unfortunately, - // the raw pointer to the edge that we provide is not enough information to - // infer much of anything useful about that edge. - // - // In order to better support use cases that care in particular about edges - // -- as opposed to the target thing -- tracing implementations are - // responsible for providing extra context information about each edge they - // trace, as it is traced. This contains, at a minimum, an edge name and, - // when tracing an array, the index. Further specialization can be achived - // (with some complexity), by associating a functor with the tracer so - // that, when requested, the user can generate totally custom edge - // descriptions. - - // Returns the current edge's name. It is only valid to call this when - // inside the trace callback, however, the edge name will always be set. - const char* contextName() const { MOZ_ASSERT(contextName_); return contextName_; } - - // Returns the current edge's index, if marked as part of an array of edges. - // This must be called only inside the trace callback. When not tracing an - // array, the value will be InvalidIndex. - const static size_t InvalidIndex = size_t(-1); - size_t contextIndex() const { return contextIndex_; } - - // Build a description of this edge in the heap graph. This call may invoke - // the context functor, if set, which may inspect arbitrary areas of the - // heap. On the other hand, the description provided by this method may be - // substantially more accurate and useful than those provided by only the - // contextName and contextIndex. - void getTracingEdgeName(char* buffer, size_t bufferSize); - - // The trace implementation may associate a callback with one or more edges - // using AutoTracingDetails. This functor is called by getTracingEdgeName - // and is responsible for providing a textual representation of the - // currently being traced edge. The callback has access to the full heap, - // including the currently set tracing context. - class ContextFunctor { - public: - virtual void operator()(CallbackTracer* trc, char* buf, size_t bufsize) = 0; - }; - -#ifdef DEBUG - enum class TracerKind { DoNotCare, Moving, GrayBuffering, VerifyTraceProtoAndIface }; - virtual TracerKind getTracerKind() const { return TracerKind::DoNotCare; } -#endif - - // In C++, overriding a method hides all methods in the base class with - // that name, not just methods with that signature. Thus, the typed edge - // methods have to have distinct names to allow us to override them - // individually, which is freqently useful if, for example, we only want to - // process only one type of edge. - void dispatchToOnEdge(JSObject** objp) { onObjectEdge(objp); } - void dispatchToOnEdge(JSString** strp) { onStringEdge(strp); } - void dispatchToOnEdge(JS::Symbol** symp) { onSymbolEdge(symp); } - void dispatchToOnEdge(JSScript** scriptp) { onScriptEdge(scriptp); } - void dispatchToOnEdge(js::Shape** shapep) { onShapeEdge(shapep); } - void dispatchToOnEdge(js::ObjectGroup** groupp) { onObjectGroupEdge(groupp); } - void dispatchToOnEdge(js::BaseShape** basep) { onBaseShapeEdge(basep); } - void dispatchToOnEdge(js::jit::JitCode** codep) { onJitCodeEdge(codep); } - void dispatchToOnEdge(js::LazyScript** lazyp) { onLazyScriptEdge(lazyp); } - void dispatchToOnEdge(js::Scope** scopep) { onScopeEdge(scopep); } - - private: - friend class AutoTracingName; - const char* contextName_; - - friend class AutoTracingIndex; - size_t contextIndex_; - - friend class AutoTracingDetails; - ContextFunctor* contextFunctor_; -}; - -// Set the name portion of the tracer's context for the current edge. -class MOZ_RAII AutoTracingName -{ - CallbackTracer* trc_; - const char* prior_; - - public: - AutoTracingName(CallbackTracer* trc, const char* name) : trc_(trc), prior_(trc->contextName_) { - MOZ_ASSERT(name); - trc->contextName_ = name; - } - ~AutoTracingName() { - MOZ_ASSERT(trc_->contextName_); - trc_->contextName_ = prior_; - } -}; - -// Set the index portion of the tracer's context for the current range. -class MOZ_RAII AutoTracingIndex -{ - CallbackTracer* trc_; - - public: - explicit AutoTracingIndex(JSTracer* trc, size_t initial = 0) : trc_(nullptr) { - if (trc->isCallbackTracer()) { - trc_ = trc->asCallbackTracer(); - MOZ_ASSERT(trc_->contextIndex_ == CallbackTracer::InvalidIndex); - trc_->contextIndex_ = initial; - } - } - ~AutoTracingIndex() { - if (trc_) { - MOZ_ASSERT(trc_->contextIndex_ != CallbackTracer::InvalidIndex); - trc_->contextIndex_ = CallbackTracer::InvalidIndex; - } - } - - void operator++() { - if (trc_) { - MOZ_ASSERT(trc_->contextIndex_ != CallbackTracer::InvalidIndex); - ++trc_->contextIndex_; - } - } -}; - -// Set a context callback for the trace callback to use, if it needs a detailed -// edge description. -class MOZ_RAII AutoTracingDetails -{ - CallbackTracer* trc_; - - public: - AutoTracingDetails(JSTracer* trc, CallbackTracer::ContextFunctor& func) : trc_(nullptr) { - if (trc->isCallbackTracer()) { - trc_ = trc->asCallbackTracer(); - MOZ_ASSERT(trc_->contextFunctor_ == nullptr); - trc_->contextFunctor_ = &func; - } - } - ~AutoTracingDetails() { - if (trc_) { - MOZ_ASSERT(trc_->contextFunctor_); - trc_->contextFunctor_ = nullptr; - } - } -}; - -} // namespace JS - -JS::CallbackTracer* -JSTracer::asCallbackTracer() -{ - MOZ_ASSERT(isCallbackTracer()); - return static_cast(this); -} - -namespace JS { - -// The JS::TraceEdge family of functions traces the given GC thing reference. -// This performs the tracing action configured on the given JSTracer: typically -// calling the JSTracer::callback or marking the thing as live. -// -// The argument to JS::TraceEdge is an in-out param: when the function returns, -// the garbage collector might have moved the GC thing. In this case, the -// reference passed to JS::TraceEdge will be updated to the thing's new -// location. Callers of this method are responsible for updating any state that -// is dependent on the object's address. For example, if the object's address -// is used as a key in a hashtable, then the object must be removed and -// re-inserted with the correct hash. -// -// Note that while |edgep| must never be null, it is fine for |*edgep| to be -// nullptr. -template -extern JS_PUBLIC_API(void) -TraceEdge(JSTracer* trc, JS::Heap* edgep, const char* name); - -extern JS_PUBLIC_API(void) -TraceEdge(JSTracer* trc, JS::TenuredHeap* edgep, const char* name); - -// Edges that are always traced as part of root marking do not require -// incremental barriers. This function allows for marking non-barriered -// pointers, but asserts that this happens during root marking. -// -// Note that while |edgep| must never be null, it is fine for |*edgep| to be -// nullptr. -template -extern JS_PUBLIC_API(void) -UnsafeTraceRoot(JSTracer* trc, T* edgep, const char* name); - -extern JS_PUBLIC_API(void) -TraceChildren(JSTracer* trc, GCCellPtr thing); - -using ZoneSet = js::HashSet, js::SystemAllocPolicy>; -using CompartmentSet = js::HashSet, - js::SystemAllocPolicy>; - -/** - * Trace every value within |compartments| that is wrapped by a - * cross-compartment wrapper from a compartment that is not an element of - * |compartments|. - */ -extern JS_PUBLIC_API(void) -TraceIncomingCCWs(JSTracer* trc, const JS::CompartmentSet& compartments); - -} // namespace JS - -extern JS_PUBLIC_API(void) -JS_GetTraceThingInfo(char* buf, size_t bufsize, JSTracer* trc, - void* thing, JS::TraceKind kind, bool includeDetails); - -namespace js { - -// Trace an edge that is not a GC root and is not wrapped in a barriered -// wrapper for some reason. -// -// This method does not check if |*edgep| is non-null before tracing through -// it, so callers must check any nullable pointer before calling this method. -template -extern JS_PUBLIC_API(void) -UnsafeTraceManuallyBarrieredEdge(JSTracer* trc, T* edgep, const char* name); - -namespace gc { - -// Return true if the given edge is not live and is about to be swept. -template -extern JS_PUBLIC_API(bool) -EdgeNeedsSweep(JS::Heap* edgep); - -// Not part of the public API, but declared here so we can use it in GCPolicy -// which is. -template -bool -IsAboutToBeFinalizedUnbarriered(T* thingp); - -} // namespace gc -} // namespace js - -#endif /* js_TracingAPI_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/TrackedOptimizationInfo.h b/android/arm64-v8a/include/spidermonkey/js/TrackedOptimizationInfo.h deleted file mode 100644 index b697765c..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/TrackedOptimizationInfo.h +++ /dev/null @@ -1,285 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_TrackedOptimizationInfo_h -#define js_TrackedOptimizationInfo_h - -#include "mozilla/Maybe.h" - -namespace JS { - -#define TRACKED_STRATEGY_LIST(_) \ - _(GetProp_ArgumentsLength) \ - _(GetProp_ArgumentsCallee) \ - _(GetProp_InferredConstant) \ - _(GetProp_Constant) \ - _(GetProp_NotDefined) \ - _(GetProp_StaticName) \ - _(GetProp_SimdGetter) \ - _(GetProp_TypedObject) \ - _(GetProp_DefiniteSlot) \ - _(GetProp_Unboxed) \ - _(GetProp_CommonGetter) \ - _(GetProp_InlineAccess) \ - _(GetProp_Innerize) \ - _(GetProp_InlineCache) \ - _(GetProp_SharedCache) \ - _(GetProp_ModuleNamespace) \ - \ - _(SetProp_CommonSetter) \ - _(SetProp_TypedObject) \ - _(SetProp_DefiniteSlot) \ - _(SetProp_Unboxed) \ - _(SetProp_InlineAccess) \ - _(SetProp_InlineCache) \ - \ - _(GetElem_TypedObject) \ - _(GetElem_Dense) \ - _(GetElem_TypedStatic) \ - _(GetElem_TypedArray) \ - _(GetElem_String) \ - _(GetElem_Arguments) \ - _(GetElem_ArgumentsInlined) \ - _(GetElem_InlineCache) \ - \ - _(SetElem_TypedObject) \ - _(SetElem_TypedStatic) \ - _(SetElem_TypedArray) \ - _(SetElem_Dense) \ - _(SetElem_Arguments) \ - _(SetElem_InlineCache) \ - \ - _(BinaryArith_Concat) \ - _(BinaryArith_SpecializedTypes) \ - _(BinaryArith_SpecializedOnBaselineTypes) \ - _(BinaryArith_SharedCache) \ - _(BinaryArith_Call) \ - \ - _(InlineCache_OptimizedStub) \ - \ - _(Call_Inline) - - -// Ordering is important below. All outcomes before GenericSuccess will be -// considered failures, and all outcomes after GenericSuccess will be -// considered successes. -#define TRACKED_OUTCOME_LIST(_) \ - _(GenericFailure) \ - _(Disabled) \ - _(NoTypeInfo) \ - _(NoAnalysisInfo) \ - _(NoShapeInfo) \ - _(UnknownObject) \ - _(UnknownProperties) \ - _(Singleton) \ - _(NotSingleton) \ - _(NotFixedSlot) \ - _(InconsistentFixedSlot) \ - _(NotObject) \ - _(NotStruct) \ - _(NotUnboxed) \ - _(NotUndefined) \ - _(UnboxedConvertedToNative) \ - _(StructNoField) \ - _(InconsistentFieldType) \ - _(InconsistentFieldOffset) \ - _(NeedsTypeBarrier) \ - _(InDictionaryMode) \ - _(NoProtoFound) \ - _(MultiProtoPaths) \ - _(NonWritableProperty) \ - _(ProtoIndexedProps) \ - _(ArrayBadFlags) \ - _(ArrayDoubleConversion) \ - _(ArrayRange) \ - _(ArraySeenNegativeIndex) \ - _(TypedObjectHasDetachedBuffer) \ - _(TypedObjectArrayRange) \ - _(AccessNotDense) \ - _(AccessNotSimdObject) \ - _(AccessNotTypedObject) \ - _(AccessNotTypedArray) \ - _(AccessNotString) \ - _(OperandNotString) \ - _(OperandNotNumber) \ - _(OperandNotStringOrNumber) \ - _(OperandNotSimpleArith) \ - _(StaticTypedArrayUint32) \ - _(StaticTypedArrayCantComputeMask) \ - _(OutOfBounds) \ - _(GetElemStringNotCached) \ - _(NonNativeReceiver) \ - _(IndexType) \ - _(SetElemNonDenseNonTANotCached) \ - _(NoSimdJitSupport) \ - _(SimdTypeNotOptimized) \ - _(UnknownSimdProperty) \ - _(NotModuleNamespace) \ - _(UnknownProperty) \ - \ - _(ICOptStub_GenericSuccess) \ - \ - _(ICGetPropStub_ReadSlot) \ - _(ICGetPropStub_CallGetter) \ - _(ICGetPropStub_ArrayLength) \ - _(ICGetPropStub_UnboxedRead) \ - _(ICGetPropStub_UnboxedReadExpando) \ - _(ICGetPropStub_UnboxedArrayLength) \ - _(ICGetPropStub_TypedArrayLength) \ - _(ICGetPropStub_DOMProxyShadowed) \ - _(ICGetPropStub_DOMProxyUnshadowed) \ - _(ICGetPropStub_GenericProxy) \ - _(ICGetPropStub_ArgumentsLength) \ - \ - _(ICSetPropStub_Slot) \ - _(ICSetPropStub_GenericProxy) \ - _(ICSetPropStub_DOMProxyShadowed) \ - _(ICSetPropStub_DOMProxyUnshadowed) \ - _(ICSetPropStub_CallSetter) \ - _(ICSetPropStub_AddSlot) \ - _(ICSetPropStub_SetUnboxed) \ - \ - _(ICGetElemStub_ReadSlot) \ - _(ICGetElemStub_CallGetter) \ - _(ICGetElemStub_ReadUnboxed) \ - _(ICGetElemStub_Dense) \ - _(ICGetElemStub_DenseHole) \ - _(ICGetElemStub_TypedArray) \ - _(ICGetElemStub_ArgsElementMapped) \ - _(ICGetElemStub_ArgsElementUnmapped) \ - \ - _(ICSetElemStub_Dense) \ - _(ICSetElemStub_TypedArray) \ - \ - _(ICNameStub_ReadSlot) \ - _(ICNameStub_CallGetter) \ - _(ICNameStub_TypeOfNoProperty) \ - \ - _(CantInlineGeneric) \ - _(CantInlineNoTarget) \ - _(CantInlineNotInterpreted) \ - _(CantInlineNoBaseline) \ - _(CantInlineLazy) \ - _(CantInlineNotConstructor) \ - _(CantInlineClassConstructor) \ - _(CantInlineDisabledIon) \ - _(CantInlineTooManyArgs) \ - _(CantInlineNeedsArgsObj) \ - _(CantInlineDebuggee) \ - _(CantInlineUnknownProps) \ - _(CantInlineExceededDepth) \ - _(CantInlineExceededTotalBytecodeLength) \ - _(CantInlineBigCaller) \ - _(CantInlineBigCallee) \ - _(CantInlineBigCalleeInlinedBytecodeLength) \ - _(CantInlineNotHot) \ - _(CantInlineNotInDispatch) \ - _(CantInlineUnreachable) \ - _(CantInlineNativeBadForm) \ - _(CantInlineNativeBadType) \ - _(CantInlineNativeNoTemplateObj) \ - _(CantInlineBound) \ - _(CantInlineNativeNoSpecialization) \ - _(HasCommonInliningPath) \ - \ - _(GenericSuccess) \ - _(Inlined) \ - _(DOM) \ - _(Monomorphic) \ - _(Polymorphic) - -#define TRACKED_TYPESITE_LIST(_) \ - _(Receiver) \ - _(Operand) \ - _(Index) \ - _(Value) \ - _(Call_Target) \ - _(Call_This) \ - _(Call_Arg) \ - _(Call_Return) - -enum class TrackedStrategy : uint32_t { -#define STRATEGY_OP(name) name, - TRACKED_STRATEGY_LIST(STRATEGY_OP) -#undef STRATEGY_OPT - - Count -}; - -enum class TrackedOutcome : uint32_t { -#define OUTCOME_OP(name) name, - TRACKED_OUTCOME_LIST(OUTCOME_OP) -#undef OUTCOME_OP - - Count -}; - -enum class TrackedTypeSite : uint32_t { -#define TYPESITE_OP(name) name, - TRACKED_TYPESITE_LIST(TYPESITE_OP) -#undef TYPESITE_OP - - Count -}; - -JS_PUBLIC_API(const char*) -TrackedStrategyString(TrackedStrategy strategy); - -JS_PUBLIC_API(const char*) -TrackedOutcomeString(TrackedOutcome outcome); - -JS_PUBLIC_API(const char*) -TrackedTypeSiteString(TrackedTypeSite site); - -struct ForEachTrackedOptimizationAttemptOp -{ - virtual void operator()(TrackedStrategy strategy, TrackedOutcome outcome) = 0; -}; - -struct ForEachTrackedOptimizationTypeInfoOp -{ - // Called 0+ times per entry, once for each type in the type set that Ion - // saw during MIR construction. readType is always called _before_ - // operator() on the same entry. - // - // The keyedBy parameter describes how the type is keyed: - // - "primitive" for primitive types - // - "constructor" for object types tied to a scripted constructor - // function. - // - "alloc site" for object types tied to an allocation site. - // - "prototype" for object types tied neither to a constructor nor - // to an allocation site, but to a prototype. - // - "singleton" for object types which only has a single value. - // - "function" for object types referring to scripted functions. - // - "native" for object types referring to native functions. - // - // The name parameter is the string representation of the type. If the - // type is keyed by "constructor", or if the type itself refers to a - // scripted function, the name is the function's displayAtom. If the type - // is keyed by "native", this is nullptr. - // - // The location parameter is the filename if the type is keyed by - // "constructor", "alloc site", or if the type itself refers to a scripted - // function. If the type is keyed by "native", it is the offset of the - // native function, suitable for use with addr2line on Linux or atos on OS - // X. Otherwise it is nullptr. - // - // The lineno parameter is the line number if the type is keyed by - // "constructor", "alloc site", or if the type itself refers to a scripted - // function. Otherwise it is Nothing(). - // - // The location parameter is the only one that may need escaping if being - // quoted. - virtual void readType(const char* keyedBy, const char* name, - const char* location, mozilla::Maybe lineno) = 0; - - // Called once per entry. - virtual void operator()(TrackedTypeSite site, const char* mirType) = 0; -}; - -} // namespace JS - -#endif // js_TrackedOptimizationInfo_h diff --git a/android/arm64-v8a/include/spidermonkey/js/TypeDecls.h b/android/arm64-v8a/include/spidermonkey/js/TypeDecls.h deleted file mode 100644 index acb93f97..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/TypeDecls.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -// This file contains public type declarations that are used *frequently*. If -// it doesn't occur at least 10 times in Gecko, it probably shouldn't be in -// here. -// -// It includes only: -// - forward declarations of structs and classes; -// - typedefs; -// - enums (maybe). -// It does *not* contain any struct or class definitions. - -#ifndef js_TypeDecls_h -#define js_TypeDecls_h - -#include -#include - -#include "js-config.h" - -struct JSContext; -class JSFunction; -class JSObject; -class JSScript; -class JSString; -class JSAddonId; - -struct jsid; - -namespace JS { - -typedef unsigned char Latin1Char; - -class Symbol; -class Value; -template class Handle; -template class MutableHandle; -template class Rooted; -template class PersistentRooted; - -typedef Handle HandleFunction; -typedef Handle HandleId; -typedef Handle HandleObject; -typedef Handle HandleScript; -typedef Handle HandleString; -typedef Handle HandleSymbol; -typedef Handle HandleValue; - -typedef MutableHandle MutableHandleFunction; -typedef MutableHandle MutableHandleId; -typedef MutableHandle MutableHandleObject; -typedef MutableHandle MutableHandleScript; -typedef MutableHandle MutableHandleString; -typedef MutableHandle MutableHandleSymbol; -typedef MutableHandle MutableHandleValue; - -typedef Rooted RootedObject; -typedef Rooted RootedFunction; -typedef Rooted RootedScript; -typedef Rooted RootedString; -typedef Rooted RootedSymbol; -typedef Rooted RootedId; -typedef Rooted RootedValue; - -typedef PersistentRooted PersistentRootedFunction; -typedef PersistentRooted PersistentRootedId; -typedef PersistentRooted PersistentRootedObject; -typedef PersistentRooted PersistentRootedScript; -typedef PersistentRooted PersistentRootedString; -typedef PersistentRooted PersistentRootedSymbol; -typedef PersistentRooted PersistentRootedValue; - -} // namespace JS - -#endif /* js_TypeDecls_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/UbiNode.h b/android/arm64-v8a/include/spidermonkey/js/UbiNode.h deleted file mode 100644 index c8742f33..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/UbiNode.h +++ /dev/null @@ -1,1144 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNode_h -#define js_UbiNode_h - -#include "mozilla/Alignment.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Maybe.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" -#include "mozilla/RangedPtr.h" -#include "mozilla/TypeTraits.h" -#include "mozilla/Variant.h" - -#include "jspubtd.h" - -#include "js/GCAPI.h" -#include "js/HashTable.h" -#include "js/RootingAPI.h" -#include "js/TracingAPI.h" -#include "js/TypeDecls.h" -#include "js/UniquePtr.h" -#include "js/Value.h" -#include "js/Vector.h" - -// JS::ubi::Node -// -// JS::ubi::Node is a pointer-like type designed for internal use by heap -// analysis tools. A ubi::Node can refer to: -// -// - a JS value, like a string, object, or symbol; -// - an internal SpiderMonkey structure, like a shape or a scope chain object -// - an instance of some embedding-provided type: in Firefox, an XPCOM -// object, or an internal DOM node class instance -// -// A ubi::Node instance provides metadata about its referent, and can -// enumerate its referent's outgoing edges, so you can implement heap analysis -// algorithms that walk the graph - finding paths between objects, or -// computing heap dominator trees, say - using ubi::Node, while remaining -// ignorant of the details of the types you're operating on. -// -// Of course, when it comes to presenting the results in a developer-facing -// tool, you'll need to stop being ignorant of those details, because you have -// to discuss the ubi::Nodes' referents with the developer. Here, ubi::Node -// can hand you dynamically checked, properly typed pointers to the original -// objects via the as method, or generate descriptions of the referent -// itself. -// -// ubi::Node instances are lightweight (two-word) value types. Instances: -// - compare equal if and only if they refer to the same object; -// - have hash values that respect their equality relation; and -// - have serializations that are only equal if the ubi::Nodes are equal. -// -// A ubi::Node is only valid for as long as its referent is alive; if its -// referent goes away, the ubi::Node becomes a dangling pointer. A ubi::Node -// that refers to a GC-managed object is not automatically a GC root; if the -// GC frees or relocates its referent, the ubi::Node becomes invalid. A -// ubi::Node that refers to a reference-counted object does not bump the -// reference count. -// -// ubi::Node values require no supporting data structures, making them -// feasible for use in memory-constrained devices --- ideally, the memory -// requirements of the algorithm which uses them will be the limiting factor, -// not the demands of ubi::Node itself. -// -// One can construct a ubi::Node value given a pointer to a type that ubi::Node -// supports. In the other direction, one can convert a ubi::Node back to a -// pointer; these downcasts are checked dynamically. In particular, one can -// convert a 'JSContext*' to a ubi::Node, yielding a node with an outgoing edge -// for every root registered with the runtime; starting from this, one can walk -// the entire heap. (Of course, one could also start traversal at any other kind -// of type to which one has a pointer.) -// -// -// Extending ubi::Node To Handle Your Embedding's Types -// -// To add support for a new ubi::Node referent type R, you must define a -// specialization of the ubi::Concrete template, ubi::Concrete, which -// inherits from ubi::Base. ubi::Node itself uses the specialization for -// compile-time information (i.e. the checked conversions between R * and -// ubi::Node), and the inheritance for run-time dispatching. -// -// -// ubi::Node Exposes Implementation Details -// -// In many cases, a JavaScript developer's view of their data differs -// substantially from its actual implementation. For example, while the -// ECMAScript specification describes objects as maps from property names to -// sets of attributes (like ECMAScript's [[Value]]), in practice many objects -// have only a pointer to a shape, shared with other similar objects, and -// indexed slots that contain the [[Value]] attributes. As another example, a -// string produced by concatenating two other strings may sometimes be -// represented by a "rope", a structure that points to the two original -// strings. -// -// We intend to use ubi::Node to write tools that report memory usage, so it's -// important that ubi::Node accurately portray how much memory nodes consume. -// Thus, for example, when data that apparently belongs to multiple nodes is -// in fact shared in a common structure, ubi::Node's graph uses a separate -// node for that shared structure, and presents edges to it from the data's -// apparent owners. For example, ubi::Node exposes SpiderMonkey objects' -// shapes and base shapes, and exposes rope string and substring structure, -// because these optimizations become visible when a tool reports how much -// memory a structure consumes. -// -// However, fine granularity is not a goal. When a particular object is the -// exclusive owner of a separate block of memory, ubi::Node may present the -// object and its block as a single node, and add their sizes together when -// reporting the node's size, as there is no meaningful loss of data in this -// case. Thus, for example, a ubi::Node referring to a JavaScript object, when -// asked for the object's size in bytes, includes the object's slot and -// element arrays' sizes in the total. There is no separate ubi::Node value -// representing the slot and element arrays, since they are owned exclusively -// by the object. -// -// -// Presenting Analysis Results To JavaScript Developers -// -// If an analysis provides its results in terms of ubi::Node values, a user -// interface presenting those results will generally need to clean them up -// before they can be understood by JavaScript developers. For example, -// JavaScript developers should not need to understand shapes, only JavaScript -// objects. Similarly, they should not need to understand the distinction -// between DOM nodes and the JavaScript shadow objects that represent them. -// -// -// Rooting Restrictions -// -// At present there is no way to root ubi::Node instances, so instances can't be -// live across any operation that might GC. Analyses using ubi::Node must either -// run to completion and convert their results to some other rootable type, or -// save their intermediate state in some rooted structure if they must GC before -// they complete. (For algorithms like path-finding and dominator tree -// computation, we implement the algorithm avoiding any operation that could -// cause a GC --- and use AutoCheckCannotGC to verify this.) -// -// If this restriction prevents us from implementing interesting tools, we may -// teach the GC how to root ubi::Nodes, fix up hash tables that use them as -// keys, etc. -// -// -// Hostile Graph Structure -// -// Analyses consuming ubi::Node graphs must be robust when presented with graphs -// that are deliberately constructed to exploit their weaknesses. When operating -// on live graphs, web content has control over the object graph, and less -// direct control over shape and string structure, and analyses should be -// prepared to handle extreme cases gracefully. For example, if an analysis were -// to use the C++ stack in a depth-first traversal, carefully constructed -// content could cause the analysis to overflow the stack. -// -// When ubi::Nodes refer to nodes deserialized from a heap snapshot, analyses -// must be even more careful: since snapshots often come from potentially -// compromised e10s content processes, even properties normally guaranteed by -// the platform (the proper linking of DOM nodes, for example) might be -// corrupted. While it is the deserializer's responsibility to check the basic -// structure of the snapshot file, the analyses should be prepared for ubi::Node -// graphs constructed from snapshots to be even more bizarre. - -class JSAtom; - -namespace JS { -namespace ubi { - -class Edge; -class EdgeRange; -class StackFrame; - -} // namespace ubi -} // namespace JS - -namespace JS { -namespace ubi { - -using mozilla::Forward; -using mozilla::Maybe; -using mozilla::Move; -using mozilla::RangedPtr; -using mozilla::Variant; - -template -using Vector = mozilla::Vector; - -/*** ubi::StackFrame ******************************************************************************/ - -// Concrete JS::ubi::StackFrame instances backed by a live SavedFrame object -// store their strings as JSAtom*, while deserialized stack frames from offline -// heap snapshots store their strings as const char16_t*. In order to provide -// zero-cost accessors to these strings in a single interface that works with -// both cases, we use this variant type. -class AtomOrTwoByteChars : public Variant { - using Base = Variant; - - public: - template - MOZ_IMPLICIT AtomOrTwoByteChars(T&& rhs) : Base(Forward(rhs)) { } - - template - AtomOrTwoByteChars& operator=(T&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move disallowed"); - this->~AtomOrTwoByteChars(); - new (this) AtomOrTwoByteChars(Forward(rhs)); - return *this; - } - - // Return the length of the given AtomOrTwoByteChars string. - size_t length(); - - // Copy the given AtomOrTwoByteChars string into the destination buffer, - // inflating if necessary. Does NOT null terminate. Returns the number of - // characters written to destination. - size_t copyToBuffer(RangedPtr destination, size_t length); -}; - -// The base class implemented by each ConcreteStackFrame type. Subclasses -// must not add data members to this class. -class BaseStackFrame { - friend class StackFrame; - - BaseStackFrame(const StackFrame&) = delete; - BaseStackFrame& operator=(const StackFrame&) = delete; - - protected: - void* ptr; - explicit BaseStackFrame(void* ptr) : ptr(ptr) { } - - public: - // This is a value type that should not have a virtual destructor. Don't add - // destructors in subclasses! - - // Get a unique identifier for this StackFrame. The identifier is not valid - // across garbage collections. - virtual uint64_t identifier() const { return uint64_t(uintptr_t(ptr)); } - - // Get this frame's parent frame. - virtual StackFrame parent() const = 0; - - // Get this frame's line number. - virtual uint32_t line() const = 0; - - // Get this frame's column number. - virtual uint32_t column() const = 0; - - // Get this frame's source name. Never null. - virtual AtomOrTwoByteChars source() const = 0; - - // Return this frame's function name if named, otherwise the inferred - // display name. Can be null. - virtual AtomOrTwoByteChars functionDisplayName() const = 0; - - // Returns true if this frame's function is system JavaScript running with - // trusted principals, false otherwise. - virtual bool isSystem() const = 0; - - // Return true if this frame's function is a self-hosted JavaScript builtin, - // false otherwise. - virtual bool isSelfHosted(JSContext* cx) const = 0; - - // Construct a SavedFrame stack for the stack starting with this frame and - // containing all of its parents. The SavedFrame objects will be placed into - // cx's current compartment. - // - // Note that the process of - // - // SavedFrame - // | - // V - // JS::ubi::StackFrame - // | - // V - // offline heap snapshot - // | - // V - // JS::ubi::StackFrame - // | - // V - // SavedFrame - // - // is lossy because we cannot serialize and deserialize the SavedFrame's - // principals in the offline heap snapshot, so JS::ubi::StackFrame - // simplifies the principals check into the boolean isSystem() state. This - // is fine because we only expose JS::ubi::Stack to devtools and chrome - // code, and not to the web platform. - virtual MOZ_MUST_USE bool constructSavedFrameStack(JSContext* cx, - MutableHandleObject outSavedFrameStack) - const = 0; - - // Trace the concrete implementation of JS::ubi::StackFrame. - virtual void trace(JSTracer* trc) = 0; -}; - -// A traits template with a specialization for each backing type that implements -// the ubi::BaseStackFrame interface. Each specialization must be the a subclass -// of ubi::BaseStackFrame. -template class ConcreteStackFrame; - -// A JS::ubi::StackFrame represents a frame in a recorded stack. It can be -// backed either by a live SavedFrame object or by a structure deserialized from -// an offline heap snapshot. -// -// It is a value type that may be memcpy'd hither and thither without worrying -// about constructors or destructors, similar to POD types. -// -// Its lifetime is the same as the lifetime of the graph that is being analyzed -// by the JS::ubi::Node that the JS::ubi::StackFrame came from. That is, if the -// graph being analyzed is the live heap graph, the JS::ubi::StackFrame is only -// valid within the scope of an AutoCheckCannotGC; if the graph being analyzed -// is an offline heap snapshot, the JS::ubi::StackFrame is valid as long as the -// offline heap snapshot is alive. -class StackFrame { - // Storage in which we allocate BaseStackFrame subclasses. - mozilla::AlignedStorage2 storage; - - BaseStackFrame* base() { return storage.addr(); } - const BaseStackFrame* base() const { return storage.addr(); } - - template - void construct(T* ptr) { - static_assert(mozilla::IsBaseOf>::value, - "ConcreteStackFrame must inherit from BaseStackFrame"); - static_assert(sizeof(ConcreteStackFrame) == sizeof(*base()), - "ubi::ConcreteStackFrame specializations must be the same size as " - "ubi::BaseStackFrame"); - ConcreteStackFrame::construct(base(), ptr); - } - struct ConstructFunctor; - - public: - StackFrame() { construct(nullptr); } - - template - MOZ_IMPLICIT StackFrame(T* ptr) { - construct(ptr); - } - - template - StackFrame& operator=(T* ptr) { - construct(ptr); - return *this; - } - - // Constructors accepting SpiderMonkey's generic-pointer-ish types. - - template - explicit StackFrame(const JS::Handle& handle) { - construct(handle.get()); - } - - template - StackFrame& operator=(const JS::Handle& handle) { - construct(handle.get()); - return *this; - } - - template - explicit StackFrame(const JS::Rooted& root) { - construct(root.get()); - } - - template - StackFrame& operator=(const JS::Rooted& root) { - construct(root.get()); - return *this; - } - - // Because StackFrame is just a vtable pointer and an instance pointer, we - // can memcpy everything around instead of making concrete classes define - // virtual constructors. See the comment above Node's copy constructor for - // more details; that comment applies here as well. - StackFrame(const StackFrame& rhs) { - memcpy(storage.u.mBytes, rhs.storage.u.mBytes, sizeof(storage.u)); - } - - StackFrame& operator=(const StackFrame& rhs) { - memcpy(storage.u.mBytes, rhs.storage.u.mBytes, sizeof(storage.u)); - return *this; - } - - bool operator==(const StackFrame& rhs) const { return base()->ptr == rhs.base()->ptr; } - bool operator!=(const StackFrame& rhs) const { return !(*this == rhs); } - - explicit operator bool() const { - return base()->ptr != nullptr; - } - - // Copy this StackFrame's source name into the given |destination| - // buffer. Copy no more than |length| characters. The result is *not* null - // terminated. Returns how many characters were written into the buffer. - size_t source(RangedPtr destination, size_t length) const; - - // Copy this StackFrame's function display name into the given |destination| - // buffer. Copy no more than |length| characters. The result is *not* null - // terminated. Returns how many characters were written into the buffer. - size_t functionDisplayName(RangedPtr destination, size_t length) const; - - // Get the size of the respective strings. 0 is returned for null strings. - size_t sourceLength(); - size_t functionDisplayNameLength(); - - // Methods that forward to virtual calls through BaseStackFrame. - - void trace(JSTracer* trc) { base()->trace(trc); } - uint64_t identifier() const { - auto id = base()->identifier(); - MOZ_ASSERT(JS::Value::isNumberRepresentable(id)); - return id; - } - uint32_t line() const { return base()->line(); } - uint32_t column() const { return base()->column(); } - AtomOrTwoByteChars source() const { return base()->source(); } - AtomOrTwoByteChars functionDisplayName() const { return base()->functionDisplayName(); } - StackFrame parent() const { return base()->parent(); } - bool isSystem() const { return base()->isSystem(); } - bool isSelfHosted(JSContext* cx) const { return base()->isSelfHosted(cx); } - MOZ_MUST_USE bool constructSavedFrameStack(JSContext* cx, - MutableHandleObject outSavedFrameStack) const { - return base()->constructSavedFrameStack(cx, outSavedFrameStack); - } - - struct HashPolicy { - using Lookup = JS::ubi::StackFrame; - - static js::HashNumber hash(const Lookup& lookup) { - return lookup.identifier(); - } - - static bool match(const StackFrame& key, const Lookup& lookup) { - return key == lookup; - } - - static void rekey(StackFrame& k, const StackFrame& newKey) { - k = newKey; - } - }; -}; - -// The ubi::StackFrame null pointer. Any attempt to operate on a null -// ubi::StackFrame crashes. -template<> -class ConcreteStackFrame : public BaseStackFrame { - explicit ConcreteStackFrame(void* ptr) : BaseStackFrame(ptr) { } - - public: - static void construct(void* storage, void*) { new (storage) ConcreteStackFrame(nullptr); } - - uint64_t identifier() const override { return 0; } - void trace(JSTracer* trc) override { } - MOZ_MUST_USE bool constructSavedFrameStack(JSContext* cx, MutableHandleObject out) - const override - { - out.set(nullptr); - return true; - } - - uint32_t line() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - uint32_t column() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - AtomOrTwoByteChars source() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - AtomOrTwoByteChars functionDisplayName() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - StackFrame parent() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - bool isSystem() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - bool isSelfHosted(JSContext* cx) const override { MOZ_CRASH("null JS::ubi::StackFrame"); } -}; - -MOZ_MUST_USE bool ConstructSavedFrameStackSlow(JSContext* cx, JS::ubi::StackFrame& frame, - MutableHandleObject outSavedFrameStack); - - -/*** ubi::Node ************************************************************************************/ - -// A concrete node specialization can claim its referent is a member of a -// particular "coarse type" which is less specific than the actual -// implementation type but generally more palatable for web developers. For -// example, JitCode can be considered to have a coarse type of "Script". This is -// used by some analyses for putting nodes into different buckets. The default, -// if a concrete specialization does not provide its own mapping to a CoarseType -// variant, is "Other". -// -// NB: the values associated with a particular enum variant must not change or -// be reused for new variants. Doing so will cause inspecting ubi::Nodes backed -// by an offline heap snapshot from an older SpiderMonkey/Firefox version to -// break. Consider this enum append only. -enum class CoarseType: uint32_t { - Other = 0, - Object = 1, - Script = 2, - String = 3, - - FIRST = Other, - LAST = String -}; - -inline uint32_t -CoarseTypeToUint32(CoarseType type) -{ - return static_cast(type); -} - -inline bool -Uint32IsValidCoarseType(uint32_t n) -{ - auto first = static_cast(CoarseType::FIRST); - auto last = static_cast(CoarseType::LAST); - MOZ_ASSERT(first < last); - return first <= n && n <= last; -} - -inline CoarseType -Uint32ToCoarseType(uint32_t n) -{ - MOZ_ASSERT(Uint32IsValidCoarseType(n)); - return static_cast(n); -} - -// The base class implemented by each ubi::Node referent type. Subclasses must -// not add data members to this class. -class Base { - friend class Node; - - // For performance's sake, we'd prefer to avoid a virtual destructor; and - // an empty constructor seems consistent with the 'lightweight value type' - // visible behavior we're trying to achieve. But if the destructor isn't - // virtual, and a subclass overrides it, the subclass's destructor will be - // ignored. Is there a way to make the compiler catch that error? - - protected: - // Space for the actual pointer. Concrete subclasses should define a - // properly typed 'get' member function to access this. - void* ptr; - - explicit Base(void* ptr) : ptr(ptr) { } - - public: - bool operator==(const Base& rhs) const { - // Some compilers will indeed place objects of different types at - // the same address, so technically, we should include the vtable - // in this comparison. But it seems unlikely to cause problems in - // practice. - return ptr == rhs.ptr; - } - bool operator!=(const Base& rhs) const { return !(*this == rhs); } - - // An identifier for this node, guaranteed to be stable and unique for as - // long as this ubi::Node's referent is alive and at the same address. - // - // This is probably suitable for use in serializations, as it is an integral - // type. It may also help save memory when constructing HashSets of - // ubi::Nodes: since a uint64_t will always be smaller-or-equal-to the size - // of a ubi::Node, a HashSet may use less space per element - // than a HashSet. - // - // (Note that 'unique' only means 'up to equality on ubi::Node'; see the - // caveats about multiple objects allocated at the same address for - // 'ubi::Node::operator=='.) - using Id = uint64_t; - virtual Id identifier() const { return Id(uintptr_t(ptr)); } - - // Returns true if this node is pointing to something on the live heap, as - // opposed to something from a deserialized core dump. Returns false, - // otherwise. - virtual bool isLive() const { return true; }; - - // Return the coarse-grained type-of-thing that this node represents. - virtual CoarseType coarseType() const { return CoarseType::Other; } - - // Return a human-readable name for the referent's type. The result should - // be statically allocated. (You can use u"strings" for this.) - // - // This must always return Concrete::concreteTypeName; we use that - // pointer as a tag for this particular referent type. - virtual const char16_t* typeName() const = 0; - - // Return the size of this node, in bytes. Include any structures that this - // node owns exclusively that are not exposed as their own ubi::Nodes. - // |mallocSizeOf| should be a malloc block sizing function; see - // |mfbt/MemoryReporting.h|. - // - // Because we can use |JS::ubi::Node|s backed by a snapshot that was taken - // on a 64-bit platform when we are currently on a 32-bit platform, we - // cannot rely on |size_t| for node sizes. Instead, |Size| is uint64_t on - // all platforms. - using Size = uint64_t; - virtual Size size(mozilla::MallocSizeOf mallocSizeof) const { return 1; } - - // Return an EdgeRange that initially contains all the referent's outgoing - // edges. The caller takes ownership of the EdgeRange. - // - // If wantNames is true, compute names for edges. Doing so can be expensive - // in time and memory. - virtual js::UniquePtr edges(JSContext* cx, bool wantNames) const = 0; - - // Return the Zone to which this node's referent belongs, or nullptr if the - // referent is not of a type allocated in SpiderMonkey Zones. - virtual JS::Zone* zone() const { return nullptr; } - - // Return the compartment for this node. Some ubi::Node referents are not - // associated with JSCompartments, such as JSStrings (which are associated - // with Zones). When the referent is not associated with a compartment, - // nullptr is returned. - virtual JSCompartment* compartment() const { return nullptr; } - - // Return whether this node's referent's allocation stack was captured. - virtual bool hasAllocationStack() const { return false; } - - // Get the stack recorded at the time this node's referent was - // allocated. This must only be called when hasAllocationStack() is true. - virtual StackFrame allocationStack() const { - MOZ_CRASH("Concrete classes that have an allocation stack must override both " - "hasAllocationStack and allocationStack."); - } - - // Methods for JSObject Referents - // - // These methods are only semantically valid if the referent is either a - // JSObject in the live heap, or represents a previously existing JSObject - // from some deserialized heap snapshot. - - // Return the object's [[Class]]'s name. - virtual const char* jsObjectClassName() const { return nullptr; } - - // If this object was constructed with `new` and we have the data available, - // place the contructor function's display name in the out parameter. - // Otherwise, place nullptr in the out parameter. Caller maintains ownership - // of the out parameter. True is returned on success, false is returned on - // OOM. - virtual MOZ_MUST_USE bool jsObjectConstructorName(JSContext* cx, UniqueTwoByteChars& outName) - const - { - outName.reset(nullptr); - return true; - } - - // Methods for CoarseType::Script referents - - // Return the script's source's filename if available. If unavailable, - // return nullptr. - virtual const char* scriptFilename() const { return nullptr; } - - private: - Base(const Base& rhs) = delete; - Base& operator=(const Base& rhs) = delete; -}; - -// A traits template with a specialization for each referent type that -// ubi::Node supports. The specialization must be the concrete subclass of Base -// that represents a pointer to the referent type. It must include these -// members: -// -// // The specific char16_t array returned by Concrete::typeName(). -// static const char16_t concreteTypeName[]; -// -// // Construct an instance of this concrete class in |storage| referring -// // to |referent|. Implementations typically use a placement 'new'. -// // -// // In some cases, |referent| will contain dynamic type information that -// // identifies it a some more specific subclass of |Referent|. For -// // example, when |Referent| is |JSObject|, then |referent->getClass()| -// // could tell us that it's actually a JSFunction. Similarly, if -// // |Referent| is |nsISupports|, we would like a ubi::Node that knows its -// // final implementation type. -// // -// // So we delegate the actual construction to this specialization, which -// // knows Referent's details. -// static void construct(void* storage, Referent* referent); -template -class Concrete; - -// A container for a Base instance; all members simply forward to the contained -// instance. This container allows us to pass ubi::Node instances by value. -class Node { - // Storage in which we allocate Base subclasses. - mozilla::AlignedStorage2 storage; - Base* base() { return storage.addr(); } - const Base* base() const { return storage.addr(); } - - template - void construct(T* ptr) { - static_assert(sizeof(Concrete) == sizeof(*base()), - "ubi::Base specializations must be the same size as ubi::Base"); - static_assert(mozilla::IsBaseOf>::value, - "ubi::Concrete must inherit from ubi::Base"); - Concrete::construct(base(), ptr); - } - struct ConstructFunctor; - - public: - Node() { construct(nullptr); } - - template - MOZ_IMPLICIT Node(T* ptr) { - construct(ptr); - } - template - Node& operator=(T* ptr) { - construct(ptr); - return *this; - } - - // We can construct and assign from rooted forms of pointers. - template - MOZ_IMPLICIT Node(const Rooted& root) { - construct(root.get()); - } - template - Node& operator=(const Rooted& root) { - construct(root.get()); - return *this; - } - - // Constructors accepting SpiderMonkey's other generic-pointer-ish types. - // Note that we *do* want an implicit constructor here: JS::Value and - // JS::ubi::Node are both essentially tagged references to other sorts of - // objects, so letting conversions happen automatically is appropriate. - MOZ_IMPLICIT Node(JS::HandleValue value); - explicit Node(const JS::GCCellPtr& thing); - - // copy construction and copy assignment just use memcpy, since we know - // instances contain nothing but a vtable pointer and a data pointer. - // - // To be completely correct, concrete classes could provide a virtual - // 'construct' member function, which we could invoke on rhs to construct an - // instance in our storage. But this is good enough; there's no need to jump - // through vtables for copying and assignment that are just going to move - // two words around. The compiler knows how to optimize memcpy. - Node(const Node& rhs) { - memcpy(storage.u.mBytes, rhs.storage.u.mBytes, sizeof(storage.u)); - } - - Node& operator=(const Node& rhs) { - memcpy(storage.u.mBytes, rhs.storage.u.mBytes, sizeof(storage.u)); - return *this; - } - - bool operator==(const Node& rhs) const { return *base() == *rhs.base(); } - bool operator!=(const Node& rhs) const { return *base() != *rhs.base(); } - - explicit operator bool() const { - return base()->ptr != nullptr; - } - - bool isLive() const { return base()->isLive(); } - - // Get the canonical type name for the given type T. - template - static const char16_t* canonicalTypeName() { return Concrete::concreteTypeName; } - - template - bool is() const { - return base()->typeName() == canonicalTypeName(); - } - - template - T* as() const { - MOZ_ASSERT(isLive()); - MOZ_ASSERT(is()); - return static_cast(base()->ptr); - } - - template - T* asOrNull() const { - MOZ_ASSERT(isLive()); - return is() ? static_cast(base()->ptr) : nullptr; - } - - // If this node refers to something that can be represented as a JavaScript - // value that is safe to expose to JavaScript code, return that value. - // Otherwise return UndefinedValue(). JSStrings, JS::Symbols, and some (but - // not all!) JSObjects can be exposed. - JS::Value exposeToJS() const; - - CoarseType coarseType() const { return base()->coarseType(); } - const char16_t* typeName() const { return base()->typeName(); } - JS::Zone* zone() const { return base()->zone(); } - JSCompartment* compartment() const { return base()->compartment(); } - const char* jsObjectClassName() const { return base()->jsObjectClassName(); } - MOZ_MUST_USE bool jsObjectConstructorName(JSContext* cx, UniqueTwoByteChars& outName) const { - return base()->jsObjectConstructorName(cx, outName); - } - - const char* scriptFilename() const { return base()->scriptFilename(); } - - using Size = Base::Size; - Size size(mozilla::MallocSizeOf mallocSizeof) const { - auto size = base()->size(mallocSizeof); - MOZ_ASSERT(size > 0, - "C++ does not have zero-sized types! Choose 1 if you just need a " - "conservative default."); - return size; - } - - js::UniquePtr edges(JSContext* cx, bool wantNames = true) const { - return base()->edges(cx, wantNames); - } - - bool hasAllocationStack() const { return base()->hasAllocationStack(); } - StackFrame allocationStack() const { - return base()->allocationStack(); - } - - using Id = Base::Id; - Id identifier() const { - auto id = base()->identifier(); - MOZ_ASSERT(JS::Value::isNumberRepresentable(id)); - return id; - } - - // A hash policy for ubi::Nodes. - // This simply uses the stock PointerHasher on the ubi::Node's pointer. - // We specialize DefaultHasher below to make this the default. - class HashPolicy { - typedef js::PointerHasher::value> PtrHash; - - public: - typedef Node Lookup; - - static js::HashNumber hash(const Lookup& l) { return PtrHash::hash(l.base()->ptr); } - static bool match(const Node& k, const Lookup& l) { return k == l; } - static void rekey(Node& k, const Node& newKey) { k = newKey; } - }; -}; - -using NodeSet = js::HashSet, js::SystemAllocPolicy>; -using NodeSetPtr = mozilla::UniquePtr>; - -/*** Edge and EdgeRange ***************************************************************************/ - -using EdgeName = UniqueTwoByteChars; - -// An outgoing edge to a referent node. -class Edge { - public: - Edge() : name(nullptr), referent() { } - - // Construct an initialized Edge, taking ownership of |name|. - Edge(char16_t* name, const Node& referent) - : name(name) - , referent(referent) - { } - - // Move construction and assignment. - Edge(Edge&& rhs) - : name(mozilla::Move(rhs.name)) - , referent(rhs.referent) - { } - - Edge& operator=(Edge&& rhs) { - MOZ_ASSERT(&rhs != this); - this->~Edge(); - new (this) Edge(mozilla::Move(rhs)); - return *this; - } - - Edge(const Edge&) = delete; - Edge& operator=(const Edge&) = delete; - - // This edge's name. This may be nullptr, if Node::edges was called with - // false as the wantNames parameter. - // - // The storage is owned by this Edge, and will be freed when this Edge is - // destructed. You may take ownership of the name by `mozilla::Move`ing it - // out of the edge; it is just a UniquePtr. - // - // (In real life we'll want a better representation for names, to avoid - // creating tons of strings when the names follow a pattern; and we'll need - // to think about lifetimes carefully to ensure traversal stays cheap.) - EdgeName name; - - // This edge's referent. - Node referent; -}; - -// EdgeRange is an abstract base class for iterating over a node's outgoing -// edges. (This is modeled after js::HashTable::Range.) -// -// Concrete instances of this class need not be as lightweight as Node itself, -// since they're usually only instantiated while iterating over a particular -// object's edges. For example, a dumb implementation for JS Cells might use -// JS::TraceChildren to to get the outgoing edges, and then store them in an -// array internal to the EdgeRange. -class EdgeRange { - protected: - // The current front edge of this range, or nullptr if this range is empty. - Edge* front_; - - EdgeRange() : front_(nullptr) { } - - public: - virtual ~EdgeRange() { } - - // True if there are no more edges in this range. - bool empty() const { return !front_; } - - // The front edge of this range. This is owned by the EdgeRange, and is - // only guaranteed to live until the next call to popFront, or until - // the EdgeRange is destructed. - const Edge& front() const { return *front_; } - Edge& front() { return *front_; } - - // Remove the front edge from this range. This should only be called if - // !empty(). - virtual void popFront() = 0; - - private: - EdgeRange(const EdgeRange&) = delete; - EdgeRange& operator=(const EdgeRange&) = delete; -}; - - -typedef mozilla::Vector EdgeVector; - -// An EdgeRange concrete class that holds a pre-existing vector of -// Edges. A PreComputedEdgeRange does not take ownership of its -// EdgeVector; it is up to the PreComputedEdgeRange's consumer to manage -// that lifetime. -class PreComputedEdgeRange : public EdgeRange { - EdgeVector& edges; - size_t i; - - void settle() { - front_ = i < edges.length() ? &edges[i] : nullptr; - } - - public: - explicit PreComputedEdgeRange(EdgeVector& edges) - : edges(edges), - i(0) - { - settle(); - } - - void popFront() override { - MOZ_ASSERT(!empty()); - i++; - settle(); - } -}; - -/*** RootList *************************************************************************************/ - -// RootList is a class that can be pointed to by a |ubi::Node|, creating a -// fictional root-of-roots which has edges to every GC root in the JS -// runtime. Having a single root |ubi::Node| is useful for algorithms written -// with the assumption that there aren't multiple roots (such as computing -// dominator trees) and you want a single point of entry. It also ensures that -// the roots themselves get visited by |ubi::BreadthFirst| (they would otherwise -// only be used as starting points). -// -// RootList::init itself causes a minor collection, but once the list of roots -// has been created, GC must not occur, as the referent ubi::Nodes are not -// stable across GC. The init calls emplace on |noGC|'s AutoCheckCannotGC, whose -// lifetime must extend at least as long as the RootList itself. -// -// Example usage: -// -// { -// mozilla::Maybe maybeNoGC; -// JS::ubi::RootList rootList(cx, maybeNoGC); -// if (!rootList.init()) -// return false; -// -// // The AutoCheckCannotGC is guaranteed to exist if init returned true. -// MOZ_ASSERT(maybeNoGC.isSome()); -// -// JS::ubi::Node root(&rootList); -// -// ... -// } -class MOZ_STACK_CLASS RootList { - Maybe& noGC; - - public: - JSContext* cx; - EdgeVector edges; - bool wantNames; - - RootList(JSContext* cx, Maybe& noGC, bool wantNames = false); - - // Find all GC roots. - MOZ_MUST_USE bool init(); - // Find only GC roots in the provided set of |JSCompartment|s. - MOZ_MUST_USE bool init(CompartmentSet& debuggees); - // Find only GC roots in the given Debugger object's set of debuggee - // compartments. - MOZ_MUST_USE bool init(HandleObject debuggees); - - // Returns true if the RootList has been initialized successfully, false - // otherwise. - bool initialized() { return noGC.isSome(); } - - // Explicitly add the given Node as a root in this RootList. If wantNames is - // true, you must pass an edgeName. The RootList does not take ownership of - // edgeName. - MOZ_MUST_USE bool addRoot(Node node, const char16_t* edgeName = nullptr); -}; - - -/*** Concrete classes for ubi::Node referent types ************************************************/ - -template<> -class Concrete : public Base { - protected: - explicit Concrete(RootList* ptr) : Base(ptr) { } - RootList& get() const { return *static_cast(ptr); } - - public: - static void construct(void* storage, RootList* ptr) { new (storage) Concrete(ptr); } - - js::UniquePtr edges(JSContext* cx, bool wantNames) const override; - - const char16_t* typeName() const override { return concreteTypeName; } - static const char16_t concreteTypeName[]; -}; - -// A reusable ubi::Concrete specialization base class for types supported by -// JS::TraceChildren. -template -class TracerConcrete : public Base { - js::UniquePtr edges(JSContext* cx, bool wantNames) const override; - JS::Zone* zone() const override; - - protected: - explicit TracerConcrete(Referent* ptr) : Base(ptr) { } - Referent& get() const { return *static_cast(ptr); } -}; - -// For JS::TraceChildren-based types that have a 'compartment' method. -template -class TracerConcreteWithCompartment : public TracerConcrete { - typedef TracerConcrete TracerBase; - JSCompartment* compartment() const override; - - protected: - explicit TracerConcreteWithCompartment(Referent* ptr) : TracerBase(ptr) { } -}; - -// Define specializations for some commonly-used public JSAPI types. -// These can use the generic templates above. -template<> -class Concrete : TracerConcrete { - protected: - explicit Concrete(JS::Symbol* ptr) : TracerConcrete(ptr) { } - - public: - static void construct(void* storage, JS::Symbol* ptr) { - new (storage) Concrete(ptr); - } - - Size size(mozilla::MallocSizeOf mallocSizeOf) const override; - - const char16_t* typeName() const override { return concreteTypeName; } - static const char16_t concreteTypeName[]; -}; - -template<> -class Concrete : TracerConcreteWithCompartment { - protected: - explicit Concrete(JSScript *ptr) : TracerConcreteWithCompartment(ptr) { } - - public: - static void construct(void *storage, JSScript *ptr) { new (storage) Concrete(ptr); } - - CoarseType coarseType() const final { return CoarseType::Script; } - Size size(mozilla::MallocSizeOf mallocSizeOf) const override; - const char* scriptFilename() const final; - - const char16_t* typeName() const override { return concreteTypeName; } - static const char16_t concreteTypeName[]; -}; - -// The JSObject specialization. -template<> -class Concrete : public TracerConcreteWithCompartment { - protected: - explicit Concrete(JSObject* ptr) : TracerConcreteWithCompartment(ptr) { } - - public: - static void construct(void* storage, JSObject* ptr) { - new (storage) Concrete(ptr); - } - - const char* jsObjectClassName() const override; - MOZ_MUST_USE bool jsObjectConstructorName(JSContext* cx, UniqueTwoByteChars& outName) - const override; - Size size(mozilla::MallocSizeOf mallocSizeOf) const override; - - bool hasAllocationStack() const override; - StackFrame allocationStack() const override; - - CoarseType coarseType() const final { return CoarseType::Object; } - - const char16_t* typeName() const override { return concreteTypeName; } - static const char16_t concreteTypeName[]; -}; - -// For JSString, we extend the generic template with a 'size' implementation. -template<> -class Concrete : TracerConcrete { - protected: - explicit Concrete(JSString *ptr) : TracerConcrete(ptr) { } - - public: - static void construct(void *storage, JSString *ptr) { new (storage) Concrete(ptr); } - - Size size(mozilla::MallocSizeOf mallocSizeOf) const override; - - CoarseType coarseType() const final { return CoarseType::String; } - - const char16_t* typeName() const override { return concreteTypeName; } - static const char16_t concreteTypeName[]; -}; - -// The ubi::Node null pointer. Any attempt to operate on a null ubi::Node asserts. -template<> -class Concrete : public Base { - const char16_t* typeName() const override; - Size size(mozilla::MallocSizeOf mallocSizeOf) const override; - js::UniquePtr edges(JSContext* cx, bool wantNames) const override; - JS::Zone* zone() const override; - JSCompartment* compartment() const override; - CoarseType coarseType() const final; - - explicit Concrete(void* ptr) : Base(ptr) { } - - public: - static void construct(void* storage, void* ptr) { new (storage) Concrete(ptr); } -}; - - -} // namespace ubi -} // namespace JS - -namespace js { - -// Make ubi::Node::HashPolicy the default hash policy for ubi::Node. -template<> struct DefaultHasher : JS::ubi::Node::HashPolicy { }; -template<> struct DefaultHasher : JS::ubi::StackFrame::HashPolicy { }; - -} // namespace js - -#endif // js_UbiNode_h diff --git a/android/arm64-v8a/include/spidermonkey/js/UbiNodeBreadthFirst.h b/android/arm64-v8a/include/spidermonkey/js/UbiNodeBreadthFirst.h deleted file mode 100644 index 8446dbc6..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/UbiNodeBreadthFirst.h +++ /dev/null @@ -1,244 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNodeBreadthFirst_h -#define js_UbiNodeBreadthFirst_h - -#include "js/UbiNode.h" -#include "js/Utility.h" -#include "js/Vector.h" - -namespace JS { -namespace ubi { - -// A breadth-first traversal template for graphs of ubi::Nodes. -// -// No GC may occur while an instance of this template is live. -// -// The provided Handler type should have two members: -// -// typename NodeData; -// -// The value type of |BreadthFirst::visited|, the HashMap of -// ubi::Nodes that have been visited so far. Since the algorithm needs a -// hash table like this for its own use anyway, it is simple to let -// Handler store its own metadata about each node in the same table. -// -// For example, if you want to find a shortest path to each node from any -// traversal starting point, your |NodeData| type could record the first -// edge to reach each node, and the node from which it originates. Then, -// when the traversal is complete, you can walk backwards from any node -// to some starting point, and the path recorded will be a shortest path. -// -// This type must have a default constructor. If this type owns any other -// resources, move constructors and assignment operators are probably a -// good idea, too. -// -// bool operator() (BreadthFirst& traversal, -// Node origin, const Edge& edge, -// Handler::NodeData* referentData, bool first); -// -// The visitor function, called to report that we have traversed -// |edge| from |origin|. This is called once for each edge we traverse. -// As this is a breadth-first search, any prior calls to the visitor function -// were for origin nodes not further from the start nodes than |origin|. -// -// |traversal| is this traversal object, passed along for convenience. -// -// |referentData| is a pointer to the value of the entry in -// |traversal.visited| for |edge.referent|; the visitor function can -// store whatever metadata it likes about |edge.referent| there. -// -// |first| is true if this is the first time we have visited an edge -// leading to |edge.referent|. This could be stored in NodeData, but -// the algorithm knows whether it has just created the entry in -// |traversal.visited|, so it passes it along for convenience. -// -// The visitor function may call |traversal.abandonReferent()| if it -// doesn't want to traverse the outgoing edges of |edge.referent|. You can -// use this to limit the traversal to a given portion of the graph: it will -// never visit nodes reachable only through nodes that you have abandoned. -// Note that |abandonReferent| must be called the first time the given node -// is reached; that is, |first| must be true. -// -// The visitor function may call |traversal.stop()| if it doesn't want -// to visit any more nodes at all. -// -// The visitor function may consult |traversal.visited| for information -// about other nodes, but it should not add or remove entries. -// -// The visitor function should return true on success, or false if an -// error occurs. A false return value terminates the traversal -// immediately, and causes BreadthFirst::traverse to return -// false. -template -struct BreadthFirst { - - // Construct a breadth-first traversal object that reports the nodes it - // reaches to |handler|. The traversal asserts that no GC happens in its - // runtime during its lifetime. - // - // We do nothing with noGC, other than require it to exist, with a lifetime - // that encloses our own. - BreadthFirst(JSContext* cx, Handler& handler, const JS::AutoCheckCannotGC& noGC) - : wantNames(true), cx(cx), visited(), handler(handler), pending(), - traversalBegun(false), stopRequested(false), abandonRequested(false) - { } - - // Initialize this traversal object. Return false on OOM. - bool init() { return visited.init(); } - - // Add |node| as a starting point for the traversal. You may add - // as many starting points as you like. Return false on OOM. - bool addStart(Node node) { return pending.append(node); } - - // Add |node| as a starting point for the traversal (see addStart) and also - // add it to the |visited| set. Return false on OOM. - bool addStartVisited(Node node) { - typename NodeMap::AddPtr ptr = visited.lookupForAdd(node); - if (!ptr && !visited.add(ptr, node, typename Handler::NodeData())) - return false; - return addStart(node); - } - - // True if the handler wants us to compute edge names; doing so can be - // expensive in time and memory. True by default. - bool wantNames; - - // Traverse the graph in breadth-first order, starting at the given - // start nodes, applying |handler::operator()| for each edge traversed - // as described above. - // - // This should be called only once per instance of this class. - // - // Return false on OOM or error return from |handler::operator()|. - bool traverse() - { - MOZ_ASSERT(!traversalBegun); - traversalBegun = true; - - // While there are pending nodes, visit them. - while (!pending.empty()) { - Node origin = pending.front(); - pending.popFront(); - - // Get a range containing all origin's outgoing edges. - auto range = origin.edges(cx, wantNames); - if (!range) - return false; - - // Traverse each edge. - for (; !range->empty(); range->popFront()) { - MOZ_ASSERT(!stopRequested); - - Edge& edge = range->front(); - typename NodeMap::AddPtr a = visited.lookupForAdd(edge.referent); - bool first = !a; - - if (first) { - // This is the first time we've reached |edge.referent|. - // Mark it as visited. - if (!visited.add(a, edge.referent, typename Handler::NodeData())) - return false; - } - - MOZ_ASSERT(a); - - // Report this edge to the visitor function. - if (!handler(*this, origin, edge, &a->value(), first)) - return false; - - if (stopRequested) - return true; - - // Arrange to traverse this edge's referent's outgoing edges - // later --- unless |handler| asked us not to. - if (abandonRequested) { - // Skip the enqueue; reset flag for future iterations. - abandonRequested = false; - } else if (first) { - if (!pending.append(edge.referent)) - return false; - } - } - } - - return true; - } - - // Stop traversal, and return true from |traverse| without visiting any - // more nodes. Only |handler::operator()| should call this function; it - // may do so to stop the traversal early, without returning false and - // then making |traverse|'s caller disambiguate that result from a real - // error. - void stop() { stopRequested = true; } - - // Request that the current edge's referent's outgoing edges not be - // traversed. This must be called the first time that referent is reached. - // Other edges *to* that referent will still be traversed. - void abandonReferent() { abandonRequested = true; } - - // The context with which we were constructed. - JSContext* cx; - - // A map associating each node N that we have reached with a - // Handler::NodeData, for |handler|'s use. This is public, so that - // |handler| can access it to see the traversal thus far. - using NodeMap = js::HashMap, - js::SystemAllocPolicy>; - NodeMap visited; - - private: - // Our handler object. - Handler& handler; - - // A queue template. Appending and popping the front are constant time. - // Wasted space is never more than some recent actual population plus the - // current population. - template - class Queue { - js::Vector head, tail; - size_t frontIndex; - public: - Queue() : head(), tail(), frontIndex(0) { } - bool empty() { return frontIndex >= head.length(); } - T& front() { - MOZ_ASSERT(!empty()); - return head[frontIndex]; - } - void popFront() { - MOZ_ASSERT(!empty()); - frontIndex++; - if (frontIndex >= head.length()) { - head.clearAndFree(); - head.swap(tail); - frontIndex = 0; - } - } - bool append(const T& elt) { - return frontIndex == 0 ? head.append(elt) : tail.append(elt); - } - }; - - // A queue of nodes that we have reached, but whose outgoing edges we - // have not yet traversed. Nodes reachable in fewer edges are enqueued - // earlier. - Queue pending; - - // True if our traverse function has been called. - bool traversalBegun; - - // True if we've been asked to stop the traversal. - bool stopRequested; - - // True if we've been asked to abandon the current edge's referent. - bool abandonRequested; -}; - -} // namespace ubi -} // namespace JS - -#endif // js_UbiNodeBreadthFirst_h diff --git a/android/arm64-v8a/include/spidermonkey/js/UbiNodeCensus.h b/android/arm64-v8a/include/spidermonkey/js/UbiNodeCensus.h deleted file mode 100644 index c0859ec5..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/UbiNodeCensus.h +++ /dev/null @@ -1,251 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNodeCensus_h -#define js_UbiNodeCensus_h - -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" - -#include - -#include "jsapi.h" - -#include "js/UbiNode.h" -#include "js/UbiNodeBreadthFirst.h" - -// A census is a ubi::Node traversal that assigns each node to one or more -// buckets, and returns a report with the size of each bucket. -// -// We summarize the results of a census with counts broken down according to -// criteria selected by the API consumer code that is requesting the census. For -// example, the following breakdown might give an interesting overview of the -// heap: -// -// - all nodes -// - objects -// - objects with a specific [[Class]] * -// - strings -// - scripts -// - all other Node types -// - nodes with a specific ubi::Node::typeName * -// -// Obviously, the parts of this tree marked with * represent many separate -// counts, depending on how many distinct [[Class]] values and ubi::Node type -// names we encounter. -// -// The supported types of breakdowns are documented in -// js/src/doc/Debugger/Debugger.Memory.md. -// -// When we parse the 'breakdown' argument to takeCensus, we build a tree of -// CountType nodes. For example, for the breakdown shown in the -// Debugger.Memory.prototype.takeCensus, documentation: -// -// { -// by: "coarseType", -// objects: { by: "objectClass" }, -// other: { by: "internalType" } -// } -// -// we would build the following tree of CountType subclasses: -// -// ByCoarseType -// objects: ByObjectClass -// each class: SimpleCount -// scripts: SimpleCount -// strings: SimpleCount -// other: ByUbinodeType -// each type: SimpleCount -// -// The interior nodes are all breakdown types that categorize nodes according to -// one characteristic or another; and the leaf nodes are all SimpleType. -// -// Each CountType has its own concrete C++ type that holds the counts it -// produces. SimpleCount::Count just holds totals. ByObjectClass::Count has a -// hash table whose keys are object class names and whose values are counts of -// some other type (in the example above, SimpleCount). -// -// To keep actual count nodes small, they have no vtable. Instead, each count -// points to its CountType, which knows how to carry out all the operations we -// need on a Count. A CountType can produce new count nodes; process nodes as we -// visit them; build a JS object reporting the results; and destruct count -// nodes. - - -namespace JS { -namespace ubi { - -struct Census; - -class CountBase; - -struct CountDeleter { - void operator()(CountBase*); -}; - -using CountBasePtr = js::UniquePtr; - -// Abstract base class for CountType nodes. -struct CountType { - explicit CountType() { } - virtual ~CountType() { } - - // Destruct a count tree node that this type instance constructed. - virtual void destructCount(CountBase& count) = 0; - - // Return a fresh node for the count tree that categorizes nodes according - // to this type. Return a nullptr on OOM. - virtual CountBasePtr makeCount() = 0; - - // Trace |count| and all its children, for garbage collection. - virtual void traceCount(CountBase& count, JSTracer* trc) = 0; - - // Implement the 'count' method for counts returned by this CountType - // instance's 'newCount' method. - virtual MOZ_MUST_USE bool count(CountBase& count, - mozilla::MallocSizeOf mallocSizeOf, - const Node& node) = 0; - - // Implement the 'report' method for counts returned by this CountType - // instance's 'newCount' method. - virtual MOZ_MUST_USE bool report(JSContext* cx, CountBase& count, - MutableHandleValue report) = 0; -}; - -using CountTypePtr = js::UniquePtr; - -// An abstract base class for count tree nodes. -class CountBase { - // In lieu of a vtable, each CountBase points to its type, which - // carries not only the implementations of the CountBase methods, but also - // additional parameters for the type's behavior, as specified in the - // breakdown argument passed to takeCensus. - CountType& type; - - protected: - ~CountBase() { } - - public: - explicit CountBase(CountType& type) - : type(type) - , total_(0) - , smallestNodeIdCounted_(SIZE_MAX) - { } - - // Categorize and count |node| as appropriate for this count's type. - MOZ_MUST_USE bool count(mozilla::MallocSizeOf mallocSizeOf, const Node& node) { - total_++; - - auto id = node.identifier(); - if (id < smallestNodeIdCounted_) { - smallestNodeIdCounted_ = id; - } - -#ifdef DEBUG - size_t oldTotal = total_; -#endif - - bool ret = type.count(*this, mallocSizeOf, node); - - MOZ_ASSERT(total_ == oldTotal, - "CountType::count should not increment total_, CountBase::count handles that"); - - return ret; - } - - // Construct a JavaScript object reporting the counts recorded in this - // count, and store it in |report|. Return true on success, or false on - // failure. - MOZ_MUST_USE bool report(JSContext* cx, MutableHandleValue report) { - return type.report(cx, *this, report); - } - - // Down-cast this CountBase to its true type, based on its 'type' member, - // and run its destructor. - void destruct() { return type.destructCount(*this); } - - // Trace this count for garbage collection. - void trace(JSTracer* trc) { type.traceCount(*this, trc); } - - size_t total_; - - // The smallest JS::ubi::Node::identifier() passed to this instance's - // count() method. This provides a stable way to sort sets. - Node::Id smallestNodeIdCounted_; -}; - -class RootedCount : JS::CustomAutoRooter { - CountBasePtr count; - - void trace(JSTracer* trc) override { count->trace(trc); } - - public: - RootedCount(JSContext* cx, CountBasePtr&& count) - : CustomAutoRooter(cx), - count(Move(count)) - { } - CountBase* operator->() const { return count.get(); } - explicit operator bool() const { return count.get(); } - operator CountBasePtr&() { return count; } -}; - -// Common data for a census traversal, shared across all CountType nodes. -struct Census { - JSContext* const cx; - // If the targetZones set is non-empty, then only consider nodes whose zone - // is an element of the set. If the targetZones set is empty, then nodes in - // all zones are considered. - JS::ZoneSet targetZones; - Zone* atomsZone; - - explicit Census(JSContext* cx) : cx(cx), atomsZone(nullptr) { } - - MOZ_MUST_USE bool init(); -}; - -// A BreadthFirst handler type that conducts a census, using a CountBase to -// categorize and count each node. -class CensusHandler { - Census& census; - CountBasePtr& rootCount; - mozilla::MallocSizeOf mallocSizeOf; - - public: - CensusHandler(Census& census, CountBasePtr& rootCount, mozilla::MallocSizeOf mallocSizeOf) - : census(census), - rootCount(rootCount), - mallocSizeOf(mallocSizeOf) - { } - - MOZ_MUST_USE bool report(JSContext* cx, MutableHandleValue report) { - return rootCount->report(cx, report); - } - - // This class needs to retain no per-node data. - class NodeData { }; - - MOZ_MUST_USE bool operator() (BreadthFirst& traversal, - Node origin, const Edge& edge, - NodeData* referentData, bool first); -}; - -using CensusTraversal = BreadthFirst; - -// Examine the census options supplied by the API consumer, and (among other -// things) use that to build a CountType tree. -MOZ_MUST_USE bool ParseCensusOptions(JSContext* cx, Census& census, HandleObject options, - CountTypePtr& outResult); - -// Parse the breakdown language (as described in -// js/src/doc/Debugger/Debugger.Memory.md) into a CountTypePtr. A null pointer -// is returned on error and is reported to the cx. -CountTypePtr ParseBreakdown(JSContext* cx, HandleValue breakdownValue); - - -} // namespace ubi -} // namespace JS - -#endif // js_UbiNodeCensus_h diff --git a/android/arm64-v8a/include/spidermonkey/js/UbiNodeDominatorTree.h b/android/arm64-v8a/include/spidermonkey/js/UbiNodeDominatorTree.h deleted file mode 100644 index 3422b76b..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/UbiNodeDominatorTree.h +++ /dev/null @@ -1,677 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNodeDominatorTree_h -#define js_UbiNodeDominatorTree_h - -#include "mozilla/Attributes.h" -#include "mozilla/DebugOnly.h" -#include "mozilla/Maybe.h" -#include "mozilla/Move.h" -#include "mozilla/UniquePtr.h" - -#include "jsalloc.h" - -#include "js/UbiNode.h" -#include "js/UbiNodePostOrder.h" -#include "js/Utility.h" -#include "js/Vector.h" - -namespace JS { -namespace ubi { - -/** - * In a directed graph with a root node `R`, a node `A` is said to "dominate" a - * node `B` iff every path from `R` to `B` contains `A`. A node `A` is said to - * be the "immediate dominator" of a node `B` iff it dominates `B`, is not `B` - * itself, and does not dominate any other nodes which also dominate `B` in - * turn. - * - * If we take every node from a graph `G` and create a new graph `T` with edges - * to each node from its immediate dominator, then `T` is a tree (each node has - * only one immediate dominator, or none if it is the root). This tree is called - * a "dominator tree". - * - * This class represents a dominator tree constructed from a `JS::ubi::Node` - * heap graph. The domination relationship and dominator trees are useful tools - * for analyzing heap graphs because they tell you: - * - * - Exactly what could be reclaimed by the GC if some node `A` became - * unreachable: those nodes which are dominated by `A`, - * - * - The "retained size" of a node in the heap graph, in contrast to its - * "shallow size". The "shallow size" is the space taken by a node itself, - * not counting anything it references. The "retained size" of a node is its - * shallow size plus the size of all the things that would be collected if - * the original node wasn't (directly or indirectly) referencing them. In - * other words, the retained size is the shallow size of a node plus the - * shallow sizes of every other node it dominates. For example, the root - * node in a binary tree might have a small shallow size that does not take - * up much space itself, but it dominates the rest of the binary tree and - * its retained size is therefore significant (assuming no external - * references into the tree). - * - * The simple, engineered algorithm presented in "A Simple, Fast Dominance - * Algorithm" by Cooper el al[0] is used to find dominators and construct the - * dominator tree. This algorithm runs in O(n^2) time, but is faster in practice - * than alternative algorithms with better theoretical running times, such as - * Lengauer-Tarjan which runs in O(e * log(n)). The big caveat to that statement - * is that Cooper et al found it is faster in practice *on control flow graphs* - * and I'm not convinced that this property also holds on *heap* graphs. That - * said, the implementation of this algorithm is *much* simpler than - * Lengauer-Tarjan and has been found to be fast enough at least for the time - * being. - * - * [0]: http://www.cs.rice.edu/~keith/EMBED/dom.pdf - */ -class JS_PUBLIC_API(DominatorTree) -{ - private: - // Types. - - using PredecessorSets = js::HashMap, - js::SystemAllocPolicy>; - using NodeToIndexMap = js::HashMap, - js::SystemAllocPolicy>; - class DominatedSets; - - public: - class DominatedSetRange; - - /** - * A pointer to an immediately dominated node. - * - * Don't use this type directly; it is no safer than regular pointers. This - * is only for use indirectly with range-based for loops and - * `DominatedSetRange`. - * - * @see JS::ubi::DominatorTree::getDominatedSet - */ - class DominatedNodePtr - { - friend class DominatedSetRange; - - const JS::ubi::Vector& postOrder; - const uint32_t* ptr; - - DominatedNodePtr(const JS::ubi::Vector& postOrder, const uint32_t* ptr) - : postOrder(postOrder) - , ptr(ptr) - { } - - public: - bool operator!=(const DominatedNodePtr& rhs) const { return ptr != rhs.ptr; } - void operator++() { ptr++; } - const Node& operator*() const { return postOrder[*ptr]; } - }; - - /** - * A range of immediately dominated `JS::ubi::Node`s for use with - * range-based for loops. - * - * @see JS::ubi::DominatorTree::getDominatedSet - */ - class DominatedSetRange - { - friend class DominatedSets; - - const JS::ubi::Vector& postOrder; - const uint32_t* beginPtr; - const uint32_t* endPtr; - - DominatedSetRange(JS::ubi::Vector& postOrder, const uint32_t* begin, const uint32_t* end) - : postOrder(postOrder) - , beginPtr(begin) - , endPtr(end) - { - MOZ_ASSERT(begin <= end); - } - - public: - DominatedNodePtr begin() const { - MOZ_ASSERT(beginPtr <= endPtr); - return DominatedNodePtr(postOrder, beginPtr); - } - - DominatedNodePtr end() const { - return DominatedNodePtr(postOrder, endPtr); - } - - size_t length() const { - MOZ_ASSERT(beginPtr <= endPtr); - return endPtr - beginPtr; - } - - /** - * Safely skip ahead `n` dominators in the range, in O(1) time. - * - * Example usage: - * - * mozilla::Maybe range = myDominatorTree.getDominatedSet(myNode); - * if (range.isNothing()) { - * // Handle unknown nodes however you see fit... - * return false; - * } - * - * // Don't care about the first ten, for whatever reason. - * range->skip(10); - * for (const JS::ubi::Node& dominatedNode : *range) { - * // ... - * } - */ - void skip(size_t n) { - beginPtr += n; - if (beginPtr > endPtr) - beginPtr = endPtr; - } - }; - - private: - /** - * The set of all dominated sets in a dominator tree. - * - * Internally stores the sets in a contiguous array, with a side table of - * indices into that contiguous array to denote the start index of each - * individual set. - */ - class DominatedSets - { - JS::ubi::Vector dominated; - JS::ubi::Vector indices; - - DominatedSets(JS::ubi::Vector&& dominated, JS::ubi::Vector&& indices) - : dominated(mozilla::Move(dominated)) - , indices(mozilla::Move(indices)) - { } - - public: - // DominatedSets is not copy-able. - DominatedSets(const DominatedSets& rhs) = delete; - DominatedSets& operator=(const DominatedSets& rhs) = delete; - - // DominatedSets is move-able. - DominatedSets(DominatedSets&& rhs) - : dominated(mozilla::Move(rhs.dominated)) - , indices(mozilla::Move(rhs.indices)) - { - MOZ_ASSERT(this != &rhs, "self-move not allowed"); - } - DominatedSets& operator=(DominatedSets&& rhs) { - this->~DominatedSets(); - new (this) DominatedSets(mozilla::Move(rhs)); - return *this; - } - - /** - * Create the DominatedSets given the mapping of a node index to its - * immediate dominator. Returns `Some` on success, `Nothing` on OOM - * failure. - */ - static mozilla::Maybe Create(const JS::ubi::Vector& doms) { - auto length = doms.length(); - MOZ_ASSERT(length < UINT32_MAX); - - // Create a vector `dominated` holding a flattened set of buckets of - // immediately dominated children nodes, with a lookup table - // `indices` mapping from each node to the beginning of its bucket. - // - // This has three phases: - // - // 1. Iterate over the full set of nodes and count up the size of - // each bucket. These bucket sizes are temporarily stored in the - // `indices` vector. - // - // 2. Convert the `indices` vector to store the cumulative sum of - // the sizes of all buckets before each index, resulting in a - // mapping from node index to one past the end of that node's - // bucket. - // - // 3. Iterate over the full set of nodes again, filling in bucket - // entries from the end of the bucket's range to its - // beginning. This decrements each index as a bucket entry is - // filled in. After having filled in all of a bucket's entries, - // the index points to the start of the bucket. - - JS::ubi::Vector dominated; - JS::ubi::Vector indices; - if (!dominated.growBy(length) || !indices.growBy(length)) - return mozilla::Nothing(); - - // 1 - memset(indices.begin(), 0, length * sizeof(uint32_t)); - for (uint32_t i = 0; i < length; i++) - indices[doms[i]]++; - - // 2 - uint32_t sumOfSizes = 0; - for (uint32_t i = 0; i < length; i++) { - sumOfSizes += indices[i]; - MOZ_ASSERT(sumOfSizes <= length); - indices[i] = sumOfSizes; - } - - // 3 - for (uint32_t i = 0; i < length; i++) { - auto idxOfDom = doms[i]; - indices[idxOfDom]--; - dominated[indices[idxOfDom]] = i; - } - -#ifdef DEBUG - // Assert that our buckets are non-overlapping and don't run off the - // end of the vector. - uint32_t lastIndex = 0; - for (uint32_t i = 0; i < length; i++) { - MOZ_ASSERT(indices[i] >= lastIndex); - MOZ_ASSERT(indices[i] < length); - lastIndex = indices[i]; - } -#endif - - return mozilla::Some(DominatedSets(mozilla::Move(dominated), mozilla::Move(indices))); - } - - /** - * Get the set of nodes immediately dominated by the node at - * `postOrder[nodeIndex]`. - */ - DominatedSetRange dominatedSet(JS::ubi::Vector& postOrder, uint32_t nodeIndex) const { - MOZ_ASSERT(postOrder.length() == indices.length()); - MOZ_ASSERT(nodeIndex < indices.length()); - auto end = nodeIndex == indices.length() - 1 - ? dominated.end() - : &dominated[indices[nodeIndex + 1]]; - return DominatedSetRange(postOrder, &dominated[indices[nodeIndex]], end); - } - }; - - private: - // Data members. - JS::ubi::Vector postOrder; - NodeToIndexMap nodeToPostOrderIndex; - JS::ubi::Vector doms; - DominatedSets dominatedSets; - mozilla::Maybe> retainedSizes; - - private: - // We use `UNDEFINED` as a sentinel value in the `doms` vector to signal - // that we haven't found any dominators for the node at the corresponding - // index in `postOrder` yet. - static const uint32_t UNDEFINED = UINT32_MAX; - - DominatorTree(JS::ubi::Vector&& postOrder, NodeToIndexMap&& nodeToPostOrderIndex, - JS::ubi::Vector&& doms, DominatedSets&& dominatedSets) - : postOrder(mozilla::Move(postOrder)) - , nodeToPostOrderIndex(mozilla::Move(nodeToPostOrderIndex)) - , doms(mozilla::Move(doms)) - , dominatedSets(mozilla::Move(dominatedSets)) - , retainedSizes(mozilla::Nothing()) - { } - - static uint32_t intersect(JS::ubi::Vector& doms, uint32_t finger1, uint32_t finger2) { - while (finger1 != finger2) { - if (finger1 < finger2) - finger1 = doms[finger1]; - else if (finger2 < finger1) - finger2 = doms[finger2]; - } - return finger1; - } - - // Do the post order traversal of the heap graph and populate our - // predecessor sets. - static MOZ_MUST_USE bool doTraversal(JSContext* cx, AutoCheckCannotGC& noGC, const Node& root, - JS::ubi::Vector& postOrder, - PredecessorSets& predecessorSets) { - uint32_t nodeCount = 0; - auto onNode = [&](const Node& node) { - nodeCount++; - if (MOZ_UNLIKELY(nodeCount == UINT32_MAX)) - return false; - return postOrder.append(node); - }; - - auto onEdge = [&](const Node& origin, const Edge& edge) { - auto p = predecessorSets.lookupForAdd(edge.referent); - if (!p) { - mozilla::UniquePtr> set(js_new()); - if (!set || - !set->init() || - !predecessorSets.add(p, edge.referent, mozilla::Move(set))) - { - return false; - } - } - MOZ_ASSERT(p && p->value()); - return p->value()->put(origin); - }; - - PostOrder traversal(cx, noGC); - return traversal.init() && - traversal.addStart(root) && - traversal.traverse(onNode, onEdge); - } - - // Populates the given `map` with an entry for each node to its index in - // `postOrder`. - static MOZ_MUST_USE bool mapNodesToTheirIndices(JS::ubi::Vector& postOrder, - NodeToIndexMap& map) { - MOZ_ASSERT(!map.initialized()); - MOZ_ASSERT(postOrder.length() < UINT32_MAX); - uint32_t length = postOrder.length(); - if (!map.init(length)) - return false; - for (uint32_t i = 0; i < length; i++) - map.putNewInfallible(postOrder[i], i); - return true; - } - - // Convert the Node -> NodeSet predecessorSets to a index -> Vector - // form. - static MOZ_MUST_USE bool convertPredecessorSetsToVectors( - const Node& root, - JS::ubi::Vector& postOrder, - PredecessorSets& predecessorSets, - NodeToIndexMap& nodeToPostOrderIndex, - JS::ubi::Vector>& predecessorVectors) - { - MOZ_ASSERT(postOrder.length() < UINT32_MAX); - uint32_t length = postOrder.length(); - - MOZ_ASSERT(predecessorVectors.length() == 0); - if (!predecessorVectors.growBy(length)) - return false; - - for (uint32_t i = 0; i < length - 1; i++) { - auto& node = postOrder[i]; - MOZ_ASSERT(node != root, - "Only the last node should be root, since this was a post order traversal."); - - auto ptr = predecessorSets.lookup(node); - MOZ_ASSERT(ptr, - "Because this isn't the root, it had better have predecessors, or else how " - "did we even find it."); - - auto& predecessors = ptr->value(); - if (!predecessorVectors[i].reserve(predecessors->count())) - return false; - for (auto range = predecessors->all(); !range.empty(); range.popFront()) { - auto ptr = nodeToPostOrderIndex.lookup(range.front()); - MOZ_ASSERT(ptr); - predecessorVectors[i].infallibleAppend(ptr->value()); - } - } - predecessorSets.finish(); - return true; - } - - // Initialize `doms` such that the immediate dominator of the `root` is the - // `root` itself and all others are `UNDEFINED`. - static MOZ_MUST_USE bool initializeDominators(JS::ubi::Vector& doms, - uint32_t length) { - MOZ_ASSERT(doms.length() == 0); - if (!doms.growByUninitialized(length)) - return false; - doms[length - 1] = length - 1; - for (uint32_t i = 0; i < length - 1; i++) - doms[i] = UNDEFINED; - return true; - } - - void assertSanity() const { - MOZ_ASSERT(postOrder.length() == doms.length()); - MOZ_ASSERT(postOrder.length() == nodeToPostOrderIndex.count()); - MOZ_ASSERT_IF(retainedSizes.isSome(), postOrder.length() == retainedSizes->length()); - } - - MOZ_MUST_USE bool computeRetainedSizes(mozilla::MallocSizeOf mallocSizeOf) { - MOZ_ASSERT(retainedSizes.isNothing()); - auto length = postOrder.length(); - - retainedSizes.emplace(); - if (!retainedSizes->growBy(length)) { - retainedSizes = mozilla::Nothing(); - return false; - } - - // Iterate in forward order so that we know all of a node's children in - // the dominator tree have already had their retained size - // computed. Then we can simply say that the retained size of a node is - // its shallow size (JS::ubi::Node::size) plus the retained sizes of its - // immediate children in the tree. - - for (uint32_t i = 0; i < length; i++) { - auto size = postOrder[i].size(mallocSizeOf); - - for (const auto& dominated : dominatedSets.dominatedSet(postOrder, i)) { - // The root node dominates itself, but shouldn't contribute to - // its own retained size. - if (dominated == postOrder[length - 1]) { - MOZ_ASSERT(i == length - 1); - continue; - } - - auto ptr = nodeToPostOrderIndex.lookup(dominated); - MOZ_ASSERT(ptr); - auto idxOfDominated = ptr->value(); - MOZ_ASSERT(idxOfDominated < i); - size += retainedSizes.ref()[idxOfDominated]; - } - - retainedSizes.ref()[i] = size; - } - - return true; - } - - public: - // DominatorTree is not copy-able. - DominatorTree(const DominatorTree&) = delete; - DominatorTree& operator=(const DominatorTree&) = delete; - - // DominatorTree is move-able. - DominatorTree(DominatorTree&& rhs) - : postOrder(mozilla::Move(rhs.postOrder)) - , nodeToPostOrderIndex(mozilla::Move(rhs.nodeToPostOrderIndex)) - , doms(mozilla::Move(rhs.doms)) - , dominatedSets(mozilla::Move(rhs.dominatedSets)) - , retainedSizes(mozilla::Move(rhs.retainedSizes)) - { - MOZ_ASSERT(this != &rhs, "self-move is not allowed"); - } - DominatorTree& operator=(DominatorTree&& rhs) { - this->~DominatorTree(); - new (this) DominatorTree(mozilla::Move(rhs)); - return *this; - } - - /** - * Construct a `DominatorTree` of the heap graph visible from `root`. The - * `root` is also used as the root of the resulting dominator tree. - * - * The resulting `DominatorTree` instance must not outlive the - * `JS::ubi::Node` graph it was constructed from. - * - * - For `JS::ubi::Node` graphs backed by the live heap graph, this means - * that the `DominatorTree`'s lifetime _must_ be contained within the - * scope of the provided `AutoCheckCannotGC` reference because a GC will - * invalidate the nodes. - * - * - For `JS::ubi::Node` graphs backed by some other offline structure - * provided by the embedder, the resulting `DominatorTree`'s lifetime is - * bounded by that offline structure's lifetime. - * - * In practice, this means that within SpiderMonkey we must treat - * `DominatorTree` as if it were backed by the live heap graph and trust - * that embedders with knowledge of the graph's implementation will do the - * Right Thing. - * - * Returns `mozilla::Nothing()` on OOM failure. It is the caller's - * responsibility to handle and report the OOM. - */ - static mozilla::Maybe - Create(JSContext* cx, AutoCheckCannotGC& noGC, const Node& root) { - JS::ubi::Vector postOrder; - PredecessorSets predecessorSets; - if (!predecessorSets.init() || !doTraversal(cx, noGC, root, postOrder, predecessorSets)) - return mozilla::Nothing(); - - MOZ_ASSERT(postOrder.length() < UINT32_MAX); - uint32_t length = postOrder.length(); - MOZ_ASSERT(postOrder[length - 1] == root); - - // From here on out we wish to avoid hash table lookups, and we use - // indices into `postOrder` instead of actual nodes wherever - // possible. This greatly improves the performance of this - // implementation, but we have to pay a little bit of upfront cost to - // convert our data structures to play along first. - - NodeToIndexMap nodeToPostOrderIndex; - if (!mapNodesToTheirIndices(postOrder, nodeToPostOrderIndex)) - return mozilla::Nothing(); - - JS::ubi::Vector> predecessorVectors; - if (!convertPredecessorSetsToVectors(root, postOrder, predecessorSets, nodeToPostOrderIndex, - predecessorVectors)) - return mozilla::Nothing(); - - JS::ubi::Vector doms; - if (!initializeDominators(doms, length)) - return mozilla::Nothing(); - - bool changed = true; - while (changed) { - changed = false; - - // Iterate over the non-root nodes in reverse post order. - for (uint32_t indexPlusOne = length - 1; indexPlusOne > 0; indexPlusOne--) { - MOZ_ASSERT(postOrder[indexPlusOne - 1] != root); - - // Take the intersection of every predecessor's dominator set; - // that is the current best guess at the immediate dominator for - // this node. - - uint32_t newIDomIdx = UNDEFINED; - - auto& predecessors = predecessorVectors[indexPlusOne - 1]; - auto range = predecessors.all(); - for ( ; !range.empty(); range.popFront()) { - auto idx = range.front(); - if (doms[idx] != UNDEFINED) { - newIDomIdx = idx; - break; - } - } - - MOZ_ASSERT(newIDomIdx != UNDEFINED, - "Because the root is initialized to dominate itself and is the first " - "node in every path, there must exist a predecessor to this node that " - "also has a dominator."); - - for ( ; !range.empty(); range.popFront()) { - auto idx = range.front(); - if (doms[idx] != UNDEFINED) - newIDomIdx = intersect(doms, newIDomIdx, idx); - } - - // If the immediate dominator changed, we will have to do - // another pass of the outer while loop to continue the forward - // dataflow. - if (newIDomIdx != doms[indexPlusOne - 1]) { - doms[indexPlusOne - 1] = newIDomIdx; - changed = true; - } - } - } - - auto maybeDominatedSets = DominatedSets::Create(doms); - if (maybeDominatedSets.isNothing()) - return mozilla::Nothing(); - - return mozilla::Some(DominatorTree(mozilla::Move(postOrder), - mozilla::Move(nodeToPostOrderIndex), - mozilla::Move(doms), - mozilla::Move(*maybeDominatedSets))); - } - - /** - * Get the root node for this dominator tree. - */ - const Node& root() const { - return postOrder[postOrder.length() - 1]; - } - - /** - * Return the immediate dominator of the given `node`. If `node` was not - * reachable from the `root` that this dominator tree was constructed from, - * then return the null `JS::ubi::Node`. - */ - Node getImmediateDominator(const Node& node) const { - assertSanity(); - auto ptr = nodeToPostOrderIndex.lookup(node); - if (!ptr) - return Node(); - - auto idx = ptr->value(); - MOZ_ASSERT(idx < postOrder.length()); - return postOrder[doms[idx]]; - } - - /** - * Get the set of nodes immediately dominated by the given `node`. If `node` - * is not a member of this dominator tree, return `Nothing`. - * - * Example usage: - * - * mozilla::Maybe range = myDominatorTree.getDominatedSet(myNode); - * if (range.isNothing()) { - * // Handle unknown node however you see fit... - * return false; - * } - * - * for (const JS::ubi::Node& dominatedNode : *range) { - * // Do something with each immediately dominated node... - * } - */ - mozilla::Maybe getDominatedSet(const Node& node) { - assertSanity(); - auto ptr = nodeToPostOrderIndex.lookup(node); - if (!ptr) - return mozilla::Nothing(); - - auto idx = ptr->value(); - MOZ_ASSERT(idx < postOrder.length()); - return mozilla::Some(dominatedSets.dominatedSet(postOrder, idx)); - } - - /** - * Get the retained size of the given `node`. The size is placed in - * `outSize`, or 0 if `node` is not a member of the dominator tree. Returns - * false on OOM failure, leaving `outSize` unchanged. - */ - MOZ_MUST_USE bool getRetainedSize(const Node& node, mozilla::MallocSizeOf mallocSizeOf, - Node::Size& outSize) { - assertSanity(); - auto ptr = nodeToPostOrderIndex.lookup(node); - if (!ptr) { - outSize = 0; - return true; - } - - if (retainedSizes.isNothing() && !computeRetainedSizes(mallocSizeOf)) - return false; - - auto idx = ptr->value(); - MOZ_ASSERT(idx < postOrder.length()); - outSize = retainedSizes.ref()[idx]; - return true; - } -}; - -} // namespace ubi -} // namespace JS - -#endif // js_UbiNodeDominatorTree_h diff --git a/android/arm64-v8a/include/spidermonkey/js/UbiNodePostOrder.h b/android/arm64-v8a/include/spidermonkey/js/UbiNodePostOrder.h deleted file mode 100644 index a5042677..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/UbiNodePostOrder.h +++ /dev/null @@ -1,191 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNodePostOrder_h -#define js_UbiNodePostOrder_h - -#include "mozilla/Attributes.h" -#include "mozilla/Maybe.h" -#include "mozilla/Move.h" - -#include "jsalloc.h" - -#include "js/UbiNode.h" -#include "js/Utility.h" -#include "js/Vector.h" - -namespace JS { -namespace ubi { - -/** - * A post-order depth-first traversal of `ubi::Node` graphs. - * - * No GC may occur while an instance of `PostOrder` is live. - * - * The `NodeVisitor` type provided to `PostOrder::traverse` must have the - * following member: - * - * bool operator()(Node& node) - * - * The node visitor method. This method is called once for each `node` - * reachable from the start set in post-order. - * - * This visitor function should return true on success, or false if an error - * occurs. A false return value terminates the traversal immediately, and - * causes `PostOrder::traverse` to return false. - * - * The `EdgeVisitor` type provided to `PostOrder::traverse` must have the - * following member: - * - * bool operator()(Node& origin, Edge& edge) - * - * The edge visitor method. This method is called once for each outgoing - * `edge` from `origin` that is reachable from the start set. - * - * NB: UNLIKE NODES, THERE IS NO GUARANTEED ORDER IN WHICH EDGES AND THEIR - * ORIGINS ARE VISITED! - * - * This visitor function should return true on success, or false if an error - * occurs. A false return value terminates the traversal immediately, and - * causes `PostOrder::traverse` to return false. - */ -struct PostOrder { - private: - struct OriginAndEdges { - Node origin; - EdgeVector edges; - - OriginAndEdges(const Node& node, EdgeVector&& edges) - : origin(node) - , edges(mozilla::Move(edges)) - { } - - OriginAndEdges(const OriginAndEdges& rhs) = delete; - OriginAndEdges& operator=(const OriginAndEdges& rhs) = delete; - - OriginAndEdges(OriginAndEdges&& rhs) - : origin(rhs.origin) - , edges(mozilla::Move(rhs.edges)) - { - MOZ_ASSERT(&rhs != this, "self-move disallowed"); - } - - OriginAndEdges& operator=(OriginAndEdges&& rhs) { - this->~OriginAndEdges(); - new (this) OriginAndEdges(mozilla::Move(rhs)); - return *this; - } - }; - - using Stack = js::Vector; - using Set = js::HashSet, js::SystemAllocPolicy>; - - JSContext* cx; - Set seen; - Stack stack; -#ifdef DEBUG - bool traversed; -#endif - - private: - MOZ_MUST_USE bool fillEdgesFromRange(EdgeVector& edges, js::UniquePtr& range) { - MOZ_ASSERT(range); - for ( ; !range->empty(); range->popFront()) { - if (!edges.append(mozilla::Move(range->front()))) - return false; - } - return true; - } - - MOZ_MUST_USE bool pushForTraversing(const Node& node) { - EdgeVector edges; - auto range = node.edges(cx, /* wantNames */ false); - return range && - fillEdgesFromRange(edges, range) && - stack.append(OriginAndEdges(node, mozilla::Move(edges))); - } - - - public: - // Construct a post-order traversal object. - // - // The traversal asserts that no GC happens in its runtime during its - // lifetime via the `AutoCheckCannotGC&` parameter. We do nothing with it, - // other than require it to exist with a lifetime that encloses our own. - PostOrder(JSContext* cx, AutoCheckCannotGC&) - : cx(cx) - , seen() - , stack() -#ifdef DEBUG - , traversed(false) -#endif - { } - - // Initialize this traversal object. Return false on OOM. - MOZ_MUST_USE bool init() { return seen.init(); } - - // Add `node` as a starting point for the traversal. You may add - // as many starting points as you like. Returns false on OOM. - MOZ_MUST_USE bool addStart(const Node& node) { - if (!seen.put(node)) - return false; - return pushForTraversing(node); - } - - // Traverse the graph in post-order, starting with the set of nodes passed - // to `addStart` and applying `onNode::operator()` for each node in the - // graph and `onEdge::operator()` for each edge in the graph, as described - // above. - // - // This should be called only once per instance of this class. - // - // Return false on OOM or error return from `onNode::operator()` or - // `onEdge::operator()`. - template - MOZ_MUST_USE bool traverse(NodeVisitor onNode, EdgeVisitor onEdge) { -#ifdef DEBUG - MOZ_ASSERT(!traversed, "Can only traverse() once!"); - traversed = true; -#endif - - while (!stack.empty()) { - auto& origin = stack.back().origin; - auto& edges = stack.back().edges; - - if (edges.empty()) { - if (!onNode(origin)) - return false; - stack.popBack(); - continue; - } - - Edge edge = mozilla::Move(edges.back()); - edges.popBack(); - - if (!onEdge(origin, edge)) - return false; - - auto ptr = seen.lookupForAdd(edge.referent); - // We've already seen this node, don't follow its edges. - if (ptr) - continue; - - // Mark the referent as seen and follow its edges. - if (!seen.add(ptr, edge.referent) || - !pushForTraversing(edge.referent)) - { - return false; - } - } - - return true; - } -}; - -} // namespace ubi -} // namespace JS - -#endif // js_UbiNodePostOrder_h diff --git a/android/arm64-v8a/include/spidermonkey/js/UbiNodeShortestPaths.h b/android/arm64-v8a/include/spidermonkey/js/UbiNodeShortestPaths.h deleted file mode 100644 index edd5aebb..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/UbiNodeShortestPaths.h +++ /dev/null @@ -1,350 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNodeShortestPaths_h -#define js_UbiNodeShortestPaths_h - -#include "mozilla/Attributes.h" -#include "mozilla/Maybe.h" -#include "mozilla/Move.h" - -#include "jsalloc.h" - -#include "js/UbiNodeBreadthFirst.h" -#include "js/Vector.h" - -namespace JS { -namespace ubi { - -/** - * A back edge along a path in the heap graph. - */ -struct JS_PUBLIC_API(BackEdge) -{ - private: - Node predecessor_; - EdgeName name_; - - public: - using Ptr = mozilla::UniquePtr>; - - BackEdge() : predecessor_(), name_(nullptr) { } - - MOZ_MUST_USE bool init(const Node& predecessor, Edge& edge) { - MOZ_ASSERT(!predecessor_); - MOZ_ASSERT(!name_); - - predecessor_ = predecessor; - name_ = mozilla::Move(edge.name); - return true; - } - - BackEdge(const BackEdge&) = delete; - BackEdge& operator=(const BackEdge&) = delete; - - BackEdge(BackEdge&& rhs) - : predecessor_(rhs.predecessor_) - , name_(mozilla::Move(rhs.name_)) - { - MOZ_ASSERT(&rhs != this); - } - - BackEdge& operator=(BackEdge&& rhs) { - this->~BackEdge(); - new(this) BackEdge(Move(rhs)); - return *this; - } - - Ptr clone() const; - - const EdgeName& name() const { return name_; } - EdgeName& name() { return name_; } - - const JS::ubi::Node& predecessor() const { return predecessor_; } -}; - -/** - * A path is a series of back edges from which we discovered a target node. - */ -using Path = JS::ubi::Vector; - -/** - * The `JS::ubi::ShortestPaths` type represents a collection of up to N shortest - * retaining paths for each of a target set of nodes, starting from the same - * root node. - */ -struct JS_PUBLIC_API(ShortestPaths) -{ - private: - // Types, type aliases, and data members. - - using BackEdgeVector = JS::ubi::Vector; - using NodeToBackEdgeVectorMap = js::HashMap, - js::SystemAllocPolicy>; - - struct Handler; - using Traversal = BreadthFirst; - - /** - * A `JS::ubi::BreadthFirst` traversal handler that records back edges for - * how we reached each node, allowing us to reconstruct the shortest - * retaining paths after the traversal. - */ - struct Handler - { - using NodeData = BackEdge; - - ShortestPaths& shortestPaths; - size_t totalMaxPathsToRecord; - size_t totalPathsRecorded; - - explicit Handler(ShortestPaths& shortestPaths) - : shortestPaths(shortestPaths) - , totalMaxPathsToRecord(shortestPaths.targets_.count() * shortestPaths.maxNumPaths_) - , totalPathsRecorded(0) - { - } - - bool - operator()(Traversal& traversal, JS::ubi::Node origin, JS::ubi::Edge& edge, - BackEdge* back, bool first) - { - MOZ_ASSERT(back); - MOZ_ASSERT(origin == shortestPaths.root_ || traversal.visited.has(origin)); - MOZ_ASSERT(totalPathsRecorded < totalMaxPathsToRecord); - - if (first && !back->init(origin, edge)) - return false; - - if (!shortestPaths.targets_.has(edge.referent)) - return true; - - // If `first` is true, then we moved the edge's name into `back` in - // the above call to `init`. So clone that back edge to get the - // correct edge name. If `first` is not true, then our edge name is - // still in `edge`. This accounts for the asymmetry between - // `back->clone()` in the first branch, and the `init` call in the - // second branch. - - if (first) { - BackEdgeVector paths; - if (!paths.reserve(shortestPaths.maxNumPaths_)) - return false; - auto cloned = back->clone(); - if (!cloned) - return false; - paths.infallibleAppend(mozilla::Move(cloned)); - if (!shortestPaths.paths_.putNew(edge.referent, mozilla::Move(paths))) - return false; - totalPathsRecorded++; - } else { - auto ptr = shortestPaths.paths_.lookup(edge.referent); - MOZ_ASSERT(ptr, - "This isn't the first time we have seen the target node `edge.referent`. " - "We should have inserted it into shortestPaths.paths_ the first time we " - "saw it."); - - if (ptr->value().length() < shortestPaths.maxNumPaths_) { - BackEdge::Ptr thisBackEdge(js_new()); - if (!thisBackEdge || !thisBackEdge->init(origin, edge)) - return false; - ptr->value().infallibleAppend(mozilla::Move(thisBackEdge)); - totalPathsRecorded++; - } - } - - MOZ_ASSERT(totalPathsRecorded <= totalMaxPathsToRecord); - if (totalPathsRecorded == totalMaxPathsToRecord) - traversal.stop(); - - return true; - } - - }; - - // The maximum number of paths to record for each node. - uint32_t maxNumPaths_; - - // The root node we are starting the search from. - Node root_; - - // The set of nodes we are searching for paths to. - NodeSet targets_; - - // The resulting paths. - NodeToBackEdgeVectorMap paths_; - - // Need to keep alive the traversal's back edges so we can walk them later - // when the traversal is over when recreating the shortest paths. - Traversal::NodeMap backEdges_; - - private: - // Private methods. - - ShortestPaths(uint32_t maxNumPaths, const Node& root, NodeSet&& targets) - : maxNumPaths_(maxNumPaths) - , root_(root) - , targets_(mozilla::Move(targets)) - , paths_() - , backEdges_() - { - MOZ_ASSERT(maxNumPaths_ > 0); - MOZ_ASSERT(root_); - MOZ_ASSERT(targets_.initialized()); - } - - bool initialized() const { - return targets_.initialized() && - paths_.initialized() && - backEdges_.initialized(); - } - - public: - // Public methods. - - ShortestPaths(ShortestPaths&& rhs) - : maxNumPaths_(rhs.maxNumPaths_) - , root_(rhs.root_) - , targets_(mozilla::Move(rhs.targets_)) - , paths_(mozilla::Move(rhs.paths_)) - , backEdges_(mozilla::Move(rhs.backEdges_)) - { - MOZ_ASSERT(this != &rhs, "self-move is not allowed"); - } - - ShortestPaths& operator=(ShortestPaths&& rhs) { - this->~ShortestPaths(); - new (this) ShortestPaths(mozilla::Move(rhs)); - return *this; - } - - ShortestPaths(const ShortestPaths&) = delete; - ShortestPaths& operator=(const ShortestPaths&) = delete; - - /** - * Construct a new `JS::ubi::ShortestPaths`, finding up to `maxNumPaths` - * shortest retaining paths for each target node in `targets` starting from - * `root`. - * - * The resulting `ShortestPaths` instance must not outlive the - * `JS::ubi::Node` graph it was constructed from. - * - * - For `JS::ubi::Node` graphs backed by the live heap graph, this means - * that the `ShortestPaths`'s lifetime _must_ be contained within the - * scope of the provided `AutoCheckCannotGC` reference because a GC will - * invalidate the nodes. - * - * - For `JS::ubi::Node` graphs backed by some other offline structure - * provided by the embedder, the resulting `ShortestPaths`'s lifetime is - * bounded by that offline structure's lifetime. - * - * Returns `mozilla::Nothing()` on OOM failure. It is the caller's - * responsibility to handle and report the OOM. - */ - static mozilla::Maybe - Create(JSContext* cx, AutoCheckCannotGC& noGC, uint32_t maxNumPaths, const Node& root, NodeSet&& targets) { - MOZ_ASSERT(targets.count() > 0); - MOZ_ASSERT(maxNumPaths > 0); - - size_t count = targets.count(); - ShortestPaths paths(maxNumPaths, root, mozilla::Move(targets)); - if (!paths.paths_.init(count)) - return mozilla::Nothing(); - - Handler handler(paths); - Traversal traversal(cx, handler, noGC); - traversal.wantNames = true; - if (!traversal.init() || !traversal.addStart(root) || !traversal.traverse()) - return mozilla::Nothing(); - - // Take ownership of the back edges we created while traversing the - // graph so that we can follow them from `paths_` and don't - // use-after-free. - paths.backEdges_ = mozilla::Move(traversal.visited); - - MOZ_ASSERT(paths.initialized()); - return mozilla::Some(mozilla::Move(paths)); - } - - /** - * Get a range that iterates over each target node we searched for retaining - * paths for. The returned range must not outlive the `ShortestPaths` - * instance. - */ - NodeSet::Range eachTarget() const { - MOZ_ASSERT(initialized()); - return targets_.all(); - } - - /** - * Invoke the provided functor/lambda/callable once for each retaining path - * discovered for `target`. The `func` is passed a single `JS::ubi::Path&` - * argument, which contains each edge along the path ordered starting from - * the root and ending at the target, and must not outlive the scope of the - * call. - * - * Note that it is possible that we did not find any paths from the root to - * the given target, in which case `func` will not be invoked. - */ - template - MOZ_MUST_USE bool forEachPath(const Node& target, Func func) { - MOZ_ASSERT(initialized()); - MOZ_ASSERT(targets_.has(target)); - - auto ptr = paths_.lookup(target); - - // We didn't find any paths to this target, so nothing to do here. - if (!ptr) - return true; - - MOZ_ASSERT(ptr->value().length() <= maxNumPaths_); - - Path path; - for (const auto& backEdge : ptr->value()) { - path.clear(); - - if (!path.append(backEdge.get())) - return false; - - Node here = backEdge->predecessor(); - MOZ_ASSERT(here); - - while (here != root_) { - auto p = backEdges_.lookup(here); - MOZ_ASSERT(p); - if (!path.append(&p->value())) - return false; - here = p->value().predecessor(); - MOZ_ASSERT(here); - } - - path.reverse(); - - if (!func(path)) - return false; - } - - return true; - } -}; - -#ifdef DEBUG -// A helper function to dump the first `maxNumPaths` shortest retaining paths to -// `node` from the GC roots. Useful when GC things you expect to have been -// reclaimed by the collector haven't been! -// -// Usage: -// -// JSObject* foo = ...; -// JS::ubi::dumpPaths(rt, JS::ubi::Node(foo)); -JS_PUBLIC_API(void) -dumpPaths(JSRuntime* rt, Node node, uint32_t maxNumPaths = 10); -#endif - -} // namespace ubi -} // namespace JS - -#endif // js_UbiNodeShortestPaths_h diff --git a/android/arm64-v8a/include/spidermonkey/js/UniquePtr.h b/android/arm64-v8a/include/spidermonkey/js/UniquePtr.h deleted file mode 100644 index 0236bab4..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/UniquePtr.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UniquePtr_h -#define js_UniquePtr_h - -#include "mozilla/UniquePtr.h" - -#include "js/Utility.h" - -namespace js { - -// Replacement for mozilla::UniquePtr that defaults to js::DefaultDelete. -template > -using UniquePtr = mozilla::UniquePtr; - -namespace detail { - -template -struct UniqueSelector -{ - typedef UniquePtr SingleObject; -}; - -template -struct UniqueSelector -{ - typedef UniquePtr UnknownBound; -}; - -template -struct UniqueSelector -{ - typedef UniquePtr KnownBound; -}; - -} // namespace detail - -// Replacement for mozilla::MakeUnique that correctly calls js_new and produces -// a js::UniquePtr. -template -typename detail::UniqueSelector::SingleObject -MakeUnique(Args&&... aArgs) -{ - return UniquePtr(js_new(mozilla::Forward(aArgs)...)); -} - -template -typename detail::UniqueSelector::UnknownBound -MakeUnique(decltype(sizeof(int)) aN) = delete; - -template -typename detail::UniqueSelector::KnownBound -MakeUnique(Args&&... aArgs) = delete; - -} // namespace js - -#endif /* js_UniquePtr_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/Utility.h b/android/arm64-v8a/include/spidermonkey/js/Utility.h deleted file mode 100644 index 75214c32..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/Utility.h +++ /dev/null @@ -1,577 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_Utility_h -#define js_Utility_h - -#include "mozilla/Assertions.h" -#include "mozilla/Atomics.h" -#include "mozilla/Attributes.h" -#include "mozilla/Compiler.h" -#include "mozilla/Move.h" -#include "mozilla/Scoped.h" -#include "mozilla/TemplateLib.h" -#include "mozilla/UniquePtr.h" - -#include -#include - -#ifdef JS_OOM_DO_BACKTRACES -#include -#include -#endif - -#include "jstypes.h" - -/* The public JS engine namespace. */ -namespace JS {} - -/* The mozilla-shared reusable template/utility namespace. */ -namespace mozilla {} - -/* The private JS engine namespace. */ -namespace js {} - -#define JS_STATIC_ASSERT(cond) static_assert(cond, "JS_STATIC_ASSERT") -#define JS_STATIC_ASSERT_IF(cond, expr) MOZ_STATIC_ASSERT_IF(cond, expr, "JS_STATIC_ASSERT_IF") - -extern MOZ_NORETURN MOZ_COLD JS_PUBLIC_API(void) -JS_Assert(const char* s, const char* file, int ln); - -/* - * Custom allocator support for SpiderMonkey - */ -#if defined JS_USE_CUSTOM_ALLOCATOR -# include "jscustomallocator.h" -#else - -namespace js { -namespace oom { - -/* - * To make testing OOM in certain helper threads more effective, - * allow restricting the OOM testing to a certain helper thread - * type. This allows us to fail e.g. in off-thread script parsing - * without causing an OOM in the main thread first. - */ -enum ThreadType { - THREAD_TYPE_NONE = 0, // 0 - THREAD_TYPE_MAIN, // 1 - THREAD_TYPE_ASMJS, // 2 - THREAD_TYPE_ION, // 3 - THREAD_TYPE_PARSE, // 4 - THREAD_TYPE_COMPRESS, // 5 - THREAD_TYPE_GCHELPER, // 6 - THREAD_TYPE_GCPARALLEL, // 7 - THREAD_TYPE_PROMISE_TASK, // 8 - THREAD_TYPE_MAX // Used to check shell function arguments -}; - -/* - * Getter/Setter functions to encapsulate mozilla::ThreadLocal, - * implementation is in jsutil.cpp. - */ -# if defined(DEBUG) || defined(JS_OOM_BREAKPOINT) -extern bool InitThreadType(void); -extern void SetThreadType(ThreadType); -extern uint32_t GetThreadType(void); -# else -inline bool InitThreadType(void) { return true; } -inline void SetThreadType(ThreadType t) {}; -inline uint32_t GetThreadType(void) { return 0; } -# endif - -} /* namespace oom */ -} /* namespace js */ - -# if defined(DEBUG) || defined(JS_OOM_BREAKPOINT) - -#ifdef JS_OOM_BREAKPOINT -static MOZ_NEVER_INLINE void js_failedAllocBreakpoint() { asm(""); } -#define JS_OOM_CALL_BP_FUNC() js_failedAllocBreakpoint() -#else -#define JS_OOM_CALL_BP_FUNC() do {} while(0) -#endif - -namespace js { -namespace oom { - -/* - * Out of memory testing support. We provide various testing functions to - * simulate OOM conditions and so we can test that they are handled correctly. - */ - -extern JS_PUBLIC_DATA(uint32_t) targetThread; -extern JS_PUBLIC_DATA(uint64_t) maxAllocations; -extern JS_PUBLIC_DATA(uint64_t) counter; -extern JS_PUBLIC_DATA(bool) failAlways; - -extern void -SimulateOOMAfter(uint64_t allocations, uint32_t thread, bool always); - -extern void -ResetSimulatedOOM(); - -inline bool -IsThreadSimulatingOOM() -{ - return js::oom::targetThread && js::oom::targetThread == js::oom::GetThreadType(); -} - -inline bool -IsSimulatedOOMAllocation() -{ - return IsThreadSimulatingOOM() && - (counter == maxAllocations || (counter > maxAllocations && failAlways)); -} - -inline bool -ShouldFailWithOOM() -{ - if (!IsThreadSimulatingOOM()) - return false; - - counter++; - if (IsSimulatedOOMAllocation()) { - JS_OOM_CALL_BP_FUNC(); - return true; - } - return false; -} - -inline bool -HadSimulatedOOM() { - return counter >= maxAllocations; -} - -} /* namespace oom */ -} /* namespace js */ - -# define JS_OOM_POSSIBLY_FAIL() \ - do { \ - if (js::oom::ShouldFailWithOOM()) \ - return nullptr; \ - } while (0) - -# define JS_OOM_POSSIBLY_FAIL_BOOL() \ - do { \ - if (js::oom::ShouldFailWithOOM()) \ - return false; \ - } while (0) - -# else - -# define JS_OOM_POSSIBLY_FAIL() do {} while(0) -# define JS_OOM_POSSIBLY_FAIL_BOOL() do {} while(0) -namespace js { -namespace oom { -static inline bool IsSimulatedOOMAllocation() { return false; } -static inline bool ShouldFailWithOOM() { return false; } -} /* namespace oom */ -} /* namespace js */ - -# endif /* DEBUG || JS_OOM_BREAKPOINT */ - -namespace js { - -/* Disable OOM testing in sections which are not OOM safe. */ -struct MOZ_RAII AutoEnterOOMUnsafeRegion -{ - MOZ_NORETURN MOZ_COLD void crash(const char* reason); - MOZ_NORETURN MOZ_COLD void crash(size_t size, const char* reason); - - using AnnotateOOMAllocationSizeCallback = void(*)(size_t); - static AnnotateOOMAllocationSizeCallback annotateOOMSizeCallback; - static void setAnnotateOOMAllocationSizeCallback(AnnotateOOMAllocationSizeCallback callback) { - annotateOOMSizeCallback = callback; - } - -#if defined(DEBUG) || defined(JS_OOM_BREAKPOINT) - AutoEnterOOMUnsafeRegion() - : oomEnabled_(oom::IsThreadSimulatingOOM() && oom::maxAllocations != UINT64_MAX), - oomAfter_(0) - { - if (oomEnabled_) { - MOZ_ALWAYS_TRUE(owner_.compareExchange(nullptr, this)); - oomAfter_ = int64_t(oom::maxAllocations) - int64_t(oom::counter); - oom::maxAllocations = UINT64_MAX; - } - } - - ~AutoEnterOOMUnsafeRegion() { - if (oomEnabled_) { - MOZ_ASSERT(oom::maxAllocations == UINT64_MAX); - int64_t maxAllocations = int64_t(oom::counter) + oomAfter_; - MOZ_ASSERT(maxAllocations >= 0, - "alloc count + oom limit exceeds range, your oom limit is probably too large"); - oom::maxAllocations = uint64_t(maxAllocations); - MOZ_ALWAYS_TRUE(owner_.compareExchange(this, nullptr)); - } - } - - private: - // Used to catch concurrent use from other threads. - static mozilla::Atomic owner_; - - bool oomEnabled_; - int64_t oomAfter_; -#endif -}; - -} /* namespace js */ - -static inline void* js_malloc(size_t bytes) -{ - JS_OOM_POSSIBLY_FAIL(); - return malloc(bytes); -} - -static inline void* js_calloc(size_t bytes) -{ - JS_OOM_POSSIBLY_FAIL(); - return calloc(bytes, 1); -} - -static inline void* js_calloc(size_t nmemb, size_t size) -{ - JS_OOM_POSSIBLY_FAIL(); - return calloc(nmemb, size); -} - -static inline void* js_realloc(void* p, size_t bytes) -{ - // realloc() with zero size is not portable, as some implementations may - // return nullptr on success and free |p| for this. We assume nullptr - // indicates failure and that |p| is still valid. - MOZ_ASSERT(bytes != 0); - - JS_OOM_POSSIBLY_FAIL(); - return realloc(p, bytes); -} - -static inline void js_free(void* p) -{ - free(p); -} - -static inline char* js_strdup(const char* s) -{ - JS_OOM_POSSIBLY_FAIL(); - return strdup(s); -} -#endif/* JS_USE_CUSTOM_ALLOCATOR */ - -#include - -/* - * Low-level memory management in SpiderMonkey: - * - * ** Do not use the standard malloc/free/realloc: SpiderMonkey allows these - * to be redefined (via JS_USE_CUSTOM_ALLOCATOR) and Gecko even #define's - * these symbols. - * - * ** Do not use the builtin C++ operator new and delete: these throw on - * error and we cannot override them not to. - * - * Allocation: - * - * - If the lifetime of the allocation is tied to the lifetime of a GC-thing - * (that is, finalizing the GC-thing will free the allocation), call one of - * the following functions: - * - * JSContext::{malloc_,realloc_,calloc_,new_} - * JSRuntime::{malloc_,realloc_,calloc_,new_} - * - * These functions accumulate the number of bytes allocated which is used as - * part of the GC-triggering heuristic. - * - * The difference between the JSContext and JSRuntime versions is that the - * cx version reports an out-of-memory error on OOM. (This follows from the - * general SpiderMonkey idiom that a JSContext-taking function reports its - * own errors.) - * - * - Otherwise, use js_malloc/js_realloc/js_calloc/js_new - * - * Deallocation: - * - * - Ordinarily, use js_free/js_delete. - * - * - For deallocations during GC finalization, use one of the following - * operations on the FreeOp provided to the finalizer: - * - * FreeOp::{free_,delete_} - * - * The advantage of these operations is that the memory is batched and freed - * on another thread. - */ - -/* - * Given a class which should provide a 'new' method, add - * JS_DECLARE_NEW_METHODS (see js::MallocProvider for an example). - * - * Note: Do not add a ; at the end of a use of JS_DECLARE_NEW_METHODS, - * or the build will break. - */ -#define JS_DECLARE_NEW_METHODS(NEWNAME, ALLOCATOR, QUALIFIERS) \ - template \ - QUALIFIERS T * \ - NEWNAME(Args&&... args) MOZ_HEAP_ALLOCATOR { \ - void* memory = ALLOCATOR(sizeof(T)); \ - return MOZ_LIKELY(memory) \ - ? new(memory) T(mozilla::Forward(args)...) \ - : nullptr; \ - } - -/* - * Given a class which should provide 'make' methods, add - * JS_DECLARE_MAKE_METHODS (see js::MallocProvider for an example). This - * method is functionally the same as JS_DECLARE_NEW_METHODS: it just declares - * methods that return mozilla::UniquePtr instances that will singly-manage - * ownership of the created object. - * - * Note: Do not add a ; at the end of a use of JS_DECLARE_MAKE_METHODS, - * or the build will break. - */ -#define JS_DECLARE_MAKE_METHODS(MAKENAME, NEWNAME, QUALIFIERS)\ - template \ - QUALIFIERS mozilla::UniquePtr> \ - MAKENAME(Args&&... args) MOZ_HEAP_ALLOCATOR { \ - T* ptr = NEWNAME(mozilla::Forward(args)...); \ - return mozilla::UniquePtr>(ptr); \ - } - -JS_DECLARE_NEW_METHODS(js_new, js_malloc, static MOZ_ALWAYS_INLINE) - -namespace js { - -/* - * Calculate the number of bytes needed to allocate |numElems| contiguous - * instances of type |T|. Return false if the calculation overflowed. - */ -template -MOZ_MUST_USE inline bool -CalculateAllocSize(size_t numElems, size_t* bytesOut) -{ - *bytesOut = numElems * sizeof(T); - return (numElems & mozilla::tl::MulOverflowMask::value) == 0; -} - -/* - * Calculate the number of bytes needed to allocate a single instance of type - * |T| followed by |numExtra| contiguous instances of type |Extra|. Return - * false if the calculation overflowed. - */ -template -MOZ_MUST_USE inline bool -CalculateAllocSizeWithExtra(size_t numExtra, size_t* bytesOut) -{ - *bytesOut = sizeof(T) + numExtra * sizeof(Extra); - return (numExtra & mozilla::tl::MulOverflowMask::value) == 0 && - *bytesOut >= sizeof(T); -} - -} /* namespace js */ - -template -static MOZ_ALWAYS_INLINE void -js_delete(const T* p) -{ - if (p) { - p->~T(); - js_free(const_cast(p)); - } -} - -template -static MOZ_ALWAYS_INLINE void -js_delete_poison(const T* p) -{ - if (p) { - p->~T(); - memset(const_cast(p), 0x3B, sizeof(T)); - js_free(const_cast(p)); - } -} - -template -static MOZ_ALWAYS_INLINE T* -js_pod_malloc() -{ - return static_cast(js_malloc(sizeof(T))); -} - -template -static MOZ_ALWAYS_INLINE T* -js_pod_calloc() -{ - return static_cast(js_calloc(sizeof(T))); -} - -template -static MOZ_ALWAYS_INLINE T* -js_pod_malloc(size_t numElems) -{ - size_t bytes; - if (MOZ_UNLIKELY(!js::CalculateAllocSize(numElems, &bytes))) - return nullptr; - return static_cast(js_malloc(bytes)); -} - -template -static MOZ_ALWAYS_INLINE T* -js_pod_calloc(size_t numElems) -{ - size_t bytes; - if (MOZ_UNLIKELY(!js::CalculateAllocSize(numElems, &bytes))) - return nullptr; - return static_cast(js_calloc(bytes)); -} - -template -static MOZ_ALWAYS_INLINE T* -js_pod_realloc(T* prior, size_t oldSize, size_t newSize) -{ - MOZ_ASSERT(!(oldSize & mozilla::tl::MulOverflowMask::value)); - size_t bytes; - if (MOZ_UNLIKELY(!js::CalculateAllocSize(newSize, &bytes))) - return nullptr; - return static_cast(js_realloc(prior, bytes)); -} - -namespace js { - -template -struct ScopedFreePtrTraits -{ - typedef T* type; - static T* empty() { return nullptr; } - static void release(T* ptr) { js_free(ptr); } -}; -SCOPED_TEMPLATE(ScopedJSFreePtr, ScopedFreePtrTraits) - -template -struct ScopedDeletePtrTraits : public ScopedFreePtrTraits -{ - static void release(T* ptr) { js_delete(ptr); } -}; -SCOPED_TEMPLATE(ScopedJSDeletePtr, ScopedDeletePtrTraits) - -template -struct ScopedReleasePtrTraits : public ScopedFreePtrTraits -{ - static void release(T* ptr) { if (ptr) ptr->release(); } -}; -SCOPED_TEMPLATE(ScopedReleasePtr, ScopedReleasePtrTraits) - -} /* namespace js */ - -namespace JS { - -template -struct DeletePolicy -{ - constexpr DeletePolicy() {} - - template - MOZ_IMPLICIT DeletePolicy(DeletePolicy other, - typename mozilla::EnableIf::value, - int>::Type dummy = 0) - {} - - void operator()(const T* ptr) { - js_delete(const_cast(ptr)); - } -}; - -struct FreePolicy -{ - void operator()(const void* ptr) { - js_free(const_cast(ptr)); - } -}; - -typedef mozilla::UniquePtr UniqueChars; -typedef mozilla::UniquePtr UniqueTwoByteChars; - -} // namespace JS - -namespace js { - -/* Integral types for all hash functions. */ -typedef uint32_t HashNumber; -const unsigned HashNumberSizeBits = 32; - -namespace detail { - -/* - * Given a raw hash code, h, return a number that can be used to select a hash - * bucket. - * - * This function aims to produce as uniform an output distribution as possible, - * especially in the most significant (leftmost) bits, even though the input - * distribution may be highly nonrandom, given the constraints that this must - * be deterministic and quick to compute. - * - * Since the leftmost bits of the result are best, the hash bucket index is - * computed by doing ScrambleHashCode(h) / (2^32/N) or the equivalent - * right-shift, not ScrambleHashCode(h) % N or the equivalent bit-mask. - * - * FIXME: OrderedHashTable uses a bit-mask; see bug 775896. - */ -inline HashNumber -ScrambleHashCode(HashNumber h) -{ - /* - * Simply returning h would not cause any hash tables to produce wrong - * answers. But it can produce pathologically bad performance: The caller - * right-shifts the result, keeping only the highest bits. The high bits of - * hash codes are very often completely entropy-free. (So are the lowest - * bits.) - * - * So we use Fibonacci hashing, as described in Knuth, The Art of Computer - * Programming, 6.4. This mixes all the bits of the input hash code h. - * - * The value of goldenRatio is taken from the hex - * expansion of the golden ratio, which starts 1.9E3779B9.... - * This value is especially good if values with consecutive hash codes - * are stored in a hash table; see Knuth for details. - */ - static const HashNumber goldenRatio = 0x9E3779B9U; - return h * goldenRatio; -} - -} /* namespace detail */ - -} /* namespace js */ - -/* sixgill annotation defines */ -#ifndef HAVE_STATIC_ANNOTATIONS -# define HAVE_STATIC_ANNOTATIONS -# ifdef XGILL_PLUGIN -# define STATIC_PRECONDITION(COND) __attribute__((precondition(#COND))) -# define STATIC_PRECONDITION_ASSUME(COND) __attribute__((precondition_assume(#COND))) -# define STATIC_POSTCONDITION(COND) __attribute__((postcondition(#COND))) -# define STATIC_POSTCONDITION_ASSUME(COND) __attribute__((postcondition_assume(#COND))) -# define STATIC_INVARIANT(COND) __attribute__((invariant(#COND))) -# define STATIC_INVARIANT_ASSUME(COND) __attribute__((invariant_assume(#COND))) -# define STATIC_ASSUME(COND) \ - JS_BEGIN_MACRO \ - __attribute__((assume_static(#COND), unused)) \ - int STATIC_PASTE1(assume_static_, __COUNTER__); \ - JS_END_MACRO -# else /* XGILL_PLUGIN */ -# define STATIC_PRECONDITION(COND) /* nothing */ -# define STATIC_PRECONDITION_ASSUME(COND) /* nothing */ -# define STATIC_POSTCONDITION(COND) /* nothing */ -# define STATIC_POSTCONDITION_ASSUME(COND) /* nothing */ -# define STATIC_INVARIANT(COND) /* nothing */ -# define STATIC_INVARIANT_ASSUME(COND) /* nothing */ -# define STATIC_ASSUME(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO -# endif /* XGILL_PLUGIN */ -# define STATIC_SKIP_INFERENCE STATIC_INVARIANT(skip_inference()) -#endif /* HAVE_STATIC_ANNOTATIONS */ - -#endif /* js_Utility_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/Value.h b/android/arm64-v8a/include/spidermonkey/js/Value.h deleted file mode 100644 index 00fdad58..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/Value.h +++ /dev/null @@ -1,1509 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* JS::Value implementation. */ - -#ifndef js_Value_h -#define js_Value_h - -#include "mozilla/Attributes.h" -#include "mozilla/Casting.h" -#include "mozilla/FloatingPoint.h" -#include "mozilla/Likely.h" - -#include /* for std::numeric_limits */ - -#include "js-config.h" -#include "jstypes.h" - -#include "js/GCAPI.h" -#include "js/RootingAPI.h" -#include "js/Utility.h" - -namespace JS { class Value; } - -/* JS::Value can store a full int32_t. */ -#define JSVAL_INT_BITS 32 -#define JSVAL_INT_MIN ((int32_t)0x80000000) -#define JSVAL_INT_MAX ((int32_t)0x7fffffff) - -#if defined(JS_PUNBOX64) -# define JSVAL_TAG_SHIFT 47 -#endif - -// Use enums so that printing a JS::Value in the debugger shows nice -// symbolic type tags. - -#if defined(_MSC_VER) -# define JS_ENUM_HEADER(id, type) enum id : type -# define JS_ENUM_FOOTER(id) -#else -# define JS_ENUM_HEADER(id, type) enum id -# define JS_ENUM_FOOTER(id) __attribute__((packed)) -#endif - -/* Remember to propagate changes to the C defines below. */ -JS_ENUM_HEADER(JSValueType, uint8_t) -{ - JSVAL_TYPE_DOUBLE = 0x00, - JSVAL_TYPE_INT32 = 0x01, - JSVAL_TYPE_UNDEFINED = 0x02, - JSVAL_TYPE_BOOLEAN = 0x03, - JSVAL_TYPE_MAGIC = 0x04, - JSVAL_TYPE_STRING = 0x05, - JSVAL_TYPE_SYMBOL = 0x06, - JSVAL_TYPE_PRIVATE_GCTHING = 0x07, - JSVAL_TYPE_NULL = 0x08, - JSVAL_TYPE_OBJECT = 0x0c, - - /* These never appear in a jsval; they are only provided as an out-of-band value. */ - JSVAL_TYPE_UNKNOWN = 0x20, - JSVAL_TYPE_MISSING = 0x21 -} JS_ENUM_FOOTER(JSValueType); - -static_assert(sizeof(JSValueType) == 1, - "compiler typed enum support is apparently buggy"); - -#if defined(JS_NUNBOX32) - -/* Remember to propagate changes to the C defines below. */ -JS_ENUM_HEADER(JSValueTag, uint32_t) -{ - JSVAL_TAG_CLEAR = 0xFFFFFF80, - JSVAL_TAG_INT32 = JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32, - JSVAL_TAG_UNDEFINED = JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED, - JSVAL_TAG_STRING = JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING, - JSVAL_TAG_SYMBOL = JSVAL_TAG_CLEAR | JSVAL_TYPE_SYMBOL, - JSVAL_TAG_BOOLEAN = JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN, - JSVAL_TAG_MAGIC = JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC, - JSVAL_TAG_NULL = JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL, - JSVAL_TAG_OBJECT = JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT, - JSVAL_TAG_PRIVATE_GCTHING = JSVAL_TAG_CLEAR | JSVAL_TYPE_PRIVATE_GCTHING -} JS_ENUM_FOOTER(JSValueTag); - -static_assert(sizeof(JSValueTag) == sizeof(uint32_t), - "compiler typed enum support is apparently buggy"); - -#elif defined(JS_PUNBOX64) - -/* Remember to propagate changes to the C defines below. */ -JS_ENUM_HEADER(JSValueTag, uint32_t) -{ - JSVAL_TAG_MAX_DOUBLE = 0x1FFF0, - JSVAL_TAG_INT32 = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_INT32, - JSVAL_TAG_UNDEFINED = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_UNDEFINED, - JSVAL_TAG_STRING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_STRING, - JSVAL_TAG_SYMBOL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_SYMBOL, - JSVAL_TAG_BOOLEAN = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN, - JSVAL_TAG_MAGIC = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC, - JSVAL_TAG_NULL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL, - JSVAL_TAG_OBJECT = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT, - JSVAL_TAG_PRIVATE_GCTHING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_PRIVATE_GCTHING -} JS_ENUM_FOOTER(JSValueTag); - -static_assert(sizeof(JSValueTag) == sizeof(uint32_t), - "compiler typed enum support is apparently buggy"); - -JS_ENUM_HEADER(JSValueShiftedTag, uint64_t) -{ - JSVAL_SHIFTED_TAG_MAX_DOUBLE = ((((uint64_t)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF), - JSVAL_SHIFTED_TAG_INT32 = (((uint64_t)JSVAL_TAG_INT32) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_UNDEFINED = (((uint64_t)JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_STRING = (((uint64_t)JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_SYMBOL = (((uint64_t)JSVAL_TAG_SYMBOL) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_BOOLEAN = (((uint64_t)JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_MAGIC = (((uint64_t)JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_NULL = (((uint64_t)JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_OBJECT = (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_PRIVATE_GCTHING = (((uint64_t)JSVAL_TAG_PRIVATE_GCTHING) << JSVAL_TAG_SHIFT) -} JS_ENUM_FOOTER(JSValueShiftedTag); - -static_assert(sizeof(JSValueShiftedTag) == sizeof(uint64_t), - "compiler typed enum support is apparently buggy"); - -#endif - -/* - * All our supported compilers implement C++11 |enum Foo : T| syntax, so don't - * expose these macros. (This macro exists *only* because gcc bug 51242 - * makes bit-fields of - * typed enums trigger a warning that can't be turned off. Don't expose it - * beyond this file!) - */ -#undef JS_ENUM_HEADER -#undef JS_ENUM_FOOTER - -#if defined(JS_NUNBOX32) - -#define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_CLEAR | (type))) - -#define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET JSVAL_TAG_NULL -#define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET JSVAL_TAG_OBJECT -#define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32 -#define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET JSVAL_TAG_STRING - -#elif defined(JS_PUNBOX64) - -#define JSVAL_PAYLOAD_MASK 0x00007FFFFFFFFFFFLL -#define JSVAL_TAG_MASK 0xFFFF800000000000LL -#define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_MAX_DOUBLE | (type))) -#define JSVAL_TYPE_TO_SHIFTED_TAG(type) (((uint64_t)JSVAL_TYPE_TO_TAG(type)) << JSVAL_TAG_SHIFT) - -#define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET JSVAL_TAG_NULL -#define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET JSVAL_TAG_OBJECT -#define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32 -#define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET JSVAL_TAG_STRING - -#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET JSVAL_SHIFTED_TAG_NULL -#define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET JSVAL_SHIFTED_TAG_OBJECT -#define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET JSVAL_SHIFTED_TAG_UNDEFINED -#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET JSVAL_SHIFTED_TAG_STRING - -#endif /* JS_PUNBOX64 */ - -typedef enum JSWhyMagic -{ - /** a hole in a native object's elements */ - JS_ELEMENTS_HOLE, - - /** there is not a pending iterator value */ - JS_NO_ITER_VALUE, - - /** exception value thrown when closing a generator */ - JS_GENERATOR_CLOSING, - - /** compiler sentinel value */ - JS_NO_CONSTANT, - - /** used in debug builds to catch tracing errors */ - JS_THIS_POISON, - - /** used in debug builds to catch tracing errors */ - JS_ARG_POISON, - - /** an empty subnode in the AST serializer */ - JS_SERIALIZE_NO_NODE, - - /** lazy arguments value on the stack */ - JS_LAZY_ARGUMENTS, - - /** optimized-away 'arguments' value */ - JS_OPTIMIZED_ARGUMENTS, - - /** magic value passed to natives to indicate construction */ - JS_IS_CONSTRUCTING, - - /** value of static block object slot */ - JS_BLOCK_NEEDS_CLONE, - - /** see class js::HashableValue */ - JS_HASH_KEY_EMPTY, - - /** error while running Ion code */ - JS_ION_ERROR, - - /** missing recover instruction result */ - JS_ION_BAILOUT, - - /** optimized out slot */ - JS_OPTIMIZED_OUT, - - /** uninitialized lexical bindings that produce ReferenceError on touch. */ - JS_UNINITIALIZED_LEXICAL, - - /** for local use */ - JS_GENERIC_MAGIC, - - JS_WHY_MAGIC_COUNT -} JSWhyMagic; - -namespace JS { - -static inline constexpr JS::Value UndefinedValue(); -static inline JS::Value PoisonedObjectValue(JSObject* obj); - -namespace detail { - -constexpr int CanonicalizedNaNSignBit = 0; -constexpr uint64_t CanonicalizedNaNSignificand = 0x8000000000000ULL; - -constexpr uint64_t CanonicalizedNaNBits = - mozilla::SpecificNaNBits::value; - -} // namespace detail - -/** - * Returns a generic quiet NaN value, with all payload bits set to zero. - * - * Among other properties, this NaN's bit pattern conforms to JS::Value's - * bit pattern restrictions. - */ -static MOZ_ALWAYS_INLINE double -GenericNaN() -{ - return mozilla::SpecificNaN(detail::CanonicalizedNaNSignBit, - detail::CanonicalizedNaNSignificand); -} - -/* MSVC with PGO miscompiles this function. */ -#if defined(_MSC_VER) -# pragma optimize("g", off) -#endif -static inline double -CanonicalizeNaN(double d) -{ - if (MOZ_UNLIKELY(mozilla::IsNaN(d))) - return GenericNaN(); - return d; -} -#if defined(_MSC_VER) -# pragma optimize("", on) -#endif - -/** - * JS::Value is the interface for a single JavaScript Engine value. A few - * general notes on JS::Value: - * - * - JS::Value has setX() and isX() members for X in - * - * { Int32, Double, String, Symbol, Boolean, Undefined, Null, Object, Magic } - * - * JS::Value also contains toX() for each of the non-singleton types. - * - * - Magic is a singleton type whose payload contains either a JSWhyMagic "reason" for - * the magic value or a uint32_t value. By providing JSWhyMagic values when - * creating and checking for magic values, it is possible to assert, at - * runtime, that only magic values with the expected reason flow through a - * particular value. For example, if cx->exception has a magic value, the - * reason must be JS_GENERATOR_CLOSING. - * - * - The JS::Value operations are preferred. The JSVAL_* operations remain for - * compatibility; they may be removed at some point. These operations mostly - * provide similar functionality. But there are a few key differences. One - * is that JS::Value gives null a separate type. - * Also, to help prevent mistakenly boxing a nullable JSObject* as an object, - * Value::setObject takes a JSObject&. (Conversely, Value::toObject returns a - * JSObject&.) A convenience member Value::setObjectOrNull is provided. - * - * - JSVAL_VOID is the same as the singleton value of the Undefined type. - * - * - Note that JS::Value is 8 bytes on 32 and 64-bit architectures. Thus, on - * 32-bit user code should avoid copying jsval/JS::Value as much as possible, - * preferring to pass by const Value&. - */ -class MOZ_NON_PARAM alignas(8) Value -{ - public: -#if defined(JS_NUNBOX32) - using PayloadType = uint32_t; -#elif defined(JS_PUNBOX64) - using PayloadType = uint64_t; -#endif - - /* - * N.B. the default constructor leaves Value unitialized. Adding a default - * constructor prevents Value from being stored in a union. - */ - Value() = default; - Value(const Value& v) = default; - - /** - * Returns false if creating a NumberValue containing the given type would - * be lossy, true otherwise. - */ - template - static bool isNumberRepresentable(const T t) { - return T(double(t)) == t; - } - - /*** Mutators ***/ - - void setNull() { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_NULL, 0); - } - - void setUndefined() { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_UNDEFINED, 0); - } - - void setInt32(int32_t i) { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_INT32, uint32_t(i)); - } - - int32_t& getInt32Ref() { - MOZ_ASSERT(isInt32()); - return data.s.payload.i32; - } - - void setDouble(double d) { - // Don't assign to data.asDouble to fix a miscompilation with - // GCC 5.2.1 and 5.3.1. See bug 1312488. - data = layout(d); - MOZ_ASSERT(isDouble()); - } - - void setNaN() { - setDouble(GenericNaN()); - } - - double& getDoubleRef() { - MOZ_ASSERT(isDouble()); - return data.asDouble; - } - - void setString(JSString* str) { - MOZ_ASSERT(uintptr_t(str) > 0x1000); - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_STRING, PayloadType(str)); - } - - void setSymbol(JS::Symbol* sym) { - MOZ_ASSERT(uintptr_t(sym) > 0x1000); - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_SYMBOL, PayloadType(sym)); - } - - void setObject(JSObject& obj) { - MOZ_ASSERT(uintptr_t(&obj) > 0x1000 || uintptr_t(&obj) == 0x48); -#if defined(JS_PUNBOX64) - // VisualStudio cannot contain parenthesized C++ style cast and shift - // inside decltype in template parameter: - // AssertionConditionType> 1))> - // It throws syntax error. - MOZ_ASSERT((((uintptr_t)&obj) >> JSVAL_TAG_SHIFT) == 0); -#endif - setObjectNoCheck(&obj); - } - - private: - void setObjectNoCheck(JSObject* obj) { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_OBJECT, PayloadType(obj)); - } - - friend inline Value PoisonedObjectValue(JSObject* obj); - - public: - void setBoolean(bool b) { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_BOOLEAN, uint32_t(b)); - } - - void setMagic(JSWhyMagic why) { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_MAGIC, uint32_t(why)); - } - - void setMagicUint32(uint32_t payload) { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_MAGIC, payload); - } - - bool setNumber(uint32_t ui) { - if (ui > JSVAL_INT_MAX) { - setDouble((double)ui); - return false; - } else { - setInt32((int32_t)ui); - return true; - } - } - - bool setNumber(double d) { - int32_t i; - if (mozilla::NumberIsInt32(d, &i)) { - setInt32(i); - return true; - } - - setDouble(d); - return false; - } - - void setObjectOrNull(JSObject* arg) { - if (arg) - setObject(*arg); - else - setNull(); - } - - void swap(Value& rhs) { - uint64_t tmp = rhs.data.asBits; - rhs.data.asBits = data.asBits; - data.asBits = tmp; - } - - private: - JSValueTag toTag() const { -#if defined(JS_NUNBOX32) - return data.s.tag; -#elif defined(JS_PUNBOX64) - return JSValueTag(data.asBits >> JSVAL_TAG_SHIFT); -#endif - } - - public: - /*** JIT-only interfaces to interact with and create raw Values ***/ -#if defined(JS_NUNBOX32) - PayloadType toNunboxPayload() const { - return data.s.payload.i32; - } - - JSValueTag toNunboxTag() const { - return data.s.tag; - } -#elif defined(JS_PUNBOX64) - const void* bitsAsPunboxPointer() const { - return reinterpret_cast(data.asBits); - } -#endif - - /*** Value type queries ***/ - - /* - * N.B. GCC, in some but not all cases, chooses to emit signed comparison - * of JSValueTag even though its underlying type has been forced to be - * uint32_t. Thus, all comparisons should explicitly cast operands to - * uint32_t. - */ - - bool isUndefined() const { -#if defined(JS_NUNBOX32) - return toTag() == JSVAL_TAG_UNDEFINED; -#elif defined(JS_PUNBOX64) - return data.asBits == JSVAL_SHIFTED_TAG_UNDEFINED; -#endif - } - - bool isNull() const { -#if defined(JS_NUNBOX32) - return toTag() == JSVAL_TAG_NULL; -#elif defined(JS_PUNBOX64) - return data.asBits == JSVAL_SHIFTED_TAG_NULL; -#endif - } - - bool isNullOrUndefined() const { - return isNull() || isUndefined(); - } - - bool isInt32() const { - return toTag() == JSVAL_TAG_INT32; - } - - bool isInt32(int32_t i32) const { - return data.asBits == bitsFromTagAndPayload(JSVAL_TAG_INT32, uint32_t(i32)); - } - - bool isDouble() const { -#if defined(JS_NUNBOX32) - return uint32_t(toTag()) <= uint32_t(JSVAL_TAG_CLEAR); -#elif defined(JS_PUNBOX64) - return (data.asBits | mozilla::DoubleTypeTraits::kSignBit) <= JSVAL_SHIFTED_TAG_MAX_DOUBLE; -#endif - } - - bool isNumber() const { -#if defined(JS_NUNBOX32) - MOZ_ASSERT(toTag() != JSVAL_TAG_CLEAR); - return uint32_t(toTag()) <= uint32_t(JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET); -#elif defined(JS_PUNBOX64) - return data.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET; -#endif - } - - bool isString() const { - return toTag() == JSVAL_TAG_STRING; - } - - bool isSymbol() const { - return toTag() == JSVAL_TAG_SYMBOL; - } - - bool isObject() const { -#if defined(JS_NUNBOX32) - return toTag() == JSVAL_TAG_OBJECT; -#elif defined(JS_PUNBOX64) - MOZ_ASSERT((data.asBits >> JSVAL_TAG_SHIFT) <= JSVAL_TAG_OBJECT); - return data.asBits >= JSVAL_SHIFTED_TAG_OBJECT; -#endif - } - - bool isPrimitive() const { -#if defined(JS_NUNBOX32) - return uint32_t(toTag()) < uint32_t(JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET); -#elif defined(JS_PUNBOX64) - return data.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET; -#endif - } - - bool isObjectOrNull() const { - MOZ_ASSERT(uint32_t(toTag()) <= uint32_t(JSVAL_TAG_OBJECT)); -#if defined(JS_NUNBOX32) - return uint32_t(toTag()) >= uint32_t(JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET); -#elif defined(JS_PUNBOX64) - return data.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET; -#endif - } - - bool isGCThing() const { -#if defined(JS_NUNBOX32) - /* gcc sometimes generates signed < without explicit casts. */ - return uint32_t(toTag()) >= uint32_t(JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET); -#elif defined(JS_PUNBOX64) - return data.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET; -#endif - } - - bool isBoolean() const { - return toTag() == JSVAL_TAG_BOOLEAN; - } - - bool isTrue() const { - return data.asBits == bitsFromTagAndPayload(JSVAL_TAG_BOOLEAN, uint32_t(true)); - } - - bool isFalse() const { - return data.asBits == bitsFromTagAndPayload(JSVAL_TAG_BOOLEAN, uint32_t(false)); - } - - bool isMagic() const { - return toTag() == JSVAL_TAG_MAGIC; - } - - bool isMagic(JSWhyMagic why) const { - MOZ_ASSERT_IF(isMagic(), data.s.payload.why == why); - return isMagic(); - } - - bool isMarkable() const { - return isGCThing() && !isNull(); - } - - JS::TraceKind traceKind() const { - MOZ_ASSERT(isMarkable()); - static_assert((JSVAL_TAG_STRING & 0x03) == size_t(JS::TraceKind::String), - "Value type tags must correspond with JS::TraceKinds."); - static_assert((JSVAL_TAG_SYMBOL & 0x03) == size_t(JS::TraceKind::Symbol), - "Value type tags must correspond with JS::TraceKinds."); - static_assert((JSVAL_TAG_OBJECT & 0x03) == size_t(JS::TraceKind::Object), - "Value type tags must correspond with JS::TraceKinds."); - if (MOZ_UNLIKELY(isPrivateGCThing())) - return JS::GCThingTraceKind(toGCThing()); - return JS::TraceKind(toTag() & 0x03); - } - - JSWhyMagic whyMagic() const { - MOZ_ASSERT(isMagic()); - return data.s.payload.why; - } - - uint32_t magicUint32() const { - MOZ_ASSERT(isMagic()); - return data.s.payload.u32; - } - - /*** Comparison ***/ - - bool operator==(const Value& rhs) const { - return data.asBits == rhs.data.asBits; - } - - bool operator!=(const Value& rhs) const { - return data.asBits != rhs.data.asBits; - } - - friend inline bool SameType(const Value& lhs, const Value& rhs); - - /*** Extract the value's typed payload ***/ - - int32_t toInt32() const { - MOZ_ASSERT(isInt32()); -#if defined(JS_NUNBOX32) - return data.s.payload.i32; -#elif defined(JS_PUNBOX64) - return int32_t(data.asBits); -#endif - } - - double toDouble() const { - MOZ_ASSERT(isDouble()); - return data.asDouble; - } - - double toNumber() const { - MOZ_ASSERT(isNumber()); - return isDouble() ? toDouble() : double(toInt32()); - } - - JSString* toString() const { - MOZ_ASSERT(isString()); -#if defined(JS_NUNBOX32) - return data.s.payload.str; -#elif defined(JS_PUNBOX64) - return reinterpret_cast(data.asBits & JSVAL_PAYLOAD_MASK); -#endif - } - - JS::Symbol* toSymbol() const { - MOZ_ASSERT(isSymbol()); -#if defined(JS_NUNBOX32) - return data.s.payload.sym; -#elif defined(JS_PUNBOX64) - return reinterpret_cast(data.asBits & JSVAL_PAYLOAD_MASK); -#endif - } - - JSObject& toObject() const { - MOZ_ASSERT(isObject()); -#if defined(JS_NUNBOX32) - return *data.s.payload.obj; -#elif defined(JS_PUNBOX64) - return *toObjectOrNull(); -#endif - } - - JSObject* toObjectOrNull() const { - MOZ_ASSERT(isObjectOrNull()); -#if defined(JS_NUNBOX32) - return data.s.payload.obj; -#elif defined(JS_PUNBOX64) - uint64_t ptrBits = data.asBits & JSVAL_PAYLOAD_MASK; - MOZ_ASSERT((ptrBits & 0x7) == 0); - return reinterpret_cast(ptrBits); -#endif - } - - js::gc::Cell* toGCThing() const { - MOZ_ASSERT(isGCThing()); -#if defined(JS_NUNBOX32) - return data.s.payload.cell; -#elif defined(JS_PUNBOX64) - uint64_t ptrBits = data.asBits & JSVAL_PAYLOAD_MASK; - MOZ_ASSERT((ptrBits & 0x7) == 0); - return reinterpret_cast(ptrBits); -#endif - } - - js::gc::Cell* toMarkablePointer() const { - MOZ_ASSERT(isMarkable()); - return toGCThing(); - } - - GCCellPtr toGCCellPtr() const { - return GCCellPtr(toGCThing(), traceKind()); - } - - bool toBoolean() const { - MOZ_ASSERT(isBoolean()); -#if defined(JS_NUNBOX32) - return bool(data.s.payload.boo); -#elif defined(JS_PUNBOX64) - return bool(data.asBits & JSVAL_PAYLOAD_MASK); -#endif - } - - uint32_t payloadAsRawUint32() const { - MOZ_ASSERT(!isDouble()); - return data.s.payload.u32; - } - - uint64_t asRawBits() const { - return data.asBits; - } - - JSValueType extractNonDoubleType() const { - uint32_t type = toTag() & 0xF; - MOZ_ASSERT(type > JSVAL_TYPE_DOUBLE); - return JSValueType(type); - } - - /* - * Private API - * - * Private setters/getters allow the caller to read/write arbitrary types - * that fit in the 64-bit payload. It is the caller's responsibility, after - * storing to a value with setPrivateX to read only using getPrivateX. - * Privates values are given a type which ensures they are not marked. - */ - - void setPrivate(void* ptr) { - MOZ_ASSERT((uintptr_t(ptr) & 1) == 0); -#if defined(JS_NUNBOX32) - data.s.tag = JSValueTag(0); - data.s.payload.ptr = ptr; -#elif defined(JS_PUNBOX64) - data.asBits = uintptr_t(ptr) >> 1; -#endif - MOZ_ASSERT(isDouble()); - } - - void* toPrivate() const { - MOZ_ASSERT(isDouble()); -#if defined(JS_NUNBOX32) - return data.s.payload.ptr; -#elif defined(JS_PUNBOX64) - MOZ_ASSERT((data.asBits & 0x8000000000000000ULL) == 0); - return reinterpret_cast(data.asBits << 1); -#endif - } - - void setPrivateUint32(uint32_t ui) { - MOZ_ASSERT(uint32_t(int32_t(ui)) == ui); - setInt32(int32_t(ui)); - } - - uint32_t toPrivateUint32() const { - return uint32_t(toInt32()); - } - - /* - * Private GC Thing API - * - * Non-JSObject, JSString, and JS::Symbol cells may be put into the 64-bit - * payload as private GC things. Such Values are considered isMarkable() - * and isGCThing(), and as such, automatically marked. Their traceKind() - * is gotten via their cells. - */ - - void setPrivateGCThing(js::gc::Cell* cell) { - MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::String, - "Private GC thing Values must not be strings. Make a StringValue instead."); - MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::Symbol, - "Private GC thing Values must not be symbols. Make a SymbolValue instead."); - MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::Object, - "Private GC thing Values must not be objects. Make an ObjectValue instead."); - - MOZ_ASSERT(uintptr_t(cell) > 0x1000); -#if defined(JS_PUNBOX64) - // VisualStudio cannot contain parenthesized C++ style cast and shift - // inside decltype in template parameter: - // AssertionConditionType> 1))> - // It throws syntax error. - MOZ_ASSERT((((uintptr_t)cell) >> JSVAL_TAG_SHIFT) == 0); -#endif - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_PRIVATE_GCTHING, PayloadType(cell)); - } - - bool isPrivateGCThing() const { - return toTag() == JSVAL_TAG_PRIVATE_GCTHING; - } - - const size_t* payloadWord() const { -#if defined(JS_NUNBOX32) - return &data.s.payload.word; -#elif defined(JS_PUNBOX64) - return &data.asWord; -#endif - } - - const uintptr_t* payloadUIntPtr() const { -#if defined(JS_NUNBOX32) - return &data.s.payload.uintptr; -#elif defined(JS_PUNBOX64) - return &data.asUIntPtr; -#endif - } - -#if !defined(_MSC_VER) && !defined(__sparc) - // Value must be POD so that MSVC will pass it by value and not in memory - // (bug 689101); the same is true for SPARC as well (bug 737344). More - // precisely, we don't want Value return values compiled as out params. - private: -#endif - -#if MOZ_LITTLE_ENDIAN -# if defined(JS_NUNBOX32) - union layout { - uint64_t asBits; - struct { - union { - int32_t i32; - uint32_t u32; - uint32_t boo; // Don't use |bool| -- it must be four bytes. - JSString* str; - JS::Symbol* sym; - JSObject* obj; - js::gc::Cell* cell; - void* ptr; - JSWhyMagic why; - size_t word; - uintptr_t uintptr; - } payload; - JSValueTag tag; - } s; - double asDouble; - void* asPtr; - - layout() = default; - explicit constexpr layout(uint64_t bits) : asBits(bits) {} - explicit constexpr layout(double d) : asDouble(d) {} - } data; -# elif defined(JS_PUNBOX64) - union layout { - uint64_t asBits; -#if !defined(_WIN64) - /* MSVC does not pack these correctly :-( */ - struct { - uint64_t payload47 : 47; - JSValueTag tag : 17; - } debugView; -#endif - struct { - union { - int32_t i32; - uint32_t u32; - JSWhyMagic why; - } payload; - } s; - double asDouble; - void* asPtr; - size_t asWord; - uintptr_t asUIntPtr; - - layout() = default; - explicit constexpr layout(uint64_t bits) : asBits(bits) {} - explicit constexpr layout(double d) : asDouble(d) {} - } data; -# endif /* JS_PUNBOX64 */ -#else /* MOZ_LITTLE_ENDIAN */ -# if defined(JS_NUNBOX32) - union layout { - uint64_t asBits; - struct { - JSValueTag tag; - union { - int32_t i32; - uint32_t u32; - uint32_t boo; // Don't use |bool| -- it must be four bytes. - JSString* str; - JS::Symbol* sym; - JSObject* obj; - js::gc::Cell* cell; - void* ptr; - JSWhyMagic why; - size_t word; - uintptr_t uintptr; - } payload; - } s; - double asDouble; - void* asPtr; - - layout() = default; - explicit constexpr layout(uint64_t bits) : asBits(bits) {} - explicit constexpr layout(double d) : asDouble(d) {} - } data; -# elif defined(JS_PUNBOX64) - union layout { - uint64_t asBits; - struct { - JSValueTag tag : 17; - uint64_t payload47 : 47; - } debugView; - struct { - uint32_t padding; - union { - int32_t i32; - uint32_t u32; - JSWhyMagic why; - } payload; - } s; - double asDouble; - void* asPtr; - size_t asWord; - uintptr_t asUIntPtr; - - layout() = default; - explicit constexpr layout(uint64_t bits) : asBits(bits) {} - explicit constexpr layout(double d) : asDouble(d) {} - } data; -# endif /* JS_PUNBOX64 */ -#endif /* MOZ_LITTLE_ENDIAN */ - - private: - explicit constexpr Value(uint64_t asBits) : data(asBits) {} - explicit constexpr Value(double d) : data(d) {} - - void staticAssertions() { - JS_STATIC_ASSERT(sizeof(JSValueType) == 1); - JS_STATIC_ASSERT(sizeof(JSValueTag) == 4); - JS_STATIC_ASSERT(sizeof(JSWhyMagic) <= 4); - JS_STATIC_ASSERT(sizeof(Value) == 8); - } - - friend constexpr Value JS::UndefinedValue(); - - public: - static constexpr uint64_t - bitsFromTagAndPayload(JSValueTag tag, PayloadType payload) - { -#if defined(JS_NUNBOX32) - return (uint64_t(uint32_t(tag)) << 32) | payload; -#elif defined(JS_PUNBOX64) - return (uint64_t(uint32_t(tag)) << JSVAL_TAG_SHIFT) | payload; -#endif - } - - static constexpr Value - fromTagAndPayload(JSValueTag tag, PayloadType payload) - { - return fromRawBits(bitsFromTagAndPayload(tag, payload)); - } - - static constexpr Value - fromRawBits(uint64_t asBits) { - return Value(asBits); - } - - static constexpr Value - fromInt32(int32_t i) { - return fromTagAndPayload(JSVAL_TAG_INT32, uint32_t(i)); - } - - static constexpr Value - fromDouble(double d) { - return Value(d); - } -} JS_HAZ_GC_POINTER; - -static_assert(sizeof(Value) == 8, "Value size must leave three tag bits, be a binary power, and is ubiquitously depended upon everywhere"); - -inline bool -IsOptimizedPlaceholderMagicValue(const Value& v) -{ - if (v.isMagic()) { - MOZ_ASSERT(v.whyMagic() == JS_OPTIMIZED_ARGUMENTS || v.whyMagic() == JS_OPTIMIZED_OUT); - return true; - } - return false; -} - -static MOZ_ALWAYS_INLINE void -ExposeValueToActiveJS(const Value& v) -{ - if (v.isMarkable()) - js::gc::ExposeGCThingToActiveJS(GCCellPtr(v)); -} - -/************************************************************************/ - -static inline Value -NullValue() -{ - Value v; - v.setNull(); - return v; -} - -static inline constexpr Value -UndefinedValue() -{ - return Value::fromTagAndPayload(JSVAL_TAG_UNDEFINED, 0); -} - -static inline constexpr Value -Int32Value(int32_t i32) -{ - return Value::fromInt32(i32); -} - -static inline Value -DoubleValue(double dbl) -{ - Value v; - v.setDouble(dbl); - return v; -} - -static inline Value -CanonicalizedDoubleValue(double d) -{ - return MOZ_UNLIKELY(mozilla::IsNaN(d)) - ? Value::fromRawBits(detail::CanonicalizedNaNBits) - : Value::fromDouble(d); -} - -static inline bool -IsCanonicalized(double d) -{ - if (mozilla::IsInfinite(d) || mozilla::IsFinite(d)) - return true; - - uint64_t bits; - mozilla::BitwiseCast(d, &bits); - return (bits & ~mozilla::DoubleTypeTraits::kSignBit) == detail::CanonicalizedNaNBits; -} - -static inline Value -DoubleNaNValue() -{ - Value v; - v.setNaN(); - return v; -} - -static inline Value -Float32Value(float f) -{ - Value v; - v.setDouble(f); - return v; -} - -static inline Value -StringValue(JSString* str) -{ - Value v; - v.setString(str); - return v; -} - -static inline Value -SymbolValue(JS::Symbol* sym) -{ - Value v; - v.setSymbol(sym); - return v; -} - -static inline Value -BooleanValue(bool boo) -{ - Value v; - v.setBoolean(boo); - return v; -} - -static inline Value -TrueValue() -{ - Value v; - v.setBoolean(true); - return v; -} - -static inline Value -FalseValue() -{ - Value v; - v.setBoolean(false); - return v; -} - -static inline Value -ObjectValue(JSObject& obj) -{ - Value v; - v.setObject(obj); - return v; -} - -static inline Value -ObjectValueCrashOnTouch() -{ - Value v; - v.setObject(*reinterpret_cast(0x48)); - return v; -} - -static inline Value -MagicValue(JSWhyMagic why) -{ - Value v; - v.setMagic(why); - return v; -} - -static inline Value -MagicValueUint32(uint32_t payload) -{ - Value v; - v.setMagicUint32(payload); - return v; -} - -static inline Value -NumberValue(float f) -{ - Value v; - v.setNumber(f); - return v; -} - -static inline Value -NumberValue(double dbl) -{ - Value v; - v.setNumber(dbl); - return v; -} - -static inline Value -NumberValue(int8_t i) -{ - return Int32Value(i); -} - -static inline Value -NumberValue(uint8_t i) -{ - return Int32Value(i); -} - -static inline Value -NumberValue(int16_t i) -{ - return Int32Value(i); -} - -static inline Value -NumberValue(uint16_t i) -{ - return Int32Value(i); -} - -static inline Value -NumberValue(int32_t i) -{ - return Int32Value(i); -} - -static inline constexpr Value -NumberValue(uint32_t i) -{ - return i <= JSVAL_INT_MAX - ? Int32Value(int32_t(i)) - : Value::fromDouble(double(i)); -} - -namespace detail { - -template -class MakeNumberValue -{ - public: - template - static inline Value create(const T t) - { - Value v; - if (JSVAL_INT_MIN <= t && t <= JSVAL_INT_MAX) - v.setInt32(int32_t(t)); - else - v.setDouble(double(t)); - return v; - } -}; - -template <> -class MakeNumberValue -{ - public: - template - static inline Value create(const T t) - { - Value v; - if (t <= JSVAL_INT_MAX) - v.setInt32(int32_t(t)); - else - v.setDouble(double(t)); - return v; - } -}; - -} // namespace detail - -template -static inline Value -NumberValue(const T t) -{ - MOZ_ASSERT(Value::isNumberRepresentable(t), "value creation would be lossy"); - return detail::MakeNumberValue::is_signed>::create(t); -} - -static inline Value -ObjectOrNullValue(JSObject* obj) -{ - Value v; - v.setObjectOrNull(obj); - return v; -} - -static inline Value -PrivateValue(void* ptr) -{ - Value v; - v.setPrivate(ptr); - return v; -} - -static inline Value -PrivateUint32Value(uint32_t ui) -{ - Value v; - v.setPrivateUint32(ui); - return v; -} - -static inline Value -PrivateGCThingValue(js::gc::Cell* cell) -{ - Value v; - v.setPrivateGCThing(cell); - return v; -} - -static inline Value -PoisonedObjectValue(JSObject* obj) -{ - Value v; - v.setObjectNoCheck(obj); - return v; -} - -inline bool -SameType(const Value& lhs, const Value& rhs) -{ -#if defined(JS_NUNBOX32) - JSValueTag ltag = lhs.toTag(), rtag = rhs.toTag(); - return ltag == rtag || (ltag < JSVAL_TAG_CLEAR && rtag < JSVAL_TAG_CLEAR); -#elif defined(JS_PUNBOX64) - return (lhs.isDouble() && rhs.isDouble()) || - (((lhs.data.asBits ^ rhs.data.asBits) & 0xFFFF800000000000ULL) == 0); -#endif -} - -} // namespace JS - -/************************************************************************/ - -namespace JS { -JS_PUBLIC_API(void) HeapValuePostBarrier(Value* valuep, const Value& prev, const Value& next); - -template <> -struct GCPolicy -{ - static Value initial() { return UndefinedValue(); } - static void trace(JSTracer* trc, Value* v, const char* name) { - js::UnsafeTraceManuallyBarrieredEdge(trc, v, name); - } - static bool isTenured(const Value& thing) { - return !thing.isGCThing() || !IsInsideNursery(thing.toGCThing()); - } -}; - -} // namespace JS - -namespace js { - -template <> -struct BarrierMethods -{ - static gc::Cell* asGCThingOrNull(const JS::Value& v) { - return v.isMarkable() ? v.toGCThing() : nullptr; - } - static void postBarrier(JS::Value* v, const JS::Value& prev, const JS::Value& next) { - JS::HeapValuePostBarrier(v, prev, next); - } - static void exposeToJS(const JS::Value& v) { - JS::ExposeValueToActiveJS(v); - } -}; - -template class MutableValueOperations; - -/** - * A class designed for CRTP use in implementing the non-mutating parts of the - * Value interface in Value-like classes. Outer must be a class inheriting - * ValueOperations with a visible get() method returning a const - * reference to the Value abstracted by Outer. - */ -template -class ValueOperations -{ - friend class MutableValueOperations; - - const JS::Value& value() const { return static_cast(this)->get(); } - - public: - bool isUndefined() const { return value().isUndefined(); } - bool isNull() const { return value().isNull(); } - bool isBoolean() const { return value().isBoolean(); } - bool isTrue() const { return value().isTrue(); } - bool isFalse() const { return value().isFalse(); } - bool isNumber() const { return value().isNumber(); } - bool isInt32() const { return value().isInt32(); } - bool isInt32(int32_t i32) const { return value().isInt32(i32); } - bool isDouble() const { return value().isDouble(); } - bool isString() const { return value().isString(); } - bool isSymbol() const { return value().isSymbol(); } - bool isObject() const { return value().isObject(); } - bool isMagic() const { return value().isMagic(); } - bool isMagic(JSWhyMagic why) const { return value().isMagic(why); } - bool isMarkable() const { return value().isMarkable(); } - bool isPrimitive() const { return value().isPrimitive(); } - bool isGCThing() const { return value().isGCThing(); } - - bool isNullOrUndefined() const { return value().isNullOrUndefined(); } - bool isObjectOrNull() const { return value().isObjectOrNull(); } - - bool toBoolean() const { return value().toBoolean(); } - double toNumber() const { return value().toNumber(); } - int32_t toInt32() const { return value().toInt32(); } - double toDouble() const { return value().toDouble(); } - JSString* toString() const { return value().toString(); } - JS::Symbol* toSymbol() const { return value().toSymbol(); } - JSObject& toObject() const { return value().toObject(); } - JSObject* toObjectOrNull() const { return value().toObjectOrNull(); } - gc::Cell* toGCThing() const { return value().toGCThing(); } - JS::TraceKind traceKind() const { return value().traceKind(); } - void* toPrivate() const { return value().toPrivate(); } - uint32_t toPrivateUint32() const { return value().toPrivateUint32(); } - - uint64_t asRawBits() const { return value().asRawBits(); } - JSValueType extractNonDoubleType() const { return value().extractNonDoubleType(); } - - JSWhyMagic whyMagic() const { return value().whyMagic(); } - uint32_t magicUint32() const { return value().magicUint32(); } -}; - -/** - * A class designed for CRTP use in implementing all the mutating parts of the - * Value interface in Value-like classes. Outer must be a class inheriting - * MutableValueOperations with visible get() methods returning const and - * non-const references to the Value abstracted by Outer. - */ -template -class MutableValueOperations : public ValueOperations -{ - JS::Value& value() { return static_cast(this)->get(); } - - public: - void setNull() { value().setNull(); } - void setUndefined() { value().setUndefined(); } - void setInt32(int32_t i) { value().setInt32(i); } - void setDouble(double d) { value().setDouble(d); } - void setNaN() { setDouble(JS::GenericNaN()); } - void setBoolean(bool b) { value().setBoolean(b); } - void setMagic(JSWhyMagic why) { value().setMagic(why); } - bool setNumber(uint32_t ui) { return value().setNumber(ui); } - bool setNumber(double d) { return value().setNumber(d); } - void setString(JSString* str) { this->value().setString(str); } - void setSymbol(JS::Symbol* sym) { this->value().setSymbol(sym); } - void setObject(JSObject& obj) { this->value().setObject(obj); } - void setObjectOrNull(JSObject* arg) { this->value().setObjectOrNull(arg); } - void setPrivate(void* ptr) { this->value().setPrivate(ptr); } - void setPrivateUint32(uint32_t ui) { this->value().setPrivateUint32(ui); } - void setPrivateGCThing(js::gc::Cell* cell) { this->value().setPrivateGCThing(cell); } -}; - -/* - * Augment the generic Heap interface when T = Value with - * type-querying, value-extracting, and mutating operations. - */ -template <> -class HeapBase : public ValueOperations > -{ - typedef JS::Heap Outer; - - friend class ValueOperations; - - void setBarriered(const JS::Value& v) { - *static_cast*>(this) = v; - } - - public: - void setNull() { setBarriered(JS::NullValue()); } - void setUndefined() { setBarriered(JS::UndefinedValue()); } - void setInt32(int32_t i) { setBarriered(JS::Int32Value(i)); } - void setDouble(double d) { setBarriered(JS::DoubleValue(d)); } - void setNaN() { setDouble(JS::GenericNaN()); } - void setBoolean(bool b) { setBarriered(JS::BooleanValue(b)); } - void setMagic(JSWhyMagic why) { setBarriered(JS::MagicValue(why)); } - void setString(JSString* str) { setBarriered(JS::StringValue(str)); } - void setSymbol(JS::Symbol* sym) { setBarriered(JS::SymbolValue(sym)); } - void setObject(JSObject& obj) { setBarriered(JS::ObjectValue(obj)); } - void setPrivateGCThing(js::gc::Cell* cell) { setBarriered(JS::PrivateGCThingValue(cell)); } - - bool setNumber(uint32_t ui) { - if (ui > JSVAL_INT_MAX) { - setDouble((double)ui); - return false; - } else { - setInt32((int32_t)ui); - return true; - } - } - - bool setNumber(double d) { - int32_t i; - if (mozilla::NumberIsInt32(d, &i)) { - setInt32(i); - return true; - } - - setDouble(d); - return false; - } - - void setObjectOrNull(JSObject* arg) { - if (arg) - setObject(*arg); - else - setNull(); - } -}; - -template <> -class HandleBase : public ValueOperations > -{}; - -template <> -class MutableHandleBase : public MutableValueOperations > -{}; - -template <> -class RootedBase : public MutableValueOperations > -{}; - -template <> -class PersistentRootedBase : public MutableValueOperations> -{}; - -/* - * If the Value is a GC pointer type, convert to that type and call |f| with - * the pointer. If the Value is not a GC type, calls F::defaultValue. - */ -template -auto -DispatchTyped(F f, const JS::Value& val, Args&&... args) - -> decltype(f(static_cast(nullptr), mozilla::Forward(args)...)) -{ - if (val.isString()) - return f(val.toString(), mozilla::Forward(args)...); - if (val.isObject()) - return f(&val.toObject(), mozilla::Forward(args)...); - if (val.isSymbol()) - return f(val.toSymbol(), mozilla::Forward(args)...); - if (MOZ_UNLIKELY(val.isPrivateGCThing())) - return DispatchTyped(f, val.toGCCellPtr(), mozilla::Forward(args)...); - MOZ_ASSERT(!val.isMarkable()); - return F::defaultValue(val); -} - -template struct VoidDefaultAdaptor { static void defaultValue(const S&) {} }; -template struct IdentityDefaultAdaptor { static S defaultValue(const S& v) {return v;} }; -template struct BoolDefaultAdaptor { static bool defaultValue(const S&) { return v; } }; - -} // namespace js - -/************************************************************************/ - -namespace JS { - -extern JS_PUBLIC_DATA(const HandleValue) NullHandleValue; -extern JS_PUBLIC_DATA(const HandleValue) UndefinedHandleValue; -extern JS_PUBLIC_DATA(const HandleValue) TrueHandleValue; -extern JS_PUBLIC_DATA(const HandleValue) FalseHandleValue; - -} // namespace JS - -#endif /* js_Value_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/Vector.h b/android/arm64-v8a/include/spidermonkey/js/Vector.h deleted file mode 100644 index 6fa63e93..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/Vector.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_Vector_h -#define js_Vector_h - -#include "mozilla/Vector.h" - -/* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */ -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4345) -#endif - -namespace js { - -class TempAllocPolicy; - -namespace detail { - -template -struct TypeIsGCThing : mozilla::FalseType -{}; - -// Uncomment this once we actually can assert it: -//template <> -//struct TypeIsGCThing : mozilla::TrueType -//{}; - -} // namespace detail - -template ::value>::Type - > -using Vector = mozilla::Vector; - -} // namespace js - -#endif /* js_Vector_h */ diff --git a/android/arm64-v8a/include/spidermonkey/js/WeakMapPtr.h b/android/arm64-v8a/include/spidermonkey/js/WeakMapPtr.h deleted file mode 100644 index 41860551..00000000 --- a/android/arm64-v8a/include/spidermonkey/js/WeakMapPtr.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_WeakMapPtr_h -#define js_WeakMapPtr_h - -#include "jspubtd.h" - -#include "js/TypeDecls.h" - -namespace JS { - -// A wrapper around the internal C++ representation of SpiderMonkey WeakMaps, -// usable outside the engine. -// -// The supported template specializations are enumerated in WeakMapPtr.cpp. If -// you want to use this class for a different key/value combination, add it to -// the list and the compiler will generate the relevant machinery. -template -class JS_PUBLIC_API(WeakMapPtr) -{ - public: - WeakMapPtr() : ptr(nullptr) {} - bool init(JSContext* cx); - bool initialized() { return ptr != nullptr; } - void destroy(); - virtual ~WeakMapPtr() { MOZ_ASSERT(!initialized()); } - void trace(JSTracer* tracer); - - V lookup(const K& key); - bool put(JSContext* cx, const K& key, const V& value); - - private: - void* ptr; - - // WeakMapPtr is neither copyable nor assignable. - WeakMapPtr(const WeakMapPtr& wmp) = delete; - WeakMapPtr& operator=(const WeakMapPtr& wmp) = delete; -}; - -} /* namespace JS */ - -#endif /* js_WeakMapPtr_h */ diff --git a/android/arm64-v8a/include/spidermonkey/jsalloc.h b/android/arm64-v8a/include/spidermonkey/jsalloc.h deleted file mode 100644 index b9ae5190..00000000 --- a/android/arm64-v8a/include/spidermonkey/jsalloc.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* - * JS allocation policies. - * - * The allocators here are for system memory with lifetimes which are not - * managed by the GC. See the comment at the top of vm/MallocProvider.h. - */ - -#ifndef jsalloc_h -#define jsalloc_h - -#include "js/TypeDecls.h" -#include "js/Utility.h" - -namespace js { - -enum class AllocFunction { - Malloc, - Calloc, - Realloc -}; - -struct ContextFriendFields; - -/* Policy for using system memory functions and doing no error reporting. */ -class SystemAllocPolicy -{ - public: - template T* maybe_pod_malloc(size_t numElems) { return js_pod_malloc(numElems); } - template T* maybe_pod_calloc(size_t numElems) { return js_pod_calloc(numElems); } - template T* maybe_pod_realloc(T* p, size_t oldSize, size_t newSize) { - return js_pod_realloc(p, oldSize, newSize); - } - template T* pod_malloc(size_t numElems) { return maybe_pod_malloc(numElems); } - template T* pod_calloc(size_t numElems) { return maybe_pod_calloc(numElems); } - template T* pod_realloc(T* p, size_t oldSize, size_t newSize) { - return maybe_pod_realloc(p, oldSize, newSize); - } - void free_(void* p) { js_free(p); } - void reportAllocOverflow() const {} - bool checkSimulatedOOM() const { - return !js::oom::ShouldFailWithOOM(); - } -}; - -class ExclusiveContext; -void ReportOutOfMemory(ExclusiveContext* cxArg); - -/* - * Allocation policy that calls the system memory functions and reports errors - * to the context. Since the JSContext given on construction is stored for - * the lifetime of the container, this policy may only be used for containers - * whose lifetime is a shorter than the given JSContext. - * - * FIXME bug 647103 - rewrite this in terms of temporary allocation functions, - * not the system ones. - */ -class TempAllocPolicy -{ - ContextFriendFields* const cx_; - - /* - * Non-inline helper to call JSRuntime::onOutOfMemory with minimal - * code bloat. - */ - JS_FRIEND_API(void*) onOutOfMemory(AllocFunction allocFunc, size_t nbytes, - void* reallocPtr = nullptr); - - template - T* onOutOfMemoryTyped(AllocFunction allocFunc, size_t numElems, void* reallocPtr = nullptr) { - size_t bytes; - if (MOZ_UNLIKELY(!CalculateAllocSize(numElems, &bytes))) - return nullptr; - return static_cast(onOutOfMemory(allocFunc, bytes, reallocPtr)); - } - - public: - MOZ_IMPLICIT TempAllocPolicy(JSContext* cx) : cx_((ContextFriendFields*) cx) {} // :( - MOZ_IMPLICIT TempAllocPolicy(ContextFriendFields* cx) : cx_(cx) {} - - template - T* maybe_pod_malloc(size_t numElems) { - return js_pod_malloc(numElems); - } - - template - T* maybe_pod_calloc(size_t numElems) { - return js_pod_calloc(numElems); - } - - template - T* maybe_pod_realloc(T* prior, size_t oldSize, size_t newSize) { - return js_pod_realloc(prior, oldSize, newSize); - } - - template - T* pod_malloc(size_t numElems) { - T* p = maybe_pod_malloc(numElems); - if (MOZ_UNLIKELY(!p)) - p = onOutOfMemoryTyped(AllocFunction::Malloc, numElems); - return p; - } - - template - T* pod_calloc(size_t numElems) { - T* p = maybe_pod_calloc(numElems); - if (MOZ_UNLIKELY(!p)) - p = onOutOfMemoryTyped(AllocFunction::Calloc, numElems); - return p; - } - - template - T* pod_realloc(T* prior, size_t oldSize, size_t newSize) { - T* p2 = maybe_pod_realloc(prior, oldSize, newSize); - if (MOZ_UNLIKELY(!p2)) - p2 = onOutOfMemoryTyped(AllocFunction::Realloc, newSize, prior); - return p2; - } - - void free_(void* p) { - js_free(p); - } - - JS_FRIEND_API(void) reportAllocOverflow() const; - - bool checkSimulatedOOM() const { - if (js::oom::ShouldFailWithOOM()) { - js::ReportOutOfMemory(reinterpret_cast(cx_)); - return false; - } - - return true; - } -}; - -} /* namespace js */ - -#endif /* jsalloc_h */ diff --git a/android/arm64-v8a/include/spidermonkey/jsapi.h b/android/arm64-v8a/include/spidermonkey/jsapi.h deleted file mode 100644 index 84d639a0..00000000 --- a/android/arm64-v8a/include/spidermonkey/jsapi.h +++ /dev/null @@ -1,6630 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* JavaScript API. */ - -#ifndef jsapi_h -#define jsapi_h - -#include "mozilla/AlreadyAddRefed.h" -#include "mozilla/FloatingPoint.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Range.h" -#include "mozilla/RangedPtr.h" -#include "mozilla/RefCounted.h" -#include "mozilla/RefPtr.h" -#include "mozilla/Variant.h" - -#include -#include -#include -#include - -#include "jsalloc.h" -#include "jspubtd.h" - -#include "js/CallArgs.h" -#include "js/CharacterEncoding.h" -#include "js/Class.h" -#include "js/GCVector.h" -#include "js/HashTable.h" -#include "js/Id.h" -#include "js/Principals.h" -#include "js/Realm.h" -#include "js/RootingAPI.h" -#include "js/TracingAPI.h" -#include "js/Utility.h" -#include "js/Value.h" -#include "js/Vector.h" - -/************************************************************************/ - -namespace JS { - -class TwoByteChars; - -#ifdef JS_DEBUG - -class JS_PUBLIC_API(AutoCheckRequestDepth) -{ - JSContext* cx; - public: - explicit AutoCheckRequestDepth(JSContext* cx); - explicit AutoCheckRequestDepth(js::ContextFriendFields* cx); - ~AutoCheckRequestDepth(); -}; - -# define CHECK_REQUEST(cx) \ - JS::AutoCheckRequestDepth _autoCheckRequestDepth(cx) - -#else - -# define CHECK_REQUEST(cx) \ - ((void) 0) - -#endif /* JS_DEBUG */ - -/** AutoValueArray roots an internal fixed-size array of Values. */ -template -class MOZ_RAII AutoValueArray : public AutoGCRooter -{ - const size_t length_; - Value elements_[N]; - - public: - explicit AutoValueArray(JSContext* cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, VALARRAY), length_(N) - { - /* Always initialize in case we GC before assignment. */ - mozilla::PodArrayZero(elements_); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - unsigned length() const { return length_; } - const Value* begin() const { return elements_; } - Value* begin() { return elements_; } - - HandleValue operator[](unsigned i) const { - MOZ_ASSERT(i < N); - return HandleValue::fromMarkedLocation(&elements_[i]); - } - MutableHandleValue operator[](unsigned i) { - MOZ_ASSERT(i < N); - return MutableHandleValue::fromMarkedLocation(&elements_[i]); - } - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -template -class MOZ_RAII AutoVectorRooterBase : protected AutoGCRooter -{ - typedef js::Vector VectorImpl; - VectorImpl vector; - - public: - explicit AutoVectorRooterBase(JSContext* cx, ptrdiff_t tag - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, tag), vector(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - explicit AutoVectorRooterBase(js::ContextFriendFields* cx, ptrdiff_t tag - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, tag), vector(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - typedef T ElementType; - typedef typename VectorImpl::Range Range; - - size_t length() const { return vector.length(); } - bool empty() const { return vector.empty(); } - - MOZ_MUST_USE bool append(const T& v) { return vector.append(v); } - MOZ_MUST_USE bool appendN(const T& v, size_t len) { return vector.appendN(v, len); } - MOZ_MUST_USE bool append(const T* ptr, size_t len) { return vector.append(ptr, len); } - MOZ_MUST_USE bool appendAll(const AutoVectorRooterBase& other) { - return vector.appendAll(other.vector); - } - - MOZ_MUST_USE bool insert(T* p, const T& val) { return vector.insert(p, val); } - - /* For use when space has already been reserved. */ - void infallibleAppend(const T& v) { vector.infallibleAppend(v); } - - void popBack() { vector.popBack(); } - T popCopy() { return vector.popCopy(); } - - MOZ_MUST_USE bool growBy(size_t inc) { - size_t oldLength = vector.length(); - if (!vector.growByUninitialized(inc)) - return false; - makeRangeGCSafe(oldLength); - return true; - } - - MOZ_MUST_USE bool resize(size_t newLength) { - size_t oldLength = vector.length(); - if (newLength <= oldLength) { - vector.shrinkBy(oldLength - newLength); - return true; - } - if (!vector.growByUninitialized(newLength - oldLength)) - return false; - makeRangeGCSafe(oldLength); - return true; - } - - void clear() { vector.clear(); } - - MOZ_MUST_USE bool reserve(size_t newLength) { - return vector.reserve(newLength); - } - - JS::MutableHandle operator[](size_t i) { - return JS::MutableHandle::fromMarkedLocation(&vector[i]); - } - JS::Handle operator[](size_t i) const { - return JS::Handle::fromMarkedLocation(&vector[i]); - } - - const T* begin() const { return vector.begin(); } - T* begin() { return vector.begin(); } - - const T* end() const { return vector.end(); } - T* end() { return vector.end(); } - - Range all() { return vector.all(); } - - const T& back() const { return vector.back(); } - - friend void AutoGCRooter::trace(JSTracer* trc); - - private: - void makeRangeGCSafe(size_t oldLength) { - T* t = vector.begin() + oldLength; - for (size_t i = oldLength; i < vector.length(); ++i, ++t) - memset(t, 0, sizeof(T)); - } - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -template -class MOZ_RAII AutoVectorRooter : public AutoVectorRooterBase -{ - public: - explicit AutoVectorRooter(JSContext* cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoVectorRooterBase(cx, this->GetTag(T())) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - explicit AutoVectorRooter(js::ContextFriendFields* cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoVectorRooterBase(cx, this->GetTag(T())) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class AutoValueVector : public Rooted> { - using Vec = GCVector; - using Base = Rooted; - public: - explicit AutoValueVector(JSContext* cx) : Base(cx, Vec(cx)) {} - explicit AutoValueVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {} -}; - -class AutoIdVector : public Rooted> { - using Vec = GCVector; - using Base = Rooted; - public: - explicit AutoIdVector(JSContext* cx) : Base(cx, Vec(cx)) {} - explicit AutoIdVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {} - - bool appendAll(const AutoIdVector& other) { return this->Base::appendAll(other.get()); } -}; - -class AutoObjectVector : public Rooted> { - using Vec = GCVector; - using Base = Rooted; - public: - explicit AutoObjectVector(JSContext* cx) : Base(cx, Vec(cx)) {} - explicit AutoObjectVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {} -}; - -using ValueVector = JS::GCVector; -using IdVector = JS::GCVector; -using ScriptVector = JS::GCVector; -using StringVector = JS::GCVector; - -template -class MOZ_RAII AutoHashMapRooter : protected AutoGCRooter -{ - private: - typedef js::HashMap HashMapImpl; - - public: - explicit AutoHashMapRooter(JSContext* cx, ptrdiff_t tag - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, tag), map(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - typedef Key KeyType; - typedef Value ValueType; - typedef typename HashMapImpl::Entry Entry; - typedef typename HashMapImpl::Lookup Lookup; - typedef typename HashMapImpl::Ptr Ptr; - typedef typename HashMapImpl::AddPtr AddPtr; - - bool init(uint32_t len = 16) { - return map.init(len); - } - bool initialized() const { - return map.initialized(); - } - Ptr lookup(const Lookup& l) const { - return map.lookup(l); - } - void remove(Ptr p) { - map.remove(p); - } - AddPtr lookupForAdd(const Lookup& l) const { - return map.lookupForAdd(l); - } - - template - bool add(AddPtr& p, const KeyInput& k, const ValueInput& v) { - return map.add(p, k, v); - } - - bool add(AddPtr& p, const Key& k) { - return map.add(p, k); - } - - template - bool relookupOrAdd(AddPtr& p, const KeyInput& k, const ValueInput& v) { - return map.relookupOrAdd(p, k, v); - } - - typedef typename HashMapImpl::Range Range; - Range all() const { - return map.all(); - } - - typedef typename HashMapImpl::Enum Enum; - - void clear() { - map.clear(); - } - - void finish() { - map.finish(); - } - - bool empty() const { - return map.empty(); - } - - uint32_t count() const { - return map.count(); - } - - size_t capacity() const { - return map.capacity(); - } - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return map.sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return map.sizeOfIncludingThis(mallocSizeOf); - } - - /************************************************** Shorthand operations */ - - bool has(const Lookup& l) const { - return map.has(l); - } - - template - bool put(const KeyInput& k, const ValueInput& v) { - return map.put(k, v); - } - - template - bool putNew(const KeyInput& k, const ValueInput& v) { - return map.putNew(k, v); - } - - Ptr lookupWithDefault(const Key& k, const Value& defaultValue) { - return map.lookupWithDefault(k, defaultValue); - } - - void remove(const Lookup& l) { - map.remove(l); - } - - friend void AutoGCRooter::trace(JSTracer* trc); - - private: - AutoHashMapRooter(const AutoHashMapRooter& hmr) = delete; - AutoHashMapRooter& operator=(const AutoHashMapRooter& hmr) = delete; - - HashMapImpl map; - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -template -class MOZ_RAII AutoHashSetRooter : protected AutoGCRooter -{ - private: - typedef js::HashSet HashSetImpl; - - public: - explicit AutoHashSetRooter(JSContext* cx, ptrdiff_t tag - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, tag), set(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - typedef typename HashSetImpl::Lookup Lookup; - typedef typename HashSetImpl::Ptr Ptr; - typedef typename HashSetImpl::AddPtr AddPtr; - - bool init(uint32_t len = 16) { - return set.init(len); - } - bool initialized() const { - return set.initialized(); - } - Ptr lookup(const Lookup& l) const { - return set.lookup(l); - } - void remove(Ptr p) { - set.remove(p); - } - AddPtr lookupForAdd(const Lookup& l) const { - return set.lookupForAdd(l); - } - - bool add(AddPtr& p, const T& t) { - return set.add(p, t); - } - - bool relookupOrAdd(AddPtr& p, const Lookup& l, const T& t) { - return set.relookupOrAdd(p, l, t); - } - - typedef typename HashSetImpl::Range Range; - Range all() const { - return set.all(); - } - - typedef typename HashSetImpl::Enum Enum; - - void clear() { - set.clear(); - } - - void finish() { - set.finish(); - } - - bool empty() const { - return set.empty(); - } - - uint32_t count() const { - return set.count(); - } - - size_t capacity() const { - return set.capacity(); - } - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return set.sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return set.sizeOfIncludingThis(mallocSizeOf); - } - - /************************************************** Shorthand operations */ - - bool has(const Lookup& l) const { - return set.has(l); - } - - bool put(const T& t) { - return set.put(t); - } - - bool putNew(const T& t) { - return set.putNew(t); - } - - void remove(const Lookup& l) { - set.remove(l); - } - - friend void AutoGCRooter::trace(JSTracer* trc); - - private: - AutoHashSetRooter(const AutoHashSetRooter& hmr) = delete; - AutoHashSetRooter& operator=(const AutoHashSetRooter& hmr) = delete; - - HashSetImpl set; - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -/** - * Custom rooting behavior for internal and external clients. - */ -class MOZ_RAII JS_PUBLIC_API(CustomAutoRooter) : private AutoGCRooter -{ - public: - template - explicit CustomAutoRooter(const CX& cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, CUSTOM) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - friend void AutoGCRooter::trace(JSTracer* trc); - - protected: - virtual ~CustomAutoRooter() {} - - /** Supplied by derived class to trace roots. */ - virtual void trace(JSTracer* trc) = 0; - - private: - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -/** A handle to an array of rooted values. */ -class HandleValueArray -{ - const size_t length_; - const Value * const elements_; - - HandleValueArray(size_t len, const Value* elements) : length_(len), elements_(elements) {} - - public: - explicit HandleValueArray(const RootedValue& value) : length_(1), elements_(value.address()) {} - - MOZ_IMPLICIT HandleValueArray(const AutoValueVector& values) - : length_(values.length()), elements_(values.begin()) {} - - template - MOZ_IMPLICIT HandleValueArray(const AutoValueArray& values) : length_(N), elements_(values.begin()) {} - - /** CallArgs must already be rooted somewhere up the stack. */ - MOZ_IMPLICIT HandleValueArray(const JS::CallArgs& args) : length_(args.length()), elements_(args.array()) {} - - /** Use with care! Only call this if the data is guaranteed to be marked. */ - static HandleValueArray fromMarkedLocation(size_t len, const Value* elements) { - return HandleValueArray(len, elements); - } - - static HandleValueArray subarray(const HandleValueArray& values, size_t startIndex, size_t len) { - MOZ_ASSERT(startIndex + len <= values.length()); - return HandleValueArray(len, values.begin() + startIndex); - } - - static HandleValueArray empty() { - return HandleValueArray(0, nullptr); - } - - size_t length() const { return length_; } - const Value* begin() const { return elements_; } - - HandleValue operator[](size_t i) const { - MOZ_ASSERT(i < length_); - return HandleValue::fromMarkedLocation(&elements_[i]); - } -}; - -} /* namespace JS */ - -/************************************************************************/ - -struct JSFreeOp { - protected: - JSRuntime* runtime_; - - explicit JSFreeOp(JSRuntime* rt) - : runtime_(rt) { } - - public: - JSRuntime* runtime() const { - MOZ_ASSERT(runtime_); - return runtime_; - } -}; - -/* Callbacks and their arguments. */ - -/************************************************************************/ - -typedef enum JSGCStatus { - JSGC_BEGIN, - JSGC_END -} JSGCStatus; - -typedef void -(* JSGCCallback)(JSContext* cx, JSGCStatus status, void* data); - -typedef void -(* JSObjectsTenuredCallback)(JSContext* cx, void* data); - -typedef enum JSFinalizeStatus { - /** - * Called when preparing to sweep a group of zones, before anything has been - * swept. The collector will not yield to the mutator before calling the - * callback with JSFINALIZE_GROUP_END status. - */ - JSFINALIZE_GROUP_START, - - /** - * Called when preparing to sweep a group of zones. Weak references to - * unmarked things have been removed and things that are not swept - * incrementally have been finalized at this point. The collector may yield - * to the mutator after this point. - */ - JSFINALIZE_GROUP_END, - - /** - * Called at the end of collection when everything has been swept. - */ - JSFINALIZE_COLLECTION_END -} JSFinalizeStatus; - -typedef void -(* JSFinalizeCallback)(JSFreeOp* fop, JSFinalizeStatus status, bool isZoneGC, void* data); - -typedef void -(* JSWeakPointerZoneGroupCallback)(JSContext* cx, void* data); - -typedef void -(* JSWeakPointerCompartmentCallback)(JSContext* cx, JSCompartment* comp, void* data); - -typedef bool -(* JSInterruptCallback)(JSContext* cx); - -typedef JSObject* -(* JSGetIncumbentGlobalCallback)(JSContext* cx); - -typedef bool -(* JSEnqueuePromiseJobCallback)(JSContext* cx, JS::HandleObject job, - JS::HandleObject allocationSite, JS::HandleObject incumbentGlobal, - void* data); - -enum class PromiseRejectionHandlingState { - Unhandled, - Handled -}; - -typedef void -(* JSPromiseRejectionTrackerCallback)(JSContext* cx, JS::HandleObject promise, - PromiseRejectionHandlingState state, void* data); - -typedef void -(* JSProcessPromiseCallback)(JSContext* cx, JS::HandleObject promise); - -/** - * Possible exception types. These types are part of a JSErrorFormatString - * structure. They define which error to throw in case of a runtime error. - * - * JSEXN_WARN is used for warnings in js.msg files (for instance because we - * don't want to prepend 'Error:' to warning messages). This value can go away - * if we ever decide to use an entirely separate mechanism for warnings. - */ -typedef enum JSExnType { - JSEXN_ERR, - JSEXN_FIRST = JSEXN_ERR, - JSEXN_INTERNALERR, - JSEXN_EVALERR, - JSEXN_RANGEERR, - JSEXN_REFERENCEERR, - JSEXN_SYNTAXERR, - JSEXN_TYPEERR, - JSEXN_URIERR, - JSEXN_DEBUGGEEWOULDRUN, - JSEXN_WASMCOMPILEERROR, - JSEXN_WASMRUNTIMEERROR, - JSEXN_WARN, - JSEXN_LIMIT -} JSExnType; - -typedef struct JSErrorFormatString { - /** The error message name in ASCII. */ - const char* name; - - /** The error format string in ASCII. */ - const char* format; - - /** The number of arguments to expand in the formatted error message. */ - uint16_t argCount; - - /** One of the JSExnType constants above. */ - int16_t exnType; -} JSErrorFormatString; - -typedef const JSErrorFormatString* -(* JSErrorCallback)(void* userRef, const unsigned errorNumber); - -typedef bool -(* JSLocaleToUpperCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval); - -typedef bool -(* JSLocaleToLowerCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval); - -typedef bool -(* JSLocaleCompare)(JSContext* cx, JS::HandleString src1, JS::HandleString src2, - JS::MutableHandleValue rval); - -typedef bool -(* JSLocaleToUnicode)(JSContext* cx, const char* src, JS::MutableHandleValue rval); - -/** - * Callback used to ask the embedding for the cross compartment wrapper handler - * that implements the desired prolicy for this kind of object in the - * destination compartment. |obj| is the object to be wrapped. If |existing| is - * non-nullptr, it will point to an existing wrapper object that should be - * re-used if possible. |existing| is guaranteed to be a cross-compartment - * wrapper with a lazily-defined prototype and the correct global. It is - * guaranteed not to wrap a function. - */ -typedef JSObject* -(* JSWrapObjectCallback)(JSContext* cx, JS::HandleObject existing, JS::HandleObject obj); - -/** - * Callback used by the wrap hook to ask the embedding to prepare an object - * for wrapping in a context. This might include unwrapping other wrappers - * or even finding a more suitable object for the new compartment. - */ -typedef void -(* JSPreWrapCallback)(JSContext* cx, JS::HandleObject scope, JS::HandleObject obj, - JS::HandleObject objectPassedToWrap, - JS::MutableHandleObject retObj); - -struct JSWrapObjectCallbacks -{ - JSWrapObjectCallback wrap; - JSPreWrapCallback preWrap; -}; - -typedef void -(* JSDestroyCompartmentCallback)(JSFreeOp* fop, JSCompartment* compartment); - -typedef size_t -(* JSSizeOfIncludingThisCompartmentCallback)(mozilla::MallocSizeOf mallocSizeOf, - JSCompartment* compartment); - -typedef void -(* JSZoneCallback)(JS::Zone* zone); - -typedef void -(* JSCompartmentNameCallback)(JSContext* cx, JSCompartment* compartment, - char* buf, size_t bufsize); - -/************************************************************************/ - -static MOZ_ALWAYS_INLINE JS::Value -JS_NumberValue(double d) -{ - int32_t i; - d = JS::CanonicalizeNaN(d); - if (mozilla::NumberIsInt32(d, &i)) - return JS::Int32Value(i); - return JS::DoubleValue(d); -} - -/************************************************************************/ - -JS_PUBLIC_API(bool) -JS_StringHasBeenPinned(JSContext* cx, JSString* str); - -namespace JS { - -/** - * Container class for passing in script source buffers to the JS engine. This - * not only groups the buffer and length values, it also provides a way to - * optionally pass ownership of the buffer to the JS engine without copying. - * Rules for use: - * - * 1) The data array must be allocated with js_malloc() or js_realloc() if - * ownership is being granted to the SourceBufferHolder. - * 2) If ownership is not given to the SourceBufferHolder, then the memory - * must be kept alive until the JS compilation is complete. - * 3) Any code calling SourceBufferHolder::take() must guarantee to keep the - * memory alive until JS compilation completes. Normally only the JS - * engine should be calling take(). - * - * Example use: - * - * size_t length = 512; - * char16_t* chars = static_cast(js_malloc(sizeof(char16_t) * length)); - * JS::SourceBufferHolder srcBuf(chars, length, JS::SourceBufferHolder::GiveOwnership); - * JS::Compile(cx, options, srcBuf); - */ -class MOZ_STACK_CLASS SourceBufferHolder final -{ - public: - enum Ownership { - NoOwnership, - GiveOwnership - }; - - SourceBufferHolder(const char16_t* data, size_t dataLength, Ownership ownership) - : data_(data), - length_(dataLength), - ownsChars_(ownership == GiveOwnership) - { - // Ensure that null buffers properly return an unowned, empty, - // null-terminated string. - static const char16_t NullChar_ = 0; - if (!get()) { - data_ = &NullChar_; - length_ = 0; - ownsChars_ = false; - } - } - - SourceBufferHolder(SourceBufferHolder&& other) - : data_(other.data_), - length_(other.length_), - ownsChars_(other.ownsChars_) - { - other.data_ = nullptr; - other.length_ = 0; - other.ownsChars_ = false; - } - - ~SourceBufferHolder() { - if (ownsChars_) - js_free(const_cast(data_)); - } - - // Access the underlying source buffer without affecting ownership. - const char16_t* get() const { return data_; } - - // Length of the source buffer in char16_t code units (not bytes) - size_t length() const { return length_; } - - // Returns true if the SourceBufferHolder owns the buffer and will free - // it upon destruction. If true, it is legal to call take(). - bool ownsChars() const { return ownsChars_; } - - // Retrieve and take ownership of the underlying data buffer. The caller - // is now responsible for calling js_free() on the returned value, *but only - // after JS script compilation has completed*. - // - // After the buffer has been taken the SourceBufferHolder functions as if - // it had been constructed on an unowned buffer; get() and length() still - // work. In order for this to be safe the taken buffer must be kept alive - // until after JS script compilation completes as noted above. - // - // Note, it's the caller's responsibility to check ownsChars() before taking - // the buffer. Taking and then free'ing an unowned buffer will have dire - // consequences. - char16_t* take() { - MOZ_ASSERT(ownsChars_); - ownsChars_ = false; - return const_cast(data_); - } - - private: - SourceBufferHolder(SourceBufferHolder&) = delete; - SourceBufferHolder& operator=(SourceBufferHolder&) = delete; - - const char16_t* data_; - size_t length_; - bool ownsChars_; -}; - -} /* namespace JS */ - -/************************************************************************/ - -/* Property attributes, set in JSPropertySpec and passed to API functions. - * - * NB: The data structure in which some of these values are stored only uses - * a uint8_t to store the relevant information. Proceed with caution if - * trying to reorder or change the the first byte worth of flags. - */ -#define JSPROP_ENUMERATE 0x01 /* property is visible to for/in loop */ -#define JSPROP_READONLY 0x02 /* not settable: assignment is no-op. - This flag is only valid when neither - JSPROP_GETTER nor JSPROP_SETTER is - set. */ -#define JSPROP_PERMANENT 0x04 /* property cannot be deleted */ -#define JSPROP_PROPOP_ACCESSORS 0x08 /* Passed to JS_Define(UC)Property* and - JS_DefineElement if getters/setters - are JSGetterOp/JSSetterOp */ -#define JSPROP_GETTER 0x10 /* property holds getter function */ -#define JSPROP_SETTER 0x20 /* property holds setter function */ -#define JSPROP_SHARED 0x40 /* don't allocate a value slot for this - property; don't copy the property on - set of the same-named property in an - object that delegates to a prototype - containing this property */ -#define JSPROP_INTERNAL_USE_BIT 0x80 /* internal JS engine use only */ -#define JSFUN_STUB_GSOPS 0x200 /* use JS_PropertyStub getter/setter - instead of defaulting to class gsops - for property holding function */ - -#define JSFUN_CONSTRUCTOR 0x400 /* native that can be called as a ctor */ - -// 0x800 /* Unused */ - -#define JSFUN_HAS_REST 0x1000 /* function has ...rest parameter. */ - -#define JSFUN_FLAGS_MASK 0x1e00 /* | of all the JSFUN_* flags */ - -/* - * If set, will allow redefining a non-configurable property, but only on a - * non-DOM global. This is a temporary hack that will need to go away in bug - * 1105518. - */ -#define JSPROP_REDEFINE_NONCONFIGURABLE 0x1000 - -/* - * Resolve hooks and enumerate hooks must pass this flag when calling - * JS_Define* APIs to reify lazily-defined properties. - * - * JSPROP_RESOLVING is used only with property-defining APIs. It tells the - * engine to skip the resolve hook when performing the lookup at the beginning - * of property definition. This keeps the resolve hook from accidentally - * triggering itself: unchecked recursion. - * - * For enumerate hooks, triggering the resolve hook would be merely silly, not - * fatal, except in some cases involving non-configurable properties. - */ -#define JSPROP_RESOLVING 0x2000 - -#define JSPROP_IGNORE_ENUMERATE 0x4000 /* ignore the value in JSPROP_ENUMERATE. - This flag only valid when defining over - an existing property. */ -#define JSPROP_IGNORE_READONLY 0x8000 /* ignore the value in JSPROP_READONLY. - This flag only valid when defining over - an existing property. */ -#define JSPROP_IGNORE_PERMANENT 0x10000 /* ignore the value in JSPROP_PERMANENT. - This flag only valid when defining over - an existing property. */ -#define JSPROP_IGNORE_VALUE 0x20000 /* ignore the Value in the descriptor. Nothing was - specified when passed to Object.defineProperty - from script. */ - -/** Microseconds since the epoch, midnight, January 1, 1970 UTC. */ -extern JS_PUBLIC_API(int64_t) -JS_Now(void); - -/** Don't want to export data, so provide accessors for non-inline Values. */ -extern JS_PUBLIC_API(JS::Value) -JS_GetNaNValue(JSContext* cx); - -extern JS_PUBLIC_API(JS::Value) -JS_GetNegativeInfinityValue(JSContext* cx); - -extern JS_PUBLIC_API(JS::Value) -JS_GetPositiveInfinityValue(JSContext* cx); - -extern JS_PUBLIC_API(JS::Value) -JS_GetEmptyStringValue(JSContext* cx); - -extern JS_PUBLIC_API(JSString*) -JS_GetEmptyString(JSContext* cx); - -extern JS_PUBLIC_API(bool) -JS_ValueToObject(JSContext* cx, JS::HandleValue v, JS::MutableHandleObject objp); - -extern JS_PUBLIC_API(JSFunction*) -JS_ValueToFunction(JSContext* cx, JS::HandleValue v); - -extern JS_PUBLIC_API(JSFunction*) -JS_ValueToConstructor(JSContext* cx, JS::HandleValue v); - -extern JS_PUBLIC_API(JSString*) -JS_ValueToSource(JSContext* cx, JS::Handle v); - -extern JS_PUBLIC_API(bool) -JS_DoubleIsInt32(double d, int32_t* ip); - -extern JS_PUBLIC_API(JSType) -JS_TypeOfValue(JSContext* cx, JS::Handle v); - -namespace JS { - -extern JS_PUBLIC_API(const char*) -InformalValueTypeName(const JS::Value& v); - -} /* namespace JS */ - -extern JS_PUBLIC_API(bool) -JS_StrictlyEqual(JSContext* cx, JS::Handle v1, JS::Handle v2, bool* equal); - -extern JS_PUBLIC_API(bool) -JS_LooselyEqual(JSContext* cx, JS::Handle v1, JS::Handle v2, bool* equal); - -extern JS_PUBLIC_API(bool) -JS_SameValue(JSContext* cx, JS::Handle v1, JS::Handle v2, bool* same); - -/** True iff fun is the global eval function. */ -extern JS_PUBLIC_API(bool) -JS_IsBuiltinEvalFunction(JSFunction* fun); - -/** True iff fun is the Function constructor. */ -extern JS_PUBLIC_API(bool) -JS_IsBuiltinFunctionConstructor(JSFunction* fun); - -/************************************************************************/ - -/* - * Locking, contexts, and memory allocation. - * - * It is important that SpiderMonkey be initialized, and the first context - * be created, in a single-threaded fashion. Otherwise the behavior of the - * library is undefined. - * See: http://developer.mozilla.org/en/docs/Category:JSAPI_Reference - */ - -extern JS_PUBLIC_API(JSContext*) -JS_NewContext(uint32_t maxbytes, - uint32_t maxNurseryBytes = JS::DefaultNurseryBytes, - JSContext* parentContext = nullptr); - -extern JS_PUBLIC_API(void) -JS_DestroyContext(JSContext* cx); - -typedef double (*JS_CurrentEmbedderTimeFunction)(); - -/** - * The embedding can specify a time function that will be used in some - * situations. The function can return the time however it likes; but - * the norm is to return times in units of milliseconds since an - * arbitrary, but consistent, epoch. If the time function is not set, - * a built-in default will be used. - */ -JS_PUBLIC_API(void) -JS_SetCurrentEmbedderTimeFunction(JS_CurrentEmbedderTimeFunction timeFn); - -/** - * Return the time as computed using the current time function, or a - * suitable default if one has not been set. - */ -JS_PUBLIC_API(double) -JS_GetCurrentEmbedderTime(); - -JS_PUBLIC_API(void*) -JS_GetContextPrivate(JSContext* cx); - -JS_PUBLIC_API(void) -JS_SetContextPrivate(JSContext* cx, void* data); - -extern JS_PUBLIC_API(JSContext*) -JS_GetParentContext(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_BeginRequest(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_EndRequest(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_SetFutexCanWait(JSContext* cx); - -namespace js { - -void -AssertHeapIsIdle(JSRuntime* rt); - -} /* namespace js */ - -class MOZ_RAII JSAutoRequest -{ - public: - explicit JSAutoRequest(JSContext* cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mContext(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - JS_BeginRequest(mContext); - } - ~JSAutoRequest() { - JS_EndRequest(mContext); - } - - protected: - JSContext* mContext; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - -#if 0 - private: - static void* operator new(size_t) CPP_THROW_NEW { return 0; } - static void operator delete(void*, size_t) { } -#endif -}; - -extern JS_PUBLIC_API(JSVersion) -JS_GetVersion(JSContext* cx); - -/** - * Mutate the version on the compartment. This is generally discouraged, but - * necessary to support the version mutation in the js and xpc shell command - * set. - * - * It would be nice to put this in jsfriendapi, but the linkage requirements - * of the shells make that impossible. - */ -JS_PUBLIC_API(void) -JS_SetVersionForCompartment(JSCompartment* compartment, JSVersion version); - -extern JS_PUBLIC_API(const char*) -JS_VersionToString(JSVersion version); - -extern JS_PUBLIC_API(JSVersion) -JS_StringToVersion(const char* string); - -namespace JS { - -class JS_PUBLIC_API(ContextOptions) { - public: - ContextOptions() - : baseline_(true), - ion_(true), - asmJS_(true), - wasm_(false), - wasmAlwaysBaseline_(false), - throwOnAsmJSValidationFailure_(false), - nativeRegExp_(true), - unboxedArrays_(false), - asyncStack_(true), - throwOnDebuggeeWouldRun_(true), - dumpStackOnDebuggeeWouldRun_(false), - werror_(false), - strictMode_(false), - extraWarnings_(false) - { - } - - bool baseline() const { return baseline_; } - ContextOptions& setBaseline(bool flag) { - baseline_ = flag; - return *this; - } - ContextOptions& toggleBaseline() { - baseline_ = !baseline_; - return *this; - } - - bool ion() const { return ion_; } - ContextOptions& setIon(bool flag) { - ion_ = flag; - return *this; - } - ContextOptions& toggleIon() { - ion_ = !ion_; - return *this; - } - - bool asmJS() const { return asmJS_; } - ContextOptions& setAsmJS(bool flag) { - asmJS_ = flag; - return *this; - } - ContextOptions& toggleAsmJS() { - asmJS_ = !asmJS_; - return *this; - } - - bool wasm() const { return wasm_; } - ContextOptions& setWasm(bool flag) { - wasm_ = flag; - return *this; - } - ContextOptions& toggleWasm() { - wasm_ = !wasm_; - return *this; - } - - bool wasmAlwaysBaseline() const { return wasmAlwaysBaseline_; } - ContextOptions& setWasmAlwaysBaseline(bool flag) { - wasmAlwaysBaseline_ = flag; - return *this; - } - ContextOptions& toggleWasmAlwaysBaseline() { - wasmAlwaysBaseline_ = !wasmAlwaysBaseline_; - return *this; - } - - bool throwOnAsmJSValidationFailure() const { return throwOnAsmJSValidationFailure_; } - ContextOptions& setThrowOnAsmJSValidationFailure(bool flag) { - throwOnAsmJSValidationFailure_ = flag; - return *this; - } - ContextOptions& toggleThrowOnAsmJSValidationFailure() { - throwOnAsmJSValidationFailure_ = !throwOnAsmJSValidationFailure_; - return *this; - } - - bool nativeRegExp() const { return nativeRegExp_; } - ContextOptions& setNativeRegExp(bool flag) { - nativeRegExp_ = flag; - return *this; - } - - bool unboxedArrays() const { return unboxedArrays_; } - ContextOptions& setUnboxedArrays(bool flag) { - unboxedArrays_ = flag; - return *this; - } - - bool asyncStack() const { return asyncStack_; } - ContextOptions& setAsyncStack(bool flag) { - asyncStack_ = flag; - return *this; - } - - bool throwOnDebuggeeWouldRun() const { return throwOnDebuggeeWouldRun_; } - ContextOptions& setThrowOnDebuggeeWouldRun(bool flag) { - throwOnDebuggeeWouldRun_ = flag; - return *this; - } - - bool dumpStackOnDebuggeeWouldRun() const { return dumpStackOnDebuggeeWouldRun_; } - ContextOptions& setDumpStackOnDebuggeeWouldRun(bool flag) { - dumpStackOnDebuggeeWouldRun_ = flag; - return *this; - } - - bool werror() const { return werror_; } - ContextOptions& setWerror(bool flag) { - werror_ = flag; - return *this; - } - ContextOptions& toggleWerror() { - werror_ = !werror_; - return *this; - } - - bool strictMode() const { return strictMode_; } - ContextOptions& setStrictMode(bool flag) { - strictMode_ = flag; - return *this; - } - ContextOptions& toggleStrictMode() { - strictMode_ = !strictMode_; - return *this; - } - - bool extraWarnings() const { return extraWarnings_; } - ContextOptions& setExtraWarnings(bool flag) { - extraWarnings_ = flag; - return *this; - } - ContextOptions& toggleExtraWarnings() { - extraWarnings_ = !extraWarnings_; - return *this; - } - - private: - bool baseline_ : 1; - bool ion_ : 1; - bool asmJS_ : 1; - bool wasm_ : 1; - bool wasmAlwaysBaseline_ : 1; - bool throwOnAsmJSValidationFailure_ : 1; - bool nativeRegExp_ : 1; - bool unboxedArrays_ : 1; - bool asyncStack_ : 1; - bool throwOnDebuggeeWouldRun_ : 1; - bool dumpStackOnDebuggeeWouldRun_ : 1; - bool werror_ : 1; - bool strictMode_ : 1; - bool extraWarnings_ : 1; -}; - -JS_PUBLIC_API(ContextOptions&) -ContextOptionsRef(JSContext* cx); - -/** - * Initialize the runtime's self-hosted code. Embeddings should call this - * exactly once per runtime/context, before the first JS_NewGlobalObject - * call. - */ -JS_PUBLIC_API(bool) -InitSelfHostedCode(JSContext* cx); - -/** - * Asserts (in debug and release builds) that `obj` belongs to the current - * thread's context. - */ -JS_PUBLIC_API(void) -AssertObjectBelongsToCurrentThread(JSObject* obj); - -} /* namespace JS */ - -extern JS_PUBLIC_API(const char*) -JS_GetImplementationVersion(void); - -extern JS_PUBLIC_API(void) -JS_SetDestroyCompartmentCallback(JSContext* cx, JSDestroyCompartmentCallback callback); - -extern JS_PUBLIC_API(void) -JS_SetSizeOfIncludingThisCompartmentCallback(JSContext* cx, - JSSizeOfIncludingThisCompartmentCallback callback); - -extern JS_PUBLIC_API(void) -JS_SetDestroyZoneCallback(JSContext* cx, JSZoneCallback callback); - -extern JS_PUBLIC_API(void) -JS_SetSweepZoneCallback(JSContext* cx, JSZoneCallback callback); - -extern JS_PUBLIC_API(void) -JS_SetCompartmentNameCallback(JSContext* cx, JSCompartmentNameCallback callback); - -extern JS_PUBLIC_API(void) -JS_SetWrapObjectCallbacks(JSContext* cx, const JSWrapObjectCallbacks* callbacks); - -extern JS_PUBLIC_API(void) -JS_SetCompartmentPrivate(JSCompartment* compartment, void* data); - -extern JS_PUBLIC_API(void*) -JS_GetCompartmentPrivate(JSCompartment* compartment); - -extern JS_PUBLIC_API(void) -JS_SetZoneUserData(JS::Zone* zone, void* data); - -extern JS_PUBLIC_API(void*) -JS_GetZoneUserData(JS::Zone* zone); - -extern JS_PUBLIC_API(bool) -JS_WrapObject(JSContext* cx, JS::MutableHandleObject objp); - -extern JS_PUBLIC_API(bool) -JS_WrapValue(JSContext* cx, JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(JSObject*) -JS_TransplantObject(JSContext* cx, JS::HandleObject origobj, JS::HandleObject target); - -extern JS_PUBLIC_API(bool) -JS_RefreshCrossCompartmentWrappers(JSContext* cx, JS::Handle obj); - -/* - * At any time, a JSContext has a current (possibly-nullptr) compartment. - * Compartments are described in: - * - * developer.mozilla.org/en-US/docs/SpiderMonkey/SpiderMonkey_compartments - * - * The current compartment of a context may be changed. The preferred way to do - * this is with JSAutoCompartment: - * - * void foo(JSContext* cx, JSObject* obj) { - * // in some compartment 'c' - * { - * JSAutoCompartment ac(cx, obj); // constructor enters - * // in the compartment of 'obj' - * } // destructor leaves - * // back in compartment 'c' - * } - * - * For more complicated uses that don't neatly fit in a C++ stack frame, the - * compartment can entered and left using separate function calls: - * - * void foo(JSContext* cx, JSObject* obj) { - * // in 'oldCompartment' - * JSCompartment* oldCompartment = JS_EnterCompartment(cx, obj); - * // in the compartment of 'obj' - * JS_LeaveCompartment(cx, oldCompartment); - * // back in 'oldCompartment' - * } - * - * Note: these calls must still execute in a LIFO manner w.r.t all other - * enter/leave calls on the context. Furthermore, only the return value of a - * JS_EnterCompartment call may be passed as the 'oldCompartment' argument of - * the corresponding JS_LeaveCompartment call. - */ - -class MOZ_RAII JS_PUBLIC_API(JSAutoCompartment) -{ - JSContext* cx_; - JSCompartment* oldCompartment_; - public: - JSAutoCompartment(JSContext* cx, JSObject* target - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - JSAutoCompartment(JSContext* cx, JSScript* target - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - ~JSAutoCompartment(); - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class MOZ_RAII JS_PUBLIC_API(JSAutoNullableCompartment) -{ - JSContext* cx_; - JSCompartment* oldCompartment_; - public: - explicit JSAutoNullableCompartment(JSContext* cx, JSObject* targetOrNull - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - ~JSAutoNullableCompartment(); - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -/** NB: This API is infallible; a nullptr return value does not indicate error. */ -extern JS_PUBLIC_API(JSCompartment*) -JS_EnterCompartment(JSContext* cx, JSObject* target); - -extern JS_PUBLIC_API(void) -JS_LeaveCompartment(JSContext* cx, JSCompartment* oldCompartment); - -typedef void (*JSIterateCompartmentCallback)(JSContext* cx, void* data, JSCompartment* compartment); - -/** - * This function calls |compartmentCallback| on every compartment. Beware that - * there is no guarantee that the compartment will survive after the callback - * returns. Also, barriers are disabled via the TraceSession. - */ -extern JS_PUBLIC_API(void) -JS_IterateCompartments(JSContext* cx, void* data, - JSIterateCompartmentCallback compartmentCallback); - -/** - * Initialize standard JS class constructors, prototypes, and any top-level - * functions and constants associated with the standard classes (e.g. isNaN - * for Number). - * - * NB: This sets cx's global object to obj if it was null. - */ -extern JS_PUBLIC_API(bool) -JS_InitStandardClasses(JSContext* cx, JS::Handle obj); - -/** - * Resolve id, which must contain either a string or an int, to a standard - * class name in obj if possible, defining the class's constructor and/or - * prototype and storing true in *resolved. If id does not name a standard - * class or a top-level property induced by initializing a standard class, - * store false in *resolved and just return true. Return false on error, - * as usual for bool result-typed API entry points. - * - * This API can be called directly from a global object class's resolve op, - * to define standard classes lazily. The class's enumerate op should call - * JS_EnumerateStandardClasses(cx, obj), to define eagerly during for..in - * loops any classes not yet resolved lazily. - */ -extern JS_PUBLIC_API(bool) -JS_ResolveStandardClass(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolved); - -extern JS_PUBLIC_API(bool) -JS_MayResolveStandardClass(const JSAtomState& names, jsid id, JSObject* maybeObj); - -extern JS_PUBLIC_API(bool) -JS_EnumerateStandardClasses(JSContext* cx, JS::HandleObject obj); - -extern JS_PUBLIC_API(bool) -JS_GetClassObject(JSContext* cx, JSProtoKey key, JS::MutableHandle objp); - -extern JS_PUBLIC_API(bool) -JS_GetClassPrototype(JSContext* cx, JSProtoKey key, JS::MutableHandle objp); - -namespace JS { - -/* - * Determine if the given object is an instance/prototype/constructor for a standard - * class. If so, return the associated JSProtoKey. If not, return JSProto_Null. - */ - -extern JS_PUBLIC_API(JSProtoKey) -IdentifyStandardInstance(JSObject* obj); - -extern JS_PUBLIC_API(JSProtoKey) -IdentifyStandardPrototype(JSObject* obj); - -extern JS_PUBLIC_API(JSProtoKey) -IdentifyStandardInstanceOrPrototype(JSObject* obj); - -extern JS_PUBLIC_API(JSProtoKey) -IdentifyStandardConstructor(JSObject* obj); - -extern JS_PUBLIC_API(void) -ProtoKeyToId(JSContext* cx, JSProtoKey key, JS::MutableHandleId idp); - -} /* namespace JS */ - -extern JS_PUBLIC_API(JSProtoKey) -JS_IdToProtoKey(JSContext* cx, JS::HandleId id); - -/** - * Returns the original value of |Function.prototype| from the global object in - * which |forObj| was created. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetFunctionPrototype(JSContext* cx, JS::HandleObject forObj); - -/** - * Returns the original value of |Object.prototype| from the global object in - * which |forObj| was created. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetObjectPrototype(JSContext* cx, JS::HandleObject forObj); - -/** - * Returns the original value of |Array.prototype| from the global object in - * which |forObj| was created. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetArrayPrototype(JSContext* cx, JS::HandleObject forObj); - -/** - * Returns the original value of |Error.prototype| from the global - * object of the current compartment of cx. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetErrorPrototype(JSContext* cx); - -/** - * Returns the %IteratorPrototype% object that all built-in iterator prototype - * chains go through for the global object of the current compartment of cx. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetIteratorPrototype(JSContext* cx); - -extern JS_PUBLIC_API(JSObject*) -JS_GetGlobalForObject(JSContext* cx, JSObject* obj); - -extern JS_PUBLIC_API(bool) -JS_IsGlobalObject(JSObject* obj); - -extern JS_PUBLIC_API(JSObject*) -JS_GlobalLexicalEnvironment(JSObject* obj); - -extern JS_PUBLIC_API(bool) -JS_HasExtensibleLexicalEnvironment(JSObject* obj); - -extern JS_PUBLIC_API(JSObject*) -JS_ExtensibleLexicalEnvironment(JSObject* obj); - -/** - * May return nullptr, if |c| never had a global (e.g. the atoms compartment), - * or if |c|'s global has been collected. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetGlobalForCompartmentOrNull(JSContext* cx, JSCompartment* c); - -namespace JS { - -extern JS_PUBLIC_API(JSObject*) -CurrentGlobalOrNull(JSContext* cx); - -} // namespace JS - -/** - * Add 'Reflect.parse', a SpiderMonkey extension, to the Reflect object on the - * given global. - */ -extern JS_PUBLIC_API(bool) -JS_InitReflectParse(JSContext* cx, JS::HandleObject global); - -/** - * Add various profiling-related functions as properties of the given object. - * Defined in builtin/Profilers.cpp. - */ -extern JS_PUBLIC_API(bool) -JS_DefineProfilingFunctions(JSContext* cx, JS::HandleObject obj); - -/* Defined in vm/Debugger.cpp. */ -extern JS_PUBLIC_API(bool) -JS_DefineDebuggerObject(JSContext* cx, JS::HandleObject obj); - -#ifdef JS_HAS_CTYPES -/** - * Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes' - * object will be sealed. - */ -extern JS_PUBLIC_API(bool) -JS_InitCTypesClass(JSContext* cx, JS::HandleObject global); - -/** - * Convert a unicode string 'source' of length 'slen' to the platform native - * charset, returning a null-terminated string allocated with JS_malloc. On - * failure, this function should report an error. - */ -typedef char* -(* JSCTypesUnicodeToNativeFun)(JSContext* cx, const char16_t* source, size_t slen); - -/** - * Set of function pointers that ctypes can use for various internal functions. - * See JS_SetCTypesCallbacks below. Providing nullptr for a function is safe, - * and will result in the applicable ctypes functionality not being available. - */ -struct JSCTypesCallbacks { - JSCTypesUnicodeToNativeFun unicodeToNative; -}; - -typedef struct JSCTypesCallbacks JSCTypesCallbacks; - -/** - * Set the callbacks on the provided 'ctypesObj' object. 'callbacks' should be a - * pointer to static data that exists for the lifetime of 'ctypesObj', but it - * may safely be altered after calling this function and without having - * to call this function again. - */ -extern JS_PUBLIC_API(void) -JS_SetCTypesCallbacks(JSObject* ctypesObj, const JSCTypesCallbacks* callbacks); -#endif - -extern JS_PUBLIC_API(void*) -JS_malloc(JSContext* cx, size_t nbytes); - -extern JS_PUBLIC_API(void*) -JS_realloc(JSContext* cx, void* p, size_t oldBytes, size_t newBytes); - -/** - * A wrapper for js_free(p) that may delay js_free(p) invocation as a - * performance optimization. - * cx may be nullptr. - */ -extern JS_PUBLIC_API(void) -JS_free(JSContext* cx, void* p); - -/** - * A wrapper for js_free(p) that may delay js_free(p) invocation as a - * performance optimization as specified by the given JSFreeOp instance. - */ -extern JS_PUBLIC_API(void) -JS_freeop(JSFreeOp* fop, void* p); - -extern JS_PUBLIC_API(void) -JS_updateMallocCounter(JSContext* cx, size_t nbytes); - -extern JS_PUBLIC_API(char*) -JS_strdup(JSContext* cx, const char* s); - -/** - * Register externally maintained GC roots. - * - * traceOp: the trace operation. For each root the implementation should call - * JS::TraceEdge whenever the root contains a traceable thing. - * data: the data argument to pass to each invocation of traceOp. - */ -extern JS_PUBLIC_API(bool) -JS_AddExtraGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data); - -/** Undo a call to JS_AddExtraGCRootsTracer. */ -extern JS_PUBLIC_API(void) -JS_RemoveExtraGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data); - -/* - * Garbage collector API. - */ -extern JS_PUBLIC_API(void) -JS_GC(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_MaybeGC(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_SetGCCallback(JSContext* cx, JSGCCallback cb, void* data); - -extern JS_PUBLIC_API(void) -JS_SetObjectsTenuredCallback(JSContext* cx, JSObjectsTenuredCallback cb, - void* data); - -extern JS_PUBLIC_API(bool) -JS_AddFinalizeCallback(JSContext* cx, JSFinalizeCallback cb, void* data); - -extern JS_PUBLIC_API(void) -JS_RemoveFinalizeCallback(JSContext* cx, JSFinalizeCallback cb); - -/* - * Weak pointers and garbage collection - * - * Weak pointers are by their nature not marked as part of garbage collection, - * but they may need to be updated in two cases after a GC: - * - * 1) Their referent was found not to be live and is about to be finalized - * 2) Their referent has been moved by a compacting GC - * - * To handle this, any part of the system that maintain weak pointers to - * JavaScript GC things must register a callback with - * JS_(Add,Remove)WeakPointer{ZoneGroup,Compartment}Callback(). This callback - * must then call JS_UpdateWeakPointerAfterGC() on all weak pointers it knows - * about. - * - * Since sweeping is incremental, we have several callbacks to avoid repeatedly - * having to visit all embedder structures. The WeakPointerZoneGroupCallback is - * called once for each strongly connected group of zones, whereas the - * WeakPointerCompartmentCallback is called once for each compartment that is - * visited while sweeping. Structures that cannot contain references in more - * than one compartment should sweep the relevant per-compartment structures - * using the latter callback to minimizer per-slice overhead. - * - * The argument to JS_UpdateWeakPointerAfterGC() is an in-out param. If the - * referent is about to be finalized the pointer will be set to null. If the - * referent has been moved then the pointer will be updated to point to the new - * location. - * - * Callers of this method are responsible for updating any state that is - * dependent on the object's address. For example, if the object's address is - * used as a key in a hashtable, then the object must be removed and - * re-inserted with the correct hash. - */ - -extern JS_PUBLIC_API(bool) -JS_AddWeakPointerZoneGroupCallback(JSContext* cx, JSWeakPointerZoneGroupCallback cb, void* data); - -extern JS_PUBLIC_API(void) -JS_RemoveWeakPointerZoneGroupCallback(JSContext* cx, JSWeakPointerZoneGroupCallback cb); - -extern JS_PUBLIC_API(bool) -JS_AddWeakPointerCompartmentCallback(JSContext* cx, JSWeakPointerCompartmentCallback cb, - void* data); - -extern JS_PUBLIC_API(void) -JS_RemoveWeakPointerCompartmentCallback(JSContext* cx, JSWeakPointerCompartmentCallback cb); - -extern JS_PUBLIC_API(void) -JS_UpdateWeakPointerAfterGC(JS::Heap* objp); - -extern JS_PUBLIC_API(void) -JS_UpdateWeakPointerAfterGCUnbarriered(JSObject** objp); - -typedef enum JSGCParamKey { - /** Maximum nominal heap before last ditch GC. */ - JSGC_MAX_BYTES = 0, - - /** Number of JS_malloc bytes before last ditch GC. */ - JSGC_MAX_MALLOC_BYTES = 1, - - /** Amount of bytes allocated by the GC. */ - JSGC_BYTES = 3, - - /** Number of times GC has been invoked. Includes both major and minor GC. */ - JSGC_NUMBER = 4, - - /** Select GC mode. */ - JSGC_MODE = 6, - - /** Number of cached empty GC chunks. */ - JSGC_UNUSED_CHUNKS = 7, - - /** Total number of allocated GC chunks. */ - JSGC_TOTAL_CHUNKS = 8, - - /** Max milliseconds to spend in an incremental GC slice. */ - JSGC_SLICE_TIME_BUDGET = 9, - - /** Maximum size the GC mark stack can grow to. */ - JSGC_MARK_STACK_LIMIT = 10, - - /** - * GCs less than this far apart in time will be considered 'high-frequency GCs'. - * See setGCLastBytes in jsgc.cpp. - */ - JSGC_HIGH_FREQUENCY_TIME_LIMIT = 11, - - /** Start of dynamic heap growth. */ - JSGC_HIGH_FREQUENCY_LOW_LIMIT = 12, - - /** End of dynamic heap growth. */ - JSGC_HIGH_FREQUENCY_HIGH_LIMIT = 13, - - /** Upper bound of heap growth. */ - JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX = 14, - - /** Lower bound of heap growth. */ - JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN = 15, - - /** Heap growth for low frequency GCs. */ - JSGC_LOW_FREQUENCY_HEAP_GROWTH = 16, - - /** - * If false, the heap growth factor is fixed at 3. If true, it is determined - * based on whether GCs are high- or low- frequency. - */ - JSGC_DYNAMIC_HEAP_GROWTH = 17, - - /** If true, high-frequency GCs will use a longer mark slice. */ - JSGC_DYNAMIC_MARK_SLICE = 18, - - /** Lower limit after which we limit the heap growth. */ - JSGC_ALLOCATION_THRESHOLD = 19, - - /** - * We try to keep at least this many unused chunks in the free chunk pool at - * all times, even after a shrinking GC. - */ - JSGC_MIN_EMPTY_CHUNK_COUNT = 21, - - /** We never keep more than this many unused chunks in the free chunk pool. */ - JSGC_MAX_EMPTY_CHUNK_COUNT = 22, - - /** Whether compacting GC is enabled. */ - JSGC_COMPACTING_ENABLED = 23, - - /** If true, painting can trigger IGC slices. */ - JSGC_REFRESH_FRAME_SLICES_ENABLED = 24, -} JSGCParamKey; - -extern JS_PUBLIC_API(void) -JS_SetGCParameter(JSContext* cx, JSGCParamKey key, uint32_t value); - -extern JS_PUBLIC_API(uint32_t) -JS_GetGCParameter(JSContext* cx, JSGCParamKey key); - -extern JS_PUBLIC_API(void) -JS_SetGCParametersBasedOnAvailableMemory(JSContext* cx, uint32_t availMem); - -/** - * Create a new JSString whose chars member refers to external memory, i.e., - * memory requiring application-specific finalization. - */ -extern JS_PUBLIC_API(JSString*) -JS_NewExternalString(JSContext* cx, const char16_t* chars, size_t length, - const JSStringFinalizer* fin); - -/** - * Return whether 'str' was created with JS_NewExternalString or - * JS_NewExternalStringWithClosure. - */ -extern JS_PUBLIC_API(bool) -JS_IsExternalString(JSString* str); - -/** - * Return the 'fin' arg passed to JS_NewExternalString. - */ -extern JS_PUBLIC_API(const JSStringFinalizer*) -JS_GetExternalStringFinalizer(JSString* str); - -/** - * Set the size of the native stack that should not be exceed. To disable - * stack size checking pass 0. - * - * SpiderMonkey allows for a distinction between system code (such as GCs, which - * may incidentally be triggered by script but are not strictly performed on - * behalf of such script), trusted script (as determined by JS_SetTrustedPrincipals), - * and untrusted script. Each kind of code may have a different stack quota, - * allowing embedders to keep higher-priority machinery running in the face of - * scripted stack exhaustion by something else. - * - * The stack quotas for each kind of code should be monotonically descending, - * and may be specified with this function. If 0 is passed for a given kind - * of code, it defaults to the value of the next-highest-priority kind. - * - * This function may only be called immediately after the runtime is initialized - * and before any code is executed and/or interrupts requested. - */ -extern JS_PUBLIC_API(void) -JS_SetNativeStackQuota(JSContext* cx, size_t systemCodeStackSize, - size_t trustedScriptStackSize = 0, - size_t untrustedScriptStackSize = 0); - -/************************************************************************/ - -extern JS_PUBLIC_API(bool) -JS_ValueToId(JSContext* cx, JS::HandleValue v, JS::MutableHandleId idp); - -extern JS_PUBLIC_API(bool) -JS_StringToId(JSContext* cx, JS::HandleString s, JS::MutableHandleId idp); - -extern JS_PUBLIC_API(bool) -JS_IdToValue(JSContext* cx, jsid id, JS::MutableHandle vp); - -namespace JS { - -/** - * Convert obj to a primitive value. On success, store the result in vp and - * return true. - * - * The hint argument must be JSTYPE_STRING, JSTYPE_NUMBER, or JSTYPE_VOID (no - * hint). - * - * Implements: ES6 7.1.1 ToPrimitive(input, [PreferredType]). - */ -extern JS_PUBLIC_API(bool) -ToPrimitive(JSContext* cx, JS::HandleObject obj, JSType hint, JS::MutableHandleValue vp); - -/** - * If args.get(0) is one of the strings "string", "number", or "default", set - * *result to JSTYPE_STRING, JSTYPE_NUMBER, or JSTYPE_VOID accordingly and - * return true. Otherwise, return false with a TypeError pending. - * - * This can be useful in implementing a @@toPrimitive method. - */ -extern JS_PUBLIC_API(bool) -GetFirstArgumentAsTypeHint(JSContext* cx, CallArgs args, JSType *result); - -} /* namespace JS */ - -extern JS_PUBLIC_API(bool) -JS_PropertyStub(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(bool) -JS_StrictPropertyStub(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp, JS::ObjectOpResult& result); - -template -struct JSConstScalarSpec { - const char* name; - T val; -}; - -typedef JSConstScalarSpec JSConstDoubleSpec; -typedef JSConstScalarSpec JSConstIntegerSpec; - -struct JSJitInfo; - -/** - * Wrapper to relace JSNative for JSPropertySpecs and JSFunctionSpecs. This will - * allow us to pass one JSJitInfo per function with the property/function spec, - * without additional field overhead. - */ -typedef struct JSNativeWrapper { - JSNative op; - const JSJitInfo* info; -} JSNativeWrapper; - -/* - * Macro static initializers which make it easy to pass no JSJitInfo as part of a - * JSPropertySpec or JSFunctionSpec. - */ -#define JSNATIVE_WRAPPER(native) { {native, nullptr} } - -/** - * Description of a property. JS_DefineProperties and JS_InitClass take arrays - * of these and define many properties at once. JS_PSG, JS_PSGS and JS_PS_END - * are helper macros for defining such arrays. - */ -struct JSPropertySpec { - struct SelfHostedWrapper { - void* unused; - const char* funname; - }; - - struct ValueWrapper { - uintptr_t type; - union { - const char* string; - int32_t int32; - }; - }; - - const char* name; - uint8_t flags; - union { - struct { - union { - JSNativeWrapper native; - SelfHostedWrapper selfHosted; - } getter; - union { - JSNativeWrapper native; - SelfHostedWrapper selfHosted; - } setter; - } accessors; - ValueWrapper value; - }; - - bool isAccessor() const { - return !(flags & JSPROP_INTERNAL_USE_BIT); - } - bool getValue(JSContext* cx, JS::MutableHandleValue value) const; - - bool isSelfHosted() const { - MOZ_ASSERT(isAccessor()); - -#ifdef DEBUG - // Verify that our accessors match our JSPROP_GETTER flag. - if (flags & JSPROP_GETTER) - checkAccessorsAreSelfHosted(); - else - checkAccessorsAreNative(); -#endif - return (flags & JSPROP_GETTER); - } - - static_assert(sizeof(SelfHostedWrapper) == sizeof(JSNativeWrapper), - "JSPropertySpec::getter/setter must be compact"); - static_assert(offsetof(SelfHostedWrapper, funname) == offsetof(JSNativeWrapper, info), - "JS_SELF_HOSTED* macros below require that " - "SelfHostedWrapper::funname overlay " - "JSNativeWrapper::info"); -private: - void checkAccessorsAreNative() const { - MOZ_ASSERT(accessors.getter.native.op); - // We may not have a setter at all. So all we can assert here, for the - // native case is that if we have a jitinfo for the setter then we have - // a setter op too. This is good enough to make sure we don't have a - // SelfHostedWrapper for the setter. - MOZ_ASSERT_IF(accessors.setter.native.info, accessors.setter.native.op); - } - - void checkAccessorsAreSelfHosted() const { - MOZ_ASSERT(!accessors.getter.selfHosted.unused); - MOZ_ASSERT(!accessors.setter.selfHosted.unused); - } -}; - -namespace JS { -namespace detail { - -/* NEVER DEFINED, DON'T USE. For use by JS_CAST_NATIVE_TO only. */ -inline int CheckIsNative(JSNative native); - -/* NEVER DEFINED, DON'T USE. For use by JS_CAST_STRING_TO only. */ -template -inline int -CheckIsCharacterLiteral(const char (&arr)[N]); - -/* NEVER DEFINED, DON'T USE. For use by JS_CAST_INT32_TO only. */ -inline int CheckIsInt32(int32_t value); - -/* NEVER DEFINED, DON'T USE. For use by JS_PROPERTYOP_GETTER only. */ -inline int CheckIsGetterOp(JSGetterOp op); - -/* NEVER DEFINED, DON'T USE. For use by JS_PROPERTYOP_SETTER only. */ -inline int CheckIsSetterOp(JSSetterOp op); - -} // namespace detail -} // namespace JS - -#define JS_CAST_NATIVE_TO(v, To) \ - (static_cast(sizeof(JS::detail::CheckIsNative(v))), \ - reinterpret_cast(v)) - -#define JS_CAST_STRING_TO(s, To) \ - (static_cast(sizeof(JS::detail::CheckIsCharacterLiteral(s))), \ - reinterpret_cast(s)) - -#define JS_CAST_INT32_TO(s, To) \ - (static_cast(sizeof(JS::detail::CheckIsInt32(s))), \ - reinterpret_cast(s)) - -#define JS_CHECK_ACCESSOR_FLAGS(flags) \ - (static_cast::Type>(0), \ - (flags)) - -#define JS_PROPERTYOP_GETTER(v) \ - (static_cast(sizeof(JS::detail::CheckIsGetterOp(v))), \ - reinterpret_cast(v)) - -#define JS_PROPERTYOP_SETTER(v) \ - (static_cast(sizeof(JS::detail::CheckIsSetterOp(v))), \ - reinterpret_cast(v)) - -#define JS_STUBGETTER JS_PROPERTYOP_GETTER(JS_PropertyStub) - -#define JS_STUBSETTER JS_PROPERTYOP_SETTER(JS_StrictPropertyStub) - -#define JS_PS_ACCESSOR_SPEC(name, getter, setter, flags, extraFlags) \ - { name, uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | extraFlags), \ - { { getter, setter } } } -#define JS_PS_VALUE_SPEC(name, value, flags) \ - { name, uint8_t(flags | JSPROP_INTERNAL_USE_BIT), \ - { { value, JSNATIVE_WRAPPER(nullptr) } } } - -#define SELFHOSTED_WRAPPER(name) \ - { { nullptr, JS_CAST_STRING_TO(name, const JSJitInfo*) } } -#define STRINGVALUE_WRAPPER(value) \ - { { reinterpret_cast(JSVAL_TYPE_STRING), JS_CAST_STRING_TO(value, const JSJitInfo*) } } -#define INT32VALUE_WRAPPER(value) \ - { { reinterpret_cast(JSVAL_TYPE_INT32), JS_CAST_INT32_TO(value, const JSJitInfo*) } } - -/* - * JSPropertySpec uses JSNativeWrapper. These macros encapsulate the definition - * of JSNative-backed JSPropertySpecs, by defining the JSNativeWrappers for - * them. - */ -#define JS_PSG(name, getter, flags) \ - JS_PS_ACCESSOR_SPEC(name, JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(nullptr), flags, \ - JSPROP_SHARED) -#define JS_PSGS(name, getter, setter, flags) \ - JS_PS_ACCESSOR_SPEC(name, JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(setter), flags, \ - JSPROP_SHARED) -#define JS_SELF_HOSTED_GET(name, getterName, flags) \ - JS_PS_ACCESSOR_SPEC(name, SELFHOSTED_WRAPPER(getterName), JSNATIVE_WRAPPER(nullptr), flags, \ - JSPROP_SHARED | JSPROP_GETTER) -#define JS_SELF_HOSTED_GETSET(name, getterName, setterName, flags) \ - JS_PS_ACCESSOR_SPEC(name, SELFHOSTED_WRAPPER(getterName), SELFHOSTED_WRAPPER(setterName), \ - flags, JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER) -#define JS_SELF_HOSTED_SYM_GET(symbol, getterName, flags) \ - JS_PS_ACCESSOR_SPEC(reinterpret_cast(uint32_t(::JS::SymbolCode::symbol) + 1), \ - SELFHOSTED_WRAPPER(getterName), JSNATIVE_WRAPPER(nullptr), flags, \ - JSPROP_SHARED | JSPROP_GETTER) -#define JS_STRING_PS(name, string, flags) \ - JS_PS_VALUE_SPEC(name, STRINGVALUE_WRAPPER(string), flags) -#define JS_STRING_SYM_PS(symbol, string, flags) \ - JS_PS_VALUE_SPEC(reinterpret_cast(uint32_t(::JS::SymbolCode::symbol) + 1), \ - STRINGVALUE_WRAPPER(string), flags) -#define JS_INT32_PS(name, value, flags) \ - JS_PS_VALUE_SPEC(name, INT32VALUE_WRAPPER(value), flags) -#define JS_PS_END \ - JS_PS_ACCESSOR_SPEC(nullptr, JSNATIVE_WRAPPER(nullptr), JSNATIVE_WRAPPER(nullptr), 0, 0) - -/** - * To define a native function, set call to a JSNativeWrapper. To define a - * self-hosted function, set selfHostedName to the name of a function - * compiled during JSRuntime::initSelfHosting. - */ -struct JSFunctionSpec { - const char* name; - JSNativeWrapper call; - uint16_t nargs; - uint16_t flags; - const char* selfHostedName; -}; - -/* - * Terminating sentinel initializer to put at the end of a JSFunctionSpec array - * that's passed to JS_DefineFunctions or JS_InitClass. - */ -#define JS_FS_END JS_FS(nullptr,nullptr,0,0) - -/* - * Initializer macros for a JSFunctionSpec array element. JS_FN (whose name pays - * homage to the old JSNative/JSFastNative split) simply adds the flag - * JSFUN_STUB_GSOPS. JS_FNINFO allows the simple adding of - * JSJitInfos. JS_SELF_HOSTED_FN declares a self-hosted function. - * JS_INLINABLE_FN allows specifying an InlinableNative enum value for natives - * inlined or specialized by the JIT. Finally JS_FNSPEC has slots for all the - * fields. - * - * The _SYM variants allow defining a function with a symbol key rather than a - * string key. For example, use JS_SYM_FN(iterator, ...) to define an - * @@iterator method. - */ -#define JS_FS(name,call,nargs,flags) \ - JS_FNSPEC(name, call, nullptr, nargs, flags, nullptr) -#define JS_FN(name,call,nargs,flags) \ - JS_FNSPEC(name, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr) -#define JS_INLINABLE_FN(name,call,nargs,flags,native) \ - JS_FNSPEC(name, call, &js::jit::JitInfo_##native, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr) -#define JS_SYM_FN(symbol,call,nargs,flags) \ - JS_SYM_FNSPEC(symbol, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr) -#define JS_FNINFO(name,call,info,nargs,flags) \ - JS_FNSPEC(name, call, info, nargs, flags, nullptr) -#define JS_SELF_HOSTED_FN(name,selfHostedName,nargs,flags) \ - JS_FNSPEC(name, nullptr, nullptr, nargs, flags, selfHostedName) -#define JS_SELF_HOSTED_SYM_FN(symbol, selfHostedName, nargs, flags) \ - JS_SYM_FNSPEC(symbol, nullptr, nullptr, nargs, flags, selfHostedName) -#define JS_SYM_FNSPEC(symbol, call, info, nargs, flags, selfHostedName) \ - JS_FNSPEC(reinterpret_cast( \ - uint32_t(::JS::SymbolCode::symbol) + 1), \ - call, info, nargs, flags, selfHostedName) -#define JS_FNSPEC(name,call,info,nargs,flags,selfHostedName) \ - {name, {call, info}, nargs, flags, selfHostedName} - -extern JS_PUBLIC_API(JSObject*) -JS_InitClass(JSContext* cx, JS::HandleObject obj, JS::HandleObject parent_proto, - const JSClass* clasp, JSNative constructor, unsigned nargs, - const JSPropertySpec* ps, const JSFunctionSpec* fs, - const JSPropertySpec* static_ps, const JSFunctionSpec* static_fs); - -/** - * Set up ctor.prototype = proto and proto.constructor = ctor with the - * right property flags. - */ -extern JS_PUBLIC_API(bool) -JS_LinkConstructorAndPrototype(JSContext* cx, JS::Handle ctor, - JS::Handle proto); - -extern JS_PUBLIC_API(const JSClass*) -JS_GetClass(JSObject* obj); - -extern JS_PUBLIC_API(bool) -JS_InstanceOf(JSContext* cx, JS::Handle obj, const JSClass* clasp, JS::CallArgs* args); - -extern JS_PUBLIC_API(bool) -JS_HasInstance(JSContext* cx, JS::Handle obj, JS::Handle v, bool* bp); - -namespace JS { - -// Implementation of -// http://www.ecma-international.org/ecma-262/6.0/#sec-ordinaryhasinstance. If -// you're looking for the equivalent of "instanceof", you want JS_HasInstance, -// not this function. -extern JS_PUBLIC_API(bool) -OrdinaryHasInstance(JSContext* cx, HandleObject objArg, HandleValue v, bool* bp); - -} // namespace JS - -extern JS_PUBLIC_API(void*) -JS_GetPrivate(JSObject* obj); - -extern JS_PUBLIC_API(void) -JS_SetPrivate(JSObject* obj, void* data); - -extern JS_PUBLIC_API(void*) -JS_GetInstancePrivate(JSContext* cx, JS::Handle obj, const JSClass* clasp, - JS::CallArgs* args); - -extern JS_PUBLIC_API(JSObject*) -JS_GetConstructor(JSContext* cx, JS::Handle proto); - -namespace JS { - -enum ZoneSpecifier { - FreshZone = 0, - SystemZone = 1 -}; - -/** - * CompartmentCreationOptions specifies options relevant to creating a new - * compartment, that are either immutable characteristics of that compartment - * or that are discarded after the compartment has been created. - * - * Access to these options on an existing compartment is read-only: if you - * need particular selections, make them before you create the compartment. - */ -class JS_PUBLIC_API(CompartmentCreationOptions) -{ - public: - CompartmentCreationOptions() - : addonId_(nullptr), - traceGlobal_(nullptr), - invisibleToDebugger_(false), - mergeable_(false), - preserveJitCode_(false), - cloneSingletons_(false), - sharedMemoryAndAtomics_(false), - secureContext_(false) - { - zone_.spec = JS::FreshZone; - } - - // A null add-on ID means that the compartment is not associated with an - // add-on. - JSAddonId* addonIdOrNull() const { return addonId_; } - CompartmentCreationOptions& setAddonId(JSAddonId* id) { - addonId_ = id; - return *this; - } - - JSTraceOp getTrace() const { - return traceGlobal_; - } - CompartmentCreationOptions& setTrace(JSTraceOp op) { - traceGlobal_ = op; - return *this; - } - - void* zonePointer() const { - MOZ_ASSERT(uintptr_t(zone_.pointer) > uintptr_t(JS::SystemZone)); - return zone_.pointer; - } - ZoneSpecifier zoneSpecifier() const { return zone_.spec; } - CompartmentCreationOptions& setZone(ZoneSpecifier spec); - CompartmentCreationOptions& setSameZoneAs(JSObject* obj); - - // Certain scopes (i.e. XBL compilation scopes) are implementation details - // of the embedding, and references to them should never leak out to script. - // This flag causes the this compartment to skip firing onNewGlobalObject - // and makes addDebuggee a no-op for this global. - bool invisibleToDebugger() const { return invisibleToDebugger_; } - CompartmentCreationOptions& setInvisibleToDebugger(bool flag) { - invisibleToDebugger_ = flag; - return *this; - } - - // Compartments used for off-thread compilation have their contents merged - // into a target compartment when the compilation is finished. This is only - // allowed if this flag is set. The invisibleToDebugger flag must also be - // set for such compartments. - bool mergeable() const { return mergeable_; } - CompartmentCreationOptions& setMergeable(bool flag) { - mergeable_ = flag; - return *this; - } - - // Determines whether this compartment should preserve JIT code on - // non-shrinking GCs. - bool preserveJitCode() const { return preserveJitCode_; } - CompartmentCreationOptions& setPreserveJitCode(bool flag) { - preserveJitCode_ = flag; - return *this; - } - - bool cloneSingletons() const { return cloneSingletons_; } - CompartmentCreationOptions& setCloneSingletons(bool flag) { - cloneSingletons_ = flag; - return *this; - } - - bool getSharedMemoryAndAtomicsEnabled() const; - CompartmentCreationOptions& setSharedMemoryAndAtomicsEnabled(bool flag); - - // This flag doesn't affect JS engine behavior. It is used by Gecko to - // mark whether content windows and workers are "Secure Context"s. See - // https://w3c.github.io/webappsec-secure-contexts/ - // https://bugzilla.mozilla.org/show_bug.cgi?id=1162772#c34 - bool secureContext() const { return secureContext_; } - CompartmentCreationOptions& setSecureContext(bool flag) { - secureContext_ = flag; - return *this; - } - - private: - JSAddonId* addonId_; - JSTraceOp traceGlobal_; - union { - ZoneSpecifier spec; - void* pointer; // js::Zone* is not exposed in the API. - } zone_; - bool invisibleToDebugger_; - bool mergeable_; - bool preserveJitCode_; - bool cloneSingletons_; - bool sharedMemoryAndAtomics_; - bool secureContext_; -}; - -/** - * CompartmentBehaviors specifies behaviors of a compartment that can be - * changed after the compartment's been created. - */ -class JS_PUBLIC_API(CompartmentBehaviors) -{ - public: - class Override { - public: - Override() : mode_(Default) {} - - bool get(bool defaultValue) const { - if (mode_ == Default) - return defaultValue; - return mode_ == ForceTrue; - } - - void set(bool overrideValue) { - mode_ = overrideValue ? ForceTrue : ForceFalse; - } - - void reset() { - mode_ = Default; - } - - private: - enum Mode { - Default, - ForceTrue, - ForceFalse - }; - - Mode mode_; - }; - - CompartmentBehaviors() - : version_(JSVERSION_UNKNOWN) - , discardSource_(false) - , disableLazyParsing_(false) - , singletonsAsTemplates_(true) - { - } - - JSVersion version() const { return version_; } - CompartmentBehaviors& setVersion(JSVersion aVersion) { - MOZ_ASSERT(aVersion != JSVERSION_UNKNOWN); - version_ = aVersion; - return *this; - } - - // For certain globals, we know enough about the code that will run in them - // that we can discard script source entirely. - bool discardSource() const { return discardSource_; } - CompartmentBehaviors& setDiscardSource(bool flag) { - discardSource_ = flag; - return *this; - } - - bool disableLazyParsing() const { return disableLazyParsing_; } - CompartmentBehaviors& setDisableLazyParsing(bool flag) { - disableLazyParsing_ = flag; - return *this; - } - - bool extraWarnings(JSContext* cx) const; - Override& extraWarningsOverride() { return extraWarningsOverride_; } - - bool getSingletonsAsTemplates() const { - return singletonsAsTemplates_; - } - CompartmentBehaviors& setSingletonsAsValues() { - singletonsAsTemplates_ = false; - return *this; - } - - private: - JSVersion version_; - bool discardSource_; - bool disableLazyParsing_; - Override extraWarningsOverride_; - - // To XDR singletons, we need to ensure that all singletons are all used as - // templates, by making JSOP_OBJECT return a clone of the JSScript - // singleton, instead of returning the value which is baked in the JSScript. - bool singletonsAsTemplates_; -}; - -/** - * CompartmentOptions specifies compartment characteristics: both those that - * can't be changed on a compartment once it's been created - * (CompartmentCreationOptions), and those that can be changed on an existing - * compartment (CompartmentBehaviors). - */ -class JS_PUBLIC_API(CompartmentOptions) -{ - public: - explicit CompartmentOptions() - : creationOptions_(), - behaviors_() - {} - - CompartmentOptions(const CompartmentCreationOptions& compartmentCreation, - const CompartmentBehaviors& compartmentBehaviors) - : creationOptions_(compartmentCreation), - behaviors_(compartmentBehaviors) - {} - - // CompartmentCreationOptions specify fundamental compartment - // characteristics that must be specified when the compartment is created, - // that can't be changed after the compartment is created. - CompartmentCreationOptions& creationOptions() { - return creationOptions_; - } - const CompartmentCreationOptions& creationOptions() const { - return creationOptions_; - } - - // CompartmentBehaviors specify compartment characteristics that can be - // changed after the compartment is created. - CompartmentBehaviors& behaviors() { - return behaviors_; - } - const CompartmentBehaviors& behaviors() const { - return behaviors_; - } - - private: - CompartmentCreationOptions creationOptions_; - CompartmentBehaviors behaviors_; -}; - -JS_PUBLIC_API(const CompartmentCreationOptions&) -CompartmentCreationOptionsRef(JSCompartment* compartment); - -JS_PUBLIC_API(const CompartmentCreationOptions&) -CompartmentCreationOptionsRef(JSObject* obj); - -JS_PUBLIC_API(const CompartmentCreationOptions&) -CompartmentCreationOptionsRef(JSContext* cx); - -JS_PUBLIC_API(CompartmentBehaviors&) -CompartmentBehaviorsRef(JSCompartment* compartment); - -JS_PUBLIC_API(CompartmentBehaviors&) -CompartmentBehaviorsRef(JSObject* obj); - -JS_PUBLIC_API(CompartmentBehaviors&) -CompartmentBehaviorsRef(JSContext* cx); - -/** - * During global creation, we fire notifications to callbacks registered - * via the Debugger API. These callbacks are arbitrary script, and can touch - * the global in arbitrary ways. When that happens, the global should not be - * in a half-baked state. But this creates a problem for consumers that need - * to set slots on the global to put it in a consistent state. - * - * This API provides a way for consumers to set slots atomically (immediately - * after the global is created), before any debugger hooks are fired. It's - * unfortunately on the clunky side, but that's the way the cookie crumbles. - * - * If callers have no additional state on the global to set up, they may pass - * |FireOnNewGlobalHook| to JS_NewGlobalObject, which causes that function to - * fire the hook as its final act before returning. Otherwise, callers should - * pass |DontFireOnNewGlobalHook|, which means that they are responsible for - * invoking JS_FireOnNewGlobalObject upon successfully creating the global. If - * an error occurs and the operation aborts, callers should skip firing the - * hook. But otherwise, callers must take care to fire the hook exactly once - * before compiling any script in the global's scope (we have assertions in - * place to enforce this). This lets us be sure that debugger clients never miss - * breakpoints. - */ -enum OnNewGlobalHookOption { - FireOnNewGlobalHook, - DontFireOnNewGlobalHook -}; - -} /* namespace JS */ - -extern JS_PUBLIC_API(JSObject*) -JS_NewGlobalObject(JSContext* cx, const JSClass* clasp, JSPrincipals* principals, - JS::OnNewGlobalHookOption hookOption, - const JS::CompartmentOptions& options); -/** - * Spidermonkey does not have a good way of keeping track of what compartments should be marked on - * their own. We can mark the roots unconditionally, but marking GC things only relevant in live - * compartments is hard. To mitigate this, we create a static trace hook, installed on each global - * object, from which we can be sure the compartment is relevant, and mark it. - * - * It is still possible to specify custom trace hooks for global object classes. They can be - * provided via the CompartmentOptions passed to JS_NewGlobalObject. - */ -extern JS_PUBLIC_API(void) -JS_GlobalObjectTraceHook(JSTracer* trc, JSObject* global); - -extern JS_PUBLIC_API(void) -JS_FireOnNewGlobalObject(JSContext* cx, JS::HandleObject global); - -extern JS_PUBLIC_API(JSObject*) -JS_NewObject(JSContext* cx, const JSClass* clasp); - -extern JS_PUBLIC_API(bool) -JS_IsNative(JSObject* obj); - -/** - * Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default - * proto. If proto is nullptr, the JS object will have `null` as [[Prototype]]. - */ -extern JS_PUBLIC_API(JSObject*) -JS_NewObjectWithGivenProto(JSContext* cx, const JSClass* clasp, JS::Handle proto); - -/** Creates a new plain object, like `new Object()`, with Object.prototype as [[Prototype]]. */ -extern JS_PUBLIC_API(JSObject*) -JS_NewPlainObject(JSContext* cx); - -/** - * Freeze obj, and all objects it refers to, recursively. This will not recurse - * through non-extensible objects, on the assumption that those are already - * deep-frozen. - */ -extern JS_PUBLIC_API(bool) -JS_DeepFreezeObject(JSContext* cx, JS::Handle obj); - -/** - * Freezes an object; see ES5's Object.freeze(obj) method. - */ -extern JS_PUBLIC_API(bool) -JS_FreezeObject(JSContext* cx, JS::Handle obj); - - -/*** Property descriptors ************************************************************************/ - -namespace JS { - -struct JS_PUBLIC_API(PropertyDescriptor) { - JSObject* obj; - unsigned attrs; - JSGetterOp getter; - JSSetterOp setter; - JS::Value value; - - PropertyDescriptor() - : obj(nullptr), attrs(0), getter(nullptr), setter(nullptr), value(JS::UndefinedValue()) - {} - - static void trace(PropertyDescriptor* self, JSTracer* trc) { self->trace(trc); } - void trace(JSTracer* trc); -}; - -template -class PropertyDescriptorOperations -{ - const PropertyDescriptor& desc() const { return static_cast(this)->get(); } - - bool has(unsigned bit) const { - MOZ_ASSERT(bit != 0); - MOZ_ASSERT((bit & (bit - 1)) == 0); // only a single bit - return (desc().attrs & bit) != 0; - } - - bool hasAny(unsigned bits) const { - return (desc().attrs & bits) != 0; - } - - bool hasAll(unsigned bits) const { - return (desc().attrs & bits) == bits; - } - - // Non-API attributes bit used internally for arguments objects. - enum { SHADOWABLE = JSPROP_INTERNAL_USE_BIT }; - - public: - // Descriptors with JSGetterOp/JSSetterOp are considered data - // descriptors. It's complicated. - bool isAccessorDescriptor() const { return hasAny(JSPROP_GETTER | JSPROP_SETTER); } - bool isGenericDescriptor() const { - return (desc().attrs& - (JSPROP_GETTER | JSPROP_SETTER | JSPROP_IGNORE_READONLY | JSPROP_IGNORE_VALUE)) == - (JSPROP_IGNORE_READONLY | JSPROP_IGNORE_VALUE); - } - bool isDataDescriptor() const { return !isAccessorDescriptor() && !isGenericDescriptor(); } - - bool hasConfigurable() const { return !has(JSPROP_IGNORE_PERMANENT); } - bool configurable() const { MOZ_ASSERT(hasConfigurable()); return !has(JSPROP_PERMANENT); } - - bool hasEnumerable() const { return !has(JSPROP_IGNORE_ENUMERATE); } - bool enumerable() const { MOZ_ASSERT(hasEnumerable()); return has(JSPROP_ENUMERATE); } - - bool hasValue() const { return !isAccessorDescriptor() && !has(JSPROP_IGNORE_VALUE); } - JS::HandleValue value() const { - return JS::HandleValue::fromMarkedLocation(&desc().value); - } - - bool hasWritable() const { return !isAccessorDescriptor() && !has(JSPROP_IGNORE_READONLY); } - bool writable() const { MOZ_ASSERT(hasWritable()); return !has(JSPROP_READONLY); } - - bool hasGetterObject() const { return has(JSPROP_GETTER); } - JS::HandleObject getterObject() const { - MOZ_ASSERT(hasGetterObject()); - return JS::HandleObject::fromMarkedLocation( - reinterpret_cast(&desc().getter)); - } - bool hasSetterObject() const { return has(JSPROP_SETTER); } - JS::HandleObject setterObject() const { - MOZ_ASSERT(hasSetterObject()); - return JS::HandleObject::fromMarkedLocation( - reinterpret_cast(&desc().setter)); - } - - bool hasGetterOrSetter() const { return desc().getter || desc().setter; } - bool isShared() const { return has(JSPROP_SHARED); } - - JS::HandleObject object() const { - return JS::HandleObject::fromMarkedLocation(&desc().obj); - } - unsigned attributes() const { return desc().attrs; } - JSGetterOp getter() const { return desc().getter; } - JSSetterOp setter() const { return desc().setter; } - - void assertValid() const { -#ifdef DEBUG - MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE | JSPROP_IGNORE_ENUMERATE | - JSPROP_PERMANENT | JSPROP_IGNORE_PERMANENT | - JSPROP_READONLY | JSPROP_IGNORE_READONLY | - JSPROP_IGNORE_VALUE | - JSPROP_GETTER | - JSPROP_SETTER | - JSPROP_SHARED | - JSPROP_REDEFINE_NONCONFIGURABLE | - JSPROP_RESOLVING | - SHADOWABLE)) == 0); - MOZ_ASSERT(!hasAll(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE)); - MOZ_ASSERT(!hasAll(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT)); - if (isAccessorDescriptor()) { - MOZ_ASSERT(has(JSPROP_SHARED)); - MOZ_ASSERT(!has(JSPROP_READONLY)); - MOZ_ASSERT(!has(JSPROP_IGNORE_READONLY)); - MOZ_ASSERT(!has(JSPROP_IGNORE_VALUE)); - MOZ_ASSERT(!has(SHADOWABLE)); - MOZ_ASSERT(value().isUndefined()); - MOZ_ASSERT_IF(!has(JSPROP_GETTER), !getter()); - MOZ_ASSERT_IF(!has(JSPROP_SETTER), !setter()); - } else { - MOZ_ASSERT(!hasAll(JSPROP_IGNORE_READONLY | JSPROP_READONLY)); - MOZ_ASSERT_IF(has(JSPROP_IGNORE_VALUE), value().isUndefined()); - } - MOZ_ASSERT(getter() != JS_PropertyStub); - MOZ_ASSERT(setter() != JS_StrictPropertyStub); - - MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_ENUMERATE)); - MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_PERMANENT)); - MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_READONLY)); - MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_VALUE)); - MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_REDEFINE_NONCONFIGURABLE)); -#endif - } - - void assertComplete() const { -#ifdef DEBUG - assertValid(); - MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE | - JSPROP_PERMANENT | - JSPROP_READONLY | - JSPROP_GETTER | - JSPROP_SETTER | - JSPROP_SHARED | - JSPROP_REDEFINE_NONCONFIGURABLE | - JSPROP_RESOLVING | - SHADOWABLE)) == 0); - MOZ_ASSERT_IF(isAccessorDescriptor(), has(JSPROP_GETTER) && has(JSPROP_SETTER)); -#endif - } - - void assertCompleteIfFound() const { -#ifdef DEBUG - if (object()) - assertComplete(); -#endif - } -}; - -template -class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations -{ - PropertyDescriptor& desc() { return static_cast(this)->get(); } - - public: - void clear() { - object().set(nullptr); - setAttributes(0); - setGetter(nullptr); - setSetter(nullptr); - value().setUndefined(); - } - - void initFields(HandleObject obj, HandleValue v, unsigned attrs, - JSGetterOp getterOp, JSSetterOp setterOp) { - MOZ_ASSERT(getterOp != JS_PropertyStub); - MOZ_ASSERT(setterOp != JS_StrictPropertyStub); - - object().set(obj); - value().set(v); - setAttributes(attrs); - setGetter(getterOp); - setSetter(setterOp); - } - - void assign(PropertyDescriptor& other) { - object().set(other.obj); - setAttributes(other.attrs); - setGetter(other.getter); - setSetter(other.setter); - value().set(other.value); - } - - void setDataDescriptor(HandleValue v, unsigned attrs) { - MOZ_ASSERT((attrs & ~(JSPROP_ENUMERATE | - JSPROP_PERMANENT | - JSPROP_READONLY | - JSPROP_IGNORE_ENUMERATE | - JSPROP_IGNORE_PERMANENT | - JSPROP_IGNORE_READONLY)) == 0); - object().set(nullptr); - setAttributes(attrs); - setGetter(nullptr); - setSetter(nullptr); - value().set(v); - } - - JS::MutableHandleObject object() { - return JS::MutableHandleObject::fromMarkedLocation(&desc().obj); - } - unsigned& attributesRef() { return desc().attrs; } - JSGetterOp& getter() { return desc().getter; } - JSSetterOp& setter() { return desc().setter; } - JS::MutableHandleValue value() { - return JS::MutableHandleValue::fromMarkedLocation(&desc().value); - } - void setValue(JS::HandleValue v) { - MOZ_ASSERT(!(desc().attrs & (JSPROP_GETTER | JSPROP_SETTER))); - attributesRef() &= ~JSPROP_IGNORE_VALUE; - value().set(v); - } - - void setConfigurable(bool configurable) { - setAttributes((desc().attrs & ~(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT)) | - (configurable ? 0 : JSPROP_PERMANENT)); - } - void setEnumerable(bool enumerable) { - setAttributes((desc().attrs & ~(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE)) | - (enumerable ? JSPROP_ENUMERATE : 0)); - } - void setWritable(bool writable) { - MOZ_ASSERT(!(desc().attrs & (JSPROP_GETTER | JSPROP_SETTER))); - setAttributes((desc().attrs & ~(JSPROP_IGNORE_READONLY | JSPROP_READONLY)) | - (writable ? 0 : JSPROP_READONLY)); - } - void setAttributes(unsigned attrs) { desc().attrs = attrs; } - - void setGetter(JSGetterOp op) { - MOZ_ASSERT(op != JS_PropertyStub); - desc().getter = op; - } - void setSetter(JSSetterOp op) { - MOZ_ASSERT(op != JS_StrictPropertyStub); - desc().setter = op; - } - void setGetterObject(JSObject* obj) { - desc().getter = reinterpret_cast(obj); - desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY); - desc().attrs |= JSPROP_GETTER | JSPROP_SHARED; - } - void setSetterObject(JSObject* obj) { - desc().setter = reinterpret_cast(obj); - desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY); - desc().attrs |= JSPROP_SETTER | JSPROP_SHARED; - } - - JS::MutableHandleObject getterObject() { - MOZ_ASSERT(this->hasGetterObject()); - return JS::MutableHandleObject::fromMarkedLocation( - reinterpret_cast(&desc().getter)); - } - JS::MutableHandleObject setterObject() { - MOZ_ASSERT(this->hasSetterObject()); - return JS::MutableHandleObject::fromMarkedLocation( - reinterpret_cast(&desc().setter)); - } -}; - -} /* namespace JS */ - -namespace js { - -template <> -class RootedBase - : public JS::MutablePropertyDescriptorOperations> -{}; - -template <> -class HandleBase - : public JS::PropertyDescriptorOperations> -{}; - -template <> -class MutableHandleBase - : public JS::MutablePropertyDescriptorOperations> -{}; - -} /* namespace js */ - -namespace JS { - -extern JS_PUBLIC_API(bool) -ObjectToCompletePropertyDescriptor(JSContext* cx, - JS::HandleObject obj, - JS::HandleValue descriptor, - JS::MutableHandle desc); - -/* - * ES6 draft rev 32 (2015 Feb 2) 6.2.4.4 FromPropertyDescriptor(Desc). - * - * If desc.object() is null, then vp is set to undefined. - */ -extern JS_PUBLIC_API(bool) -FromPropertyDescriptor(JSContext* cx, - JS::Handle desc, - JS::MutableHandleValue vp); - -} // namespace JS - - -/*** Standard internal methods ******************************************************************** - * - * The functions below are the fundamental operations on objects. - * - * ES6 specifies 14 internal methods that define how objects behave. The - * standard is actually quite good on this topic, though you may have to read - * it a few times. See ES6 sections 6.1.7.2 and 6.1.7.3. - * - * When 'obj' is an ordinary object, these functions have boring standard - * behavior as specified by ES6 section 9.1; see the section about internal - * methods in js/src/vm/NativeObject.h. - * - * Proxies override the behavior of internal methods. So when 'obj' is a proxy, - * any one of the functions below could do just about anything. See - * js/public/Proxy.h. - */ - -/** - * Get the prototype of obj, storing it in result. - * - * Implements: ES6 [[GetPrototypeOf]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_GetPrototype(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject result); - -/** - * If |obj| (underneath any functionally-transparent wrapper proxies) has as - * its [[GetPrototypeOf]] trap the ordinary [[GetPrototypeOf]] behavior defined - * for ordinary objects, set |*isOrdinary = true| and store |obj|'s prototype - * in |result|. Otherwise set |*isOrdinary = false|. In case of error, both - * outparams have unspecified value. - */ -extern JS_PUBLIC_API(bool) -JS_GetPrototypeIfOrdinary(JSContext* cx, JS::HandleObject obj, bool* isOrdinary, - JS::MutableHandleObject result); - -/** - * Change the prototype of obj. - * - * Implements: ES6 [[SetPrototypeOf]] internal method. - * - * In cases where ES6 [[SetPrototypeOf]] returns false without an exception, - * JS_SetPrototype throws a TypeError and returns false. - * - * Performance warning: JS_SetPrototype is very bad for performance. It may - * cause compiled jit-code to be invalidated. It also causes not only obj but - * all other objects in the same "group" as obj to be permanently deoptimized. - * It's better to create the object with the right prototype from the start. - */ -extern JS_PUBLIC_API(bool) -JS_SetPrototype(JSContext* cx, JS::HandleObject obj, JS::HandleObject proto); - -/** - * Determine whether obj is extensible. Extensible objects can have new - * properties defined on them. Inextensible objects can't, and their - * [[Prototype]] slot is fixed as well. - * - * Implements: ES6 [[IsExtensible]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_IsExtensible(JSContext* cx, JS::HandleObject obj, bool* extensible); - -/** - * Attempt to make |obj| non-extensible. - * - * Not all failures are treated as errors. See the comment on - * JS::ObjectOpResult in js/public/Class.h. - * - * Implements: ES6 [[PreventExtensions]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_PreventExtensions(JSContext* cx, JS::HandleObject obj, JS::ObjectOpResult& result); - -/** - * Attempt to make the [[Prototype]] of |obj| immutable, such that any attempt - * to modify it will fail. If an error occurs during the attempt, return false - * (with a pending exception set, depending upon the nature of the error). If - * no error occurs, return true with |*succeeded| set to indicate whether the - * attempt successfully made the [[Prototype]] immutable. - * - * This is a nonstandard internal method. - */ -extern JS_PUBLIC_API(bool) -JS_SetImmutablePrototype(JSContext* cx, JS::HandleObject obj, bool* succeeded); - -/** - * Get a description of one of obj's own properties. If no such property exists - * on obj, return true with desc.object() set to null. - * - * Implements: ES6 [[GetOwnProperty]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_GetOwnPropertyDescriptorById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandle desc); - -extern JS_PUBLIC_API(bool) -JS_GetOwnPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* name, - JS::MutableHandle desc); - -extern JS_PUBLIC_API(bool) -JS_GetOwnUCPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char16_t* name, - JS::MutableHandle desc); - -/** - * Like JS_GetOwnPropertyDescriptorById, but also searches the prototype chain - * if no own property is found directly on obj. The object on which the - * property is found is returned in desc.object(). If the property is not found - * on the prototype chain, this returns true with desc.object() set to null. - */ -extern JS_PUBLIC_API(bool) -JS_GetPropertyDescriptorById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandle desc); - -extern JS_PUBLIC_API(bool) -JS_GetPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* name, - JS::MutableHandle desc); - -/** - * Define a property on obj. - * - * This function uses JS::ObjectOpResult to indicate conditions that ES6 - * specifies as non-error failures. This is inconvenient at best, so use this - * function only if you are implementing a proxy handler's defineProperty() - * method. For all other purposes, use one of the many DefineProperty functions - * below that throw an exception in all failure cases. - * - * Implements: ES6 [[DefineOwnProperty]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::Handle desc, - JS::ObjectOpResult& result); - -/** - * Define a property on obj, throwing a TypeError if the attempt fails. - * This is the C++ equivalent of `Object.defineProperty(obj, id, desc)`. - */ -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::Handle desc); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleString value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, int32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, uint32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, double value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleValue value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleObject value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleString value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, int32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, uint32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, double value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::Handle desc, - JS::ObjectOpResult& result); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::Handle desc); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::HandleValue value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::HandleObject value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::HandleString value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - int32_t value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - uint32_t value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - double value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleObject value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleString value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, int32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, uint32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, double value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -/** - * Compute the expression `id in obj`. - * - * If obj has an own or inherited property obj[id], set *foundp = true and - * return true. If not, set *foundp = false and return true. On error, return - * false with an exception pending. - * - * Implements: ES6 [[Has]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_HasPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_HasProperty(JSContext* cx, JS::HandleObject obj, const char* name, bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_HasUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - bool* vp); - -extern JS_PUBLIC_API(bool) -JS_HasElement(JSContext* cx, JS::HandleObject obj, uint32_t index, bool* foundp); - -/** - * Determine whether obj has an own property with the key `id`. - * - * Implements: ES6 7.3.11 HasOwnProperty(O, P). - */ -extern JS_PUBLIC_API(bool) -JS_HasOwnPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_HasOwnProperty(JSContext* cx, JS::HandleObject obj, const char* name, bool* foundp); - -/** - * Get the value of the property `obj[id]`, or undefined if no such property - * exists. This is the C++ equivalent of `vp = Reflect.get(obj, id, receiver)`. - * - * Most callers don't need the `receiver` argument. Consider using - * JS_GetProperty instead. (But if you're implementing a proxy handler's set() - * method, it's often correct to call this function and pass the receiver - * through.) - * - * Implements: ES6 [[Get]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_ForwardGetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::HandleValue receiver, JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(bool) -JS_ForwardGetElementTo(JSContext* cx, JS::HandleObject obj, uint32_t index, - JS::HandleObject receiver, JS::MutableHandleValue vp); - -/** - * Get the value of the property `obj[id]`, or undefined if no such property - * exists. The result is stored in vp. - * - * Implements: ES6 7.3.1 Get(O, P). - */ -extern JS_PUBLIC_API(bool) -JS_GetPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(bool) -JS_GetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(bool) -JS_GetUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(bool) -JS_GetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp); - -/** - * Perform the same property assignment as `Reflect.set(obj, id, v, receiver)`. - * - * This function has a `receiver` argument that most callers don't need. - * Consider using JS_SetProperty instead. - * - * Implements: ES6 [[Set]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_ForwardSetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v, - JS::HandleValue receiver, JS::ObjectOpResult& result); - -/** - * Perform the assignment `obj[id] = v`. - * - * This function performs non-strict assignment, so if the property is - * read-only, nothing happens and no error is thrown. - */ -extern JS_PUBLIC_API(bool) -JS_SetPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v); - -extern JS_PUBLIC_API(bool) -JS_SetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleValue v); - -extern JS_PUBLIC_API(bool) -JS_SetUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::HandleValue v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleValue v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleObject v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleString v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, int32_t v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, uint32_t v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, double v); - -/** - * Delete a property. This is the C++ equivalent of - * `result = Reflect.deleteProperty(obj, id)`. - * - * This function has a `result` out parameter that most callers don't need. - * Unless you can pass through an ObjectOpResult provided by your caller, it's - * probably best to use the JS_DeletePropertyById signature with just 3 - * arguments. - * - * Implements: ES6 [[Delete]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_DeletePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::ObjectOpResult& result); - -extern JS_PUBLIC_API(bool) -JS_DeleteProperty(JSContext* cx, JS::HandleObject obj, const char* name, - JS::ObjectOpResult& result); - -extern JS_PUBLIC_API(bool) -JS_DeleteUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::ObjectOpResult& result); - -extern JS_PUBLIC_API(bool) -JS_DeleteElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::ObjectOpResult& result); - -/** - * Delete a property, ignoring strict failures. This is the C++ equivalent of - * the JS `delete obj[id]` in non-strict mode code. - */ -extern JS_PUBLIC_API(bool) -JS_DeletePropertyById(JSContext* cx, JS::HandleObject obj, jsid id); - -extern JS_PUBLIC_API(bool) -JS_DeleteProperty(JSContext* cx, JS::HandleObject obj, const char* name); - -extern JS_PUBLIC_API(bool) -JS_DeleteElement(JSContext* cx, JS::HandleObject obj, uint32_t index); - -/** - * Get an array of the non-symbol enumerable properties of obj. - * This function is roughly equivalent to: - * - * var result = []; - * for (key in obj) - * result.push(key); - * return result; - * - * This is the closest thing we currently have to the ES6 [[Enumerate]] - * internal method. - * - * The array of ids returned by JS_Enumerate must be rooted to protect its - * contents from garbage collection. Use JS::Rooted. - */ -extern JS_PUBLIC_API(bool) -JS_Enumerate(JSContext* cx, JS::HandleObject obj, JS::MutableHandle props); - -/* - * API for determining callability and constructability. [[Call]] and - * [[Construct]] are internal methods that aren't present on all objects, so it - * is useful to ask if they are there or not. The standard itself asks these - * questions routinely. - */ -namespace JS { - -/** - * Return true if the given object is callable. In ES6 terms, an object is - * callable if it has a [[Call]] internal method. - * - * Implements: ES6 7.2.3 IsCallable(argument). - * - * Functions are callable. A scripted proxy or wrapper is callable if its - * target is callable. Most other objects aren't callable. - */ -extern JS_PUBLIC_API(bool) -IsCallable(JSObject* obj); - -/** - * Return true if the given object is a constructor. In ES6 terms, an object is - * a constructor if it has a [[Construct]] internal method. The expression - * `new obj()` throws a TypeError if obj is not a constructor. - * - * Implements: ES6 7.2.4 IsConstructor(argument). - * - * JS functions and classes are constructors. Arrow functions and most builtin - * functions are not. A scripted proxy or wrapper is a constructor if its - * target is a constructor. - */ -extern JS_PUBLIC_API(bool) -IsConstructor(JSObject* obj); - -} /* namespace JS */ - -/** - * Call a function, passing a this-value and arguments. This is the C++ - * equivalent of `rval = Reflect.apply(fun, obj, args)`. - * - * Implements: ES6 7.3.12 Call(F, V, [argumentsList]). - * Use this function to invoke the [[Call]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_CallFunctionValue(JSContext* cx, JS::HandleObject obj, JS::HandleValue fval, - const JS::HandleValueArray& args, JS::MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -JS_CallFunction(JSContext* cx, JS::HandleObject obj, JS::HandleFunction fun, - const JS::HandleValueArray& args, JS::MutableHandleValue rval); - -/** - * Perform the method call `rval = obj[name](args)`. - */ -extern JS_PUBLIC_API(bool) -JS_CallFunctionName(JSContext* cx, JS::HandleObject obj, const char* name, - const JS::HandleValueArray& args, JS::MutableHandleValue rval); - -namespace JS { - -static inline bool -Call(JSContext* cx, JS::HandleObject thisObj, JS::HandleFunction fun, - const JS::HandleValueArray& args, MutableHandleValue rval) -{ - return !!JS_CallFunction(cx, thisObj, fun, args, rval); -} - -static inline bool -Call(JSContext* cx, JS::HandleObject thisObj, JS::HandleValue fun, const JS::HandleValueArray& args, - MutableHandleValue rval) -{ - return !!JS_CallFunctionValue(cx, thisObj, fun, args, rval); -} - -static inline bool -Call(JSContext* cx, JS::HandleObject thisObj, const char* name, const JS::HandleValueArray& args, - MutableHandleValue rval) -{ - return !!JS_CallFunctionName(cx, thisObj, name, args, rval); -} - -extern JS_PUBLIC_API(bool) -Call(JSContext* cx, JS::HandleValue thisv, JS::HandleValue fun, const JS::HandleValueArray& args, - MutableHandleValue rval); - -static inline bool -Call(JSContext* cx, JS::HandleValue thisv, JS::HandleObject funObj, const JS::HandleValueArray& args, - MutableHandleValue rval) -{ - MOZ_ASSERT(funObj); - JS::RootedValue fun(cx, JS::ObjectValue(*funObj)); - return Call(cx, thisv, fun, args, rval); -} - -/** - * Invoke a constructor. This is the C++ equivalent of - * `rval = Reflect.construct(fun, args, newTarget)`. - * - * JS::Construct() takes a `newTarget` argument that most callers don't need. - * Consider using the four-argument Construct signature instead. (But if you're - * implementing a subclass or a proxy handler's construct() method, this is the - * right function to call.) - * - * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]). - * Use this function to invoke the [[Construct]] internal method. - */ -extern JS_PUBLIC_API(bool) -Construct(JSContext* cx, JS::HandleValue fun, HandleObject newTarget, - const JS::HandleValueArray &args, MutableHandleObject objp); - -/** - * Invoke a constructor. This is the C++ equivalent of - * `rval = new fun(...args)`. - * - * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]), when - * newTarget is omitted. - */ -extern JS_PUBLIC_API(bool) -Construct(JSContext* cx, JS::HandleValue fun, const JS::HandleValueArray& args, - MutableHandleObject objp); - -} /* namespace JS */ - -/** - * Invoke a constructor, like the JS expression `new ctor(...args)`. Returns - * the new object, or null on error. - */ -extern JS_PUBLIC_API(JSObject*) -JS_New(JSContext* cx, JS::HandleObject ctor, const JS::HandleValueArray& args); - - -/*** Other property-defining functions ***********************************************************/ - -extern JS_PUBLIC_API(JSObject*) -JS_DefineObject(JSContext* cx, JS::HandleObject obj, const char* name, - const JSClass* clasp = nullptr, unsigned attrs = 0); - -extern JS_PUBLIC_API(bool) -JS_DefineConstDoubles(JSContext* cx, JS::HandleObject obj, const JSConstDoubleSpec* cds); - -extern JS_PUBLIC_API(bool) -JS_DefineConstIntegers(JSContext* cx, JS::HandleObject obj, const JSConstIntegerSpec* cis); - -extern JS_PUBLIC_API(bool) -JS_DefineProperties(JSContext* cx, JS::HandleObject obj, const JSPropertySpec* ps); - - -/* * */ - -extern JS_PUBLIC_API(bool) -JS_AlreadyHasOwnPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_AlreadyHasOwnProperty(JSContext* cx, JS::HandleObject obj, const char* name, - bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_AlreadyHasOwnUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, - size_t namelen, bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_AlreadyHasOwnElement(JSContext* cx, JS::HandleObject obj, uint32_t index, bool* foundp); - -extern JS_PUBLIC_API(JSObject*) -JS_NewArrayObject(JSContext* cx, const JS::HandleValueArray& contents); - -extern JS_PUBLIC_API(JSObject*) -JS_NewArrayObject(JSContext* cx, size_t length); - -/** - * Returns true and sets |*isArray| indicating whether |value| is an Array - * object or a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isArray == false| when passed a proxy whose - * target is an Array, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -JS_IsArrayObject(JSContext* cx, JS::HandleValue value, bool* isArray); - -/** - * Returns true and sets |*isArray| indicating whether |obj| is an Array object - * or a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isArray == false| when passed a proxy whose - * target is an Array, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -JS_IsArrayObject(JSContext* cx, JS::HandleObject obj, bool* isArray); - -extern JS_PUBLIC_API(bool) -JS_GetArrayLength(JSContext* cx, JS::Handle obj, uint32_t* lengthp); - -extern JS_PUBLIC_API(bool) -JS_SetArrayLength(JSContext* cx, JS::Handle obj, uint32_t length); - -namespace JS { - -/** - * Returns true and sets |*isMap| indicating whether |obj| is an Map object - * or a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isMap == false| when passed a proxy whose - * target is an Map, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -IsMapObject(JSContext* cx, JS::HandleObject obj, bool* isMap); - -/** - * Returns true and sets |*isSet| indicating whether |obj| is an Set object - * or a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isSet == false| when passed a proxy whose - * target is an Set, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -IsSetObject(JSContext* cx, JS::HandleObject obj, bool* isSet); - -} /* namespace JS */ - -/** - * Assign 'undefined' to all of the object's non-reserved slots. Note: this is - * done for all slots, regardless of the associated property descriptor. - */ -JS_PUBLIC_API(void) -JS_SetAllNonReservedSlotsToUndefined(JSContext* cx, JSObject* objArg); - -/** - * Create a new array buffer with the given contents. It must be legal to pass - * these contents to free(). On success, the ownership is transferred to the - * new array buffer. - */ -extern JS_PUBLIC_API(JSObject*) -JS_NewArrayBufferWithContents(JSContext* cx, size_t nbytes, void* contents); - -/** - * Create a new array buffer with the given contents. The array buffer does not take ownership of - * contents, and JS_DetachArrayBuffer must be called before the contents are disposed of. - */ -extern JS_PUBLIC_API(JSObject*) -JS_NewArrayBufferWithExternalContents(JSContext* cx, size_t nbytes, void* contents); - -/** - * Steal the contents of the given array buffer. The array buffer has its - * length set to 0 and its contents array cleared. The caller takes ownership - * of the return value and must free it or transfer ownership via - * JS_NewArrayBufferWithContents when done using it. - */ -extern JS_PUBLIC_API(void*) -JS_StealArrayBufferContents(JSContext* cx, JS::HandleObject obj); - -/** - * Returns a pointer to the ArrayBuffer |obj|'s data. |obj| and its views will store and expose - * the data in the returned pointer: assigning into the returned pointer will affect values exposed - * by views of |obj| and vice versa. - * - * The caller must ultimately deallocate the returned pointer to avoid leaking. The memory is - * *not* garbage-collected with |obj|. These steps must be followed to deallocate: - * - * 1. The ArrayBuffer |obj| must be detached using JS_DetachArrayBuffer. - * 2. The returned pointer must be freed using JS_free. - * - * To perform step 1, callers *must* hold a reference to |obj| until they finish using the returned - * pointer. They *must not* attempt to let |obj| be GC'd, then JS_free the pointer. - * - * If |obj| isn't an ArrayBuffer, this function returns null and reports an error. - */ -extern JS_PUBLIC_API(void*) -JS_ExternalizeArrayBufferContents(JSContext* cx, JS::HandleObject obj); - -/** - * Create a new mapped array buffer with the given memory mapped contents. It - * must be legal to free the contents pointer by unmapping it. On success, - * ownership is transferred to the new mapped array buffer. - */ -extern JS_PUBLIC_API(JSObject*) -JS_NewMappedArrayBufferWithContents(JSContext* cx, size_t nbytes, void* contents); - -/** - * Create memory mapped array buffer contents. - * Caller must take care of closing fd after calling this function. - */ -extern JS_PUBLIC_API(void*) -JS_CreateMappedArrayBufferContents(int fd, size_t offset, size_t length); - -/** - * Release the allocated resource of mapped array buffer contents before the - * object is created. - * If a new object has been created by JS_NewMappedArrayBufferWithContents() - * with this content, then JS_DetachArrayBuffer() should be used instead to - * release the resource used by the object. - */ -extern JS_PUBLIC_API(void) -JS_ReleaseMappedArrayBufferContents(void* contents, size_t length); - -extern JS_PUBLIC_API(JS::Value) -JS_GetReservedSlot(JSObject* obj, uint32_t index); - -extern JS_PUBLIC_API(void) -JS_SetReservedSlot(JSObject* obj, uint32_t index, const JS::Value& v); - - -/************************************************************************/ - -/* - * Functions and scripts. - */ -extern JS_PUBLIC_API(JSFunction*) -JS_NewFunction(JSContext* cx, JSNative call, unsigned nargs, unsigned flags, - const char* name); - -namespace JS { - -extern JS_PUBLIC_API(JSFunction*) -GetSelfHostedFunction(JSContext* cx, const char* selfHostedName, HandleId id, - unsigned nargs); - -/** - * Create a new function based on the given JSFunctionSpec, *fs. - * id is the result of a successful call to - * `PropertySpecNameToPermanentId(cx, fs->name, &id)`. - * - * Unlike JS_DefineFunctions, this does not treat fs as an array. - * *fs must not be JS_FS_END. - */ -extern JS_PUBLIC_API(JSFunction*) -NewFunctionFromSpec(JSContext* cx, const JSFunctionSpec* fs, HandleId id); - -} /* namespace JS */ - -extern JS_PUBLIC_API(JSObject*) -JS_GetFunctionObject(JSFunction* fun); - -/** - * Return the function's identifier as a JSString, or null if fun is unnamed. - * The returned string lives as long as fun, so you don't need to root a saved - * reference to it if fun is well-connected or rooted, and provided you bound - * the use of the saved reference by fun's lifetime. - */ -extern JS_PUBLIC_API(JSString*) -JS_GetFunctionId(JSFunction* fun); - -/** - * Return a function's display name. This is the defined name if one was given - * where the function was defined, or it could be an inferred name by the JS - * engine in the case that the function was defined to be anonymous. This can - * still return nullptr if a useful display name could not be inferred. The - * same restrictions on rooting as those in JS_GetFunctionId apply. - */ -extern JS_PUBLIC_API(JSString*) -JS_GetFunctionDisplayId(JSFunction* fun); - -/* - * Return the arity (length) of fun. - */ -extern JS_PUBLIC_API(uint16_t) -JS_GetFunctionArity(JSFunction* fun); - -/** - * Infallible predicate to test whether obj is a function object (faster than - * comparing obj's class name to "Function", but equivalent unless someone has - * overwritten the "Function" identifier with a different constructor and then - * created instances using that constructor that might be passed in as obj). - */ -extern JS_PUBLIC_API(bool) -JS_ObjectIsFunction(JSContext* cx, JSObject* obj); - -extern JS_PUBLIC_API(bool) -JS_IsNativeFunction(JSObject* funobj, JSNative call); - -/** Return whether the given function is a valid constructor. */ -extern JS_PUBLIC_API(bool) -JS_IsConstructor(JSFunction* fun); - -extern JS_PUBLIC_API(bool) -JS_DefineFunctions(JSContext* cx, JS::Handle obj, const JSFunctionSpec* fs); - -extern JS_PUBLIC_API(JSFunction*) -JS_DefineFunction(JSContext* cx, JS::Handle obj, const char* name, JSNative call, - unsigned nargs, unsigned attrs); - -extern JS_PUBLIC_API(JSFunction*) -JS_DefineUCFunction(JSContext* cx, JS::Handle obj, - const char16_t* name, size_t namelen, JSNative call, - unsigned nargs, unsigned attrs); - -extern JS_PUBLIC_API(JSFunction*) -JS_DefineFunctionById(JSContext* cx, JS::Handle obj, JS::Handle id, JSNative call, - unsigned nargs, unsigned attrs); - -extern JS_PUBLIC_API(bool) -JS_IsFunctionBound(JSFunction* fun); - -extern JS_PUBLIC_API(JSObject*) -JS_GetBoundFunctionTarget(JSFunction* fun); - -namespace JS { - -/** - * Clone a top-level function into cx's global. This function will dynamically - * fail if funobj was lexically nested inside some other function. - */ -extern JS_PUBLIC_API(JSObject*) -CloneFunctionObject(JSContext* cx, HandleObject funobj); - -/** - * As above, but providing an explicit scope chain. scopeChain must not include - * the global object on it; that's implicit. It needs to contain the other - * objects that should end up on the clone's scope chain. - */ -extern JS_PUBLIC_API(JSObject*) -CloneFunctionObject(JSContext* cx, HandleObject funobj, AutoObjectVector& scopeChain); - -} // namespace JS - -/** - * Given a buffer, return false if the buffer might become a valid - * javascript statement with the addition of more lines. Otherwise return - * true. The intent is to support interactive compilation - accumulate - * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to - * the compiler. - */ -extern JS_PUBLIC_API(bool) -JS_BufferIsCompilableUnit(JSContext* cx, JS::Handle obj, const char* utf8, - size_t length); - -/** - * |script| will always be set. On failure, it will be set to nullptr. - */ -extern JS_PUBLIC_API(bool) -JS_CompileScript(JSContext* cx, const char* ascii, size_t length, - const JS::CompileOptions& options, - JS::MutableHandleScript script); - -/** - * |script| will always be set. On failure, it will be set to nullptr. - */ -extern JS_PUBLIC_API(bool) -JS_CompileUCScript(JSContext* cx, const char16_t* chars, size_t length, - const JS::CompileOptions& options, - JS::MutableHandleScript script); - -extern JS_PUBLIC_API(JSObject*) -JS_GetGlobalFromScript(JSScript* script); - -extern JS_PUBLIC_API(const char*) -JS_GetScriptFilename(JSScript* script); - -extern JS_PUBLIC_API(unsigned) -JS_GetScriptBaseLineNumber(JSContext* cx, JSScript* script); - -extern JS_PUBLIC_API(JSScript*) -JS_GetFunctionScript(JSContext* cx, JS::HandleFunction fun); - -namespace JS { - -/* Options for JavaScript compilation. */ - -/* - * In the most common use case, a CompileOptions instance is allocated on the - * stack, and holds non-owning references to non-POD option values: strings; - * principals; objects; and so on. The code declaring the instance guarantees - * that such option values will outlive the CompileOptions itself: objects are - * otherwise rooted; principals have had their reference counts bumped; strings - * will not be freed until the CompileOptions goes out of scope. In this - * situation, CompileOptions only refers to things others own, so it can be - * lightweight. - * - * In some cases, however, we need to hold compilation options with a - * non-stack-like lifetime. For example, JS::CompileOffThread needs to save - * compilation options where a worker thread can find them, and then return - * immediately. The worker thread will come along at some later point, and use - * the options. - * - * The compiler itself just needs to be able to access a collection of options; - * it doesn't care who owns them, or what's keeping them alive. It does its own - * addrefs/copies/tracing/etc. - * - * Furthermore, in some cases compile options are propagated from one entity to - * another (e.g. from a scriipt to a function defined in that script). This - * involves copying over some, but not all, of the options. - * - * So, we have a class hierarchy that reflects these four use cases: - * - * - TransitiveCompileOptions is the common base class, representing options - * that should get propagated from a script to functions defined in that - * script. This is never instantiated directly. - * - * - ReadOnlyCompileOptions is the only subclass of TransitiveCompileOptions, - * representing a full set of compile options. It can be used by code that - * simply needs to access options set elsewhere, like the compiler. This, - * again, is never instantiated directly. - * - * - The usual CompileOptions class must be stack-allocated, and holds - * non-owning references to the filename, element, and so on. It's derived - * from ReadOnlyCompileOptions, so the compiler can use it. - * - * - OwningCompileOptions roots / copies / reference counts of all its values, - * and unroots / frees / releases them when it is destructed. It too is - * derived from ReadOnlyCompileOptions, so the compiler accepts it. - */ - -enum class AsmJSOption : uint8_t { Enabled, Disabled, DisabledByDebugger }; - -/** - * The common base class for the CompileOptions hierarchy. - * - * Use this in code that needs to propagate compile options from one compilation - * unit to another. - */ -class JS_FRIEND_API(TransitiveCompileOptions) -{ - protected: - // The Web Platform allows scripts to be loaded from arbitrary cross-origin - // sources. This allows an attack by which a malicious website loads a - // sensitive file (say, a bank statement) cross-origin (using the user's - // cookies), and sniffs the generated syntax errors (via a window.onerror - // handler) for juicy morsels of its contents. - // - // To counter this attack, HTML5 specifies that script errors should be - // sanitized ("muted") when the script is not same-origin with the global - // for which it is loaded. Callers should set this flag for cross-origin - // scripts, and it will be propagated appropriately to child scripts and - // passed back in JSErrorReports. - bool mutedErrors_; - const char* filename_; - const char* introducerFilename_; - const char16_t* sourceMapURL_; - - // This constructor leaves 'version' set to JSVERSION_UNKNOWN. The structure - // is unusable until that's set to something more specific; the derived - // classes' constructors take care of that, in ways appropriate to their - // purpose. - TransitiveCompileOptions() - : mutedErrors_(false), - filename_(nullptr), - introducerFilename_(nullptr), - sourceMapURL_(nullptr), - version(JSVERSION_UNKNOWN), - versionSet(false), - utf8(false), - selfHostingMode(false), - canLazilyParse(true), - strictOption(false), - extraWarningsOption(false), - werrorOption(false), - asmJSOption(AsmJSOption::Disabled), - throwOnAsmJSValidationFailureOption(false), - forceAsync(false), - installedFile(false), - sourceIsLazy(false), - introductionType(nullptr), - introductionLineno(0), - introductionOffset(0), - hasIntroductionInfo(false) - { } - - // Set all POD options (those not requiring reference counts, copies, - // rooting, or other hand-holding) to their values in |rhs|. - void copyPODTransitiveOptions(const TransitiveCompileOptions& rhs); - - public: - // Read-only accessors for non-POD options. The proper way to set these - // depends on the derived type. - bool mutedErrors() const { return mutedErrors_; } - const char* filename() const { return filename_; } - const char* introducerFilename() const { return introducerFilename_; } - const char16_t* sourceMapURL() const { return sourceMapURL_; } - virtual JSObject* element() const = 0; - virtual JSString* elementAttributeName() const = 0; - virtual JSScript* introductionScript() const = 0; - - // POD options. - JSVersion version; - bool versionSet; - bool utf8; - bool selfHostingMode; - bool canLazilyParse; - bool strictOption; - bool extraWarningsOption; - bool werrorOption; - AsmJSOption asmJSOption; - bool throwOnAsmJSValidationFailureOption; - bool forceAsync; - bool installedFile; // 'true' iff pre-compiling js file in packaged app - bool sourceIsLazy; - - // |introductionType| is a statically allocated C string: - // one of "eval", "Function", or "GeneratorFunction". - const char* introductionType; - unsigned introductionLineno; - uint32_t introductionOffset; - bool hasIntroductionInfo; - - private: - void operator=(const TransitiveCompileOptions&) = delete; -}; - -/** - * The class representing a full set of compile options. - * - * Use this in code that only needs to access compilation options created - * elsewhere, like the compiler. Don't instantiate this class (the constructor - * is protected anyway); instead, create instances only of the derived classes: - * CompileOptions and OwningCompileOptions. - */ -class JS_FRIEND_API(ReadOnlyCompileOptions) : public TransitiveCompileOptions -{ - friend class CompileOptions; - - protected: - ReadOnlyCompileOptions() - : TransitiveCompileOptions(), - lineno(1), - column(0), - isRunOnce(false), - noScriptRval(false) - { } - - // Set all POD options (those not requiring reference counts, copies, - // rooting, or other hand-holding) to their values in |rhs|. - void copyPODOptions(const ReadOnlyCompileOptions& rhs); - - public: - // Read-only accessors for non-POD options. The proper way to set these - // depends on the derived type. - bool mutedErrors() const { return mutedErrors_; } - const char* filename() const { return filename_; } - const char* introducerFilename() const { return introducerFilename_; } - const char16_t* sourceMapURL() const { return sourceMapURL_; } - virtual JSObject* element() const = 0; - virtual JSString* elementAttributeName() const = 0; - virtual JSScript* introductionScript() const = 0; - - // POD options. - unsigned lineno; - unsigned column; - // isRunOnce only applies to non-function scripts. - bool isRunOnce; - bool noScriptRval; - - private: - void operator=(const ReadOnlyCompileOptions&) = delete; -}; - -/** - * Compilation options, with dynamic lifetime. An instance of this type - * makes a copy of / holds / roots all dynamically allocated resources - * (principals; elements; strings) that it refers to. Its destructor frees - * / drops / unroots them. This is heavier than CompileOptions, below, but - * unlike CompileOptions, it can outlive any given stack frame. - * - * Note that this *roots* any JS values it refers to - they're live - * unconditionally. Thus, instances of this type can't be owned, directly - * or indirectly, by a JavaScript object: if any value that this roots ever - * comes to refer to the object that owns this, then the whole cycle, and - * anything else it entrains, will never be freed. - */ -class JS_FRIEND_API(OwningCompileOptions) : public ReadOnlyCompileOptions -{ - PersistentRootedObject elementRoot; - PersistentRootedString elementAttributeNameRoot; - PersistentRootedScript introductionScriptRoot; - - public: - // A minimal constructor, for use with OwningCompileOptions::copy. This - // leaves |this.version| set to JSVERSION_UNKNOWN; the instance - // shouldn't be used until we've set that to something real (as |copy| - // will). - explicit OwningCompileOptions(JSContext* cx); - ~OwningCompileOptions(); - - JSObject* element() const override { return elementRoot; } - JSString* elementAttributeName() const override { return elementAttributeNameRoot; } - JSScript* introductionScript() const override { return introductionScriptRoot; } - - // Set this to a copy of |rhs|. Return false on OOM. - bool copy(JSContext* cx, const ReadOnlyCompileOptions& rhs); - - /* These setters make copies of their string arguments, and are fallible. */ - bool setFile(JSContext* cx, const char* f); - bool setFileAndLine(JSContext* cx, const char* f, unsigned l); - bool setSourceMapURL(JSContext* cx, const char16_t* s); - bool setIntroducerFilename(JSContext* cx, const char* s); - - /* These setters are infallible, and can be chained. */ - OwningCompileOptions& setLine(unsigned l) { lineno = l; return *this; } - OwningCompileOptions& setElement(JSObject* e) { - elementRoot = e; - return *this; - } - OwningCompileOptions& setElementAttributeName(JSString* p) { - elementAttributeNameRoot = p; - return *this; - } - OwningCompileOptions& setIntroductionScript(JSScript* s) { - introductionScriptRoot = s; - return *this; - } - OwningCompileOptions& setMutedErrors(bool mute) { - mutedErrors_ = mute; - return *this; - } - OwningCompileOptions& setVersion(JSVersion v) { - version = v; - versionSet = true; - return *this; - } - OwningCompileOptions& setUTF8(bool u) { utf8 = u; return *this; } - OwningCompileOptions& setColumn(unsigned c) { column = c; return *this; } - OwningCompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; } - OwningCompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; } - OwningCompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; } - OwningCompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; } - OwningCompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; } - OwningCompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; } - bool setIntroductionInfo(JSContext* cx, const char* introducerFn, const char* intro, - unsigned line, JSScript* script, uint32_t offset) - { - if (!setIntroducerFilename(cx, introducerFn)) - return false; - introductionType = intro; - introductionLineno = line; - introductionScriptRoot = script; - introductionOffset = offset; - hasIntroductionInfo = true; - return true; - } - - private: - void operator=(const CompileOptions& rhs) = delete; -}; - -/** - * Compilation options stored on the stack. An instance of this type - * simply holds references to dynamically allocated resources (element; - * filename; source map URL) that are owned by something else. If you - * create an instance of this type, it's up to you to guarantee that - * everything you store in it will outlive it. - */ -class MOZ_STACK_CLASS JS_FRIEND_API(CompileOptions) final : public ReadOnlyCompileOptions -{ - RootedObject elementRoot; - RootedString elementAttributeNameRoot; - RootedScript introductionScriptRoot; - - public: - explicit CompileOptions(JSContext* cx, JSVersion version = JSVERSION_UNKNOWN); - CompileOptions(js::ContextFriendFields* cx, const ReadOnlyCompileOptions& rhs) - : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx), - introductionScriptRoot(cx) - { - copyPODOptions(rhs); - - filename_ = rhs.filename(); - introducerFilename_ = rhs.introducerFilename(); - sourceMapURL_ = rhs.sourceMapURL(); - elementRoot = rhs.element(); - elementAttributeNameRoot = rhs.elementAttributeName(); - introductionScriptRoot = rhs.introductionScript(); - } - - CompileOptions(js::ContextFriendFields* cx, const TransitiveCompileOptions& rhs) - : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx), - introductionScriptRoot(cx) - { - copyPODTransitiveOptions(rhs); - - filename_ = rhs.filename(); - introducerFilename_ = rhs.introducerFilename(); - sourceMapURL_ = rhs.sourceMapURL(); - elementRoot = rhs.element(); - elementAttributeNameRoot = rhs.elementAttributeName(); - introductionScriptRoot = rhs.introductionScript(); - } - - JSObject* element() const override { return elementRoot; } - JSString* elementAttributeName() const override { return elementAttributeNameRoot; } - JSScript* introductionScript() const override { return introductionScriptRoot; } - - CompileOptions& setFile(const char* f) { filename_ = f; return *this; } - CompileOptions& setLine(unsigned l) { lineno = l; return *this; } - CompileOptions& setFileAndLine(const char* f, unsigned l) { - filename_ = f; lineno = l; return *this; - } - CompileOptions& setSourceMapURL(const char16_t* s) { sourceMapURL_ = s; return *this; } - CompileOptions& setElement(JSObject* e) { elementRoot = e; return *this; } - CompileOptions& setElementAttributeName(JSString* p) { - elementAttributeNameRoot = p; - return *this; - } - CompileOptions& setIntroductionScript(JSScript* s) { - introductionScriptRoot = s; - return *this; - } - CompileOptions& setMutedErrors(bool mute) { - mutedErrors_ = mute; - return *this; - } - CompileOptions& setVersion(JSVersion v) { - version = v; - versionSet = true; - return *this; - } - CompileOptions& setUTF8(bool u) { utf8 = u; return *this; } - CompileOptions& setColumn(unsigned c) { column = c; return *this; } - CompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; } - CompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; } - CompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; } - CompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; } - CompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; } - CompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; } - CompileOptions& setIntroductionInfo(const char* introducerFn, const char* intro, - unsigned line, JSScript* script, uint32_t offset) - { - introducerFilename_ = introducerFn; - introductionType = intro; - introductionLineno = line; - introductionScriptRoot = script; - introductionOffset = offset; - hasIntroductionInfo = true; - return *this; - } - CompileOptions& maybeMakeStrictMode(bool strict) { - strictOption = strictOption || strict; - return *this; - } - - private: - void operator=(const CompileOptions& rhs) = delete; -}; - -/** - * |script| will always be set. On failure, it will be set to nullptr. - */ -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* bytes, size_t length, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - FILE* file, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* filename, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* bytes, size_t length, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - FILE* file, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* filename, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CanCompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options, size_t length); - -/* - * Off thread compilation control flow. - * - * After successfully triggering an off thread compile of a script, the - * callback will eventually be invoked with the specified data and a token - * for the compilation. The callback will be invoked while off the main thread, - * so must ensure that its operations are thread safe. Afterwards, one of the - * following functions must be invoked on the main thread: - * - * - FinishOffThreadScript, to get the result script (or nullptr on failure). - * - CancelOffThreadScript, to free the resources without creating a script. - * - * The characters passed in to CompileOffThread must remain live until the - * callback is invoked, and the resulting script will be rooted until the call - * to FinishOffThreadScript. - */ - -extern JS_PUBLIC_API(bool) -CompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, - OffThreadCompileCallback callback, void* callbackData); - -extern JS_PUBLIC_API(JSScript*) -FinishOffThreadScript(JSContext* cx, void* token); - -extern JS_PUBLIC_API(void) -CancelOffThreadScript(JSContext* cx, void* token); - -extern JS_PUBLIC_API(bool) -CompileOffThreadModule(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, - OffThreadCompileCallback callback, void* callbackData); - -extern JS_PUBLIC_API(JSObject*) -FinishOffThreadModule(JSContext* cx, void* token); - -extern JS_PUBLIC_API(void) -CancelOffThreadModule(JSContext* cx, void* token); - -/** - * Compile a function with envChain plus the global as its scope chain. - * envChain must contain objects in the current compartment of cx. The actual - * scope chain used for the function will consist of With wrappers for those - * objects, followed by the current global of the compartment cx is in. This - * global must not be explicitly included in the scope chain. - */ -extern JS_PUBLIC_API(bool) -CompileFunction(JSContext* cx, AutoObjectVector& envChain, - const ReadOnlyCompileOptions& options, - const char* name, unsigned nargs, const char* const* argnames, - const char16_t* chars, size_t length, JS::MutableHandleFunction fun); - -/** - * Same as above, but taking a SourceBufferHolder for the function body. - */ -extern JS_PUBLIC_API(bool) -CompileFunction(JSContext* cx, AutoObjectVector& envChain, - const ReadOnlyCompileOptions& options, - const char* name, unsigned nargs, const char* const* argnames, - SourceBufferHolder& srcBuf, JS::MutableHandleFunction fun); - -/** - * Same as above, but taking a const char * for the function body. - */ -extern JS_PUBLIC_API(bool) -CompileFunction(JSContext* cx, AutoObjectVector& envChain, - const ReadOnlyCompileOptions& options, - const char* name, unsigned nargs, const char* const* argnames, - const char* bytes, size_t length, JS::MutableHandleFunction fun); - -} /* namespace JS */ - -extern JS_PUBLIC_API(JSString*) -JS_DecompileScript(JSContext* cx, JS::Handle script, const char* name, unsigned indent); - -/* - * API extension: OR this into indent to avoid pretty-printing the decompiled - * source resulting from JS_DecompileFunction. - */ -#define JS_DONT_PRETTY_PRINT ((unsigned)0x8000) - -extern JS_PUBLIC_API(JSString*) -JS_DecompileFunction(JSContext* cx, JS::Handle fun, unsigned indent); - - -/* - * NB: JS_ExecuteScript and the JS::Evaluate APIs come in two flavors: either - * they use the global as the scope, or they take an AutoObjectVector of objects - * to use as the scope chain. In the former case, the global is also used as - * the "this" keyword value and the variables object (ECMA parlance for where - * 'var' and 'function' bind names) of the execution context for script. In the - * latter case, the first object in the provided list is used, unless the list - * is empty, in which case the global is used. - * - * Why a runtime option? The alternative is to add APIs duplicating those - * for the other value of flags, and that doesn't seem worth the code bloat - * cost. Such new entry points would probably have less obvious names, too, so - * would not tend to be used. The ContextOptionsRef adjustment, OTOH, can be - * more easily hacked into existing code that does not depend on the bug; such - * code can continue to use the familiar JS::Evaluate, etc., entry points. - */ - -/** - * Evaluate a script in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -JS_ExecuteScript(JSContext* cx, JS::HandleScript script, JS::MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -JS_ExecuteScript(JSContext* cx, JS::HandleScript script); - -/** - * As above, but providing an explicit scope chain. envChain must not include - * the global object on it; that's implicit. It needs to contain the other - * objects that should end up on the script's scope chain. - */ -extern JS_PUBLIC_API(bool) -JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain, - JS::HandleScript script, JS::MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain, JS::HandleScript script); - -namespace JS { - -/** - * Like the above, but handles a cross-compartment script. If the script is - * cross-compartment, it is cloned into the current compartment before executing. - */ -extern JS_PUBLIC_API(bool) -CloneAndExecuteScript(JSContext* cx, JS::Handle script, - JS::MutableHandleValue rval); - -} /* namespace JS */ - -namespace JS { - -/** - * Evaluate the given source buffer in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleValue rval); - -/** - * As above, but providing an explicit scope chain. envChain must not include - * the global object on it; that's implicit. It needs to contain the other - * objects that should end up on the script's scope chain. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, AutoObjectVector& envChain, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleValue rval); - -/** - * Evaluate the given character buffer in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, JS::MutableHandleValue rval); - -/** - * As above, but providing an explicit scope chain. envChain must not include - * the global object on it; that's implicit. It needs to contain the other - * objects that should end up on the script's scope chain. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, AutoObjectVector& envChain, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, JS::MutableHandleValue rval); - -/** - * Evaluate the given byte buffer in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* bytes, size_t length, JS::MutableHandleValue rval); - -/** - * Evaluate the given file in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* filename, JS::MutableHandleValue rval); - -/** - * Get the HostResolveImportedModule hook for a global. - */ -extern JS_PUBLIC_API(JSFunction*) -GetModuleResolveHook(JSContext* cx); - -/** - * Set the HostResolveImportedModule hook for a global to the given function. - */ -extern JS_PUBLIC_API(void) -SetModuleResolveHook(JSContext* cx, JS::HandleFunction func); - -/** - * Parse the given source buffer as a module in the scope of the current global - * of cx and return a source text module record. - */ -extern JS_PUBLIC_API(bool) -CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleObject moduleRecord); - -/** - * Set the [[HostDefined]] field of a source text module record to the given - * value. - */ -extern JS_PUBLIC_API(void) -SetModuleHostDefinedField(JSObject* module, const JS::Value& value); - -/** - * Get the [[HostDefined]] field of a source text module record. - */ -extern JS_PUBLIC_API(JS::Value) -GetModuleHostDefinedField(JSObject* module); - -/* - * Perform the ModuleDeclarationInstantiation operation on on the give source - * text module record. - * - * This transitively resolves all module dependencies (calling the - * HostResolveImportedModule hook) and initializes the environment record for - * the module. - */ -extern JS_PUBLIC_API(bool) -ModuleDeclarationInstantiation(JSContext* cx, JS::HandleObject moduleRecord); - -/* - * Perform the ModuleEvaluation operation on on the give source text module - * record. - * - * This does nothing if this module has already been evaluated. Otherwise, it - * transitively evaluates all dependences of this module and then evaluates this - * module. - * - * ModuleDeclarationInstantiation must have completed prior to calling this. - */ -extern JS_PUBLIC_API(bool) -ModuleEvaluation(JSContext* cx, JS::HandleObject moduleRecord); - -/* - * Get a list of the module specifiers used by a source text module - * record to request importation of modules. - * - * The result is a JavaScript array of string values. To extract the individual - * values use only JS_GetArrayLength and JS_GetElement with indices 0 to - * length - 1. - */ -extern JS_PUBLIC_API(JSObject*) -GetRequestedModules(JSContext* cx, JS::HandleObject moduleRecord); - -/* - * Get the script associated with a module. - */ -extern JS_PUBLIC_API(JSScript*) -GetModuleScript(JSContext* cx, JS::HandleObject moduleRecord); - -} /* namespace JS */ - -extern JS_PUBLIC_API(bool) -JS_CheckForInterrupt(JSContext* cx); - -/* - * These functions allow setting an interrupt callback that will be called - * from the JS thread some time after any thread triggered the callback using - * JS_RequestInterruptCallback(cx). - * - * To schedule the GC and for other activities the engine internally triggers - * interrupt callbacks. The embedding should thus not rely on callbacks being - * triggered through the external API only. - * - * Important note: Additional callbacks can occur inside the callback handler - * if it re-enters the JS engine. The embedding must ensure that the callback - * is disconnected before attempting such re-entry. - */ -extern JS_PUBLIC_API(bool) -JS_AddInterruptCallback(JSContext* cx, JSInterruptCallback callback); - -extern JS_PUBLIC_API(bool) -JS_DisableInterruptCallback(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_ResetInterruptCallback(JSContext* cx, bool enable); - -extern JS_PUBLIC_API(void) -JS_RequestInterruptCallback(JSContext* cx); - -namespace JS { - -/** - * Sets the callback that's invoked whenever an incumbent global is required. - * - * SpiderMonkey doesn't itself have a notion of incumbent globals as defined - * by the html spec, so we need the embedding to provide this. - * See dom/base/ScriptSettings.h for details. - */ -extern JS_PUBLIC_API(void) -SetGetIncumbentGlobalCallback(JSContext* cx, JSGetIncumbentGlobalCallback callback); - -/** - * Sets the callback that's invoked whenever a Promise job should be enqeued. - * - * SpiderMonkey doesn't schedule Promise resolution jobs itself; instead, - * using this function the embedding can provide a callback to do that - * scheduling. The provided `callback` is invoked with the promise job, - * the corresponding Promise's allocation stack, and the `data` pointer - * passed here as arguments. - */ -extern JS_PUBLIC_API(void) -SetEnqueuePromiseJobCallback(JSContext* cx, JSEnqueuePromiseJobCallback callback, - void* data = nullptr); - -/** - * Sets the callback that's invoked whenever a Promise is rejected without - * a rejection handler, and when a Promise that was previously rejected - * without a handler gets a handler attached. - */ -extern JS_PUBLIC_API(void) -SetPromiseRejectionTrackerCallback(JSContext* cx, JSPromiseRejectionTrackerCallback callback, - void* data = nullptr); - -/** - * Returns a new instance of the Promise builtin class in the current - * compartment, with the right slot layout. If a `proto` is passed, that gets - * set as the instance's [[Prototype]] instead of the original value of - * `Promise.prototype`. - */ -extern JS_PUBLIC_API(JSObject*) -NewPromiseObject(JSContext* cx, JS::HandleObject executor, JS::HandleObject proto = nullptr); - -/** - * Returns true if the given object is an unwrapped PromiseObject, false - * otherwise. - */ -extern JS_PUBLIC_API(bool) -IsPromiseObject(JS::HandleObject obj); - -/** - * Returns the current compartment's original Promise constructor. - */ -extern JS_PUBLIC_API(JSObject*) -GetPromiseConstructor(JSContext* cx); - -/** - * Returns the current compartment's original Promise.prototype. - */ -extern JS_PUBLIC_API(JSObject*) -GetPromisePrototype(JSContext* cx); - -// Keep this in sync with the PROMISE_STATE defines in SelfHostingDefines.h. -enum class PromiseState { - Pending, - Fulfilled, - Rejected -}; - -/** - * Returns the given Promise's state as a JS::PromiseState enum value. - */ -extern JS_PUBLIC_API(PromiseState) -GetPromiseState(JS::HandleObject promise); - -/** - * Returns the given Promise's process-unique ID. - */ -JS_PUBLIC_API(uint64_t) -GetPromiseID(JS::HandleObject promise); - -/** - * Returns the given Promise's result: either the resolution value for - * fulfilled promises, or the rejection reason for rejected ones. - */ -extern JS_PUBLIC_API(JS::Value) -GetPromiseResult(JS::HandleObject promise); - -/** - * Returns a js::SavedFrame linked list of the stack that lead to the given - * Promise's allocation. - */ -extern JS_PUBLIC_API(JSObject*) -GetPromiseAllocationSite(JS::HandleObject promise); - -extern JS_PUBLIC_API(JSObject*) -GetPromiseResolutionSite(JS::HandleObject promise); - -#ifdef DEBUG -extern JS_PUBLIC_API(void) -DumpPromiseAllocationSite(JSContext* cx, JS::HandleObject promise); - -extern JS_PUBLIC_API(void) -DumpPromiseResolutionSite(JSContext* cx, JS::HandleObject promise); -#endif - -/** - * Calls the current compartment's original Promise.resolve on the original - * Promise constructor, with `resolutionValue` passed as an argument. - */ -extern JS_PUBLIC_API(JSObject*) -CallOriginalPromiseResolve(JSContext* cx, JS::HandleValue resolutionValue); - -/** - * Calls the current compartment's original Promise.reject on the original - * Promise constructor, with `resolutionValue` passed as an argument. - */ -extern JS_PUBLIC_API(JSObject*) -CallOriginalPromiseReject(JSContext* cx, JS::HandleValue rejectionValue); - -/** - * Resolves the given Promise with the given `resolutionValue`. - * - * Calls the `resolve` function that was passed to the executor function when - * the Promise was created. - */ -extern JS_PUBLIC_API(bool) -ResolvePromise(JSContext* cx, JS::HandleObject promise, JS::HandleValue resolutionValue); - -/** - * Rejects the given `promise` with the given `rejectionValue`. - * - * Calls the `reject` function that was passed to the executor function when - * the Promise was created. - */ -extern JS_PUBLIC_API(bool) -RejectPromise(JSContext* cx, JS::HandleObject promise, JS::HandleValue rejectionValue); - -/** - * Calls the current compartment's original Promise.prototype.then on the - * given `promise`, with `onResolve` and `onReject` passed as arguments. - * - * Asserts if the passed-in `promise` object isn't an unwrapped instance of - * `Promise` or a subclass or `onResolve` and `onReject` aren't both either - * `nullptr` or callable objects. - */ -extern JS_PUBLIC_API(JSObject*) -CallOriginalPromiseThen(JSContext* cx, JS::HandleObject promise, - JS::HandleObject onResolve, JS::HandleObject onReject); - -/** - * Unforgeable, optimized version of the JS builtin Promise.prototype.then. - * - * Takes a Promise instance and `onResolve`, `onReject` callables to enqueue - * as reactions for that promise. In difference to Promise.prototype.then, - * this doesn't create and return a new Promise instance. - * - * Asserts if the passed-in `promise` object isn't an unwrapped instance of - * `Promise` or a subclass or `onResolve` and `onReject` aren't both callable - * objects. - */ -extern JS_PUBLIC_API(bool) -AddPromiseReactions(JSContext* cx, JS::HandleObject promise, - JS::HandleObject onResolve, JS::HandleObject onReject); - -/** - * Unforgeable version of the JS builtin Promise.all. - * - * Takes an AutoObjectVector of Promise objects and returns a promise that's - * resolved with an array of resolution values when all those promises ahve - * been resolved, or rejected with the rejection value of the first rejected - * promise. - * - * Asserts if the array isn't dense or one of the entries isn't an unwrapped - * instance of Promise or a subclass. - */ -extern JS_PUBLIC_API(JSObject*) -GetWaitForAllPromise(JSContext* cx, const JS::AutoObjectVector& promises); - -/** - * An AsyncTask represents a SpiderMonkey-internal operation that starts on a - * JSContext's owner thread, possibly executes on other threads, completes, and - * then needs to be scheduled to run again on the JSContext's owner thread. The - * embedding provides for this final dispatch back to the JSContext's owner - * thread by calling methods on this interface when requested. - */ -struct JS_PUBLIC_API(AsyncTask) -{ - AsyncTask() : user(nullptr) {} - virtual ~AsyncTask() {} - - /** - * After the FinishAsyncTaskCallback is called and succeeds, one of these - * two functions will be called on the original JSContext's owner thread. - */ - virtual void finish(JSContext* cx) = 0; - virtual void cancel(JSContext* cx) = 0; - - /* The embedding may use this field to attach arbitrary data to a task. */ - void* user; -}; - -/** - * A new AsyncTask object, created inside SpiderMonkey on the JSContext's owner - * thread, will be passed to the StartAsyncTaskCallback before it is dispatched - * to another thread. The embedding may use the AsyncTask::user field to attach - * additional task state. - * - * If this function succeeds, SpiderMonkey will call the FinishAsyncTaskCallback - * at some point in the future. Otherwise, FinishAsyncTaskCallback will *not* - * be called. SpiderMonkey assumes that, if StartAsyncTaskCallback fails, it is - * because the JSContext is being shut down. - */ -typedef bool -(*StartAsyncTaskCallback)(JSContext* cx, AsyncTask* task); - -/** - * The FinishAsyncTaskCallback may be called from any thread and will only be - * passed AsyncTasks that have already been started via StartAsyncTaskCallback. - * If the embedding returns 'true', indicating success, the embedding must call - * either task->finish() or task->cancel() on the JSContext's owner thread at - * some point in the future. - */ -typedef bool -(*FinishAsyncTaskCallback)(AsyncTask* task); - -/** - * Set the above callbacks for the given context. - */ -extern JS_PUBLIC_API(void) -SetAsyncTaskCallbacks(JSContext* cx, StartAsyncTaskCallback start, FinishAsyncTaskCallback finish); - -} // namespace JS - -extern JS_PUBLIC_API(bool) -JS_IsRunning(JSContext* cx); - -namespace JS { - -/** - * This class can be used to store a pointer to the youngest frame of a saved - * stack in the specified JSContext. This reference will be picked up by any new - * calls performed until the class is destroyed, with the specified asyncCause, - * that must not be empty. - * - * Any stack capture initiated during these new calls will go through the async - * stack instead of the current stack. - * - * Capturing the stack before a new call is performed will not be affected. - * - * The provided chain of SavedFrame objects can live in any compartment, - * although it will be copied to the compartment where the stack is captured. - * - * See also `js/src/doc/SavedFrame/SavedFrame.md` for documentation on async - * stack frames. - */ -class MOZ_STACK_CLASS JS_PUBLIC_API(AutoSetAsyncStackForNewCalls) -{ - JSContext* cx; - RootedObject oldAsyncStack; - const char* oldAsyncCause; - bool oldAsyncCallIsExplicit; - - public: - enum class AsyncCallKind { - // The ordinary kind of call, where we may apply an async - // parent if there is no ordinary parent. - IMPLICIT, - // An explicit async parent, e.g., callFunctionWithAsyncStack, - // where we always want to override any ordinary parent. - EXPLICIT - }; - - // The stack parameter cannot be null by design, because it would be - // ambiguous whether that would clear any scheduled async stack and make the - // normal stack reappear in the new call, or just keep the async stack - // already scheduled for the new call, if any. - // - // asyncCause is owned by the caller and its lifetime must outlive the - // lifetime of the AutoSetAsyncStackForNewCalls object. It is strongly - // encouraged that asyncCause be a string constant or similar statically - // allocated string. - AutoSetAsyncStackForNewCalls(JSContext* cx, HandleObject stack, - const char* asyncCause, - AsyncCallKind kind = AsyncCallKind::IMPLICIT); - ~AutoSetAsyncStackForNewCalls(); -}; - -} // namespace JS - -/************************************************************************/ - -/* - * Strings. - * - * NB: JS_NewUCString takes ownership of bytes on success, avoiding a copy; - * but on error (signified by null return), it leaves chars owned by the - * caller. So the caller must free bytes in the error case, if it has no use - * for them. In contrast, all the JS_New*StringCopy* functions do not take - * ownership of the character memory passed to them -- they copy it. - */ -extern JS_PUBLIC_API(JSString*) -JS_NewStringCopyN(JSContext* cx, const char* s, size_t n); - -extern JS_PUBLIC_API(JSString*) -JS_NewStringCopyZ(JSContext* cx, const char* s); - -extern JS_PUBLIC_API(JSString*) -JS_NewStringCopyUTF8Z(JSContext* cx, const JS::ConstUTF8CharsZ s); - -extern JS_PUBLIC_API(JSString*) -JS_NewStringCopyUTF8N(JSContext* cx, const JS::UTF8Chars s); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeAndPinJSString(JSContext* cx, JS::HandleString str); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeStringN(JSContext* cx, const char* s, size_t length); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeString(JSContext* cx, const char* s); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeAndPinStringN(JSContext* cx, const char* s, size_t length); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeAndPinString(JSContext* cx, const char* s); - -extern JS_PUBLIC_API(JSString*) -JS_NewUCString(JSContext* cx, char16_t* chars, size_t length); - -extern JS_PUBLIC_API(JSString*) -JS_NewUCStringCopyN(JSContext* cx, const char16_t* s, size_t n); - -extern JS_PUBLIC_API(JSString*) -JS_NewUCStringCopyZ(JSContext* cx, const char16_t* s); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeUCStringN(JSContext* cx, const char16_t* s, size_t length); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeUCString(JSContext* cx, const char16_t* s); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeAndPinUCStringN(JSContext* cx, const char16_t* s, size_t length); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeAndPinUCString(JSContext* cx, const char16_t* s); - -extern JS_PUBLIC_API(bool) -JS_CompareStrings(JSContext* cx, JSString* str1, JSString* str2, int32_t* result); - -extern JS_PUBLIC_API(bool) -JS_StringEqualsAscii(JSContext* cx, JSString* str, const char* asciiBytes, bool* match); - -extern JS_PUBLIC_API(size_t) -JS_PutEscapedString(JSContext* cx, char* buffer, size_t size, JSString* str, char quote); - -extern JS_PUBLIC_API(bool) -JS_FileEscapedString(FILE* fp, JSString* str, char quote); - -/* - * Extracting string characters and length. - * - * While getting the length of a string is infallible, getting the chars can - * fail. As indicated by the lack of a JSContext parameter, there are two - * special cases where getting the chars is infallible: - * - * The first case is for strings that have been atomized, e.g. directly by - * JS_AtomizeAndPinString or implicitly because it is stored in a jsid. - * - * The second case is "flat" strings that have been explicitly prepared in a - * fallible context by JS_FlattenString. To catch errors, a separate opaque - * JSFlatString type is returned by JS_FlattenString and expected by - * JS_GetFlatStringChars. Note, though, that this is purely a syntactic - * distinction: the input and output of JS_FlattenString are the same actual - * GC-thing. If a JSString is known to be flat, JS_ASSERT_STRING_IS_FLAT can be - * used to make a debug-checked cast. Example: - * - * // in a fallible context - * JSFlatString* fstr = JS_FlattenString(cx, str); - * if (!fstr) - * return false; - * MOZ_ASSERT(fstr == JS_ASSERT_STRING_IS_FLAT(str)); - * - * // in an infallible context, for the same 'str' - * AutoCheckCannotGC nogc; - * const char16_t* chars = JS_GetTwoByteFlatStringChars(nogc, fstr) - * MOZ_ASSERT(chars); - * - * Flat strings and interned strings are always null-terminated, so - * JS_FlattenString can be used to get a null-terminated string. - * - * Additionally, string characters are stored as either Latin1Char (8-bit) - * or char16_t (16-bit). Clients can use JS_StringHasLatin1Chars and can then - * call either the Latin1* or TwoByte* functions. Some functions like - * JS_CopyStringChars and JS_GetStringCharAt accept both Latin1 and TwoByte - * strings. - */ - -extern JS_PUBLIC_API(size_t) -JS_GetStringLength(JSString* str); - -extern JS_PUBLIC_API(bool) -JS_StringIsFlat(JSString* str); - -/** Returns true iff the string's characters are stored as Latin1. */ -extern JS_PUBLIC_API(bool) -JS_StringHasLatin1Chars(JSString* str); - -extern JS_PUBLIC_API(const JS::Latin1Char*) -JS_GetLatin1StringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str, - size_t* length); - -extern JS_PUBLIC_API(const char16_t*) -JS_GetTwoByteStringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str, - size_t* length); - -extern JS_PUBLIC_API(bool) -JS_GetStringCharAt(JSContext* cx, JSString* str, size_t index, char16_t* res); - -extern JS_PUBLIC_API(char16_t) -JS_GetFlatStringCharAt(JSFlatString* str, size_t index); - -extern JS_PUBLIC_API(const char16_t*) -JS_GetTwoByteExternalStringChars(JSString* str); - -extern JS_PUBLIC_API(bool) -JS_CopyStringChars(JSContext* cx, mozilla::Range dest, JSString* str); - -extern JS_PUBLIC_API(JSFlatString*) -JS_FlattenString(JSContext* cx, JSString* str); - -extern JS_PUBLIC_API(const JS::Latin1Char*) -JS_GetLatin1FlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str); - -extern JS_PUBLIC_API(const char16_t*) -JS_GetTwoByteFlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str); - -static MOZ_ALWAYS_INLINE JSFlatString* -JSID_TO_FLAT_STRING(jsid id) -{ - MOZ_ASSERT(JSID_IS_STRING(id)); - return (JSFlatString*)(JSID_BITS(id)); -} - -static MOZ_ALWAYS_INLINE JSFlatString* -JS_ASSERT_STRING_IS_FLAT(JSString* str) -{ - MOZ_ASSERT(JS_StringIsFlat(str)); - return (JSFlatString*)str; -} - -static MOZ_ALWAYS_INLINE JSString* -JS_FORGET_STRING_FLATNESS(JSFlatString* fstr) -{ - return (JSString*)fstr; -} - -/* - * Additional APIs that avoid fallibility when given a flat string. - */ - -extern JS_PUBLIC_API(bool) -JS_FlatStringEqualsAscii(JSFlatString* str, const char* asciiBytes); - -extern JS_PUBLIC_API(size_t) -JS_PutEscapedFlatString(char* buffer, size_t size, JSFlatString* str, char quote); - -/** - * Create a dependent string, i.e., a string that owns no character storage, - * but that refers to a slice of another string's chars. Dependent strings - * are mutable by definition, so the thread safety comments above apply. - */ -extern JS_PUBLIC_API(JSString*) -JS_NewDependentString(JSContext* cx, JS::HandleString str, size_t start, - size_t length); - -/** - * Concatenate two strings, possibly resulting in a rope. - * See above for thread safety comments. - */ -extern JS_PUBLIC_API(JSString*) -JS_ConcatStrings(JSContext* cx, JS::HandleString left, JS::HandleString right); - -/** - * For JS_DecodeBytes, set *dstlenp to the size of the destination buffer before - * the call; on return, *dstlenp contains the number of characters actually - * stored. To determine the necessary destination buffer size, make a sizing - * call that passes nullptr for dst. - * - * On errors, the functions report the error. In that case, *dstlenp contains - * the number of characters or bytes transferred so far. If cx is nullptr, no - * error is reported on failure, and the functions simply return false. - * - * NB: This function does not store an additional zero byte or char16_t after the - * transcoded string. - */ -JS_PUBLIC_API(bool) -JS_DecodeBytes(JSContext* cx, const char* src, size_t srclen, char16_t* dst, - size_t* dstlenp); - -/** - * A variation on JS_EncodeCharacters where a null terminated string is - * returned that you are expected to call JS_free on when done. - */ -JS_PUBLIC_API(char*) -JS_EncodeString(JSContext* cx, JSString* str); - -/** - * Same behavior as JS_EncodeString(), but encode into UTF-8 string - */ -JS_PUBLIC_API(char*) -JS_EncodeStringToUTF8(JSContext* cx, JS::HandleString str); - -/** - * Get number of bytes in the string encoding (without accounting for a - * terminating zero bytes. The function returns (size_t) -1 if the string - * can not be encoded into bytes and reports an error using cx accordingly. - */ -JS_PUBLIC_API(size_t) -JS_GetStringEncodingLength(JSContext* cx, JSString* str); - -/** - * Encode string into a buffer. The function does not stores an additional - * zero byte. The function returns (size_t) -1 if the string can not be - * encoded into bytes with no error reported. Otherwise it returns the number - * of bytes that are necessary to encode the string. If that exceeds the - * length parameter, the string will be cut and only length bytes will be - * written into the buffer. - */ -JS_PUBLIC_API(size_t) -JS_EncodeStringToBuffer(JSContext* cx, JSString* str, char* buffer, size_t length); - -class MOZ_RAII JSAutoByteString -{ - public: - JSAutoByteString(JSContext* cx, JSString* str - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mBytes(JS_EncodeString(cx, str)) - { - MOZ_ASSERT(cx); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - explicit JSAutoByteString(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) - : mBytes(nullptr) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - ~JSAutoByteString() { - JS_free(nullptr, mBytes); - } - - /* Take ownership of the given byte array. */ - void initBytes(char* bytes) { - MOZ_ASSERT(!mBytes); - mBytes = bytes; - } - - char* encodeLatin1(JSContext* cx, JSString* str) { - MOZ_ASSERT(!mBytes); - MOZ_ASSERT(cx); - mBytes = JS_EncodeString(cx, str); - return mBytes; - } - - char* encodeLatin1(js::ExclusiveContext* cx, JSString* str); - - char* encodeUtf8(JSContext* cx, JS::HandleString str) { - MOZ_ASSERT(!mBytes); - MOZ_ASSERT(cx); - mBytes = JS_EncodeStringToUTF8(cx, str); - return mBytes; - } - - void clear() { - js_free(mBytes); - mBytes = nullptr; - } - - char* ptr() const { - return mBytes; - } - - bool operator!() const { - return !mBytes; - } - - size_t length() const { - if (!mBytes) - return 0; - return strlen(mBytes); - } - - private: - char* mBytes; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - - /* Copy and assignment are not supported. */ - JSAutoByteString(const JSAutoByteString& another); - JSAutoByteString& operator=(const JSAutoByteString& another); -}; - -namespace JS { - -extern JS_PUBLIC_API(JSAddonId*) -NewAddonId(JSContext* cx, JS::HandleString str); - -extern JS_PUBLIC_API(JSString*) -StringOfAddonId(JSAddonId* id); - -extern JS_PUBLIC_API(JSAddonId*) -AddonIdOfObject(JSObject* obj); - -} // namespace JS - -/************************************************************************/ -/* - * Symbols - */ - -namespace JS { - -/** - * Create a new Symbol with the given description. This function never returns - * a Symbol that is in the Runtime-wide symbol registry. - * - * If description is null, the new Symbol's [[Description]] attribute is - * undefined. - */ -JS_PUBLIC_API(Symbol*) -NewSymbol(JSContext* cx, HandleString description); - -/** - * Symbol.for as specified in ES6. - * - * Get a Symbol with the description 'key' from the Runtime-wide symbol registry. - * If there is not already a Symbol with that description in the registry, a new - * Symbol is created and registered. 'key' must not be null. - */ -JS_PUBLIC_API(Symbol*) -GetSymbolFor(JSContext* cx, HandleString key); - -/** - * Get the [[Description]] attribute of the given symbol. - * - * This function is infallible. If it returns null, that means the symbol's - * [[Description]] is undefined. - */ -JS_PUBLIC_API(JSString*) -GetSymbolDescription(HandleSymbol symbol); - -/* Well-known symbols. */ -#define JS_FOR_EACH_WELL_KNOWN_SYMBOL(macro) \ - macro(isConcatSpreadable) \ - macro(iterator) \ - macro(match) \ - macro(replace) \ - macro(search) \ - macro(species) \ - macro(hasInstance) \ - macro(split) \ - macro(toPrimitive) \ - macro(toStringTag) \ - macro(unscopables) - -enum class SymbolCode : uint32_t { - // There is one SymbolCode for each well-known symbol. -#define JS_DEFINE_SYMBOL_ENUM(name) name, - JS_FOR_EACH_WELL_KNOWN_SYMBOL(JS_DEFINE_SYMBOL_ENUM) // SymbolCode::iterator, etc. -#undef JS_DEFINE_SYMBOL_ENUM - Limit, - InSymbolRegistry = 0xfffffffe, // created by Symbol.for() or JS::GetSymbolFor() - UniqueSymbol = 0xffffffff // created by Symbol() or JS::NewSymbol() -}; - -/* For use in loops that iterate over the well-known symbols. */ -const size_t WellKnownSymbolLimit = size_t(SymbolCode::Limit); - -/** - * Return the SymbolCode telling what sort of symbol `symbol` is. - * - * A symbol's SymbolCode never changes once it is created. - */ -JS_PUBLIC_API(SymbolCode) -GetSymbolCode(Handle symbol); - -/** - * Get one of the well-known symbols defined by ES6. A single set of well-known - * symbols is shared by all compartments in a JSRuntime. - * - * `which` must be in the range [0, WellKnownSymbolLimit). - */ -JS_PUBLIC_API(Symbol*) -GetWellKnownSymbol(JSContext* cx, SymbolCode which); - -/** - * Return true if the given JSPropertySpec::name or JSFunctionSpec::name value - * is actually a symbol code and not a string. See JS_SYM_FN. - */ -inline bool -PropertySpecNameIsSymbol(const char* name) -{ - uintptr_t u = reinterpret_cast(name); - return u != 0 && u - 1 < WellKnownSymbolLimit; -} - -JS_PUBLIC_API(bool) -PropertySpecNameEqualsId(const char* name, HandleId id); - -/** - * Create a jsid that does not need to be marked for GC. - * - * 'name' is a JSPropertySpec::name or JSFunctionSpec::name value. The - * resulting jsid, on success, is either an interned string or a well-known - * symbol; either way it is immune to GC so there is no need to visit *idp - * during GC marking. - */ -JS_PUBLIC_API(bool) -PropertySpecNameToPermanentId(JSContext* cx, const char* name, jsid* idp); - -} /* namespace JS */ - -/************************************************************************/ -/* - * JSON functions - */ -typedef bool (* JSONWriteCallback)(const char16_t* buf, uint32_t len, void* data); - -/** - * JSON.stringify as specified by ES5. - */ -JS_PUBLIC_API(bool) -JS_Stringify(JSContext* cx, JS::MutableHandleValue value, JS::HandleObject replacer, - JS::HandleValue space, JSONWriteCallback callback, void* data); - -namespace JS { - -/** - * An API akin to JS_Stringify but with the goal of not having observable - * side-effects when the stringification is performed. This means it does not - * allow a replacer or a custom space, and has the following constraints on its - * input: - * - * 1) The input must be a plain object or array, not an abitrary value. - * 2) Every value in the graph reached by the algorithm starting with this - * object must be one of the following: null, undefined, a string (NOT a - * string object!), a boolean, a finite number (i.e. no NaN or Infinity or - * -Infinity), a plain object with no accessor properties, or an Array with - * no holes. - * - * The actual behavior differs from JS_Stringify only in asserting the above and - * NOT attempting to get the "toJSON" property from things, since that could - * clearly have side-effects. - */ -JS_PUBLIC_API(bool) -ToJSONMaybeSafely(JSContext* cx, JS::HandleObject input, - JSONWriteCallback callback, void* data); - -} /* namespace JS */ - -/** - * JSON.parse as specified by ES5. - */ -JS_PUBLIC_API(bool) -JS_ParseJSON(JSContext* cx, const char16_t* chars, uint32_t len, JS::MutableHandleValue vp); - -JS_PUBLIC_API(bool) -JS_ParseJSON(JSContext* cx, JS::HandleString str, JS::MutableHandleValue vp); - -JS_PUBLIC_API(bool) -JS_ParseJSONWithReviver(JSContext* cx, const char16_t* chars, uint32_t len, JS::HandleValue reviver, - JS::MutableHandleValue vp); - -JS_PUBLIC_API(bool) -JS_ParseJSONWithReviver(JSContext* cx, JS::HandleString str, JS::HandleValue reviver, - JS::MutableHandleValue vp); - -/************************************************************************/ - -/** - * The default locale for the ECMAScript Internationalization API - * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat). - * Note that the Internationalization API encourages clients to - * specify their own locales. - * The locale string remains owned by the caller. - */ -extern JS_PUBLIC_API(bool) -JS_SetDefaultLocale(JSContext* cx, const char* locale); - -/** - * Look up the default locale for the ECMAScript Internationalization API. - */ -extern JS_PUBLIC_API(JS::UniqueChars) -JS_GetDefaultLocale(JSContext* cx); - -/** - * Reset the default locale to OS defaults. - */ -extern JS_PUBLIC_API(void) -JS_ResetDefaultLocale(JSContext* cx); - -/** - * Locale specific string conversion and error message callbacks. - */ -struct JSLocaleCallbacks { - JSLocaleToUpperCase localeToUpperCase; - JSLocaleToLowerCase localeToLowerCase; - JSLocaleCompare localeCompare; // not used #if EXPOSE_INTL_API - JSLocaleToUnicode localeToUnicode; -}; - -/** - * Establish locale callbacks. The pointer must persist as long as the - * JSContext. Passing nullptr restores the default behaviour. - */ -extern JS_PUBLIC_API(void) -JS_SetLocaleCallbacks(JSContext* cx, const JSLocaleCallbacks* callbacks); - -/** - * Return the address of the current locale callbacks struct, which may - * be nullptr. - */ -extern JS_PUBLIC_API(const JSLocaleCallbacks*) -JS_GetLocaleCallbacks(JSContext* cx); - -/************************************************************************/ - -/* - * Error reporting. - */ - -namespace JS { -const uint16_t MaxNumErrorArguments = 10; -}; - -/** - * Report an exception represented by the sprintf-like conversion of format - * and its arguments. - */ -extern JS_PUBLIC_API(void) -JS_ReportErrorASCII(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -extern JS_PUBLIC_API(void) -JS_ReportErrorLatin1(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -extern JS_PUBLIC_API(void) -JS_ReportErrorUTF8(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -/* - * Use an errorNumber to retrieve the format string, args are char* - */ -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberASCII(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, ...); - -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberASCIIVA(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, va_list ap); - -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberLatin1(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, ...); - -#ifdef va_start -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberLatin1VA(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, va_list ap); -#endif - -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberUTF8(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, ...); - -#ifdef va_start -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberUTF8VA(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, va_list ap); -#endif - -/* - * Use an errorNumber to retrieve the format string, args are char16_t* - */ -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberUC(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, ...); - -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberUCArray(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, - const char16_t** args); - -/** - * As above, but report a warning instead (JSREPORT_IS_WARNING(report.flags)). - * Return true if there was no error trying to issue the warning, and if the - * warning was not converted into an error due to the JSOPTION_WERROR option - * being set, false otherwise. - */ -extern JS_PUBLIC_API(bool) -JS_ReportWarningASCII(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -extern JS_PUBLIC_API(bool) -JS_ReportWarningLatin1(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -extern JS_PUBLIC_API(bool) -JS_ReportWarningUTF8(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -extern JS_PUBLIC_API(bool) -JS_ReportErrorFlagsAndNumberASCII(JSContext* cx, unsigned flags, - JSErrorCallback errorCallback, void* userRef, - const unsigned errorNumber, ...); - -extern JS_PUBLIC_API(bool) -JS_ReportErrorFlagsAndNumberLatin1(JSContext* cx, unsigned flags, - JSErrorCallback errorCallback, void* userRef, - const unsigned errorNumber, ...); - -extern JS_PUBLIC_API(bool) -JS_ReportErrorFlagsAndNumberUTF8(JSContext* cx, unsigned flags, - JSErrorCallback errorCallback, void* userRef, - const unsigned errorNumber, ...); - -extern JS_PUBLIC_API(bool) -JS_ReportErrorFlagsAndNumberUC(JSContext* cx, unsigned flags, - JSErrorCallback errorCallback, void* userRef, - const unsigned errorNumber, ...); - -/** - * Complain when out of memory. - */ -extern JS_PUBLIC_API(void) -JS_ReportOutOfMemory(JSContext* cx); - -/** - * Complain when an allocation size overflows the maximum supported limit. - */ -extern JS_PUBLIC_API(void) -JS_ReportAllocationOverflow(JSContext* cx); - -class JSErrorReport -{ - // The (default) error message. - // If ownsMessage_ is true, the it is freed in destructor. - JS::ConstUTF8CharsZ message_; - - // Offending source line without final '\n'. - // If ownsLinebuf__ is true, the buffer is freed in destructor. - const char16_t* linebuf_; - - // Number of chars in linebuf_. Does not include trailing '\0'. - size_t linebufLength_; - - // The 0-based offset of error token in linebuf_. - size_t tokenOffset_; - - public: - JSErrorReport() - : linebuf_(nullptr), linebufLength_(0), tokenOffset_(0), - filename(nullptr), lineno(0), column(0), - flags(0), errorNumber(0), - exnType(0), isMuted(false), - ownsLinebuf_(false), ownsMessage_(false) - {} - - ~JSErrorReport() { - freeLinebuf(); - freeMessage(); - } - - const char* filename; /* source file name, URL, etc., or null */ - unsigned lineno; /* source line number */ - unsigned column; /* zero-based column index in line */ - unsigned flags; /* error/warning, etc. */ - unsigned errorNumber; /* the error number, e.g. see js.msg */ - int16_t exnType; /* One of the JSExnType constants */ - bool isMuted : 1; /* See the comment in ReadOnlyCompileOptions. */ - - private: - bool ownsLinebuf_ : 1; - bool ownsMessage_ : 1; - - public: - const char16_t* linebuf() const { - return linebuf_; - } - size_t linebufLength() const { - return linebufLength_; - } - size_t tokenOffset() const { - return tokenOffset_; - } - void initOwnedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg, size_t tokenOffsetArg) { - initBorrowedLinebuf(linebufArg, linebufLengthArg, tokenOffsetArg); - ownsLinebuf_ = true; - } - void initBorrowedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg, size_t tokenOffsetArg); - void freeLinebuf(); - - const JS::ConstUTF8CharsZ message() const { - return message_; - } - - void initOwnedMessage(const char* messageArg) { - initBorrowedMessage(messageArg); - ownsMessage_ = true; - } - void initBorrowedMessage(const char* messageArg) { - MOZ_ASSERT(!message_); - message_ = JS::ConstUTF8CharsZ(messageArg, strlen(messageArg)); - } - - JSString* newMessageString(JSContext* cx); - - void freeMessage(); -}; - -/* - * JSErrorReport flag values. These may be freely composed. - */ -#define JSREPORT_ERROR 0x0 /* pseudo-flag for default case */ -#define JSREPORT_WARNING 0x1 /* reported via JS_ReportWarning */ -#define JSREPORT_EXCEPTION 0x2 /* exception was thrown */ -#define JSREPORT_STRICT 0x4 /* error or warning due to strict option */ - -#define JSREPORT_USER_1 0x8 /* user-defined flag */ - -/* - * If JSREPORT_EXCEPTION is set, then a JavaScript-catchable exception - * has been thrown for this runtime error, and the host should ignore it. - * Exception-aware hosts should also check for JS_IsExceptionPending if - * JS_ExecuteScript returns failure, and signal or propagate the exception, as - * appropriate. - */ -#define JSREPORT_IS_WARNING(flags) (((flags) & JSREPORT_WARNING) != 0) -#define JSREPORT_IS_EXCEPTION(flags) (((flags) & JSREPORT_EXCEPTION) != 0) -#define JSREPORT_IS_STRICT(flags) (((flags) & JSREPORT_STRICT) != 0) - -namespace JS { - -using WarningReporter = void (*)(JSContext* cx, JSErrorReport* report); - -extern JS_PUBLIC_API(WarningReporter) -SetWarningReporter(JSContext* cx, WarningReporter reporter); - -extern JS_PUBLIC_API(WarningReporter) -GetWarningReporter(JSContext* cx); - -extern JS_PUBLIC_API(bool) -CreateError(JSContext* cx, JSExnType type, HandleObject stack, - HandleString fileName, uint32_t lineNumber, uint32_t columnNumber, - JSErrorReport* report, HandleString message, MutableHandleValue rval); - -/************************************************************************/ - -/* - * Weak Maps. - */ - -extern JS_PUBLIC_API(JSObject*) -NewWeakMapObject(JSContext* cx); - -extern JS_PUBLIC_API(bool) -IsWeakMapObject(JSObject* obj); - -extern JS_PUBLIC_API(bool) -GetWeakMapEntry(JSContext* cx, JS::HandleObject mapObj, JS::HandleObject key, - JS::MutableHandleValue val); - -extern JS_PUBLIC_API(bool) -SetWeakMapEntry(JSContext* cx, JS::HandleObject mapObj, JS::HandleObject key, - JS::HandleValue val); - -/* - * Map - */ -extern JS_PUBLIC_API(JSObject*) -NewMapObject(JSContext* cx); - -extern JS_PUBLIC_API(uint32_t) -MapSize(JSContext* cx, HandleObject obj); - -extern JS_PUBLIC_API(bool) -MapGet(JSContext* cx, HandleObject obj, - HandleValue key, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -MapHas(JSContext* cx, HandleObject obj, HandleValue key, bool* rval); - -extern JS_PUBLIC_API(bool) -MapSet(JSContext* cx, HandleObject obj, HandleValue key, HandleValue val); - -extern JS_PUBLIC_API(bool) -MapDelete(JSContext *cx, HandleObject obj, HandleValue key, bool *rval); - -extern JS_PUBLIC_API(bool) -MapClear(JSContext* cx, HandleObject obj); - -extern JS_PUBLIC_API(bool) -MapKeys(JSContext* cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -MapValues(JSContext* cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -MapEntries(JSContext* cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -MapForEach(JSContext *cx, HandleObject obj, HandleValue callbackFn, HandleValue thisVal); - -/* - * Set - */ -extern JS_PUBLIC_API(JSObject *) -NewSetObject(JSContext *cx); - -extern JS_PUBLIC_API(uint32_t) -SetSize(JSContext *cx, HandleObject obj); - -extern JS_PUBLIC_API(bool) -SetHas(JSContext *cx, HandleObject obj, HandleValue key, bool *rval); - -extern JS_PUBLIC_API(bool) -SetDelete(JSContext *cx, HandleObject obj, HandleValue key, bool *rval); - -extern JS_PUBLIC_API(bool) -SetAdd(JSContext *cx, HandleObject obj, HandleValue key); - -extern JS_PUBLIC_API(bool) -SetClear(JSContext *cx, HandleObject obj); - -extern JS_PUBLIC_API(bool) -SetKeys(JSContext *cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -SetValues(JSContext *cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -SetEntries(JSContext *cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -SetForEach(JSContext *cx, HandleObject obj, HandleValue callbackFn, HandleValue thisVal); - -} /* namespace JS */ - -/* - * Dates. - */ - -extern JS_PUBLIC_API(JSObject*) -JS_NewDateObject(JSContext* cx, int year, int mon, int mday, int hour, int min, int sec); - -/** - * Returns true and sets |*isDate| indicating whether |obj| is a Date object or - * a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isDate == false| when passed a proxy whose - * target is a Date, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -JS_ObjectIsDate(JSContext* cx, JS::HandleObject obj, bool* isDate); - -/************************************************************************/ - -/* - * Regular Expressions. - */ -#define JSREG_FOLD 0x01u /* fold uppercase to lowercase */ -#define JSREG_GLOB 0x02u /* global exec, creates array of matches */ -#define JSREG_MULTILINE 0x04u /* treat ^ and $ as begin and end of line */ -#define JSREG_STICKY 0x08u /* only match starting at lastIndex */ -#define JSREG_UNICODE 0x10u /* unicode */ - -extern JS_PUBLIC_API(JSObject*) -JS_NewRegExpObject(JSContext* cx, const char* bytes, size_t length, unsigned flags); - -extern JS_PUBLIC_API(JSObject*) -JS_NewUCRegExpObject(JSContext* cx, const char16_t* chars, size_t length, unsigned flags); - -extern JS_PUBLIC_API(bool) -JS_SetRegExpInput(JSContext* cx, JS::HandleObject obj, JS::HandleString input); - -extern JS_PUBLIC_API(bool) -JS_ClearRegExpStatics(JSContext* cx, JS::HandleObject obj); - -extern JS_PUBLIC_API(bool) -JS_ExecuteRegExp(JSContext* cx, JS::HandleObject obj, JS::HandleObject reobj, - char16_t* chars, size_t length, size_t* indexp, bool test, - JS::MutableHandleValue rval); - -/* RegExp interface for clients without a global object. */ - -extern JS_PUBLIC_API(bool) -JS_ExecuteRegExpNoStatics(JSContext* cx, JS::HandleObject reobj, char16_t* chars, size_t length, - size_t* indexp, bool test, JS::MutableHandleValue rval); - -/** - * Returns true and sets |*isRegExp| indicating whether |obj| is a RegExp - * object or a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isRegExp == false| when passed a proxy whose - * target is a RegExp, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -JS_ObjectIsRegExp(JSContext* cx, JS::HandleObject obj, bool* isRegExp); - -extern JS_PUBLIC_API(unsigned) -JS_GetRegExpFlags(JSContext* cx, JS::HandleObject obj); - -extern JS_PUBLIC_API(JSString*) -JS_GetRegExpSource(JSContext* cx, JS::HandleObject obj); - -/************************************************************************/ - -extern JS_PUBLIC_API(bool) -JS_IsExceptionPending(JSContext* cx); - -extern JS_PUBLIC_API(bool) -JS_GetPendingException(JSContext* cx, JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(void) -JS_SetPendingException(JSContext* cx, JS::HandleValue v); - -extern JS_PUBLIC_API(void) -JS_ClearPendingException(JSContext* cx); - -namespace JS { - -/** - * Save and later restore the current exception state of a given JSContext. - * This is useful for implementing behavior in C++ that's like try/catch - * or try/finally in JS. - * - * Typical usage: - * - * bool ok = JS::Evaluate(cx, ...); - * AutoSaveExceptionState savedExc(cx); - * ... cleanup that might re-enter JS ... - * return ok; - */ -class JS_PUBLIC_API(AutoSaveExceptionState) -{ - private: - JSContext* context; - bool wasPropagatingForcedReturn; - bool wasOverRecursed; - bool wasThrowing; - RootedValue exceptionValue; - - public: - /* - * Take a snapshot of cx's current exception state. Then clear any current - * pending exception in cx. - */ - explicit AutoSaveExceptionState(JSContext* cx); - - /* - * If neither drop() nor restore() was called, restore the exception - * state only if no exception is currently pending on cx. - */ - ~AutoSaveExceptionState(); - - /* - * Discard any stored exception state. - * If this is called, the destructor is a no-op. - */ - void drop() { - wasPropagatingForcedReturn = false; - wasOverRecursed = false; - wasThrowing = false; - exceptionValue.setUndefined(); - } - - /* - * Replace cx's exception state with the stored exception state. Then - * discard the stored exception state. If this is called, the - * destructor is a no-op. - */ - void restore(); -}; - -} /* namespace JS */ - -/* Deprecated API. Use AutoSaveExceptionState instead. */ -extern JS_PUBLIC_API(JSExceptionState*) -JS_SaveExceptionState(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_RestoreExceptionState(JSContext* cx, JSExceptionState* state); - -extern JS_PUBLIC_API(void) -JS_DropExceptionState(JSContext* cx, JSExceptionState* state); - -/** - * If the given object is an exception object, the exception will have (or be - * able to lazily create) an error report struct, and this function will return - * the address of that struct. Otherwise, it returns nullptr. The lifetime - * of the error report struct that might be returned is the same as the - * lifetime of the exception object. - */ -extern JS_PUBLIC_API(JSErrorReport*) -JS_ErrorFromException(JSContext* cx, JS::HandleObject obj); - -/** - * If the given object is an exception object (or an unwrappable - * cross-compartment wrapper for one), return the stack for that exception, if - * any. Will return null if the given object is not an exception object - * (including if it's null or a security wrapper that can't be unwrapped) or if - * the exception has no stack. - */ -extern JS_PUBLIC_API(JSObject*) -ExceptionStackOrNull(JS::HandleObject obj); - -/* - * Throws a StopIteration exception on cx. - */ -extern JS_PUBLIC_API(bool) -JS_ThrowStopIteration(JSContext* cx); - -extern JS_PUBLIC_API(bool) -JS_IsStopIteration(const JS::Value& v); - -/** - * A JS context always has an "owner thread". The owner thread is set when the - * context is created (to the current thread) and practically all entry points - * into the JS engine check that a context (or anything contained in the - * context: runtime, compartment, object, etc) is only touched by its owner - * thread. Embeddings may check this invariant outside the JS engine by calling - * JS_AbortIfWrongThread (which will abort if not on the owner thread, even for - * non-debug builds). - */ - -extern JS_PUBLIC_API(void) -JS_AbortIfWrongThread(JSContext* cx); - -/************************************************************************/ - -/** - * A constructor can request that the JS engine create a default new 'this' - * object of the given class, using the callee to determine parentage and - * [[Prototype]]. - */ -extern JS_PUBLIC_API(JSObject*) -JS_NewObjectForConstructor(JSContext* cx, const JSClass* clasp, const JS::CallArgs& args); - -/************************************************************************/ - -#ifdef JS_GC_ZEAL -#define JS_DEFAULT_ZEAL_FREQ 100 - -extern JS_PUBLIC_API(void) -JS_GetGCZealBits(JSContext* cx, uint32_t* zealBits, uint32_t* frequency, uint32_t* nextScheduled); - -extern JS_PUBLIC_API(void) -JS_SetGCZeal(JSContext* cx, uint8_t zeal, uint32_t frequency); - -extern JS_PUBLIC_API(void) -JS_ScheduleGC(JSContext* cx, uint32_t count); -#endif - -extern JS_PUBLIC_API(void) -JS_SetParallelParsingEnabled(JSContext* cx, bool enabled); - -extern JS_PUBLIC_API(void) -JS_SetOffthreadIonCompilationEnabled(JSContext* cx, bool enabled); - -#define JIT_COMPILER_OPTIONS(Register) \ - Register(BASELINE_WARMUP_TRIGGER, "baseline.warmup.trigger") \ - Register(ION_WARMUP_TRIGGER, "ion.warmup.trigger") \ - Register(ION_GVN_ENABLE, "ion.gvn.enable") \ - Register(ION_FORCE_IC, "ion.forceinlineCaches") \ - Register(ION_ENABLE, "ion.enable") \ - Register(ION_INTERRUPT_WITHOUT_SIGNAL, "ion.interrupt-without-signals") \ - Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis") \ - Register(BASELINE_ENABLE, "baseline.enable") \ - Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \ - Register(JUMP_THRESHOLD, "jump-threshold") \ - Register(ASMJS_ATOMICS_ENABLE, "asmjs.atomics.enable") \ - Register(WASM_TEST_MODE, "wasm.test-mode") \ - Register(WASM_FOLD_OFFSETS, "wasm.fold-offsets") - -typedef enum JSJitCompilerOption { -#define JIT_COMPILER_DECLARE(key, str) \ - JSJITCOMPILER_ ## key, - - JIT_COMPILER_OPTIONS(JIT_COMPILER_DECLARE) -#undef JIT_COMPILER_DECLARE - - JSJITCOMPILER_NOT_AN_OPTION -} JSJitCompilerOption; - -extern JS_PUBLIC_API(void) -JS_SetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t value); -extern JS_PUBLIC_API(bool) -JS_GetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t* valueOut); - -/** - * Convert a uint32_t index into a jsid. - */ -extern JS_PUBLIC_API(bool) -JS_IndexToId(JSContext* cx, uint32_t index, JS::MutableHandleId); - -/** - * Convert chars into a jsid. - * - * |chars| may not be an index. - */ -extern JS_PUBLIC_API(bool) -JS_CharsToId(JSContext* cx, JS::TwoByteChars chars, JS::MutableHandleId); - -/** - * Test if the given string is a valid ECMAScript identifier - */ -extern JS_PUBLIC_API(bool) -JS_IsIdentifier(JSContext* cx, JS::HandleString str, bool* isIdentifier); - -/** - * Test whether the given chars + length are a valid ECMAScript identifier. - * This version is infallible, so just returns whether the chars are an - * identifier. - */ -extern JS_PUBLIC_API(bool) -JS_IsIdentifier(const char16_t* chars, size_t length); - -namespace js { -class ScriptSource; -} // namespace js - -namespace JS { - -class MOZ_RAII JS_PUBLIC_API(AutoFilename) -{ - private: - js::ScriptSource* ss_; - mozilla::Variant filename_; - - AutoFilename(const AutoFilename&) = delete; - AutoFilename& operator=(const AutoFilename&) = delete; - - public: - AutoFilename() - : ss_(nullptr), - filename_(mozilla::AsVariant(nullptr)) - {} - - ~AutoFilename() { - reset(); - } - - void reset(); - - void setOwned(UniqueChars&& filename); - void setUnowned(const char* filename); - void setScriptSource(js::ScriptSource* ss); - - const char* get() const; -}; - -/** - * Return the current filename, line number and column number of the most - * currently running frame. Returns true if a scripted frame was found, false - * otherwise. - * - * If a the embedding has hidden the scripted caller for the topmost activation - * record, this will also return false. - */ -extern JS_PUBLIC_API(bool) -DescribeScriptedCaller(JSContext* cx, AutoFilename* filename = nullptr, - unsigned* lineno = nullptr, unsigned* column = nullptr); - -extern JS_PUBLIC_API(JSObject*) -GetScriptedCallerGlobal(JSContext* cx); - -/** - * Informs the JS engine that the scripted caller should be hidden. This can be - * used by the embedding to maintain an override of the scripted caller in its - * calculations, by hiding the scripted caller in the JS engine and pushing data - * onto a separate stack, which it inspects when DescribeScriptedCaller returns - * null. - * - * We maintain a counter on each activation record. Add() increments the counter - * of the topmost activation, and Remove() decrements it. The count may never - * drop below zero, and must always be exactly zero when the activation is - * popped from the stack. - */ -extern JS_PUBLIC_API(void) -HideScriptedCaller(JSContext* cx); - -extern JS_PUBLIC_API(void) -UnhideScriptedCaller(JSContext* cx); - -class MOZ_RAII AutoHideScriptedCaller -{ - public: - explicit AutoHideScriptedCaller(JSContext* cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mContext(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - HideScriptedCaller(mContext); - } - ~AutoHideScriptedCaller() { - UnhideScriptedCaller(mContext); - } - - protected: - JSContext* mContext; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -/* - * Encode/Decode interpreted scripts and functions to/from memory. - */ - -typedef mozilla::Vector TranscodeBuffer; - -enum TranscodeResult -{ - // Successful encoding / decoding. - TranscodeResult_Ok = 0, - - // A warning message, is set to the message out-param. - TranscodeResult_Failure = 0x100, - TranscodeResult_Failure_BadBuildId = TranscodeResult_Failure | 0x1, - TranscodeResult_Failure_RunOnceNotSupported = TranscodeResult_Failure | 0x2, - TranscodeResult_Failure_AsmJSNotSupported = TranscodeResult_Failure | 0x3, - TranscodeResult_Failure_UnknownClassKind = TranscodeResult_Failure | 0x4, - - // A error, the JSContext has a pending exception. - TranscodeResult_Throw = 0x200 -}; - -extern JS_PUBLIC_API(TranscodeResult) -EncodeScript(JSContext* cx, TranscodeBuffer& buffer, JS::HandleScript script); - -extern JS_PUBLIC_API(TranscodeResult) -EncodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::HandleObject funobj); - -extern JS_PUBLIC_API(TranscodeResult) -DecodeScript(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleScript scriptp, - size_t cursorIndex = 0); - -extern JS_PUBLIC_API(TranscodeResult) -DecodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleFunction funp, - size_t cursorIndex = 0); - -} /* namespace JS */ - -namespace js { - -enum class StackFormat { SpiderMonkey, V8, Default }; - -/* - * Sets the format used for stringifying Error stacks. - * - * The default format is StackFormat::SpiderMonkey. Use StackFormat::V8 - * in order to emulate V8's stack formatting. StackFormat::Default can't be - * used here. - */ -extern JS_PUBLIC_API(void) -SetStackFormat(JSContext* cx, StackFormat format); - -extern JS_PUBLIC_API(StackFormat) -GetStackFormat(JSContext* cx); - -} - -namespace JS { - -/* - * This callback represents a request by the JS engine to open for reading the - * existing cache entry for the given global and char range that may contain a - * module. If a cache entry exists, the callback shall return 'true' and return - * the size, base address and an opaque file handle as outparams. If the - * callback returns 'true', the JS engine guarantees a call to - * CloseAsmJSCacheEntryForReadOp, passing the same base address, size and - * handle. - */ -typedef bool -(* OpenAsmJSCacheEntryForReadOp)(HandleObject global, const char16_t* begin, const char16_t* limit, - size_t* size, const uint8_t** memory, intptr_t* handle); -typedef void -(* CloseAsmJSCacheEntryForReadOp)(size_t size, const uint8_t* memory, intptr_t handle); - -/** The list of reasons why an asm.js module may not be stored in the cache. */ -enum AsmJSCacheResult -{ - AsmJSCache_Success, - AsmJSCache_MIN = AsmJSCache_Success, - AsmJSCache_ModuleTooSmall, - AsmJSCache_SynchronousScript, - AsmJSCache_QuotaExceeded, - AsmJSCache_StorageInitFailure, - AsmJSCache_Disabled_Internal, - AsmJSCache_Disabled_ShellFlags, - AsmJSCache_Disabled_JitInspector, - AsmJSCache_InternalError, - AsmJSCache_Disabled_PrivateBrowsing, - AsmJSCache_LIMIT -}; - -/* - * This callback represents a request by the JS engine to open for writing a - * cache entry of the given size for the given global and char range containing - * the just-compiled module. If cache entry space is available, the callback - * shall return 'true' and return the base address and an opaque file handle as - * outparams. If the callback returns 'true', the JS engine guarantees a call - * to CloseAsmJSCacheEntryForWriteOp passing the same base address, size and - * handle. - * - * If 'installed' is true, then the cache entry is associated with a permanently - * installed JS file (e.g., in a packaged webapp). This information allows the - * embedding to store the cache entry in a installed location associated with - * the principal of 'global' where it will not be evicted until the associated - * installed JS file is removed. - */ -typedef AsmJSCacheResult -(* OpenAsmJSCacheEntryForWriteOp)(HandleObject global, bool installed, - const char16_t* begin, const char16_t* end, - size_t size, uint8_t** memory, intptr_t* handle); -typedef void -(* CloseAsmJSCacheEntryForWriteOp)(size_t size, uint8_t* memory, intptr_t handle); - -struct AsmJSCacheOps -{ - OpenAsmJSCacheEntryForReadOp openEntryForRead; - CloseAsmJSCacheEntryForReadOp closeEntryForRead; - OpenAsmJSCacheEntryForWriteOp openEntryForWrite; - CloseAsmJSCacheEntryForWriteOp closeEntryForWrite; -}; - -extern JS_PUBLIC_API(void) -SetAsmJSCacheOps(JSContext* cx, const AsmJSCacheOps* callbacks); - -/** - * Return the buildId (represented as a sequence of characters) associated with - * the currently-executing build. If the JS engine is embedded such that a - * single cache entry can be observed by different compiled versions of the JS - * engine, it is critical that the buildId shall change for each new build of - * the JS engine. - */ -typedef js::Vector BuildIdCharVector; - -typedef bool -(* BuildIdOp)(BuildIdCharVector* buildId); - -extern JS_PUBLIC_API(void) -SetBuildIdOp(JSContext* cx, BuildIdOp buildIdOp); - -/** - * The WasmModule interface allows the embedding to hold a reference to the - * underying C++ implementation of a JS WebAssembly.Module object for purposes - * of (de)serialization off the object's JSRuntime's thread. - * - * - Serialization starts when WebAssembly.Module is passed to the - * structured-clone algorithm. JS::GetWasmModule is called on the JSRuntime - * thread that initiated the structured clone to get the JS::WasmModule. - * This interface is then taken to a background thread where serializedSize() - * and serialize() are called to write the object to two files: a bytecode file - * that always allows successful deserialization and a compiled-code file keyed - * on cpu- and build-id that may become invalid if either of these change between - * serialization and deserialization. After serialization, the reference is - * dropped from the background thread. - * - * - Deserialization starts when the structured clone algorithm encounters a - * serialized WebAssembly.Module. On a background thread, the compiled-code file - * is opened and CompiledWasmModuleAssumptionsMatch is called to see if it is - * still valid (as described above). DeserializeWasmModule is then called to - * construct a JS::WasmModule (also on the background thread), passing the - * bytecode file descriptor and, if valid, the compiled-code file descriptor. - * The JS::WasmObject is then transported to the JSRuntime thread (which - * originated the request) and the wrapping WebAssembly.Module object is created - * by calling createObject(). - */ - -struct WasmModule : mozilla::external::AtomicRefCounted -{ - MOZ_DECLARE_REFCOUNTED_TYPENAME(WasmModule) - virtual ~WasmModule() {} - - virtual void serializedSize(size_t* maybeBytecodeSize, size_t* maybeCompiledSize) const = 0; - virtual void serialize(uint8_t* maybeBytecodeBegin, size_t maybeBytecodeSize, - uint8_t* maybeCompiledBegin, size_t maybeCompiledSize) const = 0; - - virtual JSObject* createObject(JSContext* cx) = 0; -}; - -extern JS_PUBLIC_API(bool) -IsWasmModuleObject(HandleObject obj); - -extern JS_PUBLIC_API(RefPtr) -GetWasmModule(HandleObject obj); - -extern JS_PUBLIC_API(bool) -CompiledWasmModuleAssumptionsMatch(PRFileDesc* compiled, BuildIdCharVector&& buildId); - -extern JS_PUBLIC_API(RefPtr) -DeserializeWasmModule(PRFileDesc* bytecode, PRFileDesc* maybeCompiled, BuildIdCharVector&& buildId, - JS::UniqueChars filename, unsigned line, unsigned column); - -/** - * Convenience class for imitating a JS level for-of loop. Typical usage: - * - * ForOfIterator it(cx); - * if (!it.init(iterable)) - * return false; - * RootedValue val(cx); - * while (true) { - * bool done; - * if (!it.next(&val, &done)) - * return false; - * if (done) - * break; - * if (!DoStuff(cx, val)) - * return false; - * } - */ -class MOZ_STACK_CLASS JS_PUBLIC_API(ForOfIterator) { - protected: - JSContext* cx_; - /* - * Use the ForOfPIC on the global object (see vm/GlobalObject.h) to try - * to optimize iteration across arrays. - * - * Case 1: Regular Iteration - * iterator - pointer to the iterator object. - * index - fixed to NOT_ARRAY (== UINT32_MAX) - * - * Case 2: Optimized Array Iteration - * iterator - pointer to the array object. - * index - current position in array. - * - * The cases are distinguished by whether or not |index| is equal to NOT_ARRAY. - */ - JS::RootedObject iterator; - uint32_t index; - - static const uint32_t NOT_ARRAY = UINT32_MAX; - - ForOfIterator(const ForOfIterator&) = delete; - ForOfIterator& operator=(const ForOfIterator&) = delete; - - public: - explicit ForOfIterator(JSContext* cx) : cx_(cx), iterator(cx_), index(NOT_ARRAY) { } - - enum NonIterableBehavior { - ThrowOnNonIterable, - AllowNonIterable - }; - - /** - * Initialize the iterator. If AllowNonIterable is passed then if getting - * the @@iterator property from iterable returns undefined init() will just - * return true instead of throwing. Callers must then check - * valueIsIterable() before continuing with the iteration. - */ - bool init(JS::HandleValue iterable, - NonIterableBehavior nonIterableBehavior = ThrowOnNonIterable); - - /** - * Get the next value from the iterator. If false *done is true - * after this call, do not examine val. - */ - bool next(JS::MutableHandleValue val, bool* done); - - /** - * If initialized with throwOnNonCallable = false, check whether - * the value is iterable. - */ - bool valueIsIterable() const { - return iterator; - } - - private: - inline bool nextFromOptimizedArray(MutableHandleValue val, bool* done); - bool materializeArrayIterator(); -}; - - -/** - * If a large allocation fails when calling pod_{calloc,realloc}CanGC, the JS - * engine may call the large-allocation- failure callback, if set, to allow the - * embedding to flush caches, possibly perform shrinking GCs, etc. to make some - * room. The allocation will then be retried (and may still fail.) - */ - -typedef void -(* LargeAllocationFailureCallback)(void* data); - -extern JS_PUBLIC_API(void) -SetLargeAllocationFailureCallback(JSContext* cx, LargeAllocationFailureCallback afc, void* data); - -/** - * Unlike the error reporter, which is only called if the exception for an OOM - * bubbles up and is not caught, the OutOfMemoryCallback is called immediately - * at the OOM site to allow the embedding to capture the current state of heap - * allocation before anything is freed. If the large-allocation-failure callback - * is called at all (not all allocation sites call the large-allocation-failure - * callback on failure), it is called before the out-of-memory callback; the - * out-of-memory callback is only called if the allocation still fails after the - * large-allocation-failure callback has returned. - */ - -typedef void -(* OutOfMemoryCallback)(JSContext* cx, void* data); - -extern JS_PUBLIC_API(void) -SetOutOfMemoryCallback(JSContext* cx, OutOfMemoryCallback cb, void* data); - -/** - * Capture all frames. - */ -struct AllFrames { }; - -/** - * Capture at most this many frames. - */ -struct MaxFrames -{ - uint32_t maxFrames; - - explicit MaxFrames(uint32_t max) - : maxFrames(max) - { - MOZ_ASSERT(max > 0); - } -}; - -/** - * Capture the first frame with the given principals. By default, do not - * consider self-hosted frames with the given principals as satisfying the stack - * capture. - */ -struct FirstSubsumedFrame -{ - JSContext* cx; - JSPrincipals* principals; - bool ignoreSelfHosted; - - /** - * Use the cx's current compartment's principals. - */ - explicit FirstSubsumedFrame(JSContext* cx, bool ignoreSelfHostedFrames = true); - - explicit FirstSubsumedFrame(JSContext* ctx, JSPrincipals* p, bool ignoreSelfHostedFrames = true) - : cx(ctx) - , principals(p) - , ignoreSelfHosted(ignoreSelfHostedFrames) - { - if (principals) - JS_HoldPrincipals(principals); - } - - // No copying because we want to avoid holding and dropping principals - // unnecessarily. - FirstSubsumedFrame(const FirstSubsumedFrame&) = delete; - FirstSubsumedFrame& operator=(const FirstSubsumedFrame&) = delete; - - FirstSubsumedFrame(FirstSubsumedFrame&& rhs) - : principals(rhs.principals) - , ignoreSelfHosted(rhs.ignoreSelfHosted) - { - MOZ_ASSERT(this != &rhs, "self move disallowed"); - rhs.principals = nullptr; - } - - FirstSubsumedFrame& operator=(FirstSubsumedFrame&& rhs) { - new (this) FirstSubsumedFrame(mozilla::Move(rhs)); - return *this; - } - - ~FirstSubsumedFrame() { - if (principals) - JS_DropPrincipals(cx, principals); - } -}; - -using StackCapture = mozilla::Variant; - -/** - * Capture the current call stack as a chain of SavedFrame JSObjects, and set - * |stackp| to the SavedFrame for the youngest stack frame, or nullptr if there - * are no JS frames on the stack. - * - * The |capture| parameter describes the portion of the JS stack to capture: - * - * * |JS::AllFrames|: Capture all frames on the stack. - * - * * |JS::MaxFrames|: Capture no more than |JS::MaxFrames::maxFrames| from the - * stack. - * - * * |JS::FirstSubsumedFrame|: Capture the first frame whose principals are - * subsumed by |JS::FirstSubsumedFrame::principals|. By default, do not - * consider self-hosted frames; this can be controlled via the - * |JS::FirstSubsumedFrame::ignoreSelfHosted| flag. Do not capture any async - * stack. - */ -extern JS_PUBLIC_API(bool) -CaptureCurrentStack(JSContext* cx, MutableHandleObject stackp, - StackCapture&& capture = StackCapture(AllFrames())); - -/* - * This is a utility function for preparing an async stack to be used - * by some other object. This may be used when you need to treat a - * given stack trace as an async parent. If you just need to capture - * the current stack, async parents and all, use CaptureCurrentStack - * instead. - * - * Here |asyncStack| is the async stack to prepare. It is copied into - * |cx|'s current compartment, and the newest frame is given - * |asyncCause| as its asynchronous cause. If |maxFrameCount| is - * non-zero, capture at most the youngest |maxFrameCount| frames. The - * new stack object is written to |stackp|. Returns true on success, - * or sets an exception and returns |false| on error. - */ -extern JS_PUBLIC_API(bool) -CopyAsyncStack(JSContext* cx, HandleObject asyncStack, - HandleString asyncCause, MutableHandleObject stackp, - unsigned maxFrameCount); - -/* - * Accessors for working with SavedFrame JSObjects - * - * Each of these functions assert that if their `HandleObject savedFrame` - * argument is non-null, its JSClass is the SavedFrame class (or it is a - * cross-compartment or Xray wrapper around an object with the SavedFrame class) - * and the object is not the SavedFrame.prototype object. - * - * Each of these functions will find the first SavedFrame object in the chain - * whose underlying stack frame principals are subsumed by the cx's current - * compartment's principals, and operate on that SavedFrame object. This - * prevents leaking information about privileged frames to un-privileged - * callers. As a result, the SavedFrame in parameters do _NOT_ need to be in the - * same compartment as the cx, and the various out parameters are _NOT_ - * guaranteed to be in the same compartment as cx. - * - * You may consider or skip over self-hosted frames by passing - * `SavedFrameSelfHosted::Include` or `SavedFrameSelfHosted::Exclude` - * respectively. - * - * Additionally, it may be the case that there is no such SavedFrame object - * whose captured frame's principals are subsumed by the caller's compartment's - * principals! If the `HandleObject savedFrame` argument is null, or the - * caller's principals do not subsume any of the chained SavedFrame object's - * principals, `SavedFrameResult::AccessDenied` is returned and a (hopefully) - * sane default value is chosen for the out param. - * - * See also `js/src/doc/SavedFrame/SavedFrame.md`. - */ - -enum class SavedFrameResult { - Ok, - AccessDenied -}; - -enum class SavedFrameSelfHosted { - Include, - Exclude -}; - -/** - * Given a SavedFrame JSObject, get its source property. Defaults to the empty - * string. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameSource(JSContext* cx, HandleObject savedFrame, MutableHandleString sourcep, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its line property. Defaults to 0. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameLine(JSContext* cx, HandleObject savedFrame, uint32_t* linep, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its column property. Defaults to 0. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameColumn(JSContext* cx, HandleObject savedFrame, uint32_t* columnp, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its functionDisplayName string, or nullptr - * if SpiderMonkey was unable to infer a name for the captured frame's - * function. Defaults to nullptr. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameFunctionDisplayName(JSContext* cx, HandleObject savedFrame, MutableHandleString namep, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its asyncCause string. Defaults to nullptr. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameAsyncCause(JSContext* cx, HandleObject savedFrame, MutableHandleString asyncCausep, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its asyncParent SavedFrame object or nullptr - * if there is no asyncParent. The `asyncParentp` out parameter is _NOT_ - * guaranteed to be in the cx's compartment. Defaults to nullptr. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameAsyncParent(JSContext* cx, HandleObject savedFrame, MutableHandleObject asyncParentp, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its parent SavedFrame object or nullptr if - * it is the oldest frame in the stack. The `parentp` out parameter is _NOT_ - * guaranteed to be in the cx's compartment. Defaults to nullptr. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameParent(JSContext* cx, HandleObject savedFrame, MutableHandleObject parentp, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject stack, stringify it in the same format as - * Error.prototype.stack. The stringified stack out parameter is placed in the - * cx's compartment. Defaults to the empty string. - * - * The same notes above about SavedFrame accessors applies here as well: cx - * doesn't need to be in stack's compartment, and stack can be null, a - * SavedFrame object, or a wrapper (CCW or Xray) around a SavedFrame object. - * - * Optional indent parameter specifies the number of white spaces to indent - * each line. - */ -extern JS_PUBLIC_API(bool) -BuildStackString(JSContext* cx, HandleObject stack, MutableHandleString stringp, - size_t indent = 0, js::StackFormat stackFormat = js::StackFormat::Default); - -/** - * Return true iff the given object is either a SavedFrame object or wrapper - * around a SavedFrame object, and it is not the SavedFrame.prototype object. - */ -extern JS_PUBLIC_API(bool) -IsSavedFrame(JSObject* obj); - -} /* namespace JS */ - - -/* Stopwatch-based performance monitoring. */ - -namespace js { - -class AutoStopwatch; - -/** - * Abstract base class for a representation of the performance of a - * component. Embeddings interested in performance monitoring should - * provide a concrete implementation of this class, as well as the - * relevant callbacks (see below). - */ -struct PerformanceGroup { - PerformanceGroup(); - - // The current iteration of the event loop. - uint64_t iteration() const; - - // `true` if an instance of `AutoStopwatch` is already monitoring - // the performance of this performance group for this iteration - // of the event loop, `false` otherwise. - bool isAcquired(uint64_t it) const; - - // `true` if a specific instance of `AutoStopwatch` is already monitoring - // the performance of this performance group for this iteration - // of the event loop, `false` otherwise. - bool isAcquired(uint64_t it, const AutoStopwatch* owner) const; - - // Mark that an instance of `AutoStopwatch` is monitoring - // the performance of this group for a given iteration. - void acquire(uint64_t it, const AutoStopwatch* owner); - - // Mark that no `AutoStopwatch` is monitoring the - // performance of this group for the iteration. - void release(uint64_t it, const AutoStopwatch* owner); - - // The number of cycles spent in this group during this iteration - // of the event loop. Note that cycles are not a reliable measure, - // especially over short intervals. See Stopwatch.* for a more - // complete discussion on the imprecision of cycle measurement. - uint64_t recentCycles(uint64_t iteration) const; - void addRecentCycles(uint64_t iteration, uint64_t cycles); - - // The number of times this group has been activated during this - // iteration of the event loop. - uint64_t recentTicks(uint64_t iteration) const; - void addRecentTicks(uint64_t iteration, uint64_t ticks); - - // The number of microseconds spent doing CPOW during this - // iteration of the event loop. - uint64_t recentCPOW(uint64_t iteration) const; - void addRecentCPOW(uint64_t iteration, uint64_t CPOW); - - // Get rid of any data that pretends to be recent. - void resetRecentData(); - - // `true` if new measures should be added to this group, `false` - // otherwise. - bool isActive() const; - void setIsActive(bool); - - // `true` if this group has been used in the current iteration, - // `false` otherwise. - bool isUsedInThisIteration() const; - void setIsUsedInThisIteration(bool); - protected: - // An implementation of `delete` for this object. Must be provided - // by the embedding. - virtual void Delete() = 0; - - private: - // The number of cycles spent in this group during this iteration - // of the event loop. Note that cycles are not a reliable measure, - // especially over short intervals. See Runtime.cpp for a more - // complete discussion on the imprecision of cycle measurement. - uint64_t recentCycles_; - - // The number of times this group has been activated during this - // iteration of the event loop. - uint64_t recentTicks_; - - // The number of microseconds spent doing CPOW during this - // iteration of the event loop. - uint64_t recentCPOW_; - - // The current iteration of the event loop. If necessary, - // may safely overflow. - uint64_t iteration_; - - // `true` if new measures should be added to this group, `false` - // otherwise. - bool isActive_; - - // `true` if this group has been used in the current iteration, - // `false` otherwise. - bool isUsedInThisIteration_; - - // The stopwatch currently monitoring the group, - // or `nullptr` if none. Used ony for comparison. - const AutoStopwatch* owner_; - - public: - // Compatibility with RefPtr<> - void AddRef(); - void Release(); - uint64_t refCount_; -}; - -using PerformanceGroupVector = mozilla::Vector, 0, SystemAllocPolicy>; - -/** - * Commit any Performance Monitoring data. - * - * Until `FlushMonitoring` has been called, all PerformanceMonitoring data is invisible - * to the outside world and can cancelled with a call to `ResetMonitoring`. - */ -extern JS_PUBLIC_API(bool) -FlushPerformanceMonitoring(JSContext*); - -/** - * Cancel any measurement that hasn't been committed. - */ -extern JS_PUBLIC_API(void) -ResetPerformanceMonitoring(JSContext*); - -/** - * Cleanup any memory used by performance monitoring. - */ -extern JS_PUBLIC_API(void) -DisposePerformanceMonitoring(JSContext*); - -/** - * Turn on/off stopwatch-based CPU monitoring. - * - * `SetStopwatchIsMonitoringCPOW` or `SetStopwatchIsMonitoringJank` - * may return `false` if monitoring could not be activated, which may - * happen if we are out of memory. - */ -extern JS_PUBLIC_API(bool) -SetStopwatchIsMonitoringCPOW(JSContext*, bool); -extern JS_PUBLIC_API(bool) -GetStopwatchIsMonitoringCPOW(JSContext*); -extern JS_PUBLIC_API(bool) -SetStopwatchIsMonitoringJank(JSContext*, bool); -extern JS_PUBLIC_API(bool) -GetStopwatchIsMonitoringJank(JSContext*); - -// Extract the CPU rescheduling data. -extern JS_PUBLIC_API(void) -GetPerfMonitoringTestCpuRescheduling(JSContext*, uint64_t* stayed, uint64_t* moved); - - -/** - * Add a number of microseconds to the time spent waiting on CPOWs - * since process start. - */ -extern JS_PUBLIC_API(void) -AddCPOWPerformanceDelta(JSContext*, uint64_t delta); - -typedef bool -(*StopwatchStartCallback)(uint64_t, void*); -extern JS_PUBLIC_API(bool) -SetStopwatchStartCallback(JSContext*, StopwatchStartCallback, void*); - -typedef bool -(*StopwatchCommitCallback)(uint64_t, PerformanceGroupVector&, void*); -extern JS_PUBLIC_API(bool) -SetStopwatchCommitCallback(JSContext*, StopwatchCommitCallback, void*); - -typedef bool -(*GetGroupsCallback)(JSContext*, PerformanceGroupVector&, void*); -extern JS_PUBLIC_API(bool) -SetGetPerformanceGroupsCallback(JSContext*, GetGroupsCallback, void*); - -} /* namespace js */ - - -#endif /* jsapi_h */ diff --git a/android/arm64-v8a/include/spidermonkey/jsbytecode.h b/android/arm64-v8a/include/spidermonkey/jsbytecode.h deleted file mode 100644 index 8e4f4cf9..00000000 --- a/android/arm64-v8a/include/spidermonkey/jsbytecode.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsbytecode_h -#define jsbytecode_h - -#include - -typedef uint8_t jsbytecode; - -#endif /* jsbytecode_h */ diff --git a/android/arm64-v8a/include/spidermonkey/jsclist.h b/android/arm64-v8a/include/spidermonkey/jsclist.h deleted file mode 100644 index b8455152..00000000 --- a/android/arm64-v8a/include/spidermonkey/jsclist.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsclist_h -#define jsclist_h - -#include "jstypes.h" - -/* -** Circular linked list -*/ -typedef struct JSCListStr { - struct JSCListStr* next; - struct JSCListStr* prev; -} JSCList; - -/* -** Insert element "_e" into the list, before "_l". -*/ -#define JS_INSERT_BEFORE(_e,_l) \ - JS_BEGIN_MACRO \ - (_e)->next = (_l); \ - (_e)->prev = (_l)->prev; \ - (_l)->prev->next = (_e); \ - (_l)->prev = (_e); \ - JS_END_MACRO - -/* -** Insert element "_e" into the list, after "_l". -*/ -#define JS_INSERT_AFTER(_e,_l) \ - JS_BEGIN_MACRO \ - (_e)->next = (_l)->next; \ - (_e)->prev = (_l); \ - (_l)->next->prev = (_e); \ - (_l)->next = (_e); \ - JS_END_MACRO - -/* -** Return the element following element "_e" -*/ -#define JS_NEXT_LINK(_e) \ - ((_e)->next) -/* -** Return the element preceding element "_e" -*/ -#define JS_PREV_LINK(_e) \ - ((_e)->prev) - -/* -** Append an element "_e" to the end of the list "_l" -*/ -#define JS_APPEND_LINK(_e,_l) JS_INSERT_BEFORE(_e,_l) - -/* -** Insert an element "_e" at the head of the list "_l" -*/ -#define JS_INSERT_LINK(_e,_l) JS_INSERT_AFTER(_e,_l) - -/* Return the head/tail of the list */ -#define JS_LIST_HEAD(_l) (_l)->next -#define JS_LIST_TAIL(_l) (_l)->prev - -/* -** Remove the element "_e" from it's circular list. -*/ -#define JS_REMOVE_LINK(_e) \ - JS_BEGIN_MACRO \ - (_e)->prev->next = (_e)->next; \ - (_e)->next->prev = (_e)->prev; \ - JS_END_MACRO - -/* -** Remove the element "_e" from it's circular list. Also initializes the -** linkage. -*/ -#define JS_REMOVE_AND_INIT_LINK(_e) \ - JS_BEGIN_MACRO \ - (_e)->prev->next = (_e)->next; \ - (_e)->next->prev = (_e)->prev; \ - (_e)->next = (_e); \ - (_e)->prev = (_e); \ - JS_END_MACRO - -/* -** Return non-zero if the given circular list "_l" is empty, zero if the -** circular list is not empty -*/ -#define JS_CLIST_IS_EMPTY(_l) \ - bool((_l)->next == (_l)) - -/* -** Initialize a circular list -*/ -#define JS_INIT_CLIST(_l) \ - JS_BEGIN_MACRO \ - (_l)->next = (_l); \ - (_l)->prev = (_l); \ - JS_END_MACRO - -#define JS_INIT_STATIC_CLIST(_l) \ - {(_l), (_l)} - -#endif /* jsclist_h */ diff --git a/android/arm64-v8a/include/spidermonkey/jscpucfg.h b/android/arm64-v8a/include/spidermonkey/jscpucfg.h deleted file mode 100644 index 80fdf6bb..00000000 --- a/android/arm64-v8a/include/spidermonkey/jscpucfg.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jscpucfg_h -#define jscpucfg_h - -#include "mozilla/EndianUtils.h" - -#ifndef JS_STACK_GROWTH_DIRECTION -# ifdef __hppa -# define JS_STACK_GROWTH_DIRECTION (1) -# else -# define JS_STACK_GROWTH_DIRECTION (-1) -# endif -#endif - -#endif /* jscpucfg_h */ diff --git a/android/arm64-v8a/include/spidermonkey/jsfriendapi.h b/android/arm64-v8a/include/spidermonkey/jsfriendapi.h deleted file mode 100644 index d6463d3d..00000000 --- a/android/arm64-v8a/include/spidermonkey/jsfriendapi.h +++ /dev/null @@ -1,3067 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsfriendapi_h -#define jsfriendapi_h - -#include "mozilla/Atomics.h" -#include "mozilla/Casting.h" -#include "mozilla/Maybe.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/UniquePtr.h" - -#include "jsapi.h" // For JSAutoByteString. See bug 1033916. -#include "jsbytecode.h" -#include "jspubtd.h" - -#include "js/CallArgs.h" -#include "js/CallNonGenericMethod.h" -#include "js/Class.h" -#include "js/Utility.h" - -#if JS_STACK_GROWTH_DIRECTION > 0 -# define JS_CHECK_STACK_SIZE(limit, sp) (MOZ_LIKELY((uintptr_t)(sp) < (limit))) -#else -# define JS_CHECK_STACK_SIZE(limit, sp) (MOZ_LIKELY((uintptr_t)(sp) > (limit))) -#endif - -class JSAtom; -struct JSErrorFormatString; -class JSLinearString; -struct JSJitInfo; -class JSErrorReport; - -namespace JS { -template -class Heap; -} /* namespace JS */ - -namespace js { -class JS_FRIEND_API(BaseProxyHandler); -class InterpreterFrame; -} /* namespace js */ - -extern JS_FRIEND_API(void) -JS_SetGrayGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data); - -extern JS_FRIEND_API(JSObject*) -JS_FindCompilationScope(JSContext* cx, JS::HandleObject obj); - -extern JS_FRIEND_API(JSFunction*) -JS_GetObjectFunction(JSObject* obj); - -extern JS_FRIEND_API(bool) -JS_SplicePrototype(JSContext* cx, JS::HandleObject obj, JS::HandleObject proto); - -extern JS_FRIEND_API(JSObject*) -JS_NewObjectWithUniqueType(JSContext* cx, const JSClass* clasp, JS::HandleObject proto); - -/** - * Allocate an object in exactly the same way as JS_NewObjectWithGivenProto, but - * without invoking the metadata callback on it. This allows creation of - * internal bookkeeping objects that are guaranteed to not have metadata - * attached to them. - */ -extern JS_FRIEND_API(JSObject*) -JS_NewObjectWithoutMetadata(JSContext* cx, const JSClass* clasp, JS::Handle proto); - -extern JS_FRIEND_API(uint32_t) -JS_ObjectCountDynamicSlots(JS::HandleObject obj); - -extern JS_FRIEND_API(size_t) -JS_SetProtoCalled(JSContext* cx); - -extern JS_FRIEND_API(size_t) -JS_GetCustomIteratorCount(JSContext* cx); - -extern JS_FRIEND_API(bool) -JS_NondeterministicGetWeakMapKeys(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret); - -extern JS_FRIEND_API(bool) -JS_NondeterministicGetWeakSetKeys(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret); - -// Raw JSScript* because this needs to be callable from a signal handler. -extern JS_FRIEND_API(unsigned) -JS_PCToLineNumber(JSScript* script, jsbytecode* pc, unsigned* columnp = nullptr); - -/** - * Determine whether the given object is backed by a DeadObjectProxy. - * - * Such objects hold no other objects (they have no outgoing reference edges) - * and will throw if you touch them (e.g. by reading/writing a property). - */ -extern JS_FRIEND_API(bool) -JS_IsDeadWrapper(JSObject* obj); - -/* - * Used by the cycle collector to trace through a shape or object group and - * all cycle-participating data it reaches, using bounded stack space. - */ -extern JS_FRIEND_API(void) -JS_TraceShapeCycleCollectorChildren(JS::CallbackTracer* trc, JS::GCCellPtr shape); -extern JS_FRIEND_API(void) -JS_TraceObjectGroupCycleCollectorChildren(JS::CallbackTracer* trc, JS::GCCellPtr group); - -enum { - JS_TELEMETRY_GC_REASON, - JS_TELEMETRY_GC_IS_ZONE_GC, - JS_TELEMETRY_GC_MS, - JS_TELEMETRY_GC_BUDGET_MS, - JS_TELEMETRY_GC_ANIMATION_MS, - JS_TELEMETRY_GC_MAX_PAUSE_MS, - JS_TELEMETRY_GC_MARK_MS, - JS_TELEMETRY_GC_SWEEP_MS, - JS_TELEMETRY_GC_COMPACT_MS, - JS_TELEMETRY_GC_MARK_ROOTS_MS, - JS_TELEMETRY_GC_MARK_GRAY_MS, - JS_TELEMETRY_GC_SLICE_MS, - JS_TELEMETRY_GC_SLOW_PHASE, - JS_TELEMETRY_GC_MMU_50, - JS_TELEMETRY_GC_RESET, - JS_TELEMETRY_GC_RESET_REASON, - JS_TELEMETRY_GC_INCREMENTAL_DISABLED, - JS_TELEMETRY_GC_NON_INCREMENTAL, - JS_TELEMETRY_GC_NON_INCREMENTAL_REASON, - JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS, - JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS, - JS_TELEMETRY_GC_MINOR_REASON, - JS_TELEMETRY_GC_MINOR_REASON_LONG, - JS_TELEMETRY_GC_MINOR_US, - JS_TELEMETRY_GC_NURSERY_BYTES, - JS_TELEMETRY_GC_PRETENURE_COUNT, - JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, - JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_ADDONS, - JS_TELEMETRY_ADDON_EXCEPTIONS, - JS_TELEMETRY_AOT_USAGE, - JS_TELEMETRY_END -}; - -typedef void -(*JSAccumulateTelemetryDataCallback)(int id, uint32_t sample, const char* key); - -extern JS_FRIEND_API(void) -JS_SetAccumulateTelemetryCallback(JSContext* cx, JSAccumulateTelemetryDataCallback callback); - -extern JS_FRIEND_API(bool) -JS_GetIsSecureContext(JSCompartment* compartment); - -extern JS_FRIEND_API(JSPrincipals*) -JS_GetCompartmentPrincipals(JSCompartment* compartment); - -extern JS_FRIEND_API(void) -JS_SetCompartmentPrincipals(JSCompartment* compartment, JSPrincipals* principals); - -extern JS_FRIEND_API(JSPrincipals*) -JS_GetScriptPrincipals(JSScript* script); - -extern JS_FRIEND_API(bool) -JS_ScriptHasMutedErrors(JSScript* script); - -extern JS_FRIEND_API(JSObject*) -JS_CloneObject(JSContext* cx, JS::HandleObject obj, JS::HandleObject proto); - -/** - * Copy the own properties of src to dst in a fast way. src and dst must both - * be native and must be in the compartment of cx. They must have the same - * class, the same parent, and the same prototype. Class reserved slots will - * NOT be copied. - * - * dst must not have any properties on it before this function is called. - * - * src must have been allocated via JS_NewObjectWithoutMetadata so that we can - * be sure it has no metadata that needs copying to dst. This also means that - * dst needs to have the compartment global as its parent. This function will - * preserve the existing metadata on dst, if any. - */ -extern JS_FRIEND_API(bool) -JS_InitializePropertiesFromCompatibleNativeObject(JSContext* cx, - JS::HandleObject dst, - JS::HandleObject src); - -extern JS_FRIEND_API(JSString*) -JS_BasicObjectToString(JSContext* cx, JS::HandleObject obj); - -namespace js { - -JS_FRIEND_API(bool) -GetBuiltinClass(JSContext* cx, JS::HandleObject obj, ESClass* cls); - -JS_FRIEND_API(const char*) -ObjectClassName(JSContext* cx, JS::HandleObject obj); - -JS_FRIEND_API(void) -ReportOverRecursed(JSContext* maybecx); - -JS_FRIEND_API(bool) -AddRawValueRoot(JSContext* cx, JS::Value* vp, const char* name); - -JS_FRIEND_API(void) -RemoveRawValueRoot(JSContext* cx, JS::Value* vp); - -JS_FRIEND_API(JSAtom*) -GetPropertyNameFromPC(JSScript* script, jsbytecode* pc); - -#ifdef JS_DEBUG - -/* - * Routines to print out values during debugging. These are FRIEND_API to help - * the debugger find them and to support temporarily hacking js::Dump* calls - * into other code. Note that there are overloads that do not require the FILE* - * parameter, which will default to stderr. - */ - -extern JS_FRIEND_API(void) -DumpString(JSString* str, FILE* fp); - -extern JS_FRIEND_API(void) -DumpAtom(JSAtom* atom, FILE* fp); - -extern JS_FRIEND_API(void) -DumpObject(JSObject* obj, FILE* fp); - -extern JS_FRIEND_API(void) -DumpChars(const char16_t* s, size_t n, FILE* fp); - -extern JS_FRIEND_API(void) -DumpValue(const JS::Value& val, FILE* fp); - -extern JS_FRIEND_API(void) -DumpId(jsid id, FILE* fp); - -extern JS_FRIEND_API(void) -DumpInterpreterFrame(JSContext* cx, FILE* fp, InterpreterFrame* start = nullptr); - -extern JS_FRIEND_API(bool) -DumpPC(JSContext* cx, FILE* fp); - -extern JS_FRIEND_API(bool) -DumpScript(JSContext* cx, JSScript* scriptArg, FILE* fp); - -// Versions for use directly in a debugger (default parameters are not handled -// well in gdb; built-in handles like stderr are not handled well in lldb.) -extern JS_FRIEND_API(void) DumpString(JSString* str); -extern JS_FRIEND_API(void) DumpAtom(JSAtom* atom); -extern JS_FRIEND_API(void) DumpObject(JSObject* obj); -extern JS_FRIEND_API(void) DumpChars(const char16_t* s, size_t n); -extern JS_FRIEND_API(void) DumpValue(const JS::Value& val); -extern JS_FRIEND_API(void) DumpId(jsid id); -extern JS_FRIEND_API(void) DumpInterpreterFrame(JSContext* cx, InterpreterFrame* start = nullptr); -extern JS_FRIEND_API(bool) DumpPC(JSContext* cx); -extern JS_FRIEND_API(bool) DumpScript(JSContext* cx, JSScript* scriptArg); - -#endif - -extern JS_FRIEND_API(void) -DumpBacktrace(JSContext* cx, FILE* fp); - -extern JS_FRIEND_API(void) -DumpBacktrace(JSContext* cx); - -} // namespace js - -namespace JS { - -/** Exposed for DumpJSStack */ -extern JS_FRIEND_API(char*) -FormatStackDump(JSContext* cx, char* buf, bool showArgs, bool showLocals, bool showThisProps); - -/** - * Set all of the uninitialized lexicals on an object to undefined. Return - * true if any lexicals were initialized and false otherwise. - * */ -extern JS_FRIEND_API(bool) -ForceLexicalInitialization(JSContext *cx, HandleObject obj); - -} // namespace JS - -/** - * Copies all own properties from |obj| to |target|. |obj| must be a "native" - * object (that is to say, normal-ish - not an Array or a Proxy). - * - * This function immediately enters a compartment, and does not impose any - * restrictions on the compartment of |cx|. - */ -extern JS_FRIEND_API(bool) -JS_CopyPropertiesFrom(JSContext* cx, JS::HandleObject target, JS::HandleObject obj); - -/* - * Single-property version of the above. This function asserts that an |own| - * property of the given name exists on |obj|. - * - * On entry, |cx| must be same-compartment with |obj|. - * - * The copyBehavior argument controls what happens with - * non-configurable properties. - */ -typedef enum { - MakeNonConfigurableIntoConfigurable, - CopyNonConfigurableAsIs -} PropertyCopyBehavior; - -extern JS_FRIEND_API(bool) -JS_CopyPropertyFrom(JSContext* cx, JS::HandleId id, JS::HandleObject target, - JS::HandleObject obj, - PropertyCopyBehavior copyBehavior = CopyNonConfigurableAsIs); - -extern JS_FRIEND_API(bool) -JS_WrapPropertyDescriptor(JSContext* cx, JS::MutableHandle desc); - -struct JSFunctionSpecWithHelp { - const char* name; - JSNative call; - uint16_t nargs; - uint16_t flags; - const JSJitInfo* jitInfo; - const char* usage; - const char* help; -}; - -#define JS_FN_HELP(name,call,nargs,flags,usage,help) \ - {name, call, nargs, (flags) | JSPROP_ENUMERATE | JSFUN_STUB_GSOPS, nullptr, usage, help} -#define JS_INLINABLE_FN_HELP(name,call,nargs,flags,native,usage,help) \ - {name, call, nargs, (flags) | JSPROP_ENUMERATE | JSFUN_STUB_GSOPS, &js::jit::JitInfo_##native,\ - usage, help} -#define JS_FS_HELP_END \ - {nullptr, nullptr, 0, 0, nullptr, nullptr} - -extern JS_FRIEND_API(bool) -JS_DefineFunctionsWithHelp(JSContext* cx, JS::HandleObject obj, const JSFunctionSpecWithHelp* fs); - -namespace js { - -extern JS_FRIEND_DATA(const js::ClassOps) ProxyClassOps; -extern JS_FRIEND_DATA(const js::ClassExtension) ProxyClassExtension; -extern JS_FRIEND_DATA(const js::ObjectOps) ProxyObjectOps; - -/* - * Helper Macros for creating JSClasses that function as proxies. - * - * NB: The macro invocation must be surrounded by braces, so as to - * allow for potential JSClass extensions. - */ -#define PROXY_MAKE_EXT(objectMoved) \ - { \ - js::proxy_WeakmapKeyDelegate, \ - objectMoved \ - } - -#define PROXY_CLASS_WITH_EXT(name, flags, extPtr) \ - { \ - name, \ - js::Class::NON_NATIVE | \ - JSCLASS_IS_PROXY | \ - JSCLASS_DELAY_METADATA_BUILDER | \ - flags, \ - &js::ProxyClassOps, \ - JS_NULL_CLASS_SPEC, \ - extPtr, \ - &js::ProxyObjectOps \ - } - -#define PROXY_CLASS_DEF(name, flags) \ - PROXY_CLASS_WITH_EXT(name, flags, &js::ProxyClassExtension) - -/* - * Proxy stubs, similar to JS_*Stub, for embedder proxy class definitions. - * - * NB: Should not be called directly. - */ - -extern JS_FRIEND_API(bool) -proxy_LookupProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleObject objp, - JS::MutableHandle propp); -extern JS_FRIEND_API(bool) -proxy_DefineProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::Handle desc, - JS::ObjectOpResult& result); -extern JS_FRIEND_API(bool) -proxy_HasProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp); -extern JS_FRIEND_API(bool) -proxy_GetProperty(JSContext* cx, JS::HandleObject obj, JS::HandleValue receiver, JS::HandleId id, - JS::MutableHandleValue vp); -extern JS_FRIEND_API(bool) -proxy_SetProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue bp, - JS::HandleValue receiver, JS::ObjectOpResult& result); -extern JS_FRIEND_API(bool) -proxy_GetOwnPropertyDescriptor(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandle desc); -extern JS_FRIEND_API(bool) -proxy_DeleteProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::ObjectOpResult& result); - -extern JS_FRIEND_API(void) -proxy_Trace(JSTracer* trc, JSObject* obj); -extern JS_FRIEND_API(JSObject*) -proxy_WeakmapKeyDelegate(JSObject* obj); -extern JS_FRIEND_API(bool) -proxy_Convert(JSContext* cx, JS::HandleObject proxy, JSType hint, JS::MutableHandleValue vp); -extern JS_FRIEND_API(void) -proxy_Finalize(FreeOp* fop, JSObject* obj); -extern JS_FRIEND_API(void) -proxy_ObjectMoved(JSObject* obj, const JSObject* old); -extern JS_FRIEND_API(bool) -proxy_HasInstance(JSContext* cx, JS::HandleObject proxy, JS::MutableHandleValue v, bool* bp); -extern JS_FRIEND_API(bool) -proxy_Call(JSContext* cx, unsigned argc, JS::Value* vp); -extern JS_FRIEND_API(bool) -proxy_Construct(JSContext* cx, unsigned argc, JS::Value* vp); -extern JS_FRIEND_API(JSObject*) -proxy_innerObject(JSObject* obj); -extern JS_FRIEND_API(bool) -proxy_Watch(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable); -extern JS_FRIEND_API(bool) -proxy_Unwatch(JSContext* cx, JS::HandleObject obj, JS::HandleId id); -extern JS_FRIEND_API(bool) -proxy_GetElements(JSContext* cx, JS::HandleObject proxy, uint32_t begin, uint32_t end, - ElementAdder* adder); -extern JS_FRIEND_API(JSString*) -proxy_FunToString(JSContext* cx, JS::HandleObject proxy, unsigned indent); - -/** - * A class of objects that return source code on demand. - * - * When code is compiled with setSourceIsLazy(true), SpiderMonkey doesn't - * retain the source code (and doesn't do lazy bytecode generation). If we ever - * need the source code, say, in response to a call to Function.prototype. - * toSource or Debugger.Source.prototype.text, then we call the 'load' member - * function of the instance of this class that has hopefully been registered - * with the runtime, passing the code's URL, and hope that it will be able to - * find the source. - */ -class SourceHook { - public: - virtual ~SourceHook() { } - - /** - * Set |*src| and |*length| to refer to the source code for |filename|. - * On success, the caller owns the buffer to which |*src| points, and - * should use JS_free to free it. - */ - virtual bool load(JSContext* cx, const char* filename, char16_t** src, size_t* length) = 0; -}; - -/** - * Have |cx| use |hook| to retrieve lazily-retrieved source code. See the - * comments for SourceHook. The context takes ownership of the hook, and - * will delete it when the context itself is deleted, or when a new hook is - * set. - */ -extern JS_FRIEND_API(void) -SetSourceHook(JSContext* cx, mozilla::UniquePtr hook); - -/** Remove |cx|'s source hook, and return it. The caller now owns the hook. */ -extern JS_FRIEND_API(mozilla::UniquePtr) -ForgetSourceHook(JSContext* cx); - -extern JS_FRIEND_API(JS::Zone*) -GetCompartmentZone(JSCompartment* comp); - -typedef bool -(* PreserveWrapperCallback)(JSContext* cx, JSObject* obj); - -typedef enum { - CollectNurseryBeforeDump, - IgnoreNurseryObjects -} DumpHeapNurseryBehaviour; - - /** - * Dump the complete object graph of heap-allocated things. - * fp is the file for the dump output. - */ -extern JS_FRIEND_API(void) -DumpHeap(JSContext* cx, FILE* fp, DumpHeapNurseryBehaviour nurseryBehaviour); - -#ifdef JS_OLD_GETTER_SETTER_METHODS -JS_FRIEND_API(bool) obj_defineGetter(JSContext* cx, unsigned argc, JS::Value* vp); -JS_FRIEND_API(bool) obj_defineSetter(JSContext* cx, unsigned argc, JS::Value* vp); -#endif - -extern JS_FRIEND_API(bool) -IsSystemCompartment(JSCompartment* comp); - -extern JS_FRIEND_API(bool) -IsSystemZone(JS::Zone* zone); - -extern JS_FRIEND_API(bool) -IsAtomsCompartment(JSCompartment* comp); - -extern JS_FRIEND_API(bool) -IsAtomsZone(JS::Zone* zone); - -struct WeakMapTracer -{ - JSContext* context; - - explicit WeakMapTracer(JSContext* cx) : context(cx) {} - - // Weak map tracer callback, called once for every binding of every - // weak map that was live at the time of the last garbage collection. - // - // m will be nullptr if the weak map is not contained in a JS Object. - // - // The callback should not GC (and will assert in a debug build if it does so.) - virtual void trace(JSObject* m, JS::GCCellPtr key, JS::GCCellPtr value) = 0; -}; - -extern JS_FRIEND_API(void) -TraceWeakMaps(WeakMapTracer* trc); - -extern JS_FRIEND_API(bool) -AreGCGrayBitsValid(JSContext* cx); - -extern JS_FRIEND_API(bool) -ZoneGlobalsAreAllGray(JS::Zone* zone); - -typedef void -(*GCThingCallback)(void* closure, JS::GCCellPtr thing); - -extern JS_FRIEND_API(void) -VisitGrayWrapperTargets(JS::Zone* zone, GCThingCallback callback, void* closure); - -extern JS_FRIEND_API(JSObject*) -GetWeakmapKeyDelegate(JSObject* key); - -/** - * Invoke cellCallback on every gray JSObject in the given zone. - */ -extern JS_FRIEND_API(void) -IterateGrayObjects(JS::Zone* zone, GCThingCallback cellCallback, void* data); - -/** - * Invoke cellCallback on every gray JSObject in the given zone while cycle - * collection is in progress. - */ -extern JS_FRIEND_API(void) -IterateGrayObjectsUnderCC(JS::Zone* zone, GCThingCallback cellCallback, void* data); - -#ifdef JS_HAS_CTYPES -extern JS_FRIEND_API(size_t) -SizeOfDataIfCDataObject(mozilla::MallocSizeOf mallocSizeOf, JSObject* obj); -#endif - -extern JS_FRIEND_API(JSCompartment*) -GetAnyCompartmentInZone(JS::Zone* zone); - -/* - * Shadow declarations of JS internal structures, for access by inline access - * functions below. Do not use these structures in any other way. When adding - * new fields for access by inline methods, make sure to add static asserts to - * the original header file to ensure that offsets are consistent. - */ -namespace shadow { - -struct ObjectGroup { - const Class* clasp; - JSObject* proto; - JSCompartment* compartment; -}; - -struct BaseShape { - const js::Class* clasp_; - JSObject* parent; -}; - -class Shape { -public: - shadow::BaseShape* base; - jsid _1; - uint32_t slotInfo; - - static const uint32_t FIXED_SLOTS_SHIFT = 27; -}; - -/** - * This layout is shared by all native objects. For non-native objects, the - * group may always be accessed safely, and other members may be as well, - * depending on the object's specific layout. - */ -struct Object { - shadow::ObjectGroup* group; - shadow::Shape* shape; - JS::Value* slots; - void* _1; - - size_t numFixedSlots() const { return shape->slotInfo >> Shape::FIXED_SLOTS_SHIFT; } - JS::Value* fixedSlots() const { - return (JS::Value*)(uintptr_t(this) + sizeof(shadow::Object)); - } - - JS::Value& slotRef(size_t slot) const { - size_t nfixed = numFixedSlots(); - if (slot < nfixed) - return fixedSlots()[slot]; - return slots[slot - nfixed]; - } -}; - -struct Function { - Object base; - uint16_t nargs; - uint16_t flags; - /* Used only for natives */ - JSNative native; - const JSJitInfo* jitinfo; - void* _1; -}; - -struct String -{ - static const uint32_t INLINE_CHARS_BIT = JS_BIT(2); - static const uint32_t LATIN1_CHARS_BIT = JS_BIT(6); - static const uint32_t ROPE_FLAGS = 0; - static const uint32_t TYPE_FLAGS_MASK = JS_BIT(6) - 1; - uint32_t flags; - uint32_t length; - union { - const JS::Latin1Char* nonInlineCharsLatin1; - const char16_t* nonInlineCharsTwoByte; - JS::Latin1Char inlineStorageLatin1[1]; - char16_t inlineStorageTwoByte[1]; - }; -}; - -} /* namespace shadow */ - -// This is equal to |&JSObject::class_|. Use it in places where you don't want -// to #include jsobj.h. -extern JS_FRIEND_DATA(const js::Class* const) ObjectClassPtr; - -inline const js::Class* -GetObjectClass(const JSObject* obj) -{ - return reinterpret_cast(obj)->group->clasp; -} - -inline const JSClass* -GetObjectJSClass(JSObject* obj) -{ - return js::Jsvalify(GetObjectClass(obj)); -} - -JS_FRIEND_API(const Class*) -ProtoKeyToClass(JSProtoKey key); - -// Returns the key for the class inherited by a given standard class (that -// is to say, the prototype of this standard class's prototype). -// -// You must be sure that this corresponds to a standard class with a cached -// JSProtoKey before calling this function. In general |key| will match the -// cached proto key, except in cases where multiple JSProtoKeys share a -// JSClass. -inline JSProtoKey -InheritanceProtoKeyForStandardClass(JSProtoKey key) -{ - // [Object] has nothing to inherit from. - if (key == JSProto_Object) - return JSProto_Null; - - // If we're ClassSpec defined return the proto key from that - if (ProtoKeyToClass(key)->specDefined()) - return ProtoKeyToClass(key)->specInheritanceProtoKey(); - - // Otherwise, we inherit [Object]. - return JSProto_Object; -} - -JS_FRIEND_API(bool) -IsFunctionObject(JSObject* obj); - -static MOZ_ALWAYS_INLINE JSCompartment* -GetObjectCompartment(JSObject* obj) -{ - return reinterpret_cast(obj)->group->compartment; -} - -JS_FRIEND_API(JSObject*) -GetGlobalForObjectCrossCompartment(JSObject* obj); - -JS_FRIEND_API(JSObject*) -GetPrototypeNoProxy(JSObject* obj); - -JS_FRIEND_API(void) -AssertSameCompartment(JSContext* cx, JSObject* obj); - -#ifdef JS_DEBUG -JS_FRIEND_API(void) -AssertSameCompartment(JSObject* objA, JSObject* objB); -#else -inline void AssertSameCompartment(JSObject* objA, JSObject* objB) {} -#endif - -JS_FRIEND_API(void) -NotifyAnimationActivity(JSObject* obj); - -/** - * Return the outermost enclosing function (script) of the scripted caller. - * This function returns nullptr in several cases: - * - no script is running on the context - * - the caller is in global or eval code - * In particular, this function will "stop" its outermost search at eval() and - * thus it will really return the outermost enclosing function *since the - * innermost eval*. - */ -JS_FRIEND_API(JSFunction*) -GetOutermostEnclosingFunctionOfScriptedCaller(JSContext* cx); - -JS_FRIEND_API(JSFunction*) -DefineFunctionWithReserved(JSContext* cx, JSObject* obj, const char* name, JSNative call, - unsigned nargs, unsigned attrs); - -JS_FRIEND_API(JSFunction*) -NewFunctionWithReserved(JSContext* cx, JSNative call, unsigned nargs, unsigned flags, - const char* name); - -JS_FRIEND_API(JSFunction*) -NewFunctionByIdWithReserved(JSContext* cx, JSNative native, unsigned nargs, unsigned flags, - jsid id); - -JS_FRIEND_API(const JS::Value&) -GetFunctionNativeReserved(JSObject* fun, size_t which); - -JS_FRIEND_API(void) -SetFunctionNativeReserved(JSObject* fun, size_t which, const JS::Value& val); - -JS_FRIEND_API(bool) -FunctionHasNativeReserved(JSObject* fun); - -JS_FRIEND_API(bool) -GetObjectProto(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject proto); - -extern JS_FRIEND_API(JSObject*) -GetStaticPrototype(JSObject* obj); - -JS_FRIEND_API(bool) -GetOriginalEval(JSContext* cx, JS::HandleObject scope, - JS::MutableHandleObject eval); - -inline void* -GetObjectPrivate(JSObject* obj) -{ - MOZ_ASSERT(GetObjectClass(obj)->flags & JSCLASS_HAS_PRIVATE); - const shadow::Object* nobj = reinterpret_cast(obj); - void** addr = reinterpret_cast(&nobj->fixedSlots()[nobj->numFixedSlots()]); - return *addr; -} - -inline const JS::Value& -GetReservedSlot(JSObject* obj, size_t slot) -{ - MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj))); - return reinterpret_cast(obj)->slotRef(slot); -} - -JS_FRIEND_API(void) -SetReservedOrProxyPrivateSlotWithBarrier(JSObject* obj, size_t slot, const JS::Value& value); - -inline void -SetReservedSlot(JSObject* obj, size_t slot, const JS::Value& value) -{ - MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj))); - shadow::Object* sobj = reinterpret_cast(obj); - if (sobj->slotRef(slot).isMarkable() || value.isMarkable()) - SetReservedOrProxyPrivateSlotWithBarrier(obj, slot, value); - else - sobj->slotRef(slot) = value; -} - -JS_FRIEND_API(uint32_t) -GetObjectSlotSpan(JSObject* obj); - -inline const JS::Value& -GetObjectSlot(JSObject* obj, size_t slot) -{ - MOZ_ASSERT(slot < GetObjectSlotSpan(obj)); - return reinterpret_cast(obj)->slotRef(slot); -} - -MOZ_ALWAYS_INLINE size_t -GetAtomLength(JSAtom* atom) -{ - return reinterpret_cast(atom)->length; -} - -static const uint32_t MaxStringLength = (1 << 28) - 1; - -MOZ_ALWAYS_INLINE size_t -GetStringLength(JSString* s) -{ - return reinterpret_cast(s)->length; -} - -MOZ_ALWAYS_INLINE size_t -GetFlatStringLength(JSFlatString* s) -{ - return reinterpret_cast(s)->length; -} - -MOZ_ALWAYS_INLINE size_t -GetLinearStringLength(JSLinearString* s) -{ - return reinterpret_cast(s)->length; -} - -MOZ_ALWAYS_INLINE bool -LinearStringHasLatin1Chars(JSLinearString* s) -{ - return reinterpret_cast(s)->flags & shadow::String::LATIN1_CHARS_BIT; -} - -MOZ_ALWAYS_INLINE bool -AtomHasLatin1Chars(JSAtom* atom) -{ - return reinterpret_cast(atom)->flags & shadow::String::LATIN1_CHARS_BIT; -} - -MOZ_ALWAYS_INLINE bool -StringHasLatin1Chars(JSString* s) -{ - return reinterpret_cast(s)->flags & shadow::String::LATIN1_CHARS_BIT; -} - -MOZ_ALWAYS_INLINE const JS::Latin1Char* -GetLatin1LinearStringChars(const JS::AutoCheckCannotGC& nogc, JSLinearString* linear) -{ - MOZ_ASSERT(LinearStringHasLatin1Chars(linear)); - - using shadow::String; - String* s = reinterpret_cast(linear); - if (s->flags & String::INLINE_CHARS_BIT) - return s->inlineStorageLatin1; - return s->nonInlineCharsLatin1; -} - -MOZ_ALWAYS_INLINE const char16_t* -GetTwoByteLinearStringChars(const JS::AutoCheckCannotGC& nogc, JSLinearString* linear) -{ - MOZ_ASSERT(!LinearStringHasLatin1Chars(linear)); - - using shadow::String; - String* s = reinterpret_cast(linear); - if (s->flags & String::INLINE_CHARS_BIT) - return s->inlineStorageTwoByte; - return s->nonInlineCharsTwoByte; -} - -MOZ_ALWAYS_INLINE JSLinearString* -AtomToLinearString(JSAtom* atom) -{ - return reinterpret_cast(atom); -} - -MOZ_ALWAYS_INLINE JSFlatString* -AtomToFlatString(JSAtom* atom) -{ - return reinterpret_cast(atom); -} - -MOZ_ALWAYS_INLINE JSLinearString* -FlatStringToLinearString(JSFlatString* s) -{ - return reinterpret_cast(s); -} - -MOZ_ALWAYS_INLINE const JS::Latin1Char* -GetLatin1AtomChars(const JS::AutoCheckCannotGC& nogc, JSAtom* atom) -{ - return GetLatin1LinearStringChars(nogc, AtomToLinearString(atom)); -} - -MOZ_ALWAYS_INLINE const char16_t* -GetTwoByteAtomChars(const JS::AutoCheckCannotGC& nogc, JSAtom* atom) -{ - return GetTwoByteLinearStringChars(nogc, AtomToLinearString(atom)); -} - -JS_FRIEND_API(JSLinearString*) -StringToLinearStringSlow(JSContext* cx, JSString* str); - -MOZ_ALWAYS_INLINE JSLinearString* -StringToLinearString(JSContext* cx, JSString* str) -{ - using shadow::String; - String* s = reinterpret_cast(str); - if (MOZ_UNLIKELY((s->flags & String::TYPE_FLAGS_MASK) == String::ROPE_FLAGS)) - return StringToLinearStringSlow(cx, str); - return reinterpret_cast(str); -} - -template -MOZ_ALWAYS_INLINE void -CopyLinearStringChars(CharType* dest, JSLinearString* s, size_t len, size_t start = 0); - -MOZ_ALWAYS_INLINE void -CopyLinearStringChars(char16_t* dest, JSLinearString* s, size_t len, size_t start = 0) -{ - MOZ_ASSERT(start + len <= GetLinearStringLength(s)); - JS::AutoCheckCannotGC nogc; - if (LinearStringHasLatin1Chars(s)) { - const JS::Latin1Char* src = GetLatin1LinearStringChars(nogc, s); - for (size_t i = 0; i < len; i++) - dest[i] = src[start + i]; - } else { - const char16_t* src = GetTwoByteLinearStringChars(nogc, s); - mozilla::PodCopy(dest, src + start, len); - } -} - -MOZ_ALWAYS_INLINE void -CopyLinearStringChars(char* dest, JSLinearString* s, size_t len, size_t start = 0) -{ - MOZ_ASSERT(start + len <= GetLinearStringLength(s)); - JS::AutoCheckCannotGC nogc; - if (LinearStringHasLatin1Chars(s)) { - const JS::Latin1Char* src = GetLatin1LinearStringChars(nogc, s); - for (size_t i = 0; i < len; i++) - dest[i] = char(src[start + i]); - } else { - const char16_t* src = GetTwoByteLinearStringChars(nogc, s); - for (size_t i = 0; i < len; i++) - dest[i] = char(src[start + i]); - } -} - -template -inline bool -CopyStringChars(JSContext* cx, CharType* dest, JSString* s, size_t len, size_t start = 0) -{ - JSLinearString* linear = StringToLinearString(cx, s); - if (!linear) - return false; - - CopyLinearStringChars(dest, linear, len, start); - return true; -} - -inline void -CopyFlatStringChars(char16_t* dest, JSFlatString* s, size_t len) -{ - CopyLinearStringChars(dest, FlatStringToLinearString(s), len); -} - -/** - * Add some or all property keys of obj to the id vector *props. - * - * The flags parameter controls which property keys are added. Pass a - * combination of the following bits: - * - * JSITER_OWNONLY - Don't also search the prototype chain; only consider - * obj's own properties. - * - * JSITER_HIDDEN - Include nonenumerable properties. - * - * JSITER_SYMBOLS - Include property keys that are symbols. The default - * behavior is to filter out symbols. - * - * JSITER_SYMBOLSONLY - Exclude non-symbol property keys. - * - * This is the closest C++ API we have to `Reflect.ownKeys(obj)`, or - * equivalently, the ES6 [[OwnPropertyKeys]] internal method. Pass - * `JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS` as flags to get - * results that match the output of Reflect.ownKeys. - */ -JS_FRIEND_API(bool) -GetPropertyKeys(JSContext* cx, JS::HandleObject obj, unsigned flags, JS::AutoIdVector* props); - -JS_FRIEND_API(bool) -AppendUnique(JSContext* cx, JS::AutoIdVector& base, JS::AutoIdVector& others); - -JS_FRIEND_API(bool) -StringIsArrayIndex(JSLinearString* str, uint32_t* indexp); - -JS_FRIEND_API(void) -SetPreserveWrapperCallback(JSContext* cx, PreserveWrapperCallback callback); - -JS_FRIEND_API(bool) -IsObjectInContextCompartment(JSObject* obj, const JSContext* cx); - -/* - * NB: keep these in sync with the copy in builtin/SelfHostingDefines.h. - * The first three are omitted because they shouldn't be used in new code. - */ -#define JSITER_ENUMERATE 0x1 /* for-in compatible hidden default iterator */ -#define JSITER_FOREACH 0x2 /* get obj[key] for each property */ -#define JSITER_KEYVALUE 0x4 /* obsolete destructuring for-in wants [key, value] */ -#define JSITER_OWNONLY 0x8 /* iterate over obj's own properties only */ -#define JSITER_HIDDEN 0x10 /* also enumerate non-enumerable properties */ -#define JSITER_SYMBOLS 0x20 /* also include symbol property keys */ -#define JSITER_SYMBOLSONLY 0x40 /* exclude string property keys */ - -JS_FRIEND_API(bool) -RunningWithTrustedPrincipals(JSContext* cx); - -inline uintptr_t -GetNativeStackLimit(JSContext* cx, StackKind kind, int extraAllowance = 0) -{ - uintptr_t limit = ContextFriendFields::get(cx)->nativeStackLimit[kind]; -#if JS_STACK_GROWTH_DIRECTION > 0 - limit += extraAllowance; -#else - limit -= extraAllowance; -#endif - return limit; -} - -inline uintptr_t -GetNativeStackLimit(JSContext* cx, int extraAllowance = 0) -{ - StackKind kind = RunningWithTrustedPrincipals(cx) ? StackForTrustedScript - : StackForUntrustedScript; - return GetNativeStackLimit(cx, kind, extraAllowance); -} - -/* - * These macros report a stack overflow and run |onerror| if we are close to - * using up the C stack. The JS_CHECK_CHROME_RECURSION variant gives us a - * little extra space so that we can ensure that crucial code is able to run. - * JS_CHECK_RECURSION_CONSERVATIVE allows less space than any other check, - * including a safety buffer (as in, it uses the untrusted limit and subtracts - * a little more from it). - */ - -#define JS_CHECK_RECURSION_LIMIT(cx, limit, onerror) \ - JS_BEGIN_MACRO \ - int stackDummy_; \ - if (!JS_CHECK_STACK_SIZE(limit, &stackDummy_)) { \ - js::ReportOverRecursed(cx); \ - onerror; \ - } \ - JS_END_MACRO - -#define JS_CHECK_RECURSION(cx, onerror) \ - JS_CHECK_RECURSION_LIMIT(cx, js::GetNativeStackLimit(cx), onerror) - -#define JS_CHECK_RECURSION_LIMIT_DONT_REPORT(cx, limit, onerror) \ - JS_BEGIN_MACRO \ - int stackDummy_; \ - if (!JS_CHECK_STACK_SIZE(limit, &stackDummy_)) { \ - onerror; \ - } \ - JS_END_MACRO - -#define JS_CHECK_RECURSION_DONT_REPORT(cx, onerror) \ - JS_CHECK_RECURSION_LIMIT_DONT_REPORT(cx, js::GetNativeStackLimit(cx), onerror) - -#define JS_CHECK_RECURSION_WITH_SP_DONT_REPORT(cx, sp, onerror) \ - JS_BEGIN_MACRO \ - if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) { \ - onerror; \ - } \ - JS_END_MACRO - -#define JS_CHECK_RECURSION_WITH_SP(cx, sp, onerror) \ - JS_BEGIN_MACRO \ - if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) { \ - js::ReportOverRecursed(cx); \ - onerror; \ - } \ - JS_END_MACRO - -#define JS_CHECK_SYSTEM_RECURSION(cx, onerror) \ - JS_CHECK_RECURSION_LIMIT(cx, js::GetNativeStackLimit(cx, js::StackForSystemCode), onerror) - -#define JS_CHECK_RECURSION_CONSERVATIVE(cx, onerror) \ - JS_CHECK_RECURSION_LIMIT(cx, \ - js::GetNativeStackLimit(cx, js::StackForUntrustedScript, -1024 * int(sizeof(size_t))), \ - onerror) - -#define JS_CHECK_RECURSION_CONSERVATIVE_DONT_REPORT(cx, onerror) \ - JS_CHECK_RECURSION_LIMIT_DONT_REPORT(cx, \ - js::GetNativeStackLimit(cx, js::StackForUntrustedScript, -1024 * int(sizeof(size_t))), \ - onerror) - -JS_FRIEND_API(void) -StartPCCountProfiling(JSContext* cx); - -JS_FRIEND_API(void) -StopPCCountProfiling(JSContext* cx); - -JS_FRIEND_API(void) -PurgePCCounts(JSContext* cx); - -JS_FRIEND_API(size_t) -GetPCCountScriptCount(JSContext* cx); - -JS_FRIEND_API(JSString*) -GetPCCountScriptSummary(JSContext* cx, size_t script); - -JS_FRIEND_API(JSString*) -GetPCCountScriptContents(JSContext* cx, size_t script); - -/** - * Generate lcov trace file content for the current compartment, and allocate a - * new buffer and return the content in it, the size of the newly allocated - * content within the buffer would be set to the length out-param. - * - * In case of out-of-memory, this function returns nullptr and does not set any - * value to the length out-param. - */ -JS_FRIEND_API(char*) -GetCodeCoverageSummary(JSContext* cx, size_t* length); - -typedef void -(* ActivityCallback)(void* arg, bool active); - -/** - * Sets a callback that is run whenever the runtime goes idle - the - * last active request ceases - and begins activity - when it was - * idle and a request begins. - */ -JS_FRIEND_API(void) -SetActivityCallback(JSContext* cx, ActivityCallback cb, void* arg); - -typedef bool -(* DOMInstanceClassHasProtoAtDepth)(const Class* instanceClass, - uint32_t protoID, uint32_t depth); -struct JSDOMCallbacks { - DOMInstanceClassHasProtoAtDepth instanceClassMatchesProto; -}; -typedef struct JSDOMCallbacks DOMCallbacks; - -extern JS_FRIEND_API(void) -SetDOMCallbacks(JSContext* cx, const DOMCallbacks* callbacks); - -extern JS_FRIEND_API(const DOMCallbacks*) -GetDOMCallbacks(JSContext* cx); - -extern JS_FRIEND_API(JSObject*) -GetTestingFunctions(JSContext* cx); - -/** - * Helper to convert FreeOp to JSFreeOp when the definition of FreeOp is not - * available and the compiler does not know that FreeOp inherits from - * JSFreeOp. - */ -inline JSFreeOp* -CastToJSFreeOp(FreeOp* fop) -{ - return reinterpret_cast(fop); -} - -/* Implemented in jsexn.cpp. */ - -/** - * Get an error type name from a JSExnType constant. - * Returns nullptr for invalid arguments and JSEXN_INTERNALERR - */ -extern JS_FRIEND_API(JSFlatString*) -GetErrorTypeName(JSContext* cx, int16_t exnType); - -#ifdef JS_DEBUG -extern JS_FRIEND_API(unsigned) -GetEnterCompartmentDepth(JSContext* cx); -#endif - -class RegExpGuard; -extern JS_FRIEND_API(bool) -RegExpToSharedNonInline(JSContext* cx, JS::HandleObject regexp, RegExpGuard* shared); - -/* Implemented in jswrapper.cpp. */ -typedef enum NukeReferencesToWindow { - NukeWindowReferences, - DontNukeWindowReferences -} NukeReferencesToWindow; - -/* - * These filters are designed to be ephemeral stack classes, and thus don't - * do any rooting or holding of their members. - */ -struct CompartmentFilter { - virtual bool match(JSCompartment* c) const = 0; -}; - -struct AllCompartments : public CompartmentFilter { - virtual bool match(JSCompartment* c) const override { return true; } -}; - -struct ContentCompartmentsOnly : public CompartmentFilter { - virtual bool match(JSCompartment* c) const override { - return !IsSystemCompartment(c); - } -}; - -struct ChromeCompartmentsOnly : public CompartmentFilter { - virtual bool match(JSCompartment* c) const override { - return IsSystemCompartment(c); - } -}; - -struct SingleCompartment : public CompartmentFilter { - JSCompartment* ours; - explicit SingleCompartment(JSCompartment* c) : ours(c) {} - virtual bool match(JSCompartment* c) const override { return c == ours; } -}; - -struct CompartmentsWithPrincipals : public CompartmentFilter { - JSPrincipals* principals; - explicit CompartmentsWithPrincipals(JSPrincipals* p) : principals(p) {} - virtual bool match(JSCompartment* c) const override { - return JS_GetCompartmentPrincipals(c) == principals; - } -}; - -extern JS_FRIEND_API(bool) -NukeCrossCompartmentWrappers(JSContext* cx, - const CompartmentFilter& sourceFilter, - const CompartmentFilter& targetFilter, - NukeReferencesToWindow nukeReferencesToWindow); - -/* Specify information about DOMProxy proxies in the DOM, for use by ICs. */ - -/* - * The DOMProxyShadowsCheck function will be called to check if the property for - * id should be gotten from the prototype, or if there is an own property that - * shadows it. - * * If ShadowsViaDirectExpando is returned, then the slot at - * listBaseExpandoSlot contains an expando object which has the property in - * question. - * * If ShadowsViaIndirectExpando is returned, then the slot at - * listBaseExpandoSlot contains a private pointer to an ExpandoAndGeneration - * and the expando object in the ExpandoAndGeneration has the property in - * question. - * * If DoesntShadow is returned then the slot at listBaseExpandoSlot should - * either be undefined or point to an expando object that would contain the - * own property. - * * If DoesntShadowUnique is returned then the slot at listBaseExpandoSlot - * should contain a private pointer to a ExpandoAndGeneration, which contains - * a JS::Value that should either be undefined or point to an expando object, - * and a uint64 value. If that value changes then the IC for getting a - * property will be invalidated. - * * If Shadows is returned, that means the property is an own property of the - * proxy but doesn't live on the expando object. - */ - -struct ExpandoAndGeneration { - ExpandoAndGeneration() - : expando(JS::UndefinedValue()), - generation(0) - {} - - void OwnerUnlinked() - { - ++generation; - } - - static size_t offsetOfExpando() - { - return offsetof(ExpandoAndGeneration, expando); - } - - static size_t offsetOfGeneration() - { - return offsetof(ExpandoAndGeneration, generation); - } - - JS::Heap expando; - uint64_t generation; -}; - -typedef enum DOMProxyShadowsResult { - ShadowCheckFailed, - Shadows, - DoesntShadow, - DoesntShadowUnique, - ShadowsViaDirectExpando, - ShadowsViaIndirectExpando -} DOMProxyShadowsResult; -typedef DOMProxyShadowsResult -(* DOMProxyShadowsCheck)(JSContext* cx, JS::HandleObject object, JS::HandleId id); -JS_FRIEND_API(void) -SetDOMProxyInformation(const void* domProxyHandlerFamily, uint32_t domProxyExpandoSlot, - DOMProxyShadowsCheck domProxyShadowsCheck); - -const void* GetDOMProxyHandlerFamily(); -uint32_t GetDOMProxyExpandoSlot(); -DOMProxyShadowsCheck GetDOMProxyShadowsCheck(); -inline bool DOMProxyIsShadowing(DOMProxyShadowsResult result) { - return result == Shadows || - result == ShadowsViaDirectExpando || - result == ShadowsViaIndirectExpando; -} - -/* Implemented in jsdate.cpp. */ - -/** Detect whether the internal date value is NaN. */ -extern JS_FRIEND_API(bool) -DateIsValid(JSContext* cx, JS::HandleObject obj, bool* isValid); - -extern JS_FRIEND_API(bool) -DateGetMsecSinceEpoch(JSContext* cx, JS::HandleObject obj, double* msecSinceEpoch); - -} /* namespace js */ - -/* Implemented in jscntxt.cpp. */ - -/** - * Report an exception, which is currently realized as a printf-style format - * string and its arguments. - */ -typedef enum JSErrNum { -#define MSG_DEF(name, count, exception, format) \ - name, -#include "js.msg" -#undef MSG_DEF - JSErr_Limit -} JSErrNum; - -namespace js { - -extern JS_FRIEND_API(const JSErrorFormatString*) -GetErrorMessage(void* userRef, const unsigned errorNumber); - -// AutoStableStringChars is here so we can use it in ErrorReport. It -// should get moved out of here if we can manage it. See bug 1040316. - -/** - * This class provides safe access to a string's chars across a GC. Once - * we allocate strings and chars in the nursery (bug 903519), this class - * will have to make a copy of the string's chars if they are allocated - * in the nursery, so it's best to avoid using this class unless you really - * need it. It's usually more efficient to use the latin1Chars/twoByteChars - * JSString methods and often the code can be rewritten so that only indexes - * instead of char pointers are used in parts of the code that can GC. - */ -class MOZ_STACK_CLASS AutoStableStringChars -{ - /* - * When copying string char, use this many bytes of inline storage. This is - * chosen to allow the inline string types to be copied without allocating. - * This is asserted in AutoStableStringChars::allocOwnChars. - */ - static const size_t InlineCapacity = 24; - - /* Ensure the string is kept alive while we're using its chars. */ - JS::RootedString s_; - union { - const char16_t* twoByteChars_; - const JS::Latin1Char* latin1Chars_; - }; - mozilla::Maybe> ownChars_; - enum State { Uninitialized, Latin1, TwoByte }; - State state_; - - public: - explicit AutoStableStringChars(JSContext* cx) - : s_(cx), state_(Uninitialized) - {} - - MOZ_MUST_USE - bool init(JSContext* cx, JSString* s); - - /* Like init(), but Latin1 chars are inflated to TwoByte. */ - MOZ_MUST_USE - bool initTwoByte(JSContext* cx, JSString* s); - - bool isLatin1() const { return state_ == Latin1; } - bool isTwoByte() const { return state_ == TwoByte; } - - const char16_t* twoByteChars() const { - MOZ_ASSERT(state_ == TwoByte); - return twoByteChars_; - } - - mozilla::Range latin1Range() const { - MOZ_ASSERT(state_ == Latin1); - return mozilla::Range(latin1Chars_, - GetStringLength(s_)); - } - - mozilla::Range twoByteRange() const { - MOZ_ASSERT(state_ == TwoByte); - return mozilla::Range(twoByteChars_, - GetStringLength(s_)); - } - - /* If we own the chars, transfer ownership to the caller. */ - bool maybeGiveOwnershipToCaller() { - MOZ_ASSERT(state_ != Uninitialized); - if (!ownChars_.isSome() || !ownChars_->extractRawBuffer()) - return false; - state_ = Uninitialized; - ownChars_.reset(); - return true; - } - - private: - AutoStableStringChars(const AutoStableStringChars& other) = delete; - void operator=(const AutoStableStringChars& other) = delete; - - bool baseIsInline(JS::Handle linearString); - template T* allocOwnChars(JSContext* cx, size_t count); - bool copyLatin1Chars(JSContext* cx, JS::Handle linearString); - bool copyTwoByteChars(JSContext* cx, JS::Handle linearString); - bool copyAndInflateLatin1Chars(JSContext*, JS::Handle linearString); -}; - -struct MOZ_STACK_CLASS JS_FRIEND_API(ErrorReport) -{ - explicit ErrorReport(JSContext* cx); - ~ErrorReport(); - - enum SniffingBehavior { - WithSideEffects, - NoSideEffects - }; - - /** - * Generate a JSErrorReport from the provided thrown value. - * - * If the value is a (possibly wrapped) Error object, the JSErrorReport will - * be exactly initialized from the Error object's information, without - * observable side effects. (The Error object's JSErrorReport is reused, if - * it has one.) - * - * Otherwise various attempts are made to derive JSErrorReport information - * from |exn| and from the current execution state. This process is - * *definitely* inconsistent with any standard, and particulars of the - * behavior implemented here generally shouldn't be relied upon. - * - * If the value of |sniffingBehavior| is |WithSideEffects|, some of these - * attempts *may* invoke user-configurable behavior when |exn| is an object: - * converting |exn| to a string, detecting and getting properties on |exn|, - * accessing |exn|'s prototype chain, and others are possible. Users *must* - * tolerate |ErrorReport::init| potentially having arbitrary effects. Any - * exceptions thrown by these operations will be caught and silently - * ignored, and "default" values will be substituted into the JSErrorReport. - * - * But if the value of |sniffingBehavior| is |NoSideEffects|, these attempts - * *will not* invoke any observable side effects. The JSErrorReport will - * simply contain fewer, less precise details. - * - * Unlike some functions involved in error handling, this function adheres - * to the usual JSAPI return value error behavior. - */ - bool init(JSContext* cx, JS::HandleValue exn, - SniffingBehavior sniffingBehavior); - - JSErrorReport* report() - { - return reportp; - } - - const JS::ConstUTF8CharsZ toStringResult() - { - return toStringResult_; - } - - private: - // More or less an equivalent of JS_ReportErrorNumber/js::ReportErrorNumberVA - // but fills in an ErrorReport instead of reporting it. Uses varargs to - // make it simpler to call js::ExpandErrorArgumentsVA. - // - // Returns false if we fail to actually populate the ErrorReport - // for some reason (probably out of memory). - bool populateUncaughtExceptionReportUTF8(JSContext* cx, ...); - bool populateUncaughtExceptionReportUTF8VA(JSContext* cx, va_list ap); - - // Reports exceptions from add-on scopes to telementry. - void ReportAddonExceptionToTelementry(JSContext* cx); - - // We may have a provided JSErrorReport, so need a way to represent that. - JSErrorReport* reportp; - - // Or we may need to synthesize a JSErrorReport one of our own. - JSErrorReport ownedReport; - - // And we have a string to maybe keep alive that has pointers into - // it from ownedReport. - JS::RootedString str; - - // And keep its chars alive too. - AutoStableStringChars strChars; - - // And we need to root our exception value. - JS::RootedObject exnObject; - - // And for our filename. - JSAutoByteString filename; - - // We may have a result of error.toString(). - // FIXME: We should not call error.toString(), since it could have side - // effect (see bug 633623). - JS::ConstUTF8CharsZ toStringResult_; - JSAutoByteString toStringResultBytesStorage; -}; - -/* Implemented in vm/StructuredClone.cpp. */ -extern JS_FRIEND_API(uint64_t) -GetSCOffset(JSStructuredCloneWriter* writer); - -namespace Scalar { - -/** - * Scalar types that can appear in typed arrays and typed objects. The enum - * values must to be kept in sync with the JS_SCALARTYPEREPR_ constants, as - * well as the TypedArrayObject::classes and TypedArrayObject::protoClasses - * definitions. - */ -enum Type { - Int8 = 0, - Uint8, - Int16, - Uint16, - Int32, - Uint32, - Float32, - Float64, - - /** - * Special type that is a uint8_t, but assignments are clamped to [0, 256). - * Treat the raw data type as a uint8_t. - */ - Uint8Clamped, - - /** - * Types that don't have their own TypedArray equivalent, for now. - */ - MaxTypedArrayViewType, - - Int64, - Float32x4, - Int8x16, - Int16x8, - Int32x4 -}; - -static inline size_t -byteSize(Type atype) -{ - switch (atype) { - case Int8: - case Uint8: - case Uint8Clamped: - return 1; - case Int16: - case Uint16: - return 2; - case Int32: - case Uint32: - case Float32: - return 4; - case Int64: - case Float64: - return 8; - case Int8x16: - case Int16x8: - case Int32x4: - case Float32x4: - return 16; - default: - MOZ_CRASH("invalid scalar type"); - } -} - -static inline bool -isSignedIntType(Type atype) { - switch (atype) { - case Int8: - case Int16: - case Int32: - case Int64: - case Int8x16: - case Int16x8: - case Int32x4: - return true; - case Uint8: - case Uint8Clamped: - case Uint16: - case Uint32: - case Float32: - case Float64: - case Float32x4: - return false; - default: - MOZ_CRASH("invalid scalar type"); - } -} - -static inline bool -isSimdType(Type atype) { - switch (atype) { - case Int8: - case Uint8: - case Uint8Clamped: - case Int16: - case Uint16: - case Int32: - case Uint32: - case Int64: - case Float32: - case Float64: - return false; - case Int8x16: - case Int16x8: - case Int32x4: - case Float32x4: - return true; - case MaxTypedArrayViewType: - break; - } - MOZ_CRASH("invalid scalar type"); -} - -static inline size_t -scalarByteSize(Type atype) { - switch (atype) { - case Int8x16: - return 1; - case Int16x8: - return 2; - case Int32x4: - case Float32x4: - return 4; - case Int8: - case Uint8: - case Uint8Clamped: - case Int16: - case Uint16: - case Int32: - case Uint32: - case Int64: - case Float32: - case Float64: - case MaxTypedArrayViewType: - break; - } - MOZ_CRASH("invalid simd type"); -} - -} /* namespace Scalar */ -} /* namespace js */ - -/* - * Create a new typed array with nelements elements. - * - * These functions (except the WithBuffer variants) fill in the array with zeros. - */ - -extern JS_FRIEND_API(JSObject*) -JS_NewInt8Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8ClampedArray(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewInt16Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewUint16Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewInt32Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewUint32Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat32Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat64Array(JSContext* cx, uint32_t nelements); - -/* - * Create a new typed array and copy in values from the given object. The - * object is used as if it were an array; that is, the new array (if - * successfully created) will have length given by array.length, and its - * elements will be those specified by array[0], array[1], and so on, after - * conversion to the typed array element type. - */ - -extern JS_FRIEND_API(JSObject*) -JS_NewInt8ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8ClampedArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewInt16ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewUint16ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewInt32ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewUint32ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat32ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat64ArrayFromArray(JSContext* cx, JS::HandleObject array); - -/* - * Create a new typed array using the given ArrayBuffer or - * SharedArrayBuffer for storage. The length value is optional; if -1 - * is passed, enough elements to use up the remainder of the byte - * array is used as the default value. - */ - -extern JS_FRIEND_API(JSObject*) -JS_NewInt8ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8ClampedArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewInt16ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewUint16ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewInt32ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewUint32ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat32ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat64ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); - -/** - * Create a new SharedArrayBuffer with the given byte length. This - * may only be called if - * JS::CompartmentCreationOptionsRef(cx).getSharedMemoryAndAtomicsEnabled() is - * true. - */ -extern JS_FRIEND_API(JSObject*) -JS_NewSharedArrayBuffer(JSContext* cx, uint32_t nbytes); - -/** - * Create a new ArrayBuffer with the given byte length. - */ -extern JS_FRIEND_API(JSObject*) -JS_NewArrayBuffer(JSContext* cx, uint32_t nbytes); - -/** - * Check whether obj supports JS_GetTypedArray* APIs. Note that this may return - * false if a security wrapper is encountered that denies the unwrapping. If - * this test or one of the JS_Is*Array tests succeeds, then it is safe to call - * the various accessor JSAPI calls defined below. - */ -extern JS_FRIEND_API(bool) -JS_IsTypedArrayObject(JSObject* obj); - -/** - * Check whether obj supports JS_GetArrayBufferView* APIs. Note that this may - * return false if a security wrapper is encountered that denies the - * unwrapping. If this test or one of the more specific tests succeeds, then it - * is safe to call the various ArrayBufferView accessor JSAPI calls defined - * below. - */ -extern JS_FRIEND_API(bool) -JS_IsArrayBufferViewObject(JSObject* obj); - -/* - * Test for specific typed array types (ArrayBufferView subtypes) - */ - -extern JS_FRIEND_API(bool) -JS_IsInt8Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsUint8Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsUint8ClampedArray(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsInt16Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsUint16Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsInt32Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsUint32Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsFloat32Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsFloat64Array(JSObject* obj); - -/** - * Return the isShared flag of a typed array, which denotes whether - * the underlying buffer is a SharedArrayBuffer. - * - * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow - * be known that it would pass such a test: it is a typed array or a wrapper of - * a typed array, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(bool) -JS_GetTypedArraySharedness(JSObject* obj); - -/* - * Test for specific typed array types (ArrayBufferView subtypes) and return - * the unwrapped object if so, else nullptr. Never throws. - */ - -namespace js { - -extern JS_FRIEND_API(JSObject*) -UnwrapInt8Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapUint8Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapUint8ClampedArray(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapInt16Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapUint16Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapInt32Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapUint32Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapFloat32Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapFloat64Array(JSObject* obj); - -extern JS_FRIEND_API(JSObject*) -UnwrapArrayBuffer(JSObject* obj); - -extern JS_FRIEND_API(JSObject*) -UnwrapArrayBufferView(JSObject* obj); - -extern JS_FRIEND_API(JSObject*) -UnwrapSharedArrayBuffer(JSObject* obj); - - -namespace detail { - -extern JS_FRIEND_DATA(const Class* const) Int8ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Uint8ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Uint8ClampedArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Int16ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Uint16ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Int32ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Uint32ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Float32ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Float64ArrayClassPtr; - -const size_t TypedArrayLengthSlot = 1; - -} // namespace detail - -#define JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Type, type) \ -inline void \ -Get ## Type ## ArrayLengthAndData(JSObject* obj, uint32_t* length, bool* isSharedMemory, type** data) \ -{ \ - MOZ_ASSERT(GetObjectClass(obj) == detail::Type ## ArrayClassPtr); \ - const JS::Value& lenSlot = GetReservedSlot(obj, detail::TypedArrayLengthSlot); \ - *length = mozilla::AssertedCast(lenSlot.toInt32()); \ - *isSharedMemory = JS_GetTypedArraySharedness(obj); \ - *data = static_cast(GetObjectPrivate(obj)); \ -} - -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int8, int8_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint8, uint8_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint8Clamped, uint8_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int16, int16_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint16, uint16_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int32, int32_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint32, uint32_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float32, float) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float64, double) - -#undef JS_DEFINE_DATA_AND_LENGTH_ACCESSOR - -// This one isn't inlined because it's rather tricky (by dint of having to deal -// with a dozen-plus classes and varying slot layouts. -extern JS_FRIEND_API(void) -GetArrayBufferViewLengthAndData(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); - -// This one isn't inlined because there are a bunch of different ArrayBuffer -// classes that would have to be individually handled here. -// -// There is an isShared out argument for API consistency (eases use from DOM). -// It will always be set to false. -extern JS_FRIEND_API(void) -GetArrayBufferLengthAndData(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); - -// Ditto for SharedArrayBuffer. -// -// There is an isShared out argument for API consistency (eases use from DOM). -// It will always be set to true. -extern JS_FRIEND_API(void) -GetSharedArrayBufferLengthAndData(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); - -} // namespace js - -JS_FRIEND_API(uint8_t*) -JS_GetSharedArrayBufferData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); - -/* - * Unwrap Typed arrays all at once. Return nullptr without throwing if the - * object cannot be viewed as the correct typed array, or the typed array - * object on success, filling both outparameters. - */ -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsInt8Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, int8_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsUint8Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsUint8ClampedArray(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsInt16Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, int16_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsUint16Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint16_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsInt32Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, int32_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsUint32Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint32_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsFloat32Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, float** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsFloat64Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, double** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsArrayBufferView(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); - -/* - * Unwrap an ArrayBuffer, return nullptr if it's a different type. - */ -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsArrayBuffer(JSObject* obj, uint32_t* length, uint8_t** data); - -/* - * Get the type of elements in a typed array, or MaxTypedArrayViewType if a DataView. - * - * |obj| must have passed a JS_IsArrayBufferView/JS_Is*Array test, or somehow - * be known that it would pass such a test: it is an ArrayBufferView or a - * wrapper of an ArrayBufferView, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(js::Scalar::Type) -JS_GetArrayBufferViewType(JSObject* obj); - -extern JS_FRIEND_API(js::Scalar::Type) -JS_GetSharedArrayBufferViewType(JSObject* obj); - -/* - * Check whether obj supports the JS_GetArrayBuffer* APIs. Note that this may - * return false if a security wrapper is encountered that denies the - * unwrapping. If this test succeeds, then it is safe to call the various - * accessor JSAPI calls defined below. - */ -extern JS_FRIEND_API(bool) -JS_IsArrayBufferObject(JSObject* obj); - -extern JS_FRIEND_API(bool) -JS_IsSharedArrayBufferObject(JSObject* obj); - -/** - * Return the available byte length of an array buffer. - * - * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known - * that it would pass such a test: it is an ArrayBuffer or a wrapper of an - * ArrayBuffer, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(uint32_t) -JS_GetArrayBufferByteLength(JSObject* obj); - -extern JS_FRIEND_API(uint32_t) -JS_GetSharedArrayBufferByteLength(JSObject* obj); - -/** - * Return true if the arrayBuffer contains any data. This will return false for - * ArrayBuffer.prototype and detached ArrayBuffers. - * - * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known - * that it would pass such a test: it is an ArrayBuffer or a wrapper of an - * ArrayBuffer, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(bool) -JS_ArrayBufferHasData(JSObject* obj); - -/** - * Return a pointer to the start of the data referenced by a typed array. The - * data is still owned by the typed array, and should not be modified on - * another thread. Furthermore, the pointer can become invalid on GC (if the - * data is small and fits inside the array's GC header), so callers must take - * care not to hold on across anything that could GC. - * - * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known - * that it would pass such a test: it is an ArrayBuffer or a wrapper of an - * ArrayBuffer, and the unwrapping will succeed. - * - * *isSharedMemory will be set to false, the argument is present to simplify - * its use from code that also interacts with SharedArrayBuffer. - */ -extern JS_FRIEND_API(uint8_t*) -JS_GetArrayBufferData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); - -/** - * Check whether the obj is ArrayBufferObject and memory mapped. Note that this - * may return false if a security wrapper is encountered that denies the - * unwrapping. - */ -extern JS_FRIEND_API(bool) -JS_IsMappedArrayBufferObject(JSObject* obj); - -/** - * Return the number of elements in a typed array. - * - * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow - * be known that it would pass such a test: it is a typed array or a wrapper of - * a typed array, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(uint32_t) -JS_GetTypedArrayLength(JSObject* obj); - -/** - * Return the byte offset from the start of an array buffer to the start of a - * typed array view. - * - * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow - * be known that it would pass such a test: it is a typed array or a wrapper of - * a typed array, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(uint32_t) -JS_GetTypedArrayByteOffset(JSObject* obj); - -/** - * Return the byte length of a typed array. - * - * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow - * be known that it would pass such a test: it is a typed array or a wrapper of - * a typed array, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(uint32_t) -JS_GetTypedArrayByteLength(JSObject* obj); - -/** - * Check whether obj supports JS_ArrayBufferView* APIs. Note that this may - * return false if a security wrapper is encountered that denies the - * unwrapping. - */ -extern JS_FRIEND_API(bool) -JS_IsArrayBufferViewObject(JSObject* obj); - -/** - * More generic name for JS_GetTypedArrayByteLength to cover DataViews as well - */ -extern JS_FRIEND_API(uint32_t) -JS_GetArrayBufferViewByteLength(JSObject* obj); - -/* - * Return a pointer to the start of the data referenced by a typed array. The - * data is still owned by the typed array, and should not be modified on - * another thread. Furthermore, the pointer can become invalid on GC (if the - * data is small and fits inside the array's GC header), so callers must take - * care not to hold on across anything that could GC. - * - * |obj| must have passed a JS_Is*Array test, or somehow be known that it would - * pass such a test: it is a typed array or a wrapper of a typed array, and the - * unwrapping will succeed. - * - * *isSharedMemory will be set to true if the typed array maps a - * SharedArrayBuffer, otherwise to false. - */ - -extern JS_FRIEND_API(int8_t*) -JS_GetInt8ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(uint8_t*) -JS_GetUint8ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(uint8_t*) -JS_GetUint8ClampedArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(int16_t*) -JS_GetInt16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(uint16_t*) -JS_GetUint16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(int32_t*) -JS_GetInt32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(uint32_t*) -JS_GetUint32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(float*) -JS_GetFloat32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(double*) -JS_GetFloat64ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); - -/** - * Same as above, but for any kind of ArrayBufferView. Prefer the type-specific - * versions when possible. - */ -extern JS_FRIEND_API(void*) -JS_GetArrayBufferViewData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); - -/** - * Return the ArrayBuffer or SharedArrayBuffer underlying an ArrayBufferView. - * This may return a detached buffer. |obj| must be an object that would - * return true for JS_IsArrayBufferViewObject(). - */ -extern JS_FRIEND_API(JSObject*) -JS_GetArrayBufferViewBuffer(JSContext* cx, JS::HandleObject obj, bool* isSharedMemory); - -/** - * Detach an ArrayBuffer, causing all associated views to no longer refer to - * the ArrayBuffer's original attached memory. - * - * The |changeData| argument is obsolete and ignored. - */ -extern JS_FRIEND_API(bool) -JS_DetachArrayBuffer(JSContext* cx, JS::HandleObject obj); - -/** - * Check whether the obj is a detached ArrayBufferObject. Note that this may - * return false if a security wrapper is encountered that denies the - * unwrapping. - */ -extern JS_FRIEND_API(bool) -JS_IsDetachedArrayBufferObject(JSObject* obj); - -/** - * Check whether obj supports JS_GetDataView* APIs. - */ -JS_FRIEND_API(bool) -JS_IsDataViewObject(JSObject* obj); - -/** - * Create a new DataView using the given ArrayBuffer for storage. The given - * buffer must be an ArrayBuffer (or a cross-compartment wrapper of an - * ArrayBuffer), and the offset and length must fit within the bounds of the - * arrayBuffer. Currently, nullptr will be returned and an exception will be - * thrown if these conditions do not hold, but do not depend on that behavior. - */ -JS_FRIEND_API(JSObject*) -JS_NewDataView(JSContext* cx, JS::HandleObject arrayBuffer, uint32_t byteOffset, int32_t byteLength); - -/** - * Return the byte offset of a data view into its array buffer. |obj| must be a - * DataView. - * - * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that - * it would pass such a test: it is a data view or a wrapper of a data view, - * and the unwrapping will succeed. - */ -JS_FRIEND_API(uint32_t) -JS_GetDataViewByteOffset(JSObject* obj); - -/** - * Return the byte length of a data view. - * - * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that - * it would pass such a test: it is a data view or a wrapper of a data view, - * and the unwrapping will succeed. If cx is nullptr, then DEBUG builds may be - * unable to assert when unwrapping should be disallowed. - */ -JS_FRIEND_API(uint32_t) -JS_GetDataViewByteLength(JSObject* obj); - -/** - * Return a pointer to the beginning of the data referenced by a DataView. - * - * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that - * it would pass such a test: it is a data view or a wrapper of a data view, - * and the unwrapping will succeed. If cx is nullptr, then DEBUG builds may be - * unable to assert when unwrapping should be disallowed. - */ -JS_FRIEND_API(void*) -JS_GetDataViewData(JSObject* obj, const JS::AutoCheckCannotGC&); - -namespace js { - -/** - * Add a watchpoint -- in the Object.prototype.watch sense -- to |obj| for the - * property |id|, using the callable object |callable| as the function to be - * called for notifications. - * - * This is an internal function exposed -- temporarily -- only so that DOM - * proxies can be watchable. Don't use it! We'll soon kill off the - * Object.prototype.{,un}watch functions, at which point this will go too. - */ -extern JS_FRIEND_API(bool) -WatchGuts(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable); - -/** - * Remove a watchpoint -- in the Object.prototype.watch sense -- from |obj| for - * the property |id|. - * - * This is an internal function exposed -- temporarily -- only so that DOM - * proxies can be watchable. Don't use it! We'll soon kill off the - * Object.prototype.{,un}watch functions, at which point this will go too. - */ -extern JS_FRIEND_API(bool) -UnwatchGuts(JSContext* cx, JS::HandleObject obj, JS::HandleId id); - -namespace jit { - -enum class InlinableNative : uint16_t; - -} // namespace jit - -} // namespace js - -/** - * A class, expected to be passed by value, which represents the CallArgs for a - * JSJitGetterOp. - */ -class JSJitGetterCallArgs : protected JS::MutableHandleValue -{ - public: - explicit JSJitGetterCallArgs(const JS::CallArgs& args) - : JS::MutableHandleValue(args.rval()) - {} - - explicit JSJitGetterCallArgs(JS::RootedValue* rooted) - : JS::MutableHandleValue(rooted) - {} - - JS::MutableHandleValue rval() { - return *this; - } -}; - -/** - * A class, expected to be passed by value, which represents the CallArgs for a - * JSJitSetterOp. - */ -class JSJitSetterCallArgs : protected JS::MutableHandleValue -{ - public: - explicit JSJitSetterCallArgs(const JS::CallArgs& args) - : JS::MutableHandleValue(args[0]) - {} - - JS::MutableHandleValue operator[](unsigned i) { - MOZ_ASSERT(i == 0); - return *this; - } - - unsigned length() const { return 1; } - - // Add get() or maybe hasDefined() as needed -}; - -struct JSJitMethodCallArgsTraits; - -/** - * A class, expected to be passed by reference, which represents the CallArgs - * for a JSJitMethodOp. - */ -class JSJitMethodCallArgs : protected JS::detail::CallArgsBase -{ - private: - typedef JS::detail::CallArgsBase Base; - friend struct JSJitMethodCallArgsTraits; - - public: - explicit JSJitMethodCallArgs(const JS::CallArgs& args) { - argv_ = args.array(); - argc_ = args.length(); - } - - JS::MutableHandleValue rval() const { - return Base::rval(); - } - - unsigned length() const { return Base::length(); } - - JS::MutableHandleValue operator[](unsigned i) const { - return Base::operator[](i); - } - - bool hasDefined(unsigned i) const { - return Base::hasDefined(i); - } - - JSObject& callee() const { - // We can't use Base::callee() because that will try to poke at - // this->usedRval_, which we don't have. - return argv_[-2].toObject(); - } - - JS::HandleValue get(unsigned i) const { - return Base::get(i); - } -}; - -struct JSJitMethodCallArgsTraits -{ - static const size_t offsetOfArgv = offsetof(JSJitMethodCallArgs, argv_); - static const size_t offsetOfArgc = offsetof(JSJitMethodCallArgs, argc_); -}; - -typedef bool -(* JSJitGetterOp)(JSContext* cx, JS::HandleObject thisObj, - void* specializedThis, JSJitGetterCallArgs args); -typedef bool -(* JSJitSetterOp)(JSContext* cx, JS::HandleObject thisObj, - void* specializedThis, JSJitSetterCallArgs args); -typedef bool -(* JSJitMethodOp)(JSContext* cx, JS::HandleObject thisObj, - void* specializedThis, const JSJitMethodCallArgs& args); - -/** - * This struct contains metadata passed from the DOM to the JS Engine for JIT - * optimizations on DOM property accessors. Eventually, this should be made - * available to general JSAPI users, but we are not currently ready to do so. - */ -struct JSJitInfo { - enum OpType { - Getter, - Setter, - Method, - StaticMethod, - InlinableNative, - // Must be last - OpTypeCount - }; - - enum ArgType { - // Basic types - String = (1 << 0), - Integer = (1 << 1), // Only 32-bit or less - Double = (1 << 2), // Maybe we want to add Float sometime too - Boolean = (1 << 3), - Object = (1 << 4), - Null = (1 << 5), - - // And derived types - Numeric = Integer | Double, - // Should "Primitive" use the WebIDL definition, which - // excludes string and null, or the typical JS one that includes them? - Primitive = Numeric | Boolean | Null | String, - ObjectOrNull = Object | Null, - Any = ObjectOrNull | Primitive, - - // Our sentinel value. - ArgTypeListEnd = (1 << 31) - }; - - static_assert(Any & String, "Any must include String."); - static_assert(Any & Integer, "Any must include Integer."); - static_assert(Any & Double, "Any must include Double."); - static_assert(Any & Boolean, "Any must include Boolean."); - static_assert(Any & Object, "Any must include Object."); - static_assert(Any & Null, "Any must include Null."); - - /** - * An enum that describes what this getter/setter/method aliases. This - * determines what things can be hoisted past this call, and if this - * call is movable what it can be hoisted past. - */ - enum AliasSet { - /** - * Alias nothing: a constant value, getting it can't affect any other - * values, nothing can affect it. - */ - AliasNone, - - /** - * Alias things that can modify the DOM but nothing else. Doing the - * call can't affect the behavior of any other function. - */ - AliasDOMSets, - - /** - * Alias the world. Calling this can change arbitrary values anywhere - * in the system. Most things fall in this bucket. - */ - AliasEverything, - - /** Must be last. */ - AliasSetCount - }; - - bool needsOuterizedThisObject() const - { - return type() != Getter && type() != Setter; - } - - bool isTypedMethodJitInfo() const - { - return isTypedMethod; - } - - OpType type() const - { - return OpType(type_); - } - - AliasSet aliasSet() const - { - return AliasSet(aliasSet_); - } - - JSValueType returnType() const - { - return JSValueType(returnType_); - } - - union { - JSJitGetterOp getter; - JSJitSetterOp setter; - JSJitMethodOp method; - /** A DOM static method, used for Promise wrappers */ - JSNative staticMethod; - }; - - union { - uint16_t protoID; - js::jit::InlinableNative inlinableNative; - }; - - union { - uint16_t depth; - - // Additional opcode for some InlinableNative functions. - uint16_t nativeOp; - }; - - // These fields are carefully packed to take up 4 bytes. If you need more - // bits for whatever reason, please see if you can steal bits from existing - // fields before adding more members to this structure. - -#define JITINFO_OP_TYPE_BITS 4 -#define JITINFO_ALIAS_SET_BITS 4 -#define JITINFO_RETURN_TYPE_BITS 8 -#define JITINFO_SLOT_INDEX_BITS 10 - - /** The OpType that says what sort of function we are. */ - uint32_t type_ : JITINFO_OP_TYPE_BITS; - - /** - * The alias set for this op. This is a _minimal_ alias set; in - * particular for a method it does not include whatever argument - * conversions might do. That's covered by argTypes and runtime - * analysis of the actual argument types being passed in. - */ - uint32_t aliasSet_ : JITINFO_ALIAS_SET_BITS; - - /** The return type tag. Might be JSVAL_TYPE_UNKNOWN. */ - uint32_t returnType_ : JITINFO_RETURN_TYPE_BITS; - - static_assert(OpTypeCount <= (1 << JITINFO_OP_TYPE_BITS), - "Not enough space for OpType"); - static_assert(AliasSetCount <= (1 << JITINFO_ALIAS_SET_BITS), - "Not enough space for AliasSet"); - static_assert((sizeof(JSValueType) * 8) <= JITINFO_RETURN_TYPE_BITS, - "Not enough space for JSValueType"); - -#undef JITINFO_RETURN_TYPE_BITS -#undef JITINFO_ALIAS_SET_BITS -#undef JITINFO_OP_TYPE_BITS - - /** Is op fallible? False in setters. */ - uint32_t isInfallible : 1; - - /** - * Is op movable? To be movable the op must - * not AliasEverything, but even that might - * not be enough (e.g. in cases when it can - * throw or is explicitly not movable). - */ - uint32_t isMovable : 1; - - /** - * Can op be dead-code eliminated? Again, this - * depends on whether the op can throw, in - * addition to the alias set. - */ - uint32_t isEliminatable : 1; - - // XXXbz should we have a JSValueType for the type of the member? - /** - * True if this is a getter that can always - * get the value from a slot of the "this" object. - */ - uint32_t isAlwaysInSlot : 1; - - /** - * True if this is a getter that can sometimes (if the slot doesn't contain - * UndefinedValue()) get the value from a slot of the "this" object. - */ - uint32_t isLazilyCachedInSlot : 1; - - /** True if this is an instance of JSTypedMethodJitInfo. */ - uint32_t isTypedMethod : 1; - - /** - * If isAlwaysInSlot or isSometimesInSlot is true, - * the index of the slot to get the value from. - * Otherwise 0. - */ - uint32_t slotIndex : JITINFO_SLOT_INDEX_BITS; - - static const size_t maxSlotIndex = (1 << JITINFO_SLOT_INDEX_BITS) - 1; - -#undef JITINFO_SLOT_INDEX_BITS -}; - -static_assert(sizeof(JSJitInfo) == (sizeof(void*) + 2 * sizeof(uint32_t)), - "There are several thousand instances of JSJitInfo stored in " - "a binary. Please don't increase its space requirements without " - "verifying that there is no other way forward (better packing, " - "smaller datatypes for fields, subclassing, etc.)."); - -struct JSTypedMethodJitInfo -{ - // We use C-style inheritance here, rather than C++ style inheritance - // because not all compilers support brace-initialization for non-aggregate - // classes. Using C++ style inheritance and constructors instead of - // brace-initialization would also force the creation of static - // constructors (on some compilers) when JSJitInfo and JSTypedMethodJitInfo - // structures are declared. Since there can be several thousand of these - // structures present and we want to have roughly equivalent performance - // across a range of compilers, we do things manually. - JSJitInfo base; - - const JSJitInfo::ArgType* const argTypes; /* For a method, a list of sets of - types that the function - expects. This can be used, - for example, to figure out - when argument coercions can - have side-effects. */ -}; - -namespace js { - -static MOZ_ALWAYS_INLINE shadow::Function* -FunctionObjectToShadowFunction(JSObject* fun) -{ - MOZ_ASSERT(GetObjectClass(fun) == FunctionClassPtr); - return reinterpret_cast(fun); -} - -/* Statically asserted in jsfun.h. */ -static const unsigned JS_FUNCTION_INTERPRETED_BITS = 0x0201; - -// Return whether the given function object is native. -static MOZ_ALWAYS_INLINE bool -FunctionObjectIsNative(JSObject* fun) -{ - return !(FunctionObjectToShadowFunction(fun)->flags & JS_FUNCTION_INTERPRETED_BITS); -} - -static MOZ_ALWAYS_INLINE JSNative -GetFunctionObjectNative(JSObject* fun) -{ - MOZ_ASSERT(FunctionObjectIsNative(fun)); - return FunctionObjectToShadowFunction(fun)->native; -} - -} // namespace js - -static MOZ_ALWAYS_INLINE const JSJitInfo* -FUNCTION_VALUE_TO_JITINFO(const JS::Value& v) -{ - MOZ_ASSERT(js::FunctionObjectIsNative(&v.toObject())); - return js::FunctionObjectToShadowFunction(&v.toObject())->jitinfo; -} - -static MOZ_ALWAYS_INLINE void -SET_JITINFO(JSFunction * func, const JSJitInfo* info) -{ - js::shadow::Function* fun = reinterpret_cast(func); - MOZ_ASSERT(!(fun->flags & js::JS_FUNCTION_INTERPRETED_BITS)); - fun->jitinfo = info; -} - -/* - * Engine-internal extensions of jsid. This code is here only until we - * eliminate Gecko's dependencies on it! - */ - -static MOZ_ALWAYS_INLINE jsid -JSID_FROM_BITS(size_t bits) -{ - jsid id; - JSID_BITS(id) = bits; - return id; -} - -namespace js { -namespace detail { -bool IdMatchesAtom(jsid id, JSAtom* atom); -} // namespace detail -} // namespace js - -/** - * Must not be used on atoms that are representable as integer jsids. - * Prefer NameToId or AtomToId over this function: - * - * A PropertyName is an atom that does not contain an integer in the range - * [0, UINT32_MAX]. However, jsid can only hold an integer in the range - * [0, JSID_INT_MAX] (where JSID_INT_MAX == 2^31-1). Thus, for the range of - * integers (JSID_INT_MAX, UINT32_MAX], to represent as a jsid 'id', it must be - * the case JSID_IS_ATOM(id) and !JSID_TO_ATOM(id)->isPropertyName(). In most - * cases when creating a jsid, code does not have to care about this corner - * case because: - * - * - When given an arbitrary JSAtom*, AtomToId must be used, which checks for - * integer atoms representable as integer jsids, and does this conversion. - * - * - When given a PropertyName*, NameToId can be used which which does not need - * to do any dynamic checks. - * - * Thus, it is only the rare third case which needs this function, which - * handles any JSAtom* that is known not to be representable with an int jsid. - */ -static MOZ_ALWAYS_INLINE jsid -NON_INTEGER_ATOM_TO_JSID(JSAtom* atom) -{ - MOZ_ASSERT(((size_t)atom & 0x7) == 0); - jsid id = JSID_FROM_BITS((size_t)atom); - MOZ_ASSERT(js::detail::IdMatchesAtom(id, atom)); - return id; -} - -/* All strings stored in jsids are atomized, but are not necessarily property names. */ -static MOZ_ALWAYS_INLINE bool -JSID_IS_ATOM(jsid id) -{ - return JSID_IS_STRING(id); -} - -static MOZ_ALWAYS_INLINE bool -JSID_IS_ATOM(jsid id, JSAtom* atom) -{ - return id == JSID_FROM_BITS((size_t)atom); -} - -static MOZ_ALWAYS_INLINE JSAtom* -JSID_TO_ATOM(jsid id) -{ - return (JSAtom*)JSID_TO_STRING(id); -} - -JS_STATIC_ASSERT(sizeof(jsid) == sizeof(void*)); - -namespace js { - -static MOZ_ALWAYS_INLINE JS::Value -IdToValue(jsid id) -{ - if (JSID_IS_STRING(id)) - return JS::StringValue(JSID_TO_STRING(id)); - if (JSID_IS_INT(id)) - return JS::Int32Value(JSID_TO_INT(id)); - if (JSID_IS_SYMBOL(id)) - return JS::SymbolValue(JSID_TO_SYMBOL(id)); - MOZ_ASSERT(JSID_IS_VOID(id)); - return JS::UndefinedValue(); -} - -/** - * If the embedder has registered a ScriptEnvironmentPreparer, - * PrepareScriptEnvironmentAndInvoke will call the preparer's 'invoke' method - * with the given |closure|, with the assumption that the preparer will set up - * any state necessary to run script in |scope|, invoke |closure| with a valid - * JSContext*, report any exceptions thrown from the closure, and return. - * - * If no preparer is registered, PrepareScriptEnvironmentAndInvoke will assert - * that |rt| has exactly one JSContext associated with it, enter the compartment - * of |scope| on that context, and invoke |closure|. - * - * In both cases, PrepareScriptEnvironmentAndInvoke will report any exceptions - * that are thrown by the closure. Consumers who want to propagate back - * whether the closure succeeded should do so via members of the closure - * itself. - */ - -struct ScriptEnvironmentPreparer { - struct Closure { - virtual bool operator()(JSContext* cx) = 0; - }; - - virtual void invoke(JS::HandleObject scope, Closure& closure) = 0; -}; - -extern JS_FRIEND_API(void) -PrepareScriptEnvironmentAndInvoke(JSContext* cx, JS::HandleObject scope, - ScriptEnvironmentPreparer::Closure& closure); - -JS_FRIEND_API(void) -SetScriptEnvironmentPreparer(JSContext* cx, ScriptEnvironmentPreparer* preparer); - -enum CTypesActivityType { - CTYPES_CALL_BEGIN, - CTYPES_CALL_END, - CTYPES_CALLBACK_BEGIN, - CTYPES_CALLBACK_END -}; - -typedef void -(* CTypesActivityCallback)(JSContext* cx, CTypesActivityType type); - -/** - * Sets a callback that is run whenever js-ctypes is about to be used when - * calling into C. - */ -JS_FRIEND_API(void) -SetCTypesActivityCallback(JSContext* cx, CTypesActivityCallback cb); - -class MOZ_RAII JS_FRIEND_API(AutoCTypesActivityCallback) { - private: - JSContext* cx; - CTypesActivityCallback callback; - CTypesActivityType endType; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - - public: - AutoCTypesActivityCallback(JSContext* cx, CTypesActivityType beginType, - CTypesActivityType endType - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - ~AutoCTypesActivityCallback() { - DoEndCallback(); - } - void DoEndCallback() { - if (callback) { - callback(cx, endType); - callback = nullptr; - } - } -}; - -// Abstract base class for objects that build allocation metadata for JavaScript -// values. -struct AllocationMetadataBuilder { - AllocationMetadataBuilder() { } - - // Return a metadata object for the newly constructed object |obj|, or - // nullptr if there's no metadata to attach. - // - // Implementations should treat all errors as fatal; there is no way to - // report errors from this callback. In particular, the caller provides an - // oomUnsafe for overriding implementations to use. - virtual JSObject* build(JSContext* cx, JS::HandleObject obj, - AutoEnterOOMUnsafeRegion& oomUnsafe) const - { - return nullptr; - } -}; - -/** - * Specify a callback to invoke when creating each JS object in the current - * compartment, which may return a metadata object to associate with the - * object. - */ -JS_FRIEND_API(void) -SetAllocationMetadataBuilder(JSContext* cx, const AllocationMetadataBuilder *callback); - -/** Get the metadata associated with an object. */ -JS_FRIEND_API(JSObject*) -GetAllocationMetadata(JSObject* obj); - -JS_FRIEND_API(bool) -GetElementsWithAdder(JSContext* cx, JS::HandleObject obj, JS::HandleObject receiver, - uint32_t begin, uint32_t end, js::ElementAdder* adder); - -JS_FRIEND_API(bool) -ForwardToNative(JSContext* cx, JSNative native, const JS::CallArgs& args); - -/** - * Helper function for HTMLDocument and HTMLFormElement. - * - * These are the only two interfaces that have [OverrideBuiltins], a named - * getter, and no named setter. They're implemented as proxies with a custom - * getOwnPropertyDescriptor() method. Unfortunately, overriding - * getOwnPropertyDescriptor() automatically affects the behavior of set(), - * which normally is just common sense but is *not* desired for these two - * interfaces. - * - * The fix is for these two interfaces to override set() to ignore the - * getOwnPropertyDescriptor() override. - * - * SetPropertyIgnoringNamedGetter is exposed to make it easier to override - * set() in this way. It carries out all the steps of BaseProxyHandler::set() - * except the initial getOwnPropertyDescriptor() call. The caller must supply - * that descriptor as the 'ownDesc' parameter. - * - * Implemented in proxy/BaseProxyHandler.cpp. - */ -JS_FRIEND_API(bool) -SetPropertyIgnoringNamedGetter(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::HandleValue v, JS::HandleValue receiver, - JS::Handle ownDesc, - JS::ObjectOpResult& result); - -JS_FRIEND_API(void) -ReportASCIIErrorWithId(JSContext* cx, const char* msg, JS::HandleId id); - -// This function is for one specific use case, please don't use this for anything else! -extern JS_FRIEND_API(bool) -ExecuteInGlobalAndReturnScope(JSContext* cx, JS::HandleObject obj, JS::HandleScript script, - JS::MutableHandleObject scope); - -#if defined(XP_WIN) && defined(_WIN64) -// Parameters use void* types to avoid #including windows.h. The return value of -// this function is returned from the exception handler. -typedef long -(*JitExceptionHandler)(void* exceptionRecord, // PEXECTION_RECORD - void* context); // PCONTEXT - -/** - * Windows uses "structured exception handling" to handle faults. When a fault - * occurs, the stack is searched for a handler (similar to C++ exception - * handling). If the search does not find a handler, the "unhandled exception - * filter" is called. Breakpad uses the unhandled exception filter to do crash - * reporting. Unfortunately, on Win64, JIT code on the stack completely throws - * off this unwinding process and prevents the unhandled exception filter from - * being called. The reason is that Win64 requires unwind information be - * registered for all code regions and JIT code has none. While it is possible - * to register full unwind information for JIT code, this is a lot of work (one - * has to be able to recover the frame pointer at any PC) so instead we register - * a handler for all JIT code that simply calls breakpad's unhandled exception - * filter (which will perform crash reporting and then terminate the process). - * This would be wrong if there was an outer __try block that expected to handle - * the fault, but this is not generally allowed. - * - * Gecko must call SetJitExceptionFilter before any JIT code is compiled and - * only once per process. - */ -extern JS_FRIEND_API(void) -SetJitExceptionHandler(JitExceptionHandler handler); -#endif - -/** - * Get the nearest enclosing with environment object for a given function. If - * the function is not scripted or is not enclosed by a with scope, returns - * the global. - */ -extern JS_FRIEND_API(JSObject*) -GetNearestEnclosingWithEnvironmentObjectForFunction(JSFunction* fun); - -/** - * Get the first SavedFrame object in this SavedFrame stack whose principals are - * subsumed by the cx's principals. If there is no such frame, return nullptr. - * - * Do NOT pass a non-SavedFrame object here. - * - * The savedFrame and cx do not need to be in the same compartment. - */ -extern JS_FRIEND_API(JSObject*) -GetFirstSubsumedSavedFrame(JSContext* cx, JS::HandleObject savedFrame, JS::SavedFrameSelfHosted selfHosted); - -extern JS_FRIEND_API(bool) -ReportIsNotFunction(JSContext* cx, JS::HandleValue v); - -extern JS_FRIEND_API(JSObject*) -ConvertArgsToArray(JSContext* cx, const JS::CallArgs& args); - -/** - * Window and WindowProxy - * - * The functions below have to do with Windows and WindowProxies. There's an - * invariant that actual Window objects (the global objects of web pages) are - * never directly exposed to script. Instead we often substitute a WindowProxy. - * - * The environment chain, on the other hand, contains the Window and never its - * WindowProxy. - * - * As a result, we have calls to these "substitute-this-object-for-that-object" - * functions sprinkled at apparently arbitrary (but actually *very* carefully - * and nervously selected) places throughout the engine and indeed the - * universe. - */ - -/** - * Tell the JS engine which Class is used for WindowProxy objects. Used by the - * functions below. - */ -extern JS_FRIEND_API(void) -SetWindowProxyClass(JSContext* cx, const Class* clasp); - -/** - * Associates a WindowProxy with a Window (global object). `windowProxy` must - * have the Class set by SetWindowProxyClass. - */ -extern JS_FRIEND_API(void) -SetWindowProxy(JSContext* cx, JS::HandleObject global, JS::HandleObject windowProxy); - -namespace detail { - -JS_FRIEND_API(bool) -IsWindowSlow(JSObject* obj); - -} // namespace detail - -/** - * Returns true iff `obj` is a global object with an associated WindowProxy, - * see SetWindowProxy. - */ -inline bool -IsWindow(JSObject* obj) -{ - if (GetObjectClass(obj)->flags & JSCLASS_IS_GLOBAL) - return detail::IsWindowSlow(obj); - return false; -} - -/** - * Returns true iff `obj` has the WindowProxy Class (see SetWindowProxyClass). - */ -JS_FRIEND_API(bool) -IsWindowProxy(JSObject* obj); - -/** - * If `obj` is a Window, get its associated WindowProxy (or a CCW or dead - * wrapper if the page was navigated away from), else return `obj`. This - * function is infallible and never returns nullptr. - */ -extern JS_FRIEND_API(JSObject*) -ToWindowProxyIfWindow(JSObject* obj); - -/** - * If `obj` is a WindowProxy, get its associated Window (the compartment's - * global), else return `obj`. This function is infallible and never returns - * nullptr. - */ -extern JS_FRIEND_API(JSObject*) -ToWindowIfWindowProxy(JSObject* obj); - -} /* namespace js */ - -class NativeProfiler -{ - public: - virtual ~NativeProfiler() {}; - virtual void sampleNative(void* addr, uint32_t size) = 0; - virtual void removeNative(void* addr) = 0; - virtual void reset() = 0; -}; - -class GCHeapProfiler -{ - public: - virtual ~GCHeapProfiler() {}; - virtual void sampleTenured(void* addr, uint32_t size) = 0; - virtual void sampleNursery(void* addr, uint32_t size) = 0; - virtual void markTenuredStart() = 0; - virtual void markTenured(void* addr) = 0; - virtual void sweepTenured() = 0; - virtual void sweepNursery() = 0; - virtual void moveNurseryToTenured(void* addrOld, void* addrNew) = 0; - virtual void reset() = 0; -}; - -class MemProfiler -{ - static mozilla::Atomic sActiveProfilerCount; - static NativeProfiler* sNativeProfiler; - - static GCHeapProfiler* GetGCHeapProfiler(void* addr); - static GCHeapProfiler* GetGCHeapProfiler(JSRuntime* runtime); - - static NativeProfiler* GetNativeProfiler() { - return sNativeProfiler; - } - - GCHeapProfiler* mGCHeapProfiler; - JSRuntime* mRuntime; - - public: - explicit MemProfiler(JSRuntime* aRuntime) : mGCHeapProfiler(nullptr), mRuntime(aRuntime) {} - - void start(GCHeapProfiler* aGCHeapProfiler); - void stop(); - - GCHeapProfiler* getGCHeapProfiler() const { - return mGCHeapProfiler; - } - - static MOZ_ALWAYS_INLINE bool enabled() { - return sActiveProfilerCount > 0; - } - - static MemProfiler* GetMemProfiler(JSContext* context); - - static void SetNativeProfiler(NativeProfiler* aProfiler) { - sNativeProfiler = aProfiler; - } - - static MOZ_ALWAYS_INLINE void SampleNative(void* addr, uint32_t size) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - NativeProfiler* profiler = GetNativeProfiler(); - if (profiler) - profiler->sampleNative(addr, size); - } - - static MOZ_ALWAYS_INLINE void SampleTenured(void* addr, uint32_t size) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(addr); - if (profiler) - profiler->sampleTenured(addr, size); - } - - static MOZ_ALWAYS_INLINE void SampleNursery(void* addr, uint32_t size) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(addr); - if (profiler) - profiler->sampleNursery(addr, size); - } - - static MOZ_ALWAYS_INLINE void RemoveNative(void* addr) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - NativeProfiler* profiler = GetNativeProfiler(); - if (profiler) - profiler->removeNative(addr); - } - - static MOZ_ALWAYS_INLINE void MarkTenuredStart(JSRuntime* runtime) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(runtime); - if (profiler) - profiler->markTenuredStart(); - } - - static MOZ_ALWAYS_INLINE void MarkTenured(void* addr) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(addr); - if (profiler) - profiler->markTenured(addr); - } - - static MOZ_ALWAYS_INLINE void SweepTenured(JSRuntime* runtime) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(runtime); - if (profiler) - profiler->sweepTenured(); - } - - static MOZ_ALWAYS_INLINE void SweepNursery(JSRuntime* runtime) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(runtime); - if (profiler) - profiler->sweepNursery(); - } - - static MOZ_ALWAYS_INLINE void MoveNurseryToTenured(void* addrOld, void* addrNew) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(addrOld); - if (profiler) - profiler->moveNurseryToTenured(addrOld, addrNew); - } -}; - -#endif /* jsfriendapi_h */ diff --git a/android/arm64-v8a/include/spidermonkey/jsperf.h b/android/arm64-v8a/include/spidermonkey/jsperf.h deleted file mode 100644 index b8f2909a..00000000 --- a/android/arm64-v8a/include/spidermonkey/jsperf.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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 perf_jsperf_h -#define perf_jsperf_h - -#include "jstypes.h" - -#include "js/TypeDecls.h" -#include "js/Utility.h" - -namespace JS { - -/* - * JS::PerfMeasurement is a generic way to access detailed performance - * measurement APIs provided by your operating system. The details of - * exactly how this works and what can be measured are highly - * system-specific, but this interface is (one hopes) implementable - * on top of all of them. - * - * To use this API, create a PerfMeasurement object, passing its - * constructor a bitmask indicating which events you are interested - * in. Thereafter, Start() zeroes all counters and starts timing; - * Stop() stops timing again; and the counters for the events you - * requested are available as data values after calling Stop(). The - * object may be reused for many measurements. - */ -class JS_FRIEND_API(PerfMeasurement) -{ - protected: - // Implementation-specific data, if any. - void* impl; - - public: - /* - * Events that may be measured. Taken directly from the list of - * "generalized hardware performance event types" in the Linux - * perf_event API, plus some of the "software events". - */ - enum EventMask { - CPU_CYCLES = 0x00000001, - INSTRUCTIONS = 0x00000002, - CACHE_REFERENCES = 0x00000004, - CACHE_MISSES = 0x00000008, - BRANCH_INSTRUCTIONS = 0x00000010, - BRANCH_MISSES = 0x00000020, - BUS_CYCLES = 0x00000040, - PAGE_FAULTS = 0x00000080, - MAJOR_PAGE_FAULTS = 0x00000100, - CONTEXT_SWITCHES = 0x00000200, - CPU_MIGRATIONS = 0x00000400, - - ALL = 0x000007ff, - NUM_MEASURABLE_EVENTS = 11 - }; - - /* - * Bitmask of events that will be measured when this object is - * active (between Start() and Stop()). This may differ from the - * bitmask passed to the constructor if the platform does not - * support measuring all of the requested events. - */ - const EventMask eventsMeasured; - - /* - * Counters for each measurable event. - * Immediately after one of these objects is created, all of the - * counters for enabled events will be zero, and all of the - * counters for disabled events will be uint64_t(-1). - */ - uint64_t cpu_cycles; - uint64_t instructions; - uint64_t cache_references; - uint64_t cache_misses; - uint64_t branch_instructions; - uint64_t branch_misses; - uint64_t bus_cycles; - uint64_t page_faults; - uint64_t major_page_faults; - uint64_t context_switches; - uint64_t cpu_migrations; - - /* - * Prepare to measure the indicated set of events. If not all of - * the requested events can be measured on the current platform, - * then the eventsMeasured bitmask will only include the subset of - * |toMeasure| corresponding to the events that can be measured. - */ - explicit PerfMeasurement(EventMask toMeasure); - - /* Done with this set of measurements, tear down OS-level state. */ - ~PerfMeasurement(); - - /* Start a measurement cycle. */ - void start(); - - /* - * End a measurement cycle, and for each enabled counter, add the - * number of measured events of that type to the appropriate - * visible variable. - */ - void stop(); - - /* Reset all enabled counters to zero. */ - void reset(); - - /* - * True if this platform supports measuring _something_, i.e. it's - * not using the stub implementation. - */ - static bool canMeasureSomething(); -}; - -/* Inject a Javascript wrapper around the above C++ class into the - * Javascript object passed as an argument (this will normally be a - * global object). The JS-visible API is identical to the C++ API. - */ -extern JS_FRIEND_API(JSObject*) - RegisterPerfMeasurement(JSContext* cx, JS::HandleObject global); - -/* - * Given a Value which contains an instance of the aforementioned - * wrapper class, extract the C++ object. Returns nullptr if the - * Value is not an instance of the wrapper. - */ -extern JS_FRIEND_API(PerfMeasurement*) - ExtractPerfMeasurement(const Value& wrapper); - -} // namespace JS - -#endif /* perf_jsperf_h */ diff --git a/android/arm64-v8a/include/spidermonkey/jsprf.h b/android/arm64-v8a/include/spidermonkey/jsprf.h deleted file mode 100644 index b84b5a5c..00000000 --- a/android/arm64-v8a/include/spidermonkey/jsprf.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsprf_h -#define jsprf_h - -/* -** API for PR printf like routines. Supports the following formats -** %d - decimal -** %u - unsigned decimal -** %x - unsigned hex -** %X - unsigned uppercase hex -** %o - unsigned octal -** %hd, %hu, %hx, %hX, %ho - "short" versions of above -** %ld, %lu, %lx, %lX, %lo - "long" versions of above -** %lld, %llu, %llx, %llX, %llo - "long long" versions of above -** %zd, %zo, %zu, %zx, %zX - size_t versions of above -** %Id, %Io, %Iu, %Ix, %IX - size_t versions of above (for Windows compat) -** You should use PRI*SIZE macros instead -** %s - string -** %c - character -** %p - pointer (deals with machine dependent pointer size) -** %f - float -** %g - float -*/ - -#include "mozilla/IntegerPrintfMacros.h" -#include "mozilla/SizePrintfMacros.h" - -#include - -#include "jstypes.h" - -/* -** sprintf into a malloc'd buffer. Return a pointer to the malloc'd -** buffer on success, nullptr on failure. Call "JS_smprintf_free" to release -** the memory returned. -*/ -extern JS_PUBLIC_API(char*) JS_smprintf(const char* fmt, ...) - MOZ_FORMAT_PRINTF(1, 2); - -/* -** Free the memory allocated, for the caller, by JS_smprintf -*/ -extern JS_PUBLIC_API(void) JS_smprintf_free(char* mem); - -/* -** "append" sprintf into a malloc'd buffer. "last" is the last value of -** the malloc'd buffer. sprintf will append data to the end of last, -** growing it as necessary using realloc. If last is nullptr, JS_sprintf_append -** will allocate the initial string. The return value is the new value of -** last for subsequent calls, or nullptr if there is a malloc failure. -*/ -extern JS_PUBLIC_API(char*) JS_sprintf_append(char* last, const char* fmt, ...) - MOZ_FORMAT_PRINTF(2, 3); - -/* -** va_list forms of the above. -*/ -extern JS_PUBLIC_API(char*) JS_vsmprintf(const char* fmt, va_list ap); -extern JS_PUBLIC_API(char*) JS_vsprintf_append(char* last, const char* fmt, va_list ap); - -#endif /* jsprf_h */ diff --git a/android/arm64-v8a/include/spidermonkey/jsprototypes.h b/android/arm64-v8a/include/spidermonkey/jsprototypes.h deleted file mode 100644 index f409dce9..00000000 --- a/android/arm64-v8a/include/spidermonkey/jsprototypes.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsprototypes_h -#define jsprototypes_h - -/* A higher-order macro for enumerating all JSProtoKey values. */ -/* - * Consumers define macros as follows: - * macro(name, code, init, clasp) - * name: The canonical name of the class. - * code: The enumerator code. There are part of the XDR API, and must not change. - * init: Initialization function. These are |extern "C";|, and clients should use - * |extern "C" {}| as appropriate when using this macro. - * clasp: The JSClass for this object, or "dummy" if it doesn't exist. - * - * - * Consumers wishing to iterate over all the JSProtoKey values, can use - * JS_FOR_EACH_PROTOTYPE. However, there are certain values that don't correspond - * to real constructors, like Null or constructors that are disabled via - * preprocessor directives. We still need to include these in the JSProtoKey list - * in order to maintain binary XDR compatibility, but we need to provide a tool - * to handle them differently. JS_FOR_PROTOTYPES fills this niche. - * - * Consumers pass two macros to JS_FOR_PROTOTYPES - |real| and |imaginary|. The - * former is invoked for entries that have real client-exposed constructors, and - * the latter is called for the rest. Consumers that don't care about this - * distinction can simply pass the same macro to both, which is exactly what - * JS_FOR_EACH_PROTOTYPE does. - */ - -#define CLASP(name) (&name##Class) -#define OCLASP(name) (&name##Object::class_) -#define TYPED_ARRAY_CLASP(type) (&TypedArrayObject::classes[Scalar::type]) -#define ERROR_CLASP(type) (&ErrorObject::classes[type]) - -#ifdef EXPOSE_INTL_API -#define IF_INTL(real,imaginary) real -#else -#define IF_INTL(real,imaginary) imaginary -#endif - -#ifdef ENABLE_BINARYDATA -#define IF_BDATA(real,imaginary) real -#else -#define IF_BDATA(real,imaginary) imaginary -#endif - -#ifdef ENABLE_SIMD -# define IF_SIMD(real,imaginary) real -#else -# define IF_SIMD(real,imaginary) imaginary -#endif - -#ifdef ENABLE_SHARED_ARRAY_BUFFER -#define IF_SAB(real,imaginary) real -#else -#define IF_SAB(real,imaginary) imaginary -#endif - -#ifdef SPIDERMONKEY_PROMISE -#define IF_PROMISE(real,imaginary) real -#else -#define IF_PROMISE(real,imaginary) imaginary -#endif - -#define JS_FOR_PROTOTYPES(real,imaginary) \ - imaginary(Null, 0, InitNullClass, dummy) \ - real(Object, 1, InitViaClassSpec, OCLASP(Plain)) \ - real(Function, 2, InitViaClassSpec, &JSFunction::class_) \ - real(Array, 3, InitViaClassSpec, OCLASP(Array)) \ - real(Boolean, 4, InitBooleanClass, OCLASP(Boolean)) \ - real(JSON, 5, InitJSONClass, CLASP(JSON)) \ - real(Date, 6, InitViaClassSpec, OCLASP(Date)) \ - real(Math, 7, InitMathClass, CLASP(Math)) \ - real(Number, 8, InitNumberClass, OCLASP(Number)) \ - real(String, 9, InitStringClass, OCLASP(String)) \ - real(RegExp, 10, InitViaClassSpec, OCLASP(RegExp)) \ - real(Error, 11, InitViaClassSpec, ERROR_CLASP(JSEXN_ERR)) \ - real(InternalError, 12, InitViaClassSpec, ERROR_CLASP(JSEXN_INTERNALERR)) \ - real(EvalError, 13, InitViaClassSpec, ERROR_CLASP(JSEXN_EVALERR)) \ - real(RangeError, 14, InitViaClassSpec, ERROR_CLASP(JSEXN_RANGEERR)) \ - real(ReferenceError, 15, InitViaClassSpec, ERROR_CLASP(JSEXN_REFERENCEERR)) \ - real(SyntaxError, 16, InitViaClassSpec, ERROR_CLASP(JSEXN_SYNTAXERR)) \ - real(TypeError, 17, InitViaClassSpec, ERROR_CLASP(JSEXN_TYPEERR)) \ - real(URIError, 18, InitViaClassSpec, ERROR_CLASP(JSEXN_URIERR)) \ - real(DebuggeeWouldRun, 19, InitViaClassSpec, ERROR_CLASP(JSEXN_DEBUGGEEWOULDRUN)) \ - real(CompileError, 20, InitViaClassSpec, ERROR_CLASP(JSEXN_WASMCOMPILEERROR)) \ - real(RuntimeError, 21, InitViaClassSpec, ERROR_CLASP(JSEXN_WASMRUNTIMEERROR)) \ - real(Iterator, 22, InitLegacyIteratorClass,OCLASP(PropertyIterator)) \ - real(StopIteration, 23, InitStopIterationClass, OCLASP(StopIteration)) \ - real(ArrayBuffer, 24, InitViaClassSpec, OCLASP(ArrayBuffer)) \ - real(Int8Array, 25, InitViaClassSpec, TYPED_ARRAY_CLASP(Int8)) \ - real(Uint8Array, 26, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint8)) \ - real(Int16Array, 27, InitViaClassSpec, TYPED_ARRAY_CLASP(Int16)) \ - real(Uint16Array, 28, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint16)) \ - real(Int32Array, 29, InitViaClassSpec, TYPED_ARRAY_CLASP(Int32)) \ - real(Uint32Array, 30, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint32)) \ - real(Float32Array, 31, InitViaClassSpec, TYPED_ARRAY_CLASP(Float32)) \ - real(Float64Array, 32, InitViaClassSpec, TYPED_ARRAY_CLASP(Float64)) \ - real(Uint8ClampedArray, 33, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint8Clamped)) \ - real(Proxy, 34, InitProxyClass, js::ProxyClassPtr) \ - real(WeakMap, 35, InitWeakMapClass, OCLASP(WeakMap)) \ - real(Map, 36, InitMapClass, OCLASP(Map)) \ - real(Set, 37, InitSetClass, OCLASP(Set)) \ - real(DataView, 38, InitDataViewClass, OCLASP(DataView)) \ - real(Symbol, 39, InitSymbolClass, OCLASP(Symbol)) \ -IF_SAB(real,imaginary)(SharedArrayBuffer, 40, InitViaClassSpec, OCLASP(SharedArrayBuffer)) \ -IF_INTL(real,imaginary) (Intl, 41, InitIntlClass, CLASP(Intl)) \ -IF_BDATA(real,imaginary)(TypedObject, 42, InitTypedObjectModuleObject, OCLASP(TypedObjectModule)) \ - real(Reflect, 43, InitReflect, nullptr) \ -IF_SIMD(real,imaginary)(SIMD, 44, InitSimdClass, OCLASP(Simd)) \ - real(WeakSet, 45, InitWeakSetClass, OCLASP(WeakSet)) \ - real(TypedArray, 46, InitViaClassSpec, &js::TypedArrayObject::sharedTypedArrayPrototypeClass) \ -IF_SAB(real,imaginary)(Atomics, 47, InitAtomicsClass, OCLASP(Atomics)) \ - real(SavedFrame, 48, InitViaClassSpec, &js::SavedFrame::class_) \ - real(WebAssembly, 49, InitWebAssemblyClass, CLASP(WebAssembly)) \ - imaginary(WasmModule, 50, dummy, dummy) \ - imaginary(WasmInstance, 51, dummy, dummy) \ - imaginary(WasmMemory, 52, dummy, dummy) \ - imaginary(WasmTable, 53, dummy, dummy) \ -IF_PROMISE(real,imaginary)(Promise, 54, InitViaClassSpec, OCLASP(Promise)) \ - -#define JS_FOR_EACH_PROTOTYPE(macro) JS_FOR_PROTOTYPES(macro,macro) - -#endif /* jsprototypes_h */ diff --git a/android/arm64-v8a/include/spidermonkey/jspubtd.h b/android/arm64-v8a/include/spidermonkey/jspubtd.h deleted file mode 100644 index 309b9d74..00000000 --- a/android/arm64-v8a/include/spidermonkey/jspubtd.h +++ /dev/null @@ -1,476 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jspubtd_h -#define jspubtd_h - -/* - * JS public API typedefs. - */ - -#include "mozilla/Assertions.h" -#include "mozilla/EnumeratedArray.h" -#include "mozilla/LinkedList.h" -#include "mozilla/PodOperations.h" - -#include "jsprototypes.h" -#include "jstypes.h" - -#include "js/TraceKind.h" -#include "js/TypeDecls.h" - -#if defined(JS_GC_ZEAL) || defined(DEBUG) -# define JSGC_HASH_TABLE_CHECKS -#endif - -namespace JS { - -class AutoIdVector; -class CallArgs; - -template -class Rooted; - -class JS_FRIEND_API(CompileOptions); -class JS_FRIEND_API(ReadOnlyCompileOptions); -class JS_FRIEND_API(OwningCompileOptions); -class JS_FRIEND_API(TransitiveCompileOptions); -class JS_PUBLIC_API(CompartmentOptions); - -struct RootingContext; -class Value; -struct Zone; - -namespace shadow { -struct Runtime; -} // namespace shadow - -} // namespace JS - -namespace js { -class RootLists; -} // namespace js - -/* - * Run-time version enumeration. For compile-time version checking, please use - * the JS_HAS_* macros in jsversion.h, or use MOZJS_MAJOR_VERSION, - * MOZJS_MINOR_VERSION, MOZJS_PATCH_VERSION, and MOZJS_ALPHA definitions. - */ -enum JSVersion { - JSVERSION_ECMA_3 = 148, - JSVERSION_1_6 = 160, - JSVERSION_1_7 = 170, - JSVERSION_1_8 = 180, - JSVERSION_ECMA_5 = 185, - JSVERSION_DEFAULT = 0, - JSVERSION_UNKNOWN = -1, - JSVERSION_LATEST = JSVERSION_ECMA_5 -}; - -/* Result of typeof operator enumeration. */ -enum JSType { - JSTYPE_VOID, /* undefined */ - JSTYPE_OBJECT, /* object */ - JSTYPE_FUNCTION, /* function */ - JSTYPE_STRING, /* string */ - JSTYPE_NUMBER, /* number */ - JSTYPE_BOOLEAN, /* boolean */ - JSTYPE_NULL, /* null */ - JSTYPE_SYMBOL, /* symbol */ - JSTYPE_LIMIT -}; - -/* Dense index into cached prototypes and class atoms for standard objects. */ -enum JSProtoKey { -#define PROTOKEY_AND_INITIALIZER(name,code,init,clasp) JSProto_##name = code, - JS_FOR_EACH_PROTOTYPE(PROTOKEY_AND_INITIALIZER) -#undef PROTOKEY_AND_INITIALIZER - JSProto_LIMIT -}; - -/* Struct forward declarations. */ -struct JSClass; -struct JSCompartment; -struct JSCrossCompartmentCall; -class JSErrorReport; -struct JSExceptionState; -struct JSFunctionSpec; -struct JSLocaleCallbacks; -struct JSObjectMap; -struct JSPrincipals; -struct JSPropertyName; -struct JSPropertySpec; -struct JSRuntime; -struct JSSecurityCallbacks; -struct JSStructuredCloneCallbacks; -struct JSStructuredCloneReader; -struct JSStructuredCloneWriter; -class JS_PUBLIC_API(JSTracer); - -class JSFlatString; - -typedef bool (*JSInitCallback)(void); - -template struct JSConstScalarSpec; -typedef JSConstScalarSpec JSConstDoubleSpec; -typedef JSConstScalarSpec JSConstIntegerSpec; - -/* - * Generic trace operation that calls JS::TraceEdge on each traceable thing's - * location reachable from data. - */ -typedef void -(* JSTraceDataOp)(JSTracer* trc, void* data); - -namespace js { -namespace gc { -class AutoTraceSession; -class StoreBuffer; -} // namespace gc - -// Whether the current thread is permitted access to any part of the specified -// runtime or zone. -JS_FRIEND_API(bool) -CurrentThreadCanAccessRuntime(const JSRuntime* rt); - -#ifdef DEBUG -JS_FRIEND_API(bool) -CurrentThreadIsPerformingGC(); -#endif - -} // namespace js - -namespace JS { - -class JS_PUBLIC_API(AutoEnterCycleCollection); -class JS_PUBLIC_API(AutoAssertOnBarrier); -struct JS_PUBLIC_API(PropertyDescriptor); - -typedef void (*OffThreadCompileCallback)(void* token, void* callbackData); - -enum class HeapState { - Idle, // doing nothing with the GC heap - Tracing, // tracing the GC heap without collecting, e.g. IterateCompartments() - MajorCollecting, // doing a GC of the major heap - MinorCollecting, // doing a GC of the minor heap (nursery) - CycleCollecting // in the "Unlink" phase of cycle collection -}; - -namespace shadow { - -struct Runtime -{ - private: - JS::HeapState heapState_; - - protected: - void setHeapState(JS::HeapState newState) { - MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(asRuntime())); - MOZ_ASSERT(heapState_ != newState); - heapState_ = newState; - } - - JS::HeapState heapState() const { - MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(asRuntime()) || - js::CurrentThreadIsPerformingGC()); - return heapState_; - } - - // In some cases, invoking GC barriers (incremental or otherwise) will break - // things. These barriers assert if this flag is set. - bool allowGCBarriers_; - friend class JS::AutoAssertOnBarrier; - - js::gc::StoreBuffer* gcStoreBufferPtr_; - - // The gray bits can become invalid if UnmarkGray overflows the stack. A - // full GC will reset this bit, since it fills in all the gray bits. - bool gcGrayBitsValid_; - - public: - Runtime() - : heapState_(JS::HeapState::Idle) - , allowGCBarriers_(true) - , gcStoreBufferPtr_(nullptr) - , gcGrayBitsValid_(false) - {} - - bool isHeapBusy() const { return heapState() != JS::HeapState::Idle; } - bool isHeapTracing() const { return heapState() == JS::HeapState::Tracing; } - bool isHeapMajorCollecting() const { return heapState() == JS::HeapState::MajorCollecting; } - bool isHeapMinorCollecting() const { return heapState() == JS::HeapState::MinorCollecting; } - bool isHeapCollecting() const { return isHeapMinorCollecting() || isHeapMajorCollecting(); } - bool isCycleCollecting() const { - return heapState() == JS::HeapState::CycleCollecting; - } - - bool allowGCBarriers() const { return allowGCBarriers_; } - - js::gc::StoreBuffer* gcStoreBufferPtr() { return gcStoreBufferPtr_; } - - bool areGCGrayBitsValid() const { return gcGrayBitsValid_; } - void setGCGrayBitsValid(bool valid) { gcGrayBitsValid_ = valid; } - - const JSRuntime* asRuntime() const { - return reinterpret_cast(this); - } - - static JS::shadow::Runtime* asShadowRuntime(JSRuntime* rt) { - return reinterpret_cast(rt); - } - - protected: - void setGCStoreBufferPtr(js::gc::StoreBuffer* storeBuffer) { - gcStoreBufferPtr_ = storeBuffer; - } -}; - -} /* namespace shadow */ - -// Decorates the Unlinking phase of CycleCollection so that accidental use -// of barriered accessors results in assertions instead of leaks. -class MOZ_STACK_CLASS JS_PUBLIC_API(AutoEnterCycleCollection) -{ -#ifdef DEBUG - JSRuntime* runtime; - - public: - explicit AutoEnterCycleCollection(JSContext* cx); - ~AutoEnterCycleCollection(); -#else - public: - explicit AutoEnterCycleCollection(JSContext* cx) {} - ~AutoEnterCycleCollection() {} -#endif -}; - -class JS_PUBLIC_API(AutoGCRooter) -{ - public: - AutoGCRooter(JSContext* cx, ptrdiff_t tag); - AutoGCRooter(JS::RootingContext* cx, ptrdiff_t tag); - - ~AutoGCRooter() { - MOZ_ASSERT(this == *stackTop); - *stackTop = down; - } - - /* Implemented in gc/RootMarking.cpp. */ - inline void trace(JSTracer* trc); - static void traceAll(JSTracer* trc); - static void traceAllWrappers(JSTracer* trc); - - protected: - AutoGCRooter * const down; - - /* - * Discriminates actual subclass of this being used. If non-negative, the - * subclass roots an array of values of the length stored in this field. - * If negative, meaning is indicated by the corresponding value in the enum - * below. Any other negative value indicates some deeper problem such as - * memory corruption. - */ - ptrdiff_t tag_; - - enum { - VALARRAY = -2, /* js::AutoValueArray */ - PARSER = -3, /* js::frontend::Parser */ - VALVECTOR = -10, /* js::AutoValueVector */ - IDVECTOR = -11, /* js::AutoIdVector */ - OBJVECTOR = -14, /* js::AutoObjectVector */ - IONMASM = -19, /* js::jit::MacroAssembler */ - WRAPVECTOR = -20, /* js::AutoWrapperVector */ - WRAPPER = -21, /* js::AutoWrapperRooter */ - CUSTOM = -26 /* js::CustomAutoRooter */ - }; - - static ptrdiff_t GetTag(const Value& value) { return VALVECTOR; } - static ptrdiff_t GetTag(const jsid& id) { return IDVECTOR; } - static ptrdiff_t GetTag(JSObject* obj) { return OBJVECTOR; } - - private: - AutoGCRooter ** const stackTop; - - /* No copy or assignment semantics. */ - AutoGCRooter(AutoGCRooter& ida) = delete; - void operator=(AutoGCRooter& ida) = delete; -}; - -// Our instantiations of Rooted and PersistentRooted require an -// instantiation of MapTypeToRootKind. -template <> -struct MapTypeToRootKind { - static const RootKind kind = RootKind::Traceable; -}; - -} /* namespace JS */ - -namespace js { - -class ExclusiveContext; - -/* - * This list enumerates the different types of conceptual stacks we have in - * SpiderMonkey. In reality, they all share the C stack, but we allow different - * stack limits depending on the type of code running. - */ -enum StackKind -{ - StackForSystemCode, // C++, such as the GC, running on behalf of the VM. - StackForTrustedScript, // Script running with trusted principals. - StackForUntrustedScript, // Script running with untrusted principals. - StackKindCount -}; - -using RootedListHeads = mozilla::EnumeratedArray*>; - -// Abstracts JS rooting mechanisms so they can be shared between the JSContext -// and JSRuntime. -class RootLists -{ - // Stack GC roots for Rooted GC heap pointers. - RootedListHeads stackRoots_; - template friend class JS::Rooted; - - // Stack GC roots for AutoFooRooter classes. - JS::AutoGCRooter* autoGCRooters_; - friend class JS::AutoGCRooter; - - // Heap GC roots for PersistentRooted pointers. - mozilla::EnumeratedArray>> heapRoots_; - template friend class JS::PersistentRooted; - - public: - RootLists() : autoGCRooters_(nullptr) { - for (auto& stackRootPtr : stackRoots_) - stackRootPtr = nullptr; - } - - ~RootLists() { - // The semantics of PersistentRooted containing pointers and tagged - // pointers are somewhat different from those of PersistentRooted - // containing a structure with a trace method. PersistentRooted - // containing pointers are allowed to outlive the owning RootLists, - // whereas those containing a traceable structure are not. - // - // The purpose of this feature is to support lazy initialization of - // global references for the several places in Gecko that do not have - // access to a tighter context, but that still need to refer to GC - // pointers. For such pointers, FinishPersistentRootedChains ensures - // that the contained references are nulled out when the owning - // RootLists dies to prevent UAF errors. - // - // However, for RootKind::Traceable, we do not know the concrete type - // of the held thing, so we simply cannot do this without accruing - // extra overhead and complexity for all users for a case that is - // unlikely to ever be used in practice. For this reason, the following - // assertion disallows usage of PersistentRooted that - // outlives the RootLists. - MOZ_ASSERT(heapRoots_[JS::RootKind::Traceable].isEmpty()); - } - - void traceStackRoots(JSTracer* trc); - void checkNoGCRooters(); - - void tracePersistentRoots(JSTracer* trc); - void finishPersistentRoots(); -}; - -} // namespace js - -namespace JS { - -/* - * JS::RootingContext is a base class of ContextFriendFields and JSContext. - * This class can be used to let code construct a Rooted<> or PersistentRooted<> - * instance, without giving it full access to the JSContext. - */ -struct RootingContext -{ - js::RootLists roots; - -#ifdef DEBUG - // Whether the derived class is a JSContext or an ExclusiveContext. - bool isJSContext; -#endif - - explicit RootingContext(bool isJSContextArg) -#ifdef DEBUG - : isJSContext(isJSContextArg) -#endif - {} - - static RootingContext* get(JSContext* cx) { - return reinterpret_cast(cx); - } -}; - -} // namespace JS - -namespace js { - -struct ContextFriendFields : public JS::RootingContext -{ - protected: - /* The current compartment. */ - JSCompartment* compartment_; - - /* The current zone. */ - JS::Zone* zone_; - - public: - /* Limit pointer for checking native stack consumption. */ - uintptr_t nativeStackLimit[js::StackKindCount]; - - explicit ContextFriendFields(bool isJSContext); - - static const ContextFriendFields* get(const JSContext* cx) { - return reinterpret_cast(cx); - } - - static ContextFriendFields* get(JSContext* cx) { - return reinterpret_cast(cx); - } - - friend JSCompartment* GetContextCompartment(const JSContext* cx); - friend JS::Zone* GetContextZone(const JSContext* cx); - template friend class JS::Rooted; -}; - -/* - * Inlinable accessors for JSContext. - * - * - These must not be available on the more restricted superclasses of - * JSContext, so we can't simply define them on ContextFriendFields. - * - * - They're perfectly ordinary JSContext functionality, so ought to be - * usable without resorting to jsfriendapi.h, and when JSContext is an - * incomplete type. - */ -inline JSCompartment* -GetContextCompartment(const JSContext* cx) -{ - return ContextFriendFields::get(cx)->compartment_; -} - -inline JS::Zone* -GetContextZone(const JSContext* cx) -{ - return ContextFriendFields::get(cx)->zone_; -} - -} /* namespace js */ - -MOZ_BEGIN_EXTERN_C - -// Defined in NSPR prio.h. -typedef struct PRFileDesc PRFileDesc; - -MOZ_END_EXTERN_C - -#endif /* jspubtd_h */ diff --git a/android/arm64-v8a/include/spidermonkey/jstypes.h b/android/arm64-v8a/include/spidermonkey/jstypes.h deleted file mode 100644 index 914674ab..00000000 --- a/android/arm64-v8a/include/spidermonkey/jstypes.h +++ /dev/null @@ -1,219 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* -** File: jstypes.h -** Description: Definitions of NSPR's basic types -** -** Prototypes and macros used to make up for deficiencies in ANSI environments -** that we have found. -** -** Since we do not wrap and all the other standard headers, authors -** of portable code will not know in general that they need these definitions. -** Instead of requiring these authors to find the dependent uses in their code -** and take the following steps only in those C files, we take steps once here -** for all C files. -**/ - -#ifndef jstypes_h -#define jstypes_h - -#include "mozilla/Attributes.h" -#include "mozilla/Casting.h" -#include "mozilla/Types.h" - -// jstypes.h is (or should be!) included by every file in SpiderMonkey. -// js-config.h and jsversion.h also should be included by every file. -// So include them here. -// XXX: including them in js/RequiredDefines.h should be a better option, since -// that is by definition the header file that should be included in all -// SpiderMonkey code. However, Gecko doesn't do this! See bug 909576. -#include "js-config.h" -#include "jsversion.h" - -/*********************************************************************** -** MACROS: JS_EXTERN_API -** JS_EXPORT_API -** DESCRIPTION: -** These are only for externally visible routines and globals. For -** internal routines, just use "extern" for type checking and that -** will not export internal cross-file or forward-declared symbols. -** Define a macro for declaring procedures return types. We use this to -** deal with windoze specific type hackery for DLL definitions. Use -** JS_EXTERN_API when the prototype for the method is declared. Use -** JS_EXPORT_API for the implementation of the method. -** -** Example: -** in dowhim.h -** JS_EXTERN_API( void ) DoWhatIMean( void ); -** in dowhim.c -** JS_EXPORT_API( void ) DoWhatIMean( void ) { return; } -** -** -***********************************************************************/ - -#define JS_EXTERN_API(type) extern MOZ_EXPORT type -#define JS_EXPORT_API(type) MOZ_EXPORT type -#define JS_EXPORT_DATA(type) MOZ_EXPORT type -#define JS_IMPORT_API(type) MOZ_IMPORT_API type -#define JS_IMPORT_DATA(type) MOZ_IMPORT_DATA type - -/* - * The linkage of JS API functions differs depending on whether the file is - * used within the JS library or not. Any source file within the JS - * interpreter should define EXPORT_JS_API whereas any client of the library - * should not. STATIC_JS_API is used to build JS as a static library. - */ -#if defined(STATIC_JS_API) -# define JS_PUBLIC_API(t) t -# define JS_PUBLIC_DATA(t) t -# define JS_FRIEND_API(t) t -# define JS_FRIEND_DATA(t) t -#elif defined(EXPORT_JS_API) || defined(STATIC_EXPORTABLE_JS_API) -# define JS_PUBLIC_API(t) MOZ_EXPORT t -# define JS_PUBLIC_DATA(t) MOZ_EXPORT t -# define JS_FRIEND_API(t) MOZ_EXPORT t -# define JS_FRIEND_DATA(t) MOZ_EXPORT t -#else -# define JS_PUBLIC_API(t) MOZ_IMPORT_API t -# define JS_PUBLIC_DATA(t) MOZ_IMPORT_DATA t -# define JS_FRIEND_API(t) MOZ_IMPORT_API t -# define JS_FRIEND_DATA(t) MOZ_IMPORT_DATA t -#endif - -#if defined(_MSC_VER) && defined(_M_IX86) -#define JS_FASTCALL __fastcall -#elif defined(__GNUC__) && defined(__i386__) -#define JS_FASTCALL __attribute__((fastcall)) -#else -#define JS_FASTCALL -#define JS_NO_FASTCALL -#endif - -/*********************************************************************** -** MACROS: JS_BEGIN_MACRO -** JS_END_MACRO -** DESCRIPTION: -** Macro body brackets so that macros with compound statement definitions -** behave syntactically more like functions when called. -***********************************************************************/ -#define JS_BEGIN_MACRO do { - -#if defined(_MSC_VER) -# define JS_END_MACRO \ - } __pragma(warning(push)) __pragma(warning(disable:4127)) \ - while (0) __pragma(warning(pop)) -#else -# define JS_END_MACRO } while (0) -#endif - -/*********************************************************************** -** MACROS: JS_BIT -** JS_BITMASK -** DESCRIPTION: -** Bit masking macros. XXX n must be <= 31 to be portable -***********************************************************************/ -#define JS_BIT(n) ((uint32_t)1 << (n)) -#define JS_BITMASK(n) (JS_BIT(n) - 1) - -/*********************************************************************** -** MACROS: JS_HOWMANY -** JS_ROUNDUP -** DESCRIPTION: -** Commonly used macros for operations on compatible types. -***********************************************************************/ -#define JS_HOWMANY(x,y) (((x)+(y)-1)/(y)) -#define JS_ROUNDUP(x,y) (JS_HOWMANY(x,y)*(y)) - -#include "jscpucfg.h" - -/* - * Define JS_64BIT iff we are building in an environment with 64-bit - * addresses. - */ -#ifdef _MSC_VER -# if defined(_M_X64) || defined(_M_AMD64) -# define JS_64BIT -# endif -#elif defined(__GNUC__) -/* Additional GCC defines are when running on Solaris, AIX, and HPUX */ -# if defined(__x86_64__) || defined(__sparcv9) || \ - defined(__64BIT__) || defined(__LP64__) -# define JS_64BIT -# endif -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Sun Studio C/C++ */ -# if defined(__x86_64) || defined(__sparcv9) -# define JS_64BIT -# endif -#elif defined(__xlc__) || defined(__xlC__) /* IBM XL C/C++ */ -# if defined(__64BIT__) -# define JS_64BIT -# endif -#elif defined(__HP_cc) || defined(__HP_aCC) /* HP-UX cc/aCC */ -# if defined(__LP64__) -# define JS_64BIT -# endif -#else -# error "Implement me" -#endif - -/*********************************************************************** -** MACROS: JS_ARRAY_LENGTH -** JS_ARRAY_END -** DESCRIPTION: -** Macros to get the number of elements and the pointer to one past the -** last element of a C array. Use them like this: -** -** char16_t buf[10]; -** JSString* str; -** ... -** for (char16_t* s = buf; s != JS_ARRAY_END(buf); ++s) *s = ...; -** ... -** str = JS_NewStringCopyN(cx, buf, JS_ARRAY_LENGTH(buf)); -** ... -** -***********************************************************************/ - -#define JS_ARRAY_LENGTH(array) (sizeof (array) / sizeof (array)[0]) -#define JS_ARRAY_END(array) ((array) + JS_ARRAY_LENGTH(array)) - -#define JS_BITS_PER_BYTE 8 -#define JS_BITS_PER_BYTE_LOG2 3 - -#if defined(JS_64BIT) -# define JS_BITS_PER_WORD 64 -#else -# define JS_BITS_PER_WORD 32 -#endif - -/*********************************************************************** -** MACROS: JS_FUNC_TO_DATA_PTR -** JS_DATA_TO_FUNC_PTR -** DESCRIPTION: -** Macros to convert between function and data pointers of the same -** size. Use them like this: -** -** JSGetterOp nativeGetter; -** JSObject* scriptedGetter; -** ... -** scriptedGetter = JS_FUNC_TO_DATA_PTR(JSObject*, nativeGetter); -** ... -** nativeGetter = JS_DATA_TO_FUNC_PTR(JSGetterOp, scriptedGetter); -** -***********************************************************************/ - -#define JS_FUNC_TO_DATA_PTR(type, fun) (mozilla::BitwiseCast(fun)) -#define JS_DATA_TO_FUNC_PTR(type, ptr) (mozilla::BitwiseCast(ptr)) - -#ifdef __GNUC__ -# define JS_EXTENSION __extension__ -# define JS_EXTENSION_(s) __extension__ ({ s; }) -#else -# define JS_EXTENSION -# define JS_EXTENSION_(s) s -#endif - -#endif /* jstypes_h */ diff --git a/android/arm64-v8a/include/spidermonkey/jsversion.h b/android/arm64-v8a/include/spidermonkey/jsversion.h deleted file mode 100644 index 8bdfe47b..00000000 --- a/android/arm64-v8a/include/spidermonkey/jsversion.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsversion_h -#define jsversion_h - -/* - * JS Capability Macros. - */ -#define JS_HAS_STR_HTML_HELPERS 1 /* (no longer used) */ -#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ -#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */ -#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */ -#define JS_HAS_CATCH_GUARD 1 /* has exception handling catch guard */ -#define JS_HAS_UNEVAL 1 /* has uneval() top-level function */ -#define JS_HAS_CONST 1 /* (no longer used) */ -#define JS_HAS_FUN_EXPR_STMT 1 /* (no longer used) */ -#define JS_HAS_FOR_EACH_IN 1 /* has for each (lhs in iterable) */ -#define JS_HAS_GENERATORS 1 /* (no longer used) */ -#define JS_HAS_BLOCK_SCOPE 1 /* (no longer used) */ -#define JS_HAS_DESTRUCTURING 2 /* (no longer used) */ -#define JS_HAS_GENERATOR_EXPRS 1 /* (no longer used) */ -#define JS_HAS_EXPR_CLOSURES 1 /* has function (formals) listexpr */ - -/* (no longer used) */ -#define JS_HAS_NEW_GLOBAL_OBJECT 1 - -/* (no longer used) */ -#define JS_HAS_DESTRUCTURING_SHORTHAND (JS_HAS_DESTRUCTURING == 2) - -/* - * Feature for Object.prototype.__{define,lookup}{G,S}etter__ legacy support; - * support likely to be made opt-in at some future time. - */ -#define JS_OLD_GETTER_SETTER_METHODS 1 - -#endif /* jsversion_h */ diff --git a/android/arm64-v8a/include/spidermonkey/jswrapper.h b/android/arm64-v8a/include/spidermonkey/jswrapper.h deleted file mode 100644 index 9b14c59e..00000000 --- a/android/arm64-v8a/include/spidermonkey/jswrapper.h +++ /dev/null @@ -1,382 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jswrapper_h -#define jswrapper_h - -#include "mozilla/Attributes.h" - -#include "js/Proxy.h" - -namespace js { - -/* - * Helper for Wrapper::New default options. - * - * Callers of Wrapper::New() who wish to specify a prototype for the created - * Wrapper, *MUST* construct a WrapperOptions with a JSContext. - */ -class MOZ_STACK_CLASS WrapperOptions : public ProxyOptions { - public: - WrapperOptions() : ProxyOptions(false), - proto_() - {} - - explicit WrapperOptions(JSContext* cx) : ProxyOptions(false), - proto_() - { - proto_.emplace(cx); - } - - inline JSObject* proto() const; - WrapperOptions& setProto(JSObject* protoArg) { - MOZ_ASSERT(proto_); - *proto_ = protoArg; - return *this; - } - - private: - mozilla::Maybe proto_; -}; - -/* - * A wrapper is a proxy with a target object to which it generally forwards - * operations, but may restrict access to certain operations or augment those - * operations in various ways. - * - * A wrapper can be "unwrapped" in C++, exposing the underlying object. - * Callers should be careful to avoid unwrapping security wrappers in the wrong - * context. - * - * Important: If you add a method implementation here, you probably also need - * to add an override in CrossCompartmentWrapper. If you don't, you risk - * compartment mismatches. See bug 945826 comment 0. - */ -class JS_FRIEND_API(Wrapper) : public BaseProxyHandler -{ - unsigned mFlags; - - public: - explicit constexpr Wrapper(unsigned aFlags, bool aHasPrototype = false, - bool aHasSecurityPolicy = false) - : BaseProxyHandler(&family, aHasPrototype, aHasSecurityPolicy), - mFlags(aFlags) - { } - - virtual bool finalizeInBackground(const Value& priv) const override; - - /* Standard internal methods. */ - virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id, - MutableHandle desc) const override; - virtual bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id, - Handle desc, - ObjectOpResult& result) const override; - virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy, - AutoIdVector& props) const override; - virtual bool delete_(JSContext* cx, HandleObject proxy, HandleId id, - ObjectOpResult& result) const override; - virtual bool enumerate(JSContext* cx, HandleObject proxy, - MutableHandleObject objp) const override; - virtual bool getPrototype(JSContext* cx, HandleObject proxy, - MutableHandleObject protop) const override; - virtual bool setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto, - ObjectOpResult& result) const override; - virtual bool getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy, bool* isOrdinary, - MutableHandleObject protop) const override; - virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy, - bool* succeeded) const override; - virtual bool preventExtensions(JSContext* cx, HandleObject proxy, - ObjectOpResult& result) const override; - virtual bool isExtensible(JSContext* cx, HandleObject proxy, bool* extensible) const override; - virtual bool has(JSContext* cx, HandleObject proxy, HandleId id, - bool* bp) const override; - virtual bool get(JSContext* cx, HandleObject proxy, HandleValue receiver, - HandleId id, MutableHandleValue vp) const override; - virtual bool set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v, - HandleValue receiver, ObjectOpResult& result) const override; - virtual bool call(JSContext* cx, HandleObject proxy, const CallArgs& args) const override; - virtual bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const override; - - /* SpiderMonkey extensions. */ - virtual bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id, - MutableHandle desc) const override; - virtual bool hasOwn(JSContext* cx, HandleObject proxy, HandleId id, - bool* bp) const override; - virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject proxy, - AutoIdVector& props) const override; - virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl, - const CallArgs& args) const override; - virtual bool hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v, - bool* bp) const override; - virtual bool getBuiltinClass(JSContext* cx, HandleObject proxy, ESClass* cls) const override; - virtual bool isArray(JSContext* cx, HandleObject proxy, - JS::IsArrayAnswer* answer) const override; - virtual const char* className(JSContext* cx, HandleObject proxy) const override; - virtual JSString* fun_toString(JSContext* cx, HandleObject proxy, - unsigned indent) const override; - virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, - RegExpGuard* g) const override; - virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, - MutableHandleValue vp) const override; - virtual bool isCallable(JSObject* obj) const override; - virtual bool isConstructor(JSObject* obj) const override; - virtual JSObject* weakmapKeyDelegate(JSObject* proxy) const override; - - public: - using BaseProxyHandler::Action; - - enum Flags { - CROSS_COMPARTMENT = 1 << 0, - LAST_USED_FLAG = CROSS_COMPARTMENT - }; - - static JSObject* New(JSContext* cx, JSObject* obj, const Wrapper* handler, - const WrapperOptions& options = WrapperOptions()); - - static JSObject* Renew(JSContext* cx, JSObject* existing, JSObject* obj, const Wrapper* handler); - - static const Wrapper* wrapperHandler(JSObject* wrapper); - - static JSObject* wrappedObject(JSObject* wrapper); - - unsigned flags() const { - return mFlags; - } - - static const char family; - static const Wrapper singleton; - static const Wrapper singletonWithPrototype; - - static JSObject* defaultProto; -}; - -inline JSObject* -WrapperOptions::proto() const -{ - return proto_ ? *proto_ : Wrapper::defaultProto; -} - -/* Base class for all cross compartment wrapper handlers. */ -class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper -{ - public: - explicit constexpr CrossCompartmentWrapper(unsigned aFlags, bool aHasPrototype = false, - bool aHasSecurityPolicy = false) - : Wrapper(CROSS_COMPARTMENT | aFlags, aHasPrototype, aHasSecurityPolicy) - { } - - /* Standard internal methods. */ - virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id, - MutableHandle desc) const override; - virtual bool defineProperty(JSContext* cx, HandleObject wrapper, HandleId id, - Handle desc, - ObjectOpResult& result) const override; - virtual bool ownPropertyKeys(JSContext* cx, HandleObject wrapper, - AutoIdVector& props) const override; - virtual bool delete_(JSContext* cx, HandleObject wrapper, HandleId id, - ObjectOpResult& result) const override; - virtual bool enumerate(JSContext* cx, HandleObject wrapper, MutableHandleObject objp) const override; - virtual bool getPrototype(JSContext* cx, HandleObject proxy, - MutableHandleObject protop) const override; - virtual bool setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto, - ObjectOpResult& result) const override; - - virtual bool getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy, bool* isOrdinary, - MutableHandleObject protop) const override; - virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy, - bool* succeeded) const override; - virtual bool preventExtensions(JSContext* cx, HandleObject wrapper, - ObjectOpResult& result) const override; - virtual bool isExtensible(JSContext* cx, HandleObject wrapper, bool* extensible) const override; - virtual bool has(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp) const override; - virtual bool get(JSContext* cx, HandleObject wrapper, HandleValue receiver, - HandleId id, MutableHandleValue vp) const override; - virtual bool set(JSContext* cx, HandleObject wrapper, HandleId id, HandleValue v, - HandleValue receiver, ObjectOpResult& result) const override; - virtual bool call(JSContext* cx, HandleObject wrapper, const CallArgs& args) const override; - virtual bool construct(JSContext* cx, HandleObject wrapper, const CallArgs& args) const override; - - /* SpiderMonkey extensions. */ - virtual bool getPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id, - MutableHandle desc) const override; - virtual bool hasOwn(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp) const override; - virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject wrapper, - AutoIdVector& props) const override; - virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl, - const CallArgs& args) const override; - virtual bool hasInstance(JSContext* cx, HandleObject wrapper, MutableHandleValue v, - bool* bp) const override; - virtual const char* className(JSContext* cx, HandleObject proxy) const override; - virtual JSString* fun_toString(JSContext* cx, HandleObject wrapper, - unsigned indent) const override; - virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const override; - virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const override; - - // Allocate CrossCompartmentWrappers in the nursery. - virtual bool canNurseryAllocate() const override { return true; } - - static const CrossCompartmentWrapper singleton; - static const CrossCompartmentWrapper singletonWithPrototype; -}; - -class JS_FRIEND_API(OpaqueCrossCompartmentWrapper) : public CrossCompartmentWrapper -{ - public: - explicit constexpr OpaqueCrossCompartmentWrapper() : CrossCompartmentWrapper(0) - { } - - /* Standard internal methods. */ - virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id, - MutableHandle desc) const override; - virtual bool defineProperty(JSContext* cx, HandleObject wrapper, HandleId id, - Handle desc, - ObjectOpResult& result) const override; - virtual bool ownPropertyKeys(JSContext* cx, HandleObject wrapper, - AutoIdVector& props) const override; - virtual bool delete_(JSContext* cx, HandleObject wrapper, HandleId id, - ObjectOpResult& result) const override; - virtual bool enumerate(JSContext* cx, HandleObject wrapper, - MutableHandleObject objp) const override; - virtual bool getPrototype(JSContext* cx, HandleObject wrapper, - MutableHandleObject protop) const override; - virtual bool setPrototype(JSContext* cx, HandleObject wrapper, HandleObject proto, - ObjectOpResult& result) const override; - virtual bool getPrototypeIfOrdinary(JSContext* cx, HandleObject wrapper, bool* isOrdinary, - MutableHandleObject protop) const override; - virtual bool setImmutablePrototype(JSContext* cx, HandleObject wrapper, - bool* succeeded) const override; - virtual bool preventExtensions(JSContext* cx, HandleObject wrapper, - ObjectOpResult& result) const override; - virtual bool isExtensible(JSContext* cx, HandleObject wrapper, bool* extensible) const override; - virtual bool has(JSContext* cx, HandleObject wrapper, HandleId id, - bool* bp) const override; - virtual bool get(JSContext* cx, HandleObject wrapper, HandleValue receiver, - HandleId id, MutableHandleValue vp) const override; - virtual bool set(JSContext* cx, HandleObject wrapper, HandleId id, HandleValue v, - HandleValue receiver, ObjectOpResult& result) const override; - virtual bool call(JSContext* cx, HandleObject wrapper, const CallArgs& args) const override; - virtual bool construct(JSContext* cx, HandleObject wrapper, const CallArgs& args) const override; - - /* SpiderMonkey extensions. */ - virtual bool getPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id, - MutableHandle desc) const override; - virtual bool hasOwn(JSContext* cx, HandleObject wrapper, HandleId id, - bool* bp) const override; - virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject wrapper, - AutoIdVector& props) const override; - virtual bool getBuiltinClass(JSContext* cx, HandleObject wrapper, ESClass* cls) const override; - virtual bool isArray(JSContext* cx, HandleObject obj, - JS::IsArrayAnswer* answer) const override; - virtual const char* className(JSContext* cx, HandleObject wrapper) const override; - virtual JSString* fun_toString(JSContext* cx, HandleObject proxy, unsigned indent) const override; - - static const OpaqueCrossCompartmentWrapper singleton; -}; - -/* - * Base class for security wrappers. A security wrapper is potentially hiding - * all or part of some wrapped object thus SecurityWrapper defaults to denying - * access to the wrappee. This is the opposite of Wrapper which tries to be - * completely transparent. - * - * NB: Currently, only a few ProxyHandler operations are overridden to deny - * access, relying on derived SecurityWrapper to block access when necessary. - */ -template -class JS_FRIEND_API(SecurityWrapper) : public Base -{ - public: - explicit constexpr SecurityWrapper(unsigned flags, bool hasPrototype = false) - : Base(flags, hasPrototype, /* hasSecurityPolicy = */ true) - { } - - virtual bool enter(JSContext* cx, HandleObject wrapper, HandleId id, Wrapper::Action act, - bool* bp) const override; - - virtual bool defineProperty(JSContext* cx, HandleObject wrapper, HandleId id, - Handle desc, - ObjectOpResult& result) const override; - virtual bool isExtensible(JSContext* cx, HandleObject wrapper, bool* extensible) const override; - virtual bool preventExtensions(JSContext* cx, HandleObject wrapper, - ObjectOpResult& result) const override; - virtual bool setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto, - ObjectOpResult& result) const override; - virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy, bool* succeeded) const override; - - virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl, - const CallArgs& args) const override; - virtual bool getBuiltinClass(JSContext* cx, HandleObject wrapper, ESClass* cls) const override; - virtual bool isArray(JSContext* cx, HandleObject wrapper, JS::IsArrayAnswer* answer) const override; - virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const override; - virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const override; - - // Allow isCallable and isConstructor. They used to be class-level, and so could not be guarded - // against. - - virtual bool watch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, - JS::HandleObject callable) const override; - virtual bool unwatch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id) const override; - - /* - * Allow our subclasses to select the superclass behavior they want without - * needing to specify an exact superclass. - */ - typedef Base Permissive; - typedef SecurityWrapper Restrictive; -}; - -typedef SecurityWrapper CrossCompartmentSecurityWrapper; - -extern JSObject* -TransparentObjectWrapper(JSContext* cx, HandleObject existing, HandleObject obj); - -inline bool -IsWrapper(JSObject* obj) -{ - return IsProxy(obj) && GetProxyHandler(obj)->family() == &Wrapper::family; -} - -// Given a JSObject, returns that object stripped of wrappers. If -// stopAtWindowProxy is true, then this returns the WindowProxy if it was -// previously wrapped. Otherwise, this returns the first object for -// which JSObject::isWrapper returns false. -JS_FRIEND_API(JSObject*) -UncheckedUnwrap(JSObject* obj, bool stopAtWindowProxy = true, unsigned* flagsp = nullptr); - -// Given a JSObject, returns that object stripped of wrappers. At each stage, -// the security wrapper has the opportunity to veto the unwrap. If -// stopAtWindowProxy is true, then this returns the WindowProxy if it was -// previously wrapped. -JS_FRIEND_API(JSObject*) -CheckedUnwrap(JSObject* obj, bool stopAtWindowProxy = true); - -// Unwrap only the outermost security wrapper, with the same semantics as -// above. This is the checked version of Wrapper::wrappedObject. -JS_FRIEND_API(JSObject*) -UnwrapOneChecked(JSObject* obj, bool stopAtWindowProxy = true); - -JS_FRIEND_API(bool) -IsCrossCompartmentWrapper(JSObject* obj); - -void -NukeCrossCompartmentWrapper(JSContext* cx, JSObject* wrapper); - -void -RemapWrapper(JSContext* cx, JSObject* wobj, JSObject* newTarget); - -JS_FRIEND_API(bool) -RemapAllWrappersForObject(JSContext* cx, JSObject* oldTarget, - JSObject* newTarget); - -// API to recompute all cross-compartment wrappers whose source and target -// match the given filters. -JS_FRIEND_API(bool) -RecomputeWrappers(JSContext* cx, const CompartmentFilter& sourceFilter, - const CompartmentFilter& targetFilter); - -} /* namespace js */ - -#endif /* jswrapper_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Alignment.h b/android/arm64-v8a/include/spidermonkey/mozilla/Alignment.h deleted file mode 100644 index 4fcda4f3..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Alignment.h +++ /dev/null @@ -1,154 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Functionality related to memory alignment. */ - -#ifndef mozilla_Alignment_h -#define mozilla_Alignment_h - -#include "mozilla/Attributes.h" -#include -#include - -namespace mozilla { - -/* - * This class, and the corresponding macro MOZ_ALIGNOF, figures out how many - * bytes of alignment a given type needs. - */ -template -class AlignmentFinder -{ - struct Aligner - { - char mChar; - T mT; - }; - -public: - static const size_t alignment = sizeof(Aligner) - sizeof(T); -}; - -#define MOZ_ALIGNOF(T) mozilla::AlignmentFinder::alignment - -/* - * Declare the MOZ_ALIGNED_DECL macro for declaring aligned types. - * - * For instance, - * - * MOZ_ALIGNED_DECL(char arr[2], 8); - * - * will declare a two-character array |arr| aligned to 8 bytes. - */ - -#if defined(__GNUC__) -# define MOZ_ALIGNED_DECL(_type, _align) \ - _type __attribute__((aligned(_align))) -#elif defined(_MSC_VER) -# define MOZ_ALIGNED_DECL(_type, _align) \ - __declspec(align(_align)) _type -#else -# warning "We don't know how to align variables on this compiler." -# define MOZ_ALIGNED_DECL(_type, _align) _type -#endif - -/* - * AlignedElem is a structure whose alignment is guaranteed to be at least N - * bytes. - * - * We support 1, 2, 4, 8, and 16-bit alignment. - */ -template -struct AlignedElem; - -/* - * We have to specialize this template because GCC doesn't like - * __attribute__((aligned(foo))) where foo is a template parameter. - */ - -template<> -struct AlignedElem<1> -{ - MOZ_ALIGNED_DECL(uint8_t elem, 1); -}; - -template<> -struct AlignedElem<2> -{ - MOZ_ALIGNED_DECL(uint8_t elem, 2); -}; - -template<> -struct AlignedElem<4> -{ - MOZ_ALIGNED_DECL(uint8_t elem, 4); -}; - -template<> -struct AlignedElem<8> -{ - MOZ_ALIGNED_DECL(uint8_t elem, 8); -}; - -template<> -struct AlignedElem<16> -{ - MOZ_ALIGNED_DECL(uint8_t elem, 16); -}; - -/* - * This utility pales in comparison to Boost's aligned_storage. The utility - * simply assumes that uint64_t is enough alignment for anyone. This may need - * to be extended one day... - * - * As an important side effect, pulling the storage into this template is - * enough obfuscation to confuse gcc's strict-aliasing analysis into not giving - * false negatives when we cast from the char buffer to whatever type we've - * constructed using the bytes. - */ -template -struct AlignedStorage -{ - union U - { - char mBytes[Nbytes]; - uint64_t mDummy; - } u; - - const void* addr() const { return u.mBytes; } - void* addr() { return u.mBytes; } - - AlignedStorage() = default; - - // AlignedStorage is non-copyable: the default copy constructor violates - // strict aliasing rules, per bug 1269319. - AlignedStorage(const AlignedStorage&) = delete; - void operator=(const AlignedStorage&) = delete; -}; - -template -struct MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS AlignedStorage2 -{ - union U - { - char mBytes[sizeof(T)]; - uint64_t mDummy; - } u; - - const T* addr() const { return reinterpret_cast(u.mBytes); } - T* addr() { return static_cast(static_cast(u.mBytes)); } - - AlignedStorage2() = default; - - // AlignedStorage2 is non-copyable: the default copy constructor violates - // strict aliasing rules, per bug 1269319. - AlignedStorage2(const AlignedStorage2&) = delete; - void operator=(const AlignedStorage2&) = delete; -}; - -} /* namespace mozilla */ - -#endif /* mozilla_Alignment_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/AllocPolicy.h b/android/arm64-v8a/include/spidermonkey/mozilla/AllocPolicy.h deleted file mode 100644 index 81f62b03..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/AllocPolicy.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * An allocation policy concept, usable for structures and algorithms to - * control how memory is allocated and how failures are handled. - */ - -#ifndef mozilla_AllocPolicy_h -#define mozilla_AllocPolicy_h - -#include "mozilla/Attributes.h" -#include "mozilla/TemplateLib.h" - -#include -#include - -namespace mozilla { - -/* - * Allocation policies are used to implement the standard allocation behaviors - * in a customizable way. Additionally, custom behaviors may be added to these - * behaviors, such as additionally reporting an error through an out-of-band - * mechanism when OOM occurs. The concept modeled here is as follows: - * - * - public copy constructor, assignment, destructor - * - template T* maybe_pod_malloc(size_t) - * Fallible, but doesn't report an error on OOM. - * - template T* maybe_pod_calloc(size_t) - * Fallible, but doesn't report an error on OOM. - * - template T* maybe_pod_realloc(T*, size_t, size_t) - * Fallible, but doesn't report an error on OOM. The old allocation - * size is passed in, in addition to the new allocation size requested. - * - template T* pod_malloc(size_t) - * Responsible for OOM reporting when null is returned. - * - template T* pod_calloc(size_t) - * Responsible for OOM reporting when null is returned. - * - template T* pod_realloc(T*, size_t, size_t) - * Responsible for OOM reporting when null is returned. The old allocation - * size is passed in, in addition to the new allocation size requested. - * - void free_(void*) - * - void reportAllocOverflow() const - * Called on allocation overflow (that is, an allocation implicitly tried - * to allocate more than the available memory space -- think allocating an - * array of large-size objects, where N * size overflows) before null is - * returned. - * - bool checkSimulatedOOM() const - * Some clients generally allocate memory yet in some circumstances won't - * need to do so. For example, appending to a vector with a small amount of - * inline storage generally allocates memory, but no allocation occurs - * unless appending exceeds inline storage. But for testing purposes, it - * can be useful to treat *every* operation as allocating. - * Clients (such as this hypothetical append method implementation) should - * call this method in situations that don't allocate, but could generally, - * to support this. The default behavior should return true; more - * complicated behavior might be to return false only after a certain - * number of allocations-or-check-simulated-OOMs (coordinating with the - * other AllocPolicy methods) have occurred. - * - * mfbt provides (and typically uses by default) only MallocAllocPolicy, which - * does nothing more than delegate to the malloc/alloc/free functions. - */ - -/* - * A policy that straightforwardly uses malloc/calloc/realloc/free and adds no - * extra behaviors. - */ -class MallocAllocPolicy -{ -public: - template - T* maybe_pod_malloc(size_t aNumElems) - { - if (aNumElems & mozilla::tl::MulOverflowMask::value) { - return nullptr; - } - return static_cast(malloc(aNumElems * sizeof(T))); - } - - template - T* maybe_pod_calloc(size_t aNumElems) - { - return static_cast(calloc(aNumElems, sizeof(T))); - } - - template - T* maybe_pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) - { - if (aNewSize & mozilla::tl::MulOverflowMask::value) { - return nullptr; - } - return static_cast(realloc(aPtr, aNewSize * sizeof(T))); - } - - template - T* pod_malloc(size_t aNumElems) - { - return maybe_pod_malloc(aNumElems); - } - - template - T* pod_calloc(size_t aNumElems) - { - return maybe_pod_calloc(aNumElems); - } - - template - T* pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) - { - return maybe_pod_realloc(aPtr, aOldSize, aNewSize); - } - - void free_(void* aPtr) - { - free(aPtr); - } - - void reportAllocOverflow() const - { - } - - MOZ_MUST_USE bool checkSimulatedOOM() const - { - return true; - } -}; - -} // namespace mozilla - -#endif /* mozilla_AllocPolicy_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/AlreadyAddRefed.h b/android/arm64-v8a/include/spidermonkey/mozilla/AlreadyAddRefed.h deleted file mode 100644 index 0d7b0cae..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/AlreadyAddRefed.h +++ /dev/null @@ -1,147 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Typed temporary pointers for reference-counted smart pointers. */ - -#ifndef AlreadyAddRefed_h -#define AlreadyAddRefed_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" - -namespace mozilla { - -struct unused_t; - -} // namespace mozilla - -/** - * already_AddRefed cooperates with reference counting smart pointers to enable - * you to assign in a pointer _without_ |AddRef|ing it. You might want to use - * this as a return type from a function that returns an already |AddRef|ed - * pointer. - * - * TODO Move already_AddRefed to namespace mozilla. This has not yet been done - * because of the sheer number of usages of already_AddRefed. - */ -template -struct MOZ_MUST_USE_TYPE MOZ_NON_AUTOABLE already_AddRefed -{ - /* - * We want to allow returning nullptr from functions returning - * already_AddRefed, for simplicity. But we also don't want to allow - * returning raw T*, instead preferring creation of already_AddRefed from - * a reference counting smart pointer. - * - * We address the latter requirement by making the (T*) constructor explicit. - * But |return nullptr| won't consider an explicit constructor, so we need - * another constructor to handle it. Plain old (decltype(nullptr)) doesn't - * cut it, because if nullptr is emulated as __null (with type int or long), - * passing nullptr to an int/long parameter triggers compiler warnings. We - * need a type that no one can pass accidentally; a pointer-to-member-function - * (where no such function exists) does the trick nicely. - * - * That handles the return-value case. What about for locals, argument types, - * and so on? |already_AddRefed(nullptr)| considers both overloads (and - * the (already_AddRefed&&) overload as well!), so there's an ambiguity. - * We can target true nullptr using decltype(nullptr), but we can't target - * emulated nullptr the same way, because passing __null to an int/long - * parameter triggers compiler warnings. So just give up on this, and provide - * this behavior through the default constructor. - * - * We can revert to simply explicit (T*) and implicit (decltype(nullptr)) when - * nullptr no longer needs to be emulated to support the ancient b2g compiler. - * (The () overload could also be removed, if desired, if we changed callers.) - */ - already_AddRefed() : mRawPtr(nullptr) {} - - // The return and argument types here are arbitrarily selected so no - // corresponding member function exists. - typedef void (already_AddRefed::* MatchNullptr)(double, float); - MOZ_IMPLICIT already_AddRefed(MatchNullptr aRawPtr) : mRawPtr(nullptr) {} - - explicit already_AddRefed(T* aRawPtr) : mRawPtr(aRawPtr) {} - - // Disallow copy constructor and copy assignment operator: move semantics used instead. - already_AddRefed(const already_AddRefed& aOther) = delete; - already_AddRefed& operator=(const already_AddRefed& aOther) = delete; - - already_AddRefed(already_AddRefed&& aOther) : mRawPtr(aOther.take()) {} - - already_AddRefed& operator=(already_AddRefed&& aOther) - { - mRawPtr = aOther.take(); - return *this; - } - - /** - * This helper is useful in cases like - * - * already_AddRefed - * Foo() - * { - * RefPtr x = ...; - * return x.forget(); - * } - * - * The autoconversion allows one to omit the idiom - * - * RefPtr y = x.forget(); - * return y.forget(); - * - * Note that nsRefPtr is the XPCOM reference counting smart pointer class. - */ - template - MOZ_IMPLICIT already_AddRefed(already_AddRefed&& aOther) : mRawPtr(aOther.take()) {} - - ~already_AddRefed() { MOZ_ASSERT(!mRawPtr); } - - // Specialize the unused operator<< for already_AddRefed, to allow - // nsCOMPtr foo; - // Unused << foo.forget(); - // Note that nsCOMPtr is the XPCOM reference counting smart pointer class. - friend void operator<<(const mozilla::unused_t& aUnused, - const already_AddRefed& aRhs) - { - auto mutableAlreadyAddRefed = const_cast*>(&aRhs); - aUnused << mutableAlreadyAddRefed->take(); - } - - MOZ_MUST_USE T* take() - { - T* rawPtr = mRawPtr; - mRawPtr = nullptr; - return rawPtr; - } - - /** - * This helper provides a static_cast replacement for already_AddRefed, so - * if you have - * - * already_AddRefed F(); - * - * you can write - * - * already_AddRefed - * G() - * { - * return F().downcast(); - * } - */ - template - already_AddRefed downcast() - { - U* tmp = static_cast(mRawPtr); - mRawPtr = nullptr; - return already_AddRefed(tmp); - } - -private: - T* MOZ_OWNING_REF mRawPtr; -}; - -#endif // AlreadyAddRefed_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Array.h b/android/arm64-v8a/include/spidermonkey/mozilla/Array.h deleted file mode 100644 index 72b89ede..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Array.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A compile-time constant-length array with bounds-checking assertions. */ - -#ifndef mozilla_Array_h -#define mozilla_Array_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" -#include "mozilla/ReverseIterator.h" - -#include - -namespace mozilla { - -template -class Array -{ - T mArr[Length]; - -public: - Array() {} - - template - MOZ_IMPLICIT Array(Args&&... aArgs) - : mArr{mozilla::Forward(aArgs)...} - { - static_assert(sizeof...(aArgs) == Length, - "The number of arguments should be equal to the template parameter Length"); - } - - T& operator[](size_t aIndex) - { - MOZ_ASSERT(aIndex < Length); - return mArr[aIndex]; - } - - const T& operator[](size_t aIndex) const - { - MOZ_ASSERT(aIndex < Length); - return mArr[aIndex]; - } - - typedef T* iterator; - typedef const T* const_iterator; - typedef ReverseIterator reverse_iterator; - typedef ReverseIterator const_reverse_iterator; - - // Methods for range-based for loops. - iterator begin() { return mArr; } - const_iterator begin() const { return mArr; } - const_iterator cbegin() const { return begin(); } - iterator end() { return mArr + Length; } - const_iterator end() const { return mArr + Length; } - const_iterator cend() const { return end(); } - - // Methods for reverse iterating. - reverse_iterator rbegin() { return reverse_iterator(end()); } - const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } - const_reverse_iterator crbegin() const { return rbegin(); } - reverse_iterator rend() { return reverse_iterator(begin()); } - const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } - const_reverse_iterator crend() const { return rend(); } -}; - -template -class Array -{ -public: - T& operator[](size_t aIndex) - { - MOZ_CRASH("indexing into zero-length array"); - } - - const T& operator[](size_t aIndex) const - { - MOZ_CRASH("indexing into zero-length array"); - } -}; - -} /* namespace mozilla */ - -#endif /* mozilla_Array_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/ArrayUtils.h b/android/arm64-v8a/include/spidermonkey/mozilla/ArrayUtils.h deleted file mode 100644 index 50236ccb..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/ArrayUtils.h +++ /dev/null @@ -1,194 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Implements various helper functions related to arrays. - */ - -#ifndef mozilla_ArrayUtils_h -#define mozilla_ArrayUtils_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -#include - -#ifdef __cplusplus - -#include "mozilla/Alignment.h" -#include "mozilla/Array.h" -#include "mozilla/EnumeratedArray.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -/* - * Safely subtract two pointers when it is known that aEnd >= aBegin, yielding a - * size_t result. - * - * Ordinary pointer subtraction yields a ptrdiff_t result, which, being signed, - * has insufficient range to express the distance between pointers at opposite - * ends of the address space. Furthermore, most compilers use ptrdiff_t to - * represent the intermediate byte address distance, before dividing by - * sizeof(T); if that intermediate result overflows, they'll produce results - * with the wrong sign even when the correct scaled distance would fit in a - * ptrdiff_t. - */ -template -MOZ_ALWAYS_INLINE size_t -PointerRangeSize(T* aBegin, T* aEnd) -{ - MOZ_ASSERT(aEnd >= aBegin); - return (size_t(aEnd) - size_t(aBegin)) / sizeof(T); -} - -/* - * Compute the length of an array with constant length. (Use of this method - * with a non-array pointer will not compile.) - * - * Beware of the implicit trailing '\0' when using this with string constants. - */ -template -constexpr size_t -ArrayLength(T (&aArr)[N]) -{ - return N; -} - -template -constexpr size_t -ArrayLength(const Array& aArr) -{ - return N; -} - -template -constexpr size_t -ArrayLength(const EnumeratedArray& aArr) -{ - return size_t(N); -} - -/* - * Compute the address one past the last element of a constant-length array. - * - * Beware of the implicit trailing '\0' when using this with string constants. - */ -template -constexpr T* -ArrayEnd(T (&aArr)[N]) -{ - return aArr + ArrayLength(aArr); -} - -template -constexpr T* -ArrayEnd(Array& aArr) -{ - return &aArr[0] + ArrayLength(aArr); -} - -template -constexpr const T* -ArrayEnd(const Array& aArr) -{ - return &aArr[0] + ArrayLength(aArr); -} - -namespace detail { - -template::value>> -struct AlignedChecker -{ - static void - test(const Pointee* aPtr) - { - MOZ_ASSERT((uintptr_t(aPtr) % MOZ_ALIGNOF(AlignType)) == 0, - "performing a range-check with a misaligned pointer"); - } -}; - -template -struct AlignedChecker -{ - static void - test(const Pointee* aPtr) - { - } -}; - -} // namespace detail - -/** - * Determines whether |aPtr| points at an object in the range [aBegin, aEnd). - * - * |aPtr| must have the same alignment as |aBegin| and |aEnd|. This usually - * should be achieved by ensuring |aPtr| points at a |U|, not just that it - * points at a |T|. - * - * It is a usage error for any argument to be misaligned. - * - * It's okay for T* to be void*, and if so U* may also be void*. In the latter - * case no argument is required to be aligned (obviously, as void* implies no - * particular alignment). - */ -template -inline typename EnableIf::value || - IsBaseOf::value || - IsVoid::value, - bool>::Type -IsInRange(const T* aPtr, const U* aBegin, const U* aEnd) -{ - MOZ_ASSERT(aBegin <= aEnd); - detail::AlignedChecker::test(aPtr); - detail::AlignedChecker::test(aBegin); - detail::AlignedChecker::test(aEnd); - return aBegin <= reinterpret_cast(aPtr) && - reinterpret_cast(aPtr) < aEnd; -} - -/** - * Convenience version of the above method when the valid range is specified as - * uintptr_t values. As above, |aPtr| must be aligned, and |aBegin| and |aEnd| - * must be aligned with respect to |T|. - */ -template -inline bool -IsInRange(const T* aPtr, uintptr_t aBegin, uintptr_t aEnd) -{ - return IsInRange(aPtr, - reinterpret_cast(aBegin), - reinterpret_cast(aEnd)); -} - -namespace detail { - -/* - * Helper for the MOZ_ARRAY_LENGTH() macro to make the length a typesafe - * compile-time constant even on compilers lacking constexpr support. - */ -template -char (&ArrayLengthHelper(T (&array)[N]))[N]; - -} /* namespace detail */ - -} /* namespace mozilla */ - -#endif /* __cplusplus */ - -/* - * MOZ_ARRAY_LENGTH() is an alternative to mozilla::ArrayLength() for C files - * that can't use C++ template functions and for static_assert() calls that - * can't call ArrayLength() when it is not a C++11 constexpr function. - */ -#ifdef __cplusplus -# define MOZ_ARRAY_LENGTH(array) sizeof(mozilla::detail::ArrayLengthHelper(array)) -#else -# define MOZ_ARRAY_LENGTH(array) (sizeof(array)/sizeof((array)[0])) -#endif - -#endif /* mozilla_ArrayUtils_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Assertions.h b/android/arm64-v8a/include/spidermonkey/mozilla/Assertions.h deleted file mode 100644 index e978af3d..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Assertions.h +++ /dev/null @@ -1,585 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implementations of runtime and static assertion macros for C and C++. */ - -#ifndef mozilla_Assertions_h -#define mozilla_Assertions_h - -#if defined(MOZILLA_INTERNAL_API) && defined(__cplusplus) -#define MOZ_DUMP_ASSERTION_STACK -#endif - -#include "mozilla/Attributes.h" -#include "mozilla/Compiler.h" -#include "mozilla/Likely.h" -#include "mozilla/MacroArgs.h" -#include "mozilla/StaticAnalysisFunctions.h" -#include "mozilla/Types.h" -#ifdef MOZ_DUMP_ASSERTION_STACK -#include "nsTraceRefcnt.h" -#endif - -#if defined(MOZ_HAS_MOZGLUE) || defined(MOZILLA_INTERNAL_API) -/* - * The crash reason set by MOZ_CRASH_ANNOTATE is consumed by the crash reporter - * if present. It is declared here (and defined in Assertions.cpp) to make it - * available to all code, even libraries that don't link with the crash reporter - * directly. - */ -MOZ_BEGIN_EXTERN_C -extern MFBT_DATA const char* gMozCrashReason; -MOZ_END_EXTERN_C - -static inline void -AnnotateMozCrashReason(const char* reason) -{ - gMozCrashReason = reason; -} -# define MOZ_CRASH_ANNOTATE(...) AnnotateMozCrashReason(__VA_ARGS__) -#else -# define MOZ_CRASH_ANNOTATE(...) do { /* nothing */ } while (0) -#endif - -#include -#include -#include -#ifdef WIN32 - /* - * TerminateProcess and GetCurrentProcess are defined in , which - * further depends on . We hardcode these few definitions manually - * because those headers clutter the global namespace with a significant - * number of undesired macros and symbols. - */ -# ifdef __cplusplus -extern "C" { -# endif -__declspec(dllimport) int __stdcall -TerminateProcess(void* hProcess, unsigned int uExitCode); -__declspec(dllimport) void* __stdcall GetCurrentProcess(void); -# ifdef __cplusplus -} -# endif -#else -# include -#endif -#ifdef ANDROID -# include -#endif - -/* - * MOZ_STATIC_ASSERT may be used to assert a condition *at compile time* in C. - * In C++11, static_assert is provided by the compiler to the same effect. - * This can be useful when you make certain assumptions about what must hold for - * optimal, or even correct, behavior. For example, you might assert that the - * size of a struct is a multiple of the target architecture's word size: - * - * struct S { ... }; - * // C - * MOZ_STATIC_ASSERT(sizeof(S) % sizeof(size_t) == 0, - * "S should be a multiple of word size for efficiency"); - * // C++11 - * static_assert(sizeof(S) % sizeof(size_t) == 0, - * "S should be a multiple of word size for efficiency"); - * - * This macro can be used in any location where both an extern declaration and a - * typedef could be used. - */ -#ifndef __cplusplus - /* - * Some of the definitions below create an otherwise-unused typedef. This - * triggers compiler warnings with some versions of gcc, so mark the typedefs - * as permissibly-unused to disable the warnings. - */ -# if defined(__GNUC__) -# define MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) -# else -# define MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE /* nothing */ -# endif -# define MOZ_STATIC_ASSERT_GLUE1(x, y) x##y -# define MOZ_STATIC_ASSERT_GLUE(x, y) MOZ_STATIC_ASSERT_GLUE1(x, y) -# if defined(__SUNPRO_CC) - /* - * The Sun Studio C++ compiler is buggy when declaring, inside a function, - * another extern'd function with an array argument whose length contains a - * sizeof, triggering the error message "sizeof expression not accepted as - * size of array parameter". This bug (6688515, not public yet) would hit - * defining moz_static_assert as a function, so we always define an extern - * array for Sun Studio. - * - * We include the line number in the symbol name in a best-effort attempt - * to avoid conflicts (see below). - */ -# define MOZ_STATIC_ASSERT(cond, reason) \ - extern char MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __LINE__)[(cond) ? 1 : -1] -# elif defined(__COUNTER__) - /* - * If there was no preferred alternative, use a compiler-agnostic version. - * - * Note that the non-__COUNTER__ version has a bug in C++: it can't be used - * in both |extern "C"| and normal C++ in the same translation unit. (Alas - * |extern "C"| isn't allowed in a function.) The only affected compiler - * we really care about is gcc 4.2. For that compiler and others like it, - * we include the line number in the function name to do the best we can to - * avoid conflicts. These should be rare: a conflict would require use of - * MOZ_STATIC_ASSERT on the same line in separate files in the same - * translation unit, *and* the uses would have to be in code with - * different linkage, *and* the first observed use must be in C++-linkage - * code. - */ -# define MOZ_STATIC_ASSERT(cond, reason) \ - typedef int MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __COUNTER__)[(cond) ? 1 : -1] MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE -# else -# define MOZ_STATIC_ASSERT(cond, reason) \ - extern void MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __LINE__)(int arg[(cond) ? 1 : -1]) MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE -# endif - -#define MOZ_STATIC_ASSERT_IF(cond, expr, reason) MOZ_STATIC_ASSERT(!(cond) || (expr), reason) -#else -#define MOZ_STATIC_ASSERT_IF(cond, expr, reason) static_assert(!(cond) || (expr), reason) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Prints |aStr| as an assertion failure (using aFilename and aLine as the - * location of the assertion) to the standard debug-output channel. - * - * Usually you should use MOZ_ASSERT or MOZ_CRASH instead of this method. This - * method is primarily for internal use in this header, and only secondarily - * for use in implementing release-build assertions. - */ -static MOZ_COLD MOZ_ALWAYS_INLINE void -MOZ_ReportAssertionFailure(const char* aStr, const char* aFilename, int aLine) - MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS -{ -#ifdef ANDROID - __android_log_print(ANDROID_LOG_FATAL, "MOZ_Assert", - "Assertion failure: %s, at %s:%d\n", - aStr, aFilename, aLine); -#else - fprintf(stderr, "Assertion failure: %s, at %s:%d\n", aStr, aFilename, aLine); -#if defined (MOZ_DUMP_ASSERTION_STACK) - nsTraceRefcnt::WalkTheStack(stderr); -#endif - fflush(stderr); -#endif -} - -static MOZ_COLD MOZ_ALWAYS_INLINE void -MOZ_ReportCrash(const char* aStr, const char* aFilename, int aLine) - MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS -{ -#ifdef ANDROID - __android_log_print(ANDROID_LOG_FATAL, "MOZ_CRASH", - "Hit MOZ_CRASH(%s) at %s:%d\n", aStr, aFilename, aLine); -#else - fprintf(stderr, "Hit MOZ_CRASH(%s) at %s:%d\n", aStr, aFilename, aLine); -#if defined(MOZ_DUMP_ASSERTION_STACK) - nsTraceRefcnt::WalkTheStack(stderr); -#endif - fflush(stderr); -#endif -} - -/** - * MOZ_REALLY_CRASH is used in the implementation of MOZ_CRASH(). You should - * call MOZ_CRASH instead. - */ -#if defined(_MSC_VER) - /* - * On MSVC use the __debugbreak compiler intrinsic, which produces an inline - * (not nested in a system function) breakpoint. This distinctively invokes - * Breakpad without requiring system library symbols on all stack-processing - * machines, as a nested breakpoint would require. - * - * We use TerminateProcess with the exit code aborting would generate - * because we don't want to invoke atexit handlers, destructors, library - * unload handlers, and so on when our process might be in a compromised - * state. - * - * We don't use abort() because it'd cause Windows to annoyingly pop up the - * process error dialog multiple times. See bug 345118 and bug 426163. - * - * We follow TerminateProcess() with a call to MOZ_NoReturn() so that the - * compiler doesn't hassle us to provide a return statement after a - * MOZ_REALLY_CRASH() call. - * - * (Technically these are Windows requirements, not MSVC requirements. But - * practically you need MSVC for debugging, and we only ship builds created - * by MSVC, so doing it this way reduces complexity.) - */ - -__declspec(noreturn) __inline void MOZ_NoReturn() {} - -# ifdef __cplusplus -# define MOZ_REALLY_CRASH() \ - do { \ - ::__debugbreak(); \ - *((volatile int*) NULL) = __LINE__; \ - ::TerminateProcess(::GetCurrentProcess(), 3); \ - ::MOZ_NoReturn(); \ - } while (0) -# else -# define MOZ_REALLY_CRASH() \ - do { \ - __debugbreak(); \ - *((volatile int*) NULL) = __LINE__; \ - TerminateProcess(GetCurrentProcess(), 3); \ - MOZ_NoReturn(); \ - } while (0) -# endif -#else -# ifdef __cplusplus -# define MOZ_REALLY_CRASH() \ - do { \ - *((volatile int*) NULL) = __LINE__; \ - ::abort(); \ - } while (0) -# else -# define MOZ_REALLY_CRASH() \ - do { \ - *((volatile int*) NULL) = __LINE__; \ - abort(); \ - } while (0) -# endif -#endif - -/* - * MOZ_CRASH([explanation-string]) crashes the program, plain and simple, in a - * Breakpad-compatible way, in both debug and release builds. - * - * MOZ_CRASH is a good solution for "handling" failure cases when you're - * unwilling or unable to handle them more cleanly -- for OOM, for likely memory - * corruption, and so on. It's also a good solution if you need safe behavior - * in release builds as well as debug builds. But if the failure is one that - * should be debugged and fixed, MOZ_ASSERT is generally preferable. - * - * The optional explanation-string, if provided, must be a string literal - * explaining why we're crashing. This argument is intended for use with - * MOZ_CRASH() calls whose rationale is non-obvious; don't use it if it's - * obvious why we're crashing. - * - * If we're a DEBUG build and we crash at a MOZ_CRASH which provides an - * explanation-string, we print the string to stderr. Otherwise, we don't - * print anything; this is because we want MOZ_CRASH to be 100% safe in release - * builds, and it's hard to print to stderr safely when memory might have been - * corrupted. - */ -#ifndef DEBUG -# define MOZ_CRASH(...) \ - do { \ - MOZ_CRASH_ANNOTATE("MOZ_CRASH(" __VA_ARGS__ ")"); \ - MOZ_REALLY_CRASH(); \ - } while (0) -#else -# define MOZ_CRASH(...) \ - do { \ - MOZ_ReportCrash("" __VA_ARGS__, __FILE__, __LINE__); \ - MOZ_CRASH_ANNOTATE("MOZ_CRASH(" __VA_ARGS__ ")"); \ - MOZ_REALLY_CRASH(); \ - } while (0) -#endif - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -/* - * MOZ_ASSERT(expr [, explanation-string]) asserts that |expr| must be truthy in - * debug builds. If it is, execution continues. Otherwise, an error message - * including the expression and the explanation-string (if provided) is printed, - * an attempt is made to invoke any existing debugger, and execution halts. - * MOZ_ASSERT is fatal: no recovery is possible. Do not assert a condition - * which can correctly be falsy. - * - * The optional explanation-string, if provided, must be a string literal - * explaining the assertion. It is intended for use with assertions whose - * correctness or rationale is non-obvious, and for assertions where the "real" - * condition being tested is best described prosaically. Don't provide an - * explanation if it's not actually helpful. - * - * // No explanation needed: pointer arguments often must not be NULL. - * MOZ_ASSERT(arg); - * - * // An explanation can be helpful to explain exactly how we know an - * // assertion is valid. - * MOZ_ASSERT(state == WAITING_FOR_RESPONSE, - * "given that and , we must have..."); - * - * // Or it might disambiguate multiple identical (save for their location) - * // assertions of the same expression. - * MOZ_ASSERT(getSlot(PRIMITIVE_THIS_SLOT).isUndefined(), - * "we already set [[PrimitiveThis]] for this Boolean object"); - * MOZ_ASSERT(getSlot(PRIMITIVE_THIS_SLOT).isUndefined(), - * "we already set [[PrimitiveThis]] for this String object"); - * - * MOZ_ASSERT has no effect in non-debug builds. It is designed to catch bugs - * *only* during debugging, not "in the field". If you want the latter, use - * MOZ_RELEASE_ASSERT, which applies to non-debug builds as well. - * - * MOZ_DIAGNOSTIC_ASSERT works like MOZ_RELEASE_ASSERT in Nightly/Aurora and - * MOZ_ASSERT in Beta/Release - use this when a condition is potentially rare - * enough to require real user testing to hit, but is not security-sensitive. - * This can cause user pain, so use it sparingly. If a MOZ_DIAGNOSTIC_ASSERT - * is firing, it should promptly be converted to a MOZ_ASSERT while the failure - * is being investigated, rather than letting users suffer. - */ - -/* - * Implement MOZ_VALIDATE_ASSERT_CONDITION_TYPE, which is used to guard against - * accidentally passing something unintended in lieu of an assertion condition. - */ - -#ifdef __cplusplus -# include "mozilla/TypeTraits.h" -namespace mozilla { -namespace detail { - -template -struct AssertionConditionType -{ - typedef typename RemoveReference::Type ValueT; - static_assert(!IsArray::value, - "Expected boolean assertion condition, got an array or a " - "string!"); - static_assert(!IsFunction::value, - "Expected boolean assertion condition, got a function! Did " - "you intend to call that function?"); - static_assert(!IsFloatingPoint::value, - "It's often a bad idea to assert that a floating-point number " - "is nonzero, because such assertions tend to intermittently " - "fail. Shouldn't your code gracefully handle this case instead " - "of asserting? Anyway, if you really want to do that, write an " - "explicit boolean condition, like !!x or x!=0."); - - static const bool isValid = true; -}; - -} // namespace detail -} // namespace mozilla -# define MOZ_VALIDATE_ASSERT_CONDITION_TYPE(x) \ - static_assert(mozilla::detail::AssertionConditionType::isValid, \ - "invalid assertion condition") -#else -# define MOZ_VALIDATE_ASSERT_CONDITION_TYPE(x) -#endif - -/* First the single-argument form. */ -#define MOZ_ASSERT_HELPER1(expr) \ - do { \ - MOZ_VALIDATE_ASSERT_CONDITION_TYPE(expr); \ - if (MOZ_UNLIKELY(!MOZ_CHECK_ASSERT_ASSIGNMENT(expr))) { \ - MOZ_ReportAssertionFailure(#expr, __FILE__, __LINE__); \ - MOZ_CRASH_ANNOTATE("MOZ_RELEASE_ASSERT(" #expr ")"); \ - MOZ_REALLY_CRASH(); \ - } \ - } while (0) -/* Now the two-argument form. */ -#define MOZ_ASSERT_HELPER2(expr, explain) \ - do { \ - MOZ_VALIDATE_ASSERT_CONDITION_TYPE(expr); \ - if (MOZ_UNLIKELY(!MOZ_CHECK_ASSERT_ASSIGNMENT(expr))) { \ - MOZ_ReportAssertionFailure(#expr " (" explain ")", __FILE__, __LINE__); \ - MOZ_CRASH_ANNOTATE("MOZ_RELEASE_ASSERT(" #expr ") (" explain ")"); \ - MOZ_REALLY_CRASH(); \ - } \ - } while (0) - -#define MOZ_RELEASE_ASSERT_GLUE(a, b) a b -#define MOZ_RELEASE_ASSERT(...) \ - MOZ_RELEASE_ASSERT_GLUE( \ - MOZ_PASTE_PREFIX_AND_ARG_COUNT(MOZ_ASSERT_HELPER, __VA_ARGS__), \ - (__VA_ARGS__)) - -#ifdef DEBUG -# define MOZ_ASSERT(...) MOZ_RELEASE_ASSERT(__VA_ARGS__) -#else -# define MOZ_ASSERT(...) do { } while (0) -#endif /* DEBUG */ - -#ifdef RELEASE_OR_BETA -# define MOZ_DIAGNOSTIC_ASSERT MOZ_ASSERT -#else -# define MOZ_DIAGNOSTIC_ASSERT MOZ_RELEASE_ASSERT -#endif - -/* - * MOZ_ASSERT_IF(cond1, cond2) is equivalent to MOZ_ASSERT(cond2) if cond1 is - * true. - * - * MOZ_ASSERT_IF(isPrime(num), num == 2 || isOdd(num)); - * - * As with MOZ_ASSERT, MOZ_ASSERT_IF has effect only in debug builds. It is - * designed to catch bugs during debugging, not "in the field". - */ -#ifdef DEBUG -# define MOZ_ASSERT_IF(cond, expr) \ - do { \ - if (cond) { \ - MOZ_ASSERT(expr); \ - } \ - } while (0) -#else -# define MOZ_ASSERT_IF(cond, expr) do { } while (0) -#endif - -/* - * MOZ_ASSUME_UNREACHABLE_MARKER() expands to an expression which states that - * it is undefined behavior for execution to reach this point. No guarantees - * are made about what will happen if this is reached at runtime. Most code - * should use MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE because it has extra - * asserts. - */ -#if defined(__clang__) || defined(__GNUC__) -# define MOZ_ASSUME_UNREACHABLE_MARKER() __builtin_unreachable() -#elif defined(_MSC_VER) -# define MOZ_ASSUME_UNREACHABLE_MARKER() __assume(0) -#else -# ifdef __cplusplus -# define MOZ_ASSUME_UNREACHABLE_MARKER() ::abort() -# else -# define MOZ_ASSUME_UNREACHABLE_MARKER() abort() -# endif -#endif - -/* - * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE([reason]) tells the compiler that it - * can assume that the macro call cannot be reached during execution. This lets - * the compiler generate better-optimized code under some circumstances, at the - * expense of the program's behavior being undefined if control reaches the - * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE. - * - * In Gecko, you probably should not use this macro outside of performance- or - * size-critical code, because it's unsafe. If you don't care about code size - * or performance, you should probably use MOZ_ASSERT or MOZ_CRASH. - * - * SpiderMonkey is a different beast, and there it's acceptable to use - * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE more widely. - * - * Note that MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE is noreturn, so it's valid - * not to return a value following a MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE - * call. - * - * Example usage: - * - * enum ValueType { - * VALUE_STRING, - * VALUE_INT, - * VALUE_FLOAT - * }; - * - * int ptrToInt(ValueType type, void* value) { - * { - * // We know for sure that type is either INT or FLOAT, and we want this - * // code to run as quickly as possible. - * switch (type) { - * case VALUE_INT: - * return *(int*) value; - * case VALUE_FLOAT: - * return (int) *(float*) value; - * default: - * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unexpected ValueType"); - * } - * } - */ - -/* - * Unconditional assert in debug builds for (assumed) unreachable code paths - * that have a safe return without crashing in release builds. - */ -#define MOZ_ASSERT_UNREACHABLE(reason) \ - MOZ_ASSERT(false, "MOZ_ASSERT_UNREACHABLE: " reason) - -#define MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE(reason) \ - do { \ - MOZ_ASSERT_UNREACHABLE(reason); \ - MOZ_ASSUME_UNREACHABLE_MARKER(); \ - } while (0) - -/** - * MOZ_FALLTHROUGH_ASSERT is an annotation to suppress compiler warnings about - * switch cases that MOZ_ASSERT(false) (or its alias MOZ_ASSERT_UNREACHABLE) in - * debug builds, but intentionally fall through in release builds to handle - * unexpected values. - * - * Why do we need MOZ_FALLTHROUGH_ASSERT in addition to MOZ_FALLTHROUGH? In - * release builds, the MOZ_ASSERT(false) will expand to `do { } while (0)`, - * requiring a MOZ_FALLTHROUGH annotation to suppress a -Wimplicit-fallthrough - * warning. In debug builds, the MOZ_ASSERT(false) will expand to something like - * `if (true) { MOZ_CRASH(); }` and the MOZ_FALLTHROUGH annotation will cause - * a -Wunreachable-code warning. The MOZ_FALLTHROUGH_ASSERT macro breaks this - * warning stalemate. - * - * // Example before MOZ_FALLTHROUGH_ASSERT: - * switch (foo) { - * default: - * // This case wants to assert in debug builds, fall through in release. - * MOZ_ASSERT(false); // -Wimplicit-fallthrough warning in release builds! - * MOZ_FALLTHROUGH; // but -Wunreachable-code warning in debug builds! - * case 5: - * return 5; - * } - * - * // Example with MOZ_FALLTHROUGH_ASSERT: - * switch (foo) { - * default: - * // This case asserts in debug builds, falls through in release. - * MOZ_FALLTHROUGH_ASSERT("Unexpected foo value?!"); - * case 5: - * return 5; - * } - */ -#ifdef DEBUG -# define MOZ_FALLTHROUGH_ASSERT(reason) MOZ_CRASH("MOZ_FALLTHROUGH_ASSERT: " reason) -#else -# define MOZ_FALLTHROUGH_ASSERT(...) MOZ_FALLTHROUGH -#endif - -/* - * MOZ_ALWAYS_TRUE(expr) and MOZ_ALWAYS_FALSE(expr) always evaluate the provided - * expression, in debug builds and in release builds both. Then, in debug - * builds only, the value of the expression is asserted either true or false - * using MOZ_ASSERT. - */ -#ifdef DEBUG -# define MOZ_ALWAYS_TRUE(expr) \ - do { \ - if ((expr)) { \ - /* Do nothing. */ \ - } else { \ - MOZ_ASSERT(false, #expr); \ - } \ - } while (0) -# define MOZ_ALWAYS_FALSE(expr) \ - do { \ - if ((expr)) { \ - MOZ_ASSERT(false, #expr); \ - } else { \ - /* Do nothing. */ \ - } \ - } while (0) -#else -# define MOZ_ALWAYS_TRUE(expr) \ - do { \ - if ((expr)) { \ - /* Silence MOZ_MUST_USE. */ \ - } \ - } while (0) -# define MOZ_ALWAYS_FALSE(expr) \ - do { \ - if ((expr)) { \ - /* Silence MOZ_MUST_USE. */ \ - } \ - } while (0) -#endif - -#undef MOZ_DUMP_ASSERTION_STACK -#undef MOZ_CRASH_CRASHREPORT - -#endif /* mozilla_Assertions_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Atomics.h b/android/arm64-v8a/include/spidermonkey/mozilla/Atomics.h deleted file mode 100644 index 213d1b9f..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Atomics.h +++ /dev/null @@ -1,800 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Implements (almost always) lock-free atomic operations. The operations here - * are a subset of that which can be found in C++11's header, with a - * different API to enforce consistent memory ordering constraints. - * - * Anyone caught using |volatile| for inter-thread memory safety needs to be - * sent a copy of this header and the C++11 standard. - */ - -#ifndef mozilla_Atomics_h -#define mozilla_Atomics_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Compiler.h" -#include "mozilla/TypeTraits.h" - -#include - -/* - * Our minimum deployment target on clang/OS X is OS X 10.6, whose SDK - * does not have . So be sure to check for support - * along with C++0x support. - */ -#if defined(_MSC_VER) -# define MOZ_HAVE_CXX11_ATOMICS -#elif defined(__clang__) || defined(__GNUC__) - /* - * Clang doesn't like from libstdc++ before 4.7 due to the - * loose typing of the atomic builtins. GCC 4.5 and 4.6 lacks inline - * definitions for unspecialized std::atomic and causes linking errors. - * Therefore, we require at least 4.7.0 for using libstdc++. - * - * libc++ is only functional with clang. - */ -# if MOZ_USING_LIBSTDCXX && MOZ_LIBSTDCXX_VERSION_AT_LEAST(4, 7, 0) -# define MOZ_HAVE_CXX11_ATOMICS -# elif MOZ_USING_LIBCXX && defined(__clang__) -# define MOZ_HAVE_CXX11_ATOMICS -# endif -#endif - -namespace mozilla { - -/** - * An enum of memory ordering possibilities for atomics. - * - * Memory ordering is the observable state of distinct values in memory. - * (It's a separate concept from atomicity, which concerns whether an - * operation can ever be observed in an intermediate state. Don't - * conflate the two!) Given a sequence of operations in source code on - * memory, it is *not* always the case that, at all times and on all - * cores, those operations will appear to have occurred in that exact - * sequence. First, the compiler might reorder that sequence, if it - * thinks another ordering will be more efficient. Second, the CPU may - * not expose so consistent a view of memory. CPUs will often perform - * their own instruction reordering, above and beyond that performed by - * the compiler. And each core has its own memory caches, and accesses - * (reads and writes both) to "memory" may only resolve to out-of-date - * cache entries -- not to the "most recently" performed operation in - * some global sense. Any access to a value that may be used by - * multiple threads, potentially across multiple cores, must therefore - * have a memory ordering imposed on it, for all code on all - * threads/cores to have a sufficiently coherent worldview. - * - * http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync and - * http://en.cppreference.com/w/cpp/atomic/memory_order go into more - * detail on all this, including examples of how each mode works. - * - * Note that for simplicity and practicality, not all of the modes in - * C++11 are supported. The missing C++11 modes are either subsumed by - * the modes we provide below, or not relevant for the CPUs we support - * in Gecko. These three modes are confusing enough as it is! - */ -enum MemoryOrdering { - /* - * Relaxed ordering is the simplest memory ordering: none at all. - * When the result of a write is observed, nothing may be inferred - * about other memory. Writes ostensibly performed "before" on the - * writing thread may not yet be visible. Writes performed "after" on - * the writing thread may already be visible, if the compiler or CPU - * reordered them. (The latter can happen if reads and/or writes get - * held up in per-processor caches.) Relaxed ordering means - * operations can always use cached values (as long as the actual - * updates to atomic values actually occur, correctly, eventually), so - * it's usually the fastest sort of atomic access. For this reason, - * *it's also the most dangerous kind of access*. - * - * Relaxed ordering is good for things like process-wide statistics - * counters that don't need to be consistent with anything else, so - * long as updates themselves are atomic. (And so long as any - * observations of that value can tolerate being out-of-date -- if you - * need some sort of up-to-date value, you need some sort of other - * synchronizing operation.) It's *not* good for locks, mutexes, - * reference counts, etc. that mediate access to other memory, or must - * be observably consistent with other memory. - * - * x86 architectures don't take advantage of the optimization - * opportunities that relaxed ordering permits. Thus it's possible - * that using relaxed ordering will "work" on x86 but fail elsewhere - * (ARM, say, which *does* implement non-sequentially-consistent - * relaxed ordering semantics). Be extra-careful using relaxed - * ordering if you can't easily test non-x86 architectures! - */ - Relaxed, - - /* - * When an atomic value is updated with ReleaseAcquire ordering, and - * that new value is observed with ReleaseAcquire ordering, prior - * writes (atomic or not) are also observable. What ReleaseAcquire - * *doesn't* give you is any observable ordering guarantees for - * ReleaseAcquire-ordered operations on different objects. For - * example, if there are two cores that each perform ReleaseAcquire - * operations on separate objects, each core may or may not observe - * the operations made by the other core. The only way the cores can - * be synchronized with ReleaseAcquire is if they both - * ReleaseAcquire-access the same object. This implies that you can't - * necessarily describe some global total ordering of ReleaseAcquire - * operations. - * - * ReleaseAcquire ordering is good for (as the name implies) atomic - * operations on values controlling ownership of things: reference - * counts, mutexes, and the like. However, if you are thinking about - * using these to implement your own locks or mutexes, you should take - * a good, hard look at actual lock or mutex primitives first. - */ - ReleaseAcquire, - - /* - * When an atomic value is updated with SequentiallyConsistent - * ordering, all writes observable when the update is observed, just - * as with ReleaseAcquire ordering. But, furthermore, a global total - * ordering of SequentiallyConsistent operations *can* be described. - * For example, if two cores perform SequentiallyConsistent operations - * on separate objects, one core will observably perform its update - * (and all previous operations will have completed), then the other - * core will observably perform its update (and all previous - * operations will have completed). (Although those previous - * operations aren't themselves ordered -- they could be intermixed, - * or ordered if they occur on atomic values with ordering - * requirements.) SequentiallyConsistent is the *simplest and safest* - * ordering of atomic operations -- it's always as if one operation - * happens, then another, then another, in some order -- and every - * core observes updates to happen in that single order. Because it - * has the most synchronization requirements, operations ordered this - * way also tend to be slowest. - * - * SequentiallyConsistent ordering can be desirable when multiple - * threads observe objects, and they all have to agree on the - * observable order of changes to them. People expect - * SequentiallyConsistent ordering, even if they shouldn't, when - * writing code, atomic or otherwise. SequentiallyConsistent is also - * the ordering of choice when designing lockless data structures. If - * you don't know what order to use, use this one. - */ - SequentiallyConsistent, -}; - -} // namespace mozilla - -// Build up the underlying intrinsics. -#ifdef MOZ_HAVE_CXX11_ATOMICS - -# include - -namespace mozilla { -namespace detail { - -/* - * We provide CompareExchangeFailureOrder to work around a bug in some - * versions of GCC's header. See bug 898491. - */ -template struct AtomicOrderConstraints; - -template<> -struct AtomicOrderConstraints -{ - static const std::memory_order AtomicRMWOrder = std::memory_order_relaxed; - static const std::memory_order LoadOrder = std::memory_order_relaxed; - static const std::memory_order StoreOrder = std::memory_order_relaxed; - static const std::memory_order CompareExchangeFailureOrder = - std::memory_order_relaxed; -}; - -template<> -struct AtomicOrderConstraints -{ - static const std::memory_order AtomicRMWOrder = std::memory_order_acq_rel; - static const std::memory_order LoadOrder = std::memory_order_acquire; - static const std::memory_order StoreOrder = std::memory_order_release; - static const std::memory_order CompareExchangeFailureOrder = - std::memory_order_acquire; -}; - -template<> -struct AtomicOrderConstraints -{ - static const std::memory_order AtomicRMWOrder = std::memory_order_seq_cst; - static const std::memory_order LoadOrder = std::memory_order_seq_cst; - static const std::memory_order StoreOrder = std::memory_order_seq_cst; - static const std::memory_order CompareExchangeFailureOrder = - std::memory_order_seq_cst; -}; - -template -struct IntrinsicBase -{ - typedef std::atomic ValueType; - typedef AtomicOrderConstraints OrderedOp; -}; - -template -struct IntrinsicMemoryOps : public IntrinsicBase -{ - typedef IntrinsicBase Base; - - static T load(const typename Base::ValueType& aPtr) - { - return aPtr.load(Base::OrderedOp::LoadOrder); - } - - static void store(typename Base::ValueType& aPtr, T aVal) - { - aPtr.store(aVal, Base::OrderedOp::StoreOrder); - } - - static T exchange(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.exchange(aVal, Base::OrderedOp::AtomicRMWOrder); - } - - static bool compareExchange(typename Base::ValueType& aPtr, - T aOldVal, T aNewVal) - { - return aPtr.compare_exchange_strong(aOldVal, aNewVal, - Base::OrderedOp::AtomicRMWOrder, - Base::OrderedOp::CompareExchangeFailureOrder); - } -}; - -template -struct IntrinsicAddSub : public IntrinsicBase -{ - typedef IntrinsicBase Base; - - static T add(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.fetch_add(aVal, Base::OrderedOp::AtomicRMWOrder); - } - - static T sub(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.fetch_sub(aVal, Base::OrderedOp::AtomicRMWOrder); - } -}; - -template -struct IntrinsicAddSub : public IntrinsicBase -{ - typedef IntrinsicBase Base; - - static T* add(typename Base::ValueType& aPtr, ptrdiff_t aVal) - { - return aPtr.fetch_add(aVal, Base::OrderedOp::AtomicRMWOrder); - } - - static T* sub(typename Base::ValueType& aPtr, ptrdiff_t aVal) - { - return aPtr.fetch_sub(aVal, Base::OrderedOp::AtomicRMWOrder); - } -}; - -template -struct IntrinsicIncDec : public IntrinsicAddSub -{ - typedef IntrinsicBase Base; - - static T inc(typename Base::ValueType& aPtr) - { - return IntrinsicAddSub::add(aPtr, 1); - } - - static T dec(typename Base::ValueType& aPtr) - { - return IntrinsicAddSub::sub(aPtr, 1); - } -}; - -template -struct AtomicIntrinsics : public IntrinsicMemoryOps, - public IntrinsicIncDec -{ - typedef IntrinsicBase Base; - - static T or_(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.fetch_or(aVal, Base::OrderedOp::AtomicRMWOrder); - } - - static T xor_(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.fetch_xor(aVal, Base::OrderedOp::AtomicRMWOrder); - } - - static T and_(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.fetch_and(aVal, Base::OrderedOp::AtomicRMWOrder); - } -}; - -template -struct AtomicIntrinsics - : public IntrinsicMemoryOps, public IntrinsicIncDec -{ -}; - -template -struct ToStorageTypeArgument -{ - static constexpr T convert (T aT) { return aT; } -}; - -} // namespace detail -} // namespace mozilla - -#elif defined(__GNUC__) - -namespace mozilla { -namespace detail { - -/* - * The __sync_* family of intrinsics is documented here: - * - * http://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Atomic-Builtins.html - * - * While these intrinsics are deprecated in favor of the newer __atomic_* - * family of intrincs: - * - * http://gcc.gnu.org/onlinedocs/gcc-4.7.3/gcc/_005f_005fatomic-Builtins.html - * - * any GCC version that supports the __atomic_* intrinsics will also support - * the header and so will be handled above. We provide a version of - * atomics using the __sync_* intrinsics to support older versions of GCC. - * - * All __sync_* intrinsics that we use below act as full memory barriers, for - * both compiler and hardware reordering, except for __sync_lock_test_and_set, - * which is a only an acquire barrier. When we call __sync_lock_test_and_set, - * we add a barrier above it as appropriate. - */ - -template struct Barrier; - -/* - * Some processors (in particular, x86) don't require quite so many calls to - * __sync_sychronize as our specializations of Barrier produce. If - * performance turns out to be an issue, defining these specializations - * on a per-processor basis would be a good first tuning step. - */ - -template<> -struct Barrier -{ - static void beforeLoad() {} - static void afterLoad() {} - static void beforeStore() {} - static void afterStore() {} -}; - -template<> -struct Barrier -{ - static void beforeLoad() {} - static void afterLoad() { __sync_synchronize(); } - static void beforeStore() { __sync_synchronize(); } - static void afterStore() {} -}; - -template<> -struct Barrier -{ - static void beforeLoad() { __sync_synchronize(); } - static void afterLoad() { __sync_synchronize(); } - static void beforeStore() { __sync_synchronize(); } - static void afterStore() { __sync_synchronize(); } -}; - -template::value> -struct AtomicStorageType -{ - // For non-enums, just use the type directly. - typedef T Type; -}; - -template -struct AtomicStorageType - : Conditional -{ - static_assert(sizeof(T) == 4 || sizeof(T) == 8, - "wrong type computed in conditional above"); -}; - -template -struct IntrinsicMemoryOps -{ - typedef typename AtomicStorageType::Type ValueType; - - static T load(const ValueType& aPtr) - { - Barrier::beforeLoad(); - T val = T(aPtr); - Barrier::afterLoad(); - return val; - } - - static void store(ValueType& aPtr, T aVal) - { - Barrier::beforeStore(); - aPtr = ValueType(aVal); - Barrier::afterStore(); - } - - static T exchange(ValueType& aPtr, T aVal) - { - // __sync_lock_test_and_set is only an acquire barrier; loads and stores - // can't be moved up from after to before it, but they can be moved down - // from before to after it. We may want a stricter ordering, so we need - // an explicit barrier. - Barrier::beforeStore(); - return T(__sync_lock_test_and_set(&aPtr, ValueType(aVal))); - } - - static bool compareExchange(ValueType& aPtr, T aOldVal, T aNewVal) - { - return __sync_bool_compare_and_swap(&aPtr, ValueType(aOldVal), ValueType(aNewVal)); - } -}; - -template -struct IntrinsicAddSub - : public IntrinsicMemoryOps -{ - typedef IntrinsicMemoryOps Base; - typedef typename Base::ValueType ValueType; - - static T add(ValueType& aPtr, T aVal) - { - return T(__sync_fetch_and_add(&aPtr, ValueType(aVal))); - } - - static T sub(ValueType& aPtr, T aVal) - { - return T(__sync_fetch_and_sub(&aPtr, ValueType(aVal))); - } -}; - -template -struct IntrinsicAddSub - : public IntrinsicMemoryOps -{ - typedef IntrinsicMemoryOps Base; - typedef typename Base::ValueType ValueType; - - /* - * The reinterpret_casts are needed so that - * __sync_fetch_and_{add,sub} will properly type-check. - * - * Also, these functions do not provide standard semantics for - * pointer types, so we need to adjust the addend. - */ - static ValueType add(ValueType& aPtr, ptrdiff_t aVal) - { - ValueType amount = reinterpret_cast(aVal * sizeof(T)); - return __sync_fetch_and_add(&aPtr, amount); - } - - static ValueType sub(ValueType& aPtr, ptrdiff_t aVal) - { - ValueType amount = reinterpret_cast(aVal * sizeof(T)); - return __sync_fetch_and_sub(&aPtr, amount); - } -}; - -template -struct IntrinsicIncDec : public IntrinsicAddSub -{ - typedef IntrinsicAddSub Base; - typedef typename Base::ValueType ValueType; - - static T inc(ValueType& aPtr) { return Base::add(aPtr, 1); } - static T dec(ValueType& aPtr) { return Base::sub(aPtr, 1); } -}; - -template -struct AtomicIntrinsics : public IntrinsicIncDec -{ - static T or_( T& aPtr, T aVal) { return __sync_fetch_and_or(&aPtr, aVal); } - static T xor_(T& aPtr, T aVal) { return __sync_fetch_and_xor(&aPtr, aVal); } - static T and_(T& aPtr, T aVal) { return __sync_fetch_and_and(&aPtr, aVal); } -}; - -template -struct AtomicIntrinsics : public IntrinsicIncDec -{ -}; - -template::value> -struct ToStorageTypeArgument -{ - typedef typename AtomicStorageType::Type ResultType; - - static constexpr ResultType convert (T aT) { return ResultType(aT); } -}; - -template -struct ToStorageTypeArgument -{ - static constexpr T convert (T aT) { return aT; } -}; - -} // namespace detail -} // namespace mozilla - -#else -# error "Atomic compiler intrinsics are not supported on your platform" -#endif - -namespace mozilla { - -namespace detail { - -template -class AtomicBase -{ - static_assert(sizeof(T) == 4 || sizeof(T) == 8, - "mozilla/Atomics.h only supports 32-bit and 64-bit types"); - -protected: - typedef typename detail::AtomicIntrinsics Intrinsics; - typedef typename Intrinsics::ValueType ValueType; - ValueType mValue; - -public: - constexpr AtomicBase() : mValue() {} - explicit constexpr AtomicBase(T aInit) - : mValue(ToStorageTypeArgument::convert(aInit)) - {} - - // Note: we can't provide operator T() here because Atomic inherits - // from AtomcBase with T=uint32_t and not T=bool. If we implemented - // operator T() here, it would cause errors when comparing Atomic with - // a regular bool. - - T operator=(T aVal) - { - Intrinsics::store(mValue, aVal); - return aVal; - } - - /** - * Performs an atomic swap operation. aVal is stored and the previous - * value of this variable is returned. - */ - T exchange(T aVal) - { - return Intrinsics::exchange(mValue, aVal); - } - - /** - * Performs an atomic compare-and-swap operation and returns true if it - * succeeded. This is equivalent to atomically doing - * - * if (mValue == aOldValue) { - * mValue = aNewValue; - * return true; - * } else { - * return false; - * } - */ - bool compareExchange(T aOldValue, T aNewValue) - { - return Intrinsics::compareExchange(mValue, aOldValue, aNewValue); - } - -private: - template - AtomicBase(const AtomicBase& aCopy) = delete; -}; - -template -class AtomicBaseIncDec : public AtomicBase -{ - typedef typename detail::AtomicBase Base; - -public: - constexpr AtomicBaseIncDec() : Base() {} - explicit constexpr AtomicBaseIncDec(T aInit) : Base(aInit) {} - - using Base::operator=; - - operator T() const { return Base::Intrinsics::load(Base::mValue); } - T operator++(int) { return Base::Intrinsics::inc(Base::mValue); } - T operator--(int) { return Base::Intrinsics::dec(Base::mValue); } - T operator++() { return Base::Intrinsics::inc(Base::mValue) + 1; } - T operator--() { return Base::Intrinsics::dec(Base::mValue) - 1; } - -private: - template - AtomicBaseIncDec(const AtomicBaseIncDec& aCopy) = delete; -}; - -} // namespace detail - -/** - * A wrapper for a type that enforces that all memory accesses are atomic. - * - * In general, where a variable |T foo| exists, |Atomic foo| can be used in - * its place. Implementations for integral and pointer types are provided - * below. - * - * Atomic accesses are sequentially consistent by default. You should - * use the default unless you are tall enough to ride the - * memory-ordering roller coaster (if you're not sure, you aren't) and - * you have a compelling reason to do otherwise. - * - * There is one exception to the case of atomic memory accesses: providing an - * initial value of the atomic value is not guaranteed to be atomic. This is a - * deliberate design choice that enables static atomic variables to be declared - * without introducing extra static constructors. - */ -template -class Atomic; - -/** - * Atomic implementation for integral types. - * - * In addition to atomic store and load operations, compound assignment and - * increment/decrement operators are implemented which perform the - * corresponding read-modify-write operation atomically. Finally, an atomic - * swap method is provided. - */ -template -class Atomic::value && - !IsSame::value>::Type> - : public detail::AtomicBaseIncDec -{ - typedef typename detail::AtomicBaseIncDec Base; - -public: - constexpr Atomic() : Base() {} - explicit constexpr Atomic(T aInit) : Base(aInit) {} - - using Base::operator=; - - T operator+=(T aDelta) - { - return Base::Intrinsics::add(Base::mValue, aDelta) + aDelta; - } - - T operator-=(T aDelta) - { - return Base::Intrinsics::sub(Base::mValue, aDelta) - aDelta; - } - - T operator|=(T aVal) - { - return Base::Intrinsics::or_(Base::mValue, aVal) | aVal; - } - - T operator^=(T aVal) - { - return Base::Intrinsics::xor_(Base::mValue, aVal) ^ aVal; - } - - T operator&=(T aVal) - { - return Base::Intrinsics::and_(Base::mValue, aVal) & aVal; - } - -private: - Atomic(Atomic& aOther) = delete; -}; - -/** - * Atomic implementation for pointer types. - * - * An atomic compare-and-swap primitive for pointer variables is provided, as - * are atomic increment and decement operators. Also provided are the compound - * assignment operators for addition and subtraction. Atomic swap (via - * exchange()) is included as well. - */ -template -class Atomic : public detail::AtomicBaseIncDec -{ - typedef typename detail::AtomicBaseIncDec Base; - -public: - constexpr Atomic() : Base() {} - explicit constexpr Atomic(T* aInit) : Base(aInit) {} - - using Base::operator=; - - T* operator+=(ptrdiff_t aDelta) - { - return Base::Intrinsics::add(Base::mValue, aDelta) + aDelta; - } - - T* operator-=(ptrdiff_t aDelta) - { - return Base::Intrinsics::sub(Base::mValue, aDelta) - aDelta; - } - -private: - Atomic(Atomic& aOther) = delete; -}; - -/** - * Atomic implementation for enum types. - * - * The atomic store and load operations and the atomic swap method is provided. - */ -template -class Atomic::value>::Type> - : public detail::AtomicBase -{ - typedef typename detail::AtomicBase Base; - -public: - constexpr Atomic() : Base() {} - explicit constexpr Atomic(T aInit) : Base(aInit) {} - - operator T() const { return T(Base::Intrinsics::load(Base::mValue)); } - - using Base::operator=; - -private: - Atomic(Atomic& aOther) = delete; -}; - -/** - * Atomic implementation for boolean types. - * - * The atomic store and load operations and the atomic swap method is provided. - * - * Note: - * - * - sizeof(Atomic) != sizeof(bool) for some implementations of - * bool and/or some implementations of std::atomic. This is allowed in - * [atomic.types.generic]p9. - * - * - It's not obvious whether the 8-bit atomic functions on Windows are always - * inlined or not. If they are not inlined, the corresponding functions in the - * runtime library are not available on Windows XP. This is why we implement - * Atomic with an underlying type of uint32_t. - */ -template -class Atomic - : protected detail::AtomicBase -{ - typedef typename detail::AtomicBase Base; - -public: - constexpr Atomic() : Base() {} - explicit constexpr Atomic(bool aInit) : Base(aInit) {} - - // We provide boolean wrappers for the underlying AtomicBase methods. - MOZ_IMPLICIT operator bool() const - { - return Base::Intrinsics::load(Base::mValue); - } - - bool operator=(bool aVal) - { - return Base::operator=(aVal); - } - - bool exchange(bool aVal) - { - return Base::exchange(aVal); - } - - bool compareExchange(bool aOldValue, bool aNewValue) - { - return Base::compareExchange(aOldValue, aNewValue); - } - -private: - Atomic(Atomic& aOther) = delete; -}; - -} // namespace mozilla - -#endif /* mozilla_Atomics_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Attributes.h b/android/arm64-v8a/include/spidermonkey/mozilla/Attributes.h deleted file mode 100644 index df6172f3..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Attributes.h +++ /dev/null @@ -1,604 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implementations of various class and method modifier attributes. */ - -#ifndef mozilla_Attributes_h -#define mozilla_Attributes_h - -#include "mozilla/Compiler.h" - -/* - * MOZ_ALWAYS_INLINE is a macro which expands to tell the compiler that the - * method decorated with it must be inlined, even if the compiler thinks - * otherwise. This is only a (much) stronger version of the inline hint: - * compilers are not guaranteed to respect it (although they're much more likely - * to do so). - * - * The MOZ_ALWAYS_INLINE_EVEN_DEBUG macro is yet stronger. It tells the - * compiler to inline even in DEBUG builds. It should be used very rarely. - */ -#if defined(_MSC_VER) -# define MOZ_ALWAYS_INLINE_EVEN_DEBUG __forceinline -#elif defined(__GNUC__) -# define MOZ_ALWAYS_INLINE_EVEN_DEBUG __attribute__((always_inline)) inline -#else -# define MOZ_ALWAYS_INLINE_EVEN_DEBUG inline -#endif - -#if !defined(DEBUG) -# define MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE_EVEN_DEBUG -#elif defined(_MSC_VER) && !defined(__cplusplus) -# define MOZ_ALWAYS_INLINE __inline -#else -# define MOZ_ALWAYS_INLINE inline -#endif - -#if defined(_MSC_VER) -/* - * g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality - * without warnings (functionality used by the macros below). These modes are - * detectable by checking whether __GXX_EXPERIMENTAL_CXX0X__ is defined or, more - * standardly, by checking whether __cplusplus has a C++11 or greater value. - * Current versions of g++ do not correctly set __cplusplus, so we check both - * for forward compatibility. - */ -# define MOZ_HAVE_NEVER_INLINE __declspec(noinline) -# define MOZ_HAVE_NORETURN __declspec(noreturn) -#elif defined(__clang__) - /* - * Per Clang documentation, "Note that marketing version numbers should not - * be used to check for language features, as different vendors use different - * numbering schemes. Instead, use the feature checking macros." - */ -# ifndef __has_extension -# define __has_extension __has_feature /* compatibility, for older versions of clang */ -# endif -# if __has_attribute(noinline) -# define MOZ_HAVE_NEVER_INLINE __attribute__((noinline)) -# endif -# if __has_attribute(noreturn) -# define MOZ_HAVE_NORETURN __attribute__((noreturn)) -# endif -#elif defined(__GNUC__) -# define MOZ_HAVE_NEVER_INLINE __attribute__((noinline)) -# define MOZ_HAVE_NORETURN __attribute__((noreturn)) -#endif - -/* - * When built with clang analyzer (a.k.a scan-build), define MOZ_HAVE_NORETURN - * to mark some false positives - */ -#ifdef __clang_analyzer__ -# if __has_extension(attribute_analyzer_noreturn) -# define MOZ_HAVE_ANALYZER_NORETURN __attribute__((analyzer_noreturn)) -# endif -#endif - -/* - * MOZ_NEVER_INLINE is a macro which expands to tell the compiler that the - * method decorated with it must never be inlined, even if the compiler would - * otherwise choose to inline the method. Compilers aren't absolutely - * guaranteed to support this, but most do. - */ -#if defined(MOZ_HAVE_NEVER_INLINE) -# define MOZ_NEVER_INLINE MOZ_HAVE_NEVER_INLINE -#else -# define MOZ_NEVER_INLINE /* no support */ -#endif - -/* - * MOZ_NORETURN, specified at the start of a function declaration, indicates - * that the given function does not return. (The function definition does not - * need to be annotated.) - * - * MOZ_NORETURN void abort(const char* msg); - * - * This modifier permits the compiler to optimize code assuming a call to such a - * function will never return. It also enables the compiler to avoid spurious - * warnings about not initializing variables, or about any other seemingly-dodgy - * operations performed after the function returns. - * - * This modifier does not affect the corresponding function's linking behavior. - */ -#if defined(MOZ_HAVE_NORETURN) -# define MOZ_NORETURN MOZ_HAVE_NORETURN -#else -# define MOZ_NORETURN /* no support */ -#endif - -/** - * MOZ_COLD tells the compiler that a function is "cold", meaning infrequently - * executed. This may lead it to optimize for size more aggressively than speed, - * or to allocate the body of the function in a distant part of the text segment - * to help keep it from taking up unnecessary icache when it isn't in use. - * - * Place this attribute at the very beginning of a function definition. For - * example, write - * - * MOZ_COLD int foo(); - * - * or - * - * MOZ_COLD int foo() { return 42; } - */ -#if defined(__GNUC__) || defined(__clang__) -# define MOZ_COLD __attribute__ ((cold)) -#else -# define MOZ_COLD -#endif - -/** - * MOZ_NONNULL tells the compiler that some of the arguments to a function are - * known to be non-null. The arguments are a list of 1-based argument indexes - * identifying arguments which are known to be non-null. - * - * Place this attribute at the very beginning of a function definition. For - * example, write - * - * MOZ_NONNULL(1, 2) int foo(char *p, char *q); - */ -#if defined(__GNUC__) || defined(__clang__) -# define MOZ_NONNULL(...) __attribute__ ((nonnull(__VA_ARGS__))) -#else -# define MOZ_NONNULL(...) -#endif - -/* - * MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS, specified at the end of a function - * declaration, indicates that for the purposes of static analysis, this - * function does not return. (The function definition does not need to be - * annotated.) - * - * MOZ_ReportCrash(const char* s, const char* file, int ln) - * MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS - * - * Some static analyzers, like scan-build from clang, can use this information - * to eliminate false positives. From the upstream documentation of scan-build: - * "This attribute is useful for annotating assertion handlers that actually - * can return, but for the purpose of using the analyzer we want to pretend - * that such functions do not return." - * - */ -#if defined(MOZ_HAVE_ANALYZER_NORETURN) -# define MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS MOZ_HAVE_ANALYZER_NORETURN -#else -# define MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS /* no support */ -#endif - -/* - * MOZ_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time - * instrumentation shipped with Clang and GCC) to not instrument the annotated - * function. Furthermore, it will prevent the compiler from inlining the - * function because inlining currently breaks the blacklisting mechanism of - * AddressSanitizer. - */ -#if defined(__has_feature) -# if __has_feature(address_sanitizer) -# define MOZ_HAVE_ASAN_BLACKLIST -# endif -#elif defined(__GNUC__) -# if defined(__SANITIZE_ADDRESS__) -# define MOZ_HAVE_ASAN_BLACKLIST -# endif -#endif - -#if defined(MOZ_HAVE_ASAN_BLACKLIST) -# define MOZ_ASAN_BLACKLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_address)) -#else -# define MOZ_ASAN_BLACKLIST /* nothing */ -#endif - -/* - * MOZ_TSAN_BLACKLIST is a macro to tell ThreadSanitizer (a compile-time - * instrumentation shipped with Clang) to not instrument the annotated function. - * Furthermore, it will prevent the compiler from inlining the function because - * inlining currently breaks the blacklisting mechanism of ThreadSanitizer. - */ -#if defined(__has_feature) -# if __has_feature(thread_sanitizer) -# define MOZ_TSAN_BLACKLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_thread)) -# else -# define MOZ_TSAN_BLACKLIST /* nothing */ -# endif -#else -# define MOZ_TSAN_BLACKLIST /* nothing */ -#endif - -/** - * MOZ_ALLOCATOR tells the compiler that the function it marks returns either a - * "fresh", "pointer-free" block of memory, or nullptr. "Fresh" means that the - * block is not pointed to by any other reachable pointer in the program. - * "Pointer-free" means that the block contains no pointers to any valid object - * in the program. It may be initialized with other (non-pointer) values. - * - * Placing this attribute on appropriate functions helps GCC analyze pointer - * aliasing more accurately in their callers. - * - * GCC warns if a caller ignores the value returned by a function marked with - * MOZ_ALLOCATOR: it is hard to imagine cases where dropping the value returned - * by a function that meets the criteria above would be intentional. - * - * Place this attribute after the argument list and 'this' qualifiers of a - * function definition. For example, write - * - * void *my_allocator(size_t) MOZ_ALLOCATOR; - * - * or - * - * void *my_allocator(size_t bytes) MOZ_ALLOCATOR { ... } - */ -#if defined(__GNUC__) || defined(__clang__) -# define MOZ_ALLOCATOR __attribute__ ((malloc, warn_unused_result)) -#else -# define MOZ_ALLOCATOR -#endif - -/** - * MOZ_MUST_USE tells the compiler to emit a warning if a function's - * return value is not used by the caller. - * - * Place this attribute at the very beginning of a function declaration. For - * example, write - * - * MOZ_MUST_USE int foo(); - * - * or - * - * MOZ_MUST_USE int foo() { return 42; } - */ -#if defined(__GNUC__) || defined(__clang__) -# define MOZ_MUST_USE __attribute__ ((warn_unused_result)) -#else -# define MOZ_MUST_USE -#endif - -/** - * MOZ_FALLTHROUGH is an annotation to suppress compiler warnings about switch - * cases that fall through without a break or return statement. MOZ_FALLTHROUGH - * is only needed on cases that have code. - * - * MOZ_FALLTHROUGH_ASSERT is an annotation to suppress compiler warnings about - * switch cases that MOZ_ASSERT(false) (or its alias MOZ_ASSERT_UNREACHABLE) in - * debug builds, but intentionally fall through in release builds. See comment - * in Assertions.h for more details. - * - * switch (foo) { - * case 1: // These cases have no code. No fallthrough annotations are needed. - * case 2: - * case 3: // This case has code, so a fallthrough annotation is needed! - * foo++; - * MOZ_FALLTHROUGH; - * case 4: - * return foo; - * - * default: - * // This case asserts in debug builds, falls through in release. - * MOZ_FALLTHROUGH_ASSERT("Unexpected foo value?!"); - * case 5: - * return 5; - * } - */ -#if defined(__clang__) && __cplusplus >= 201103L - /* clang's fallthrough annotations are only available starting in C++11. */ -# define MOZ_FALLTHROUGH [[clang::fallthrough]] -#elif defined(_MSC_VER) - /* - * MSVC's __fallthrough annotations are checked by /analyze (Code Analysis): - * https://msdn.microsoft.com/en-us/library/ms235402%28VS.80%29.aspx - */ -# include -# define MOZ_FALLTHROUGH __fallthrough -#else -# define MOZ_FALLTHROUGH /* FALLTHROUGH */ -#endif - -#ifdef __cplusplus - -/* - * The following macros are attributes that support the static analysis plugin - * included with Mozilla, and will be implemented (when such support is enabled) - * as C++11 attributes. Since such attributes are legal pretty much everywhere - * and have subtly different semantics depending on their placement, the - * following is a guide on where to place the attributes. - * - * Attributes that apply to a struct or class precede the name of the class: - * (Note that this is different from the placement of final for classes!) - * - * class MOZ_CLASS_ATTRIBUTE SomeClass {}; - * - * Attributes that apply to functions follow the parentheses and const - * qualifiers but precede final, override and the function body: - * - * void DeclaredFunction() MOZ_FUNCTION_ATTRIBUTE; - * void SomeFunction() MOZ_FUNCTION_ATTRIBUTE {} - * void PureFunction() const MOZ_FUNCTION_ATTRIBUTE = 0; - * void OverriddenFunction() MOZ_FUNCTION_ATTIRBUTE override; - * - * Attributes that apply to variables or parameters follow the variable's name: - * - * int variable MOZ_VARIABLE_ATTRIBUTE; - * - * Attributes that apply to types follow the type name: - * - * typedef int MOZ_TYPE_ATTRIBUTE MagicInt; - * int MOZ_TYPE_ATTRIBUTE someVariable; - * int* MOZ_TYPE_ATTRIBUTE magicPtrInt; - * int MOZ_TYPE_ATTRIBUTE* ptrToMagicInt; - * - * Attributes that apply to statements precede the statement: - * - * MOZ_IF_ATTRIBUTE if (x == 0) - * MOZ_DO_ATTRIBUTE do { } while (0); - * - * Attributes that apply to labels precede the label: - * - * MOZ_LABEL_ATTRIBUTE target: - * goto target; - * MOZ_CASE_ATTRIBUTE case 5: - * MOZ_DEFAULT_ATTRIBUTE default: - * - * The static analyses that are performed by the plugin are as follows: - * - * MOZ_MUST_OVERRIDE: Applies to all C++ member functions. All immediate - * subclasses must provide an exact override of this method; if a subclass - * does not override this method, the compiler will emit an error. This - * attribute is not limited to virtual methods, so if it is applied to a - * nonvirtual method and the subclass does not provide an equivalent - * definition, the compiler will emit an error. - * MOZ_STACK_CLASS: Applies to all classes. Any class with this annotation is - * expected to live on the stack, so it is a compile-time error to use it, or - * an array of such objects, as a global or static variable, or as the type of - * a new expression (unless placement new is being used). If a member of - * another class uses this class, or if another class inherits from this - * class, then it is considered to be a stack class as well, although this - * attribute need not be provided in such cases. - * MOZ_NONHEAP_CLASS: Applies to all classes. Any class with this annotation is - * expected to live on the stack or in static storage, so it is a compile-time - * error to use it, or an array of such objects, as the type of a new - * expression. If a member of another class uses this class, or if another - * class inherits from this class, then it is considered to be a non-heap class - * as well, although this attribute need not be provided in such cases. - * MOZ_HEAP_CLASS: Applies to all classes. Any class with this annotation is - * expected to live on the heap, so it is a compile-time error to use it, or - * an array of such objects, as the type of a variable declaration, or as a - * temporary object. If a member of another class uses this class, or if - * another class inherits from this class, then it is considered to be a heap - * class as well, although this attribute need not be provided in such cases. - * MOZ_NON_TEMPORARY_CLASS: Applies to all classes. Any class with this - * annotation is expected not to live in a temporary. If a member of another - * class uses this class or if another class inherits from this class, then it - * is considered to be a non-temporary class as well, although this attribute - * need not be provided in such cases. - * MOZ_RAII: Applies to all classes. Any class with this annotation is assumed - * to be a RAII guard, which is expected to live on the stack in an automatic - * allocation. It is prohibited from being allocated in a temporary, static - * storage, or on the heap. This is a combination of MOZ_STACK_CLASS and - * MOZ_NON_TEMPORARY_CLASS. - * MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS: Applies to all classes that are - * intended to prevent introducing static initializers. This attribute - * currently makes it a compile-time error to instantiate these classes - * anywhere other than at the global scope, or as a static member of a class. - * In non-debug mode, it also prohibits non-trivial constructors and - * destructors. - * MOZ_TRIVIAL_CTOR_DTOR: Applies to all classes that must have both a trivial - * or constexpr constructor and a trivial destructor. Setting this attribute - * on a class makes it a compile-time error for that class to get a - * non-trivial constructor or destructor for any reason. - * MOZ_HEAP_ALLOCATOR: Applies to any function. This indicates that the return - * value is allocated on the heap, and will as a result check such allocations - * during MOZ_STACK_CLASS and MOZ_NONHEAP_CLASS annotation checking. - * MOZ_IMPLICIT: Applies to constructors. Implicit conversion constructors - * are disallowed by default unless they are marked as MOZ_IMPLICIT. This - * attribute must be used for constructors which intend to provide implicit - * conversions. - * MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT: Applies to functions. Makes it a compile - * time error to pass arithmetic expressions on variables to the function. - * MOZ_OWNING_REF: Applies to declarations of pointers to reference counted - * types. This attribute tells the compiler that the raw pointer is a strong - * reference, where ownership through methods such as AddRef and Release is - * managed manually. This can make the compiler ignore these pointers when - * validating the usage of pointers otherwise. - * - * Example uses include owned pointers inside of unions, and pointers stored - * in POD types where a using a smart pointer class would make the object - * non-POD. - * MOZ_NON_OWNING_REF: Applies to declarations of pointers to reference counted - * types. This attribute tells the compiler that the raw pointer is a weak - * reference, which is ensured to be valid by a guarantee that the reference - * will be nulled before the pointer becomes invalid. This can make the compiler - * ignore these pointers when validating the usage of pointers otherwise. - * - * Examples include an mOwner pointer, which is nulled by the owning class's - * destructor, and is null-checked before dereferencing. - * MOZ_UNSAFE_REF: Applies to declarations of pointers to reference counted types. - * Occasionally there are non-owning references which are valid, but do not take - * the form of a MOZ_NON_OWNING_REF. Their safety may be dependent on the behaviour - * of API consumers. The string argument passed to this macro documents the safety - * conditions. This can make the compiler ignore these pointers when validating - * the usage of pointers elsewhere. - * - * Examples include an nsIAtom* member which is known at compile time to point to a - * static atom which is valid throughout the lifetime of the program, or an API which - * stores a pointer, but doesn't take ownership over it, instead requiring the API - * consumer to correctly null the value before it becomes invalid. - * - * Use of this annotation is discouraged when a strong reference or one of the above - * two annotations can be used instead. - * MOZ_NO_ADDREF_RELEASE_ON_RETURN: Applies to function declarations. Makes it - * a compile time error to call AddRef or Release on the return value of a - * function. This is intended to be used with operator->() of our smart - * pointer classes to ensure that the refcount of an object wrapped in a - * smart pointer is not manipulated directly. - * MOZ_MUST_USE_TYPE: Applies to type declarations. Makes it a compile time - * error to not use the return value of a function which has this type. This - * is intended to be used with types which it is an error to not use. - * MOZ_NEEDS_NO_VTABLE_TYPE: Applies to template class declarations. Makes it - * a compile time error to instantiate this template with a type parameter which - * has a VTable. - * MOZ_NON_MEMMOVABLE: Applies to class declarations for types that are not safe - * to be moved in memory using memmove(). - * MOZ_NEEDS_MEMMOVABLE_TYPE: Applies to template class declarations where the - * template arguments are required to be safe to move in memory using - * memmove(). Passing MOZ_NON_MEMMOVABLE types to these templates is a - * compile time error. - * MOZ_NEEDS_MEMMOVABLE_MEMBERS: Applies to class declarations where each member - * must be safe to move in memory using memmove(). MOZ_NON_MEMMOVABLE types - * used in members of these classes are compile time errors. - * MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS: Applies to template class - * declarations where an instance of the template should be considered, for - * static analysis purposes, to inherit any type annotations (such as - * MOZ_MUST_USE_TYPE and MOZ_STACK_CLASS) from its template arguments. - * MOZ_INIT_OUTSIDE_CTOR: Applies to class member declarations. Occasionally - * there are class members that are not initialized in the constructor, - * but logic elsewhere in the class ensures they are initialized prior to use. - * Using this attribute on a member disables the check that this member must be - * initialized in constructors via list-initialization, in the constructor body, - * or via functions called from the constructor body. - * MOZ_IS_CLASS_INIT: Applies to class method declarations. Occasionally the - * constructor doesn't initialize all of the member variables and another function - * is used to initialize the rest. This marker is used to make the static analysis - * tool aware that the marked function is part of the initialization process - * and to include the marked function in the scan mechanism that determines witch - * member variables still remain uninitialized. - * MOZ_NON_PARAM: Applies to types. Makes it compile time error to use the type - * in parameter without pointer or reference. - * MOZ_NON_AUTOABLE: Applies to class declarations. Makes it a compile time error to - * use `auto` in place of this type in variable declarations. This is intended to - * be used with types which are intended to be implicitly constructed into other - * other types before being assigned to variables. - * MOZ_REQUIRED_BASE_METHOD: Applies to virtual class method declarations. - * Sometimes derived classes override methods that need to be called by their - * overridden counterparts. This marker indicates that the marked method must - * be called by the method that it overrides. - */ -#ifdef MOZ_CLANG_PLUGIN -# define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override"))) -# define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class"))) -# define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class"))) -# define MOZ_HEAP_CLASS __attribute__((annotate("moz_heap_class"))) -# define MOZ_NON_TEMPORARY_CLASS __attribute__((annotate("moz_non_temporary_class"))) -# define MOZ_TRIVIAL_CTOR_DTOR __attribute__((annotate("moz_trivial_ctor_dtor"))) -# ifdef DEBUG - /* in debug builds, these classes do have non-trivial constructors. */ -# define MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS __attribute__((annotate("moz_global_class"))) -# else -# define MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS __attribute__((annotate("moz_global_class"))) \ - MOZ_TRIVIAL_CTOR_DTOR -# endif -# define MOZ_IMPLICIT __attribute__((annotate("moz_implicit"))) -# define MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT __attribute__((annotate("moz_no_arith_expr_in_arg"))) -# define MOZ_OWNING_REF __attribute__((annotate("moz_strong_ref"))) -# define MOZ_NON_OWNING_REF __attribute__((annotate("moz_weak_ref"))) -# define MOZ_UNSAFE_REF(reason) __attribute__((annotate("moz_weak_ref"))) -# define MOZ_NO_ADDREF_RELEASE_ON_RETURN __attribute__((annotate("moz_no_addref_release_on_return"))) -# define MOZ_MUST_USE_TYPE __attribute__((annotate("moz_must_use_type"))) -# define MOZ_NEEDS_NO_VTABLE_TYPE __attribute__((annotate("moz_needs_no_vtable_type"))) -# define MOZ_NON_MEMMOVABLE __attribute__((annotate("moz_non_memmovable"))) -# define MOZ_NEEDS_MEMMOVABLE_TYPE __attribute__((annotate("moz_needs_memmovable_type"))) -# define MOZ_NEEDS_MEMMOVABLE_MEMBERS __attribute__((annotate("moz_needs_memmovable_members"))) -# define MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS \ - __attribute__((annotate("moz_inherit_type_annotations_from_template_args"))) -# define MOZ_NON_AUTOABLE __attribute__((annotate("moz_non_autoable"))) -# define MOZ_INIT_OUTSIDE_CTOR \ - __attribute__((annotate("moz_ignore_ctor_initialization"))) -# define MOZ_IS_CLASS_INIT \ - __attribute__((annotate("moz_is_class_init"))) -# define MOZ_NON_PARAM \ - __attribute__((annotate("moz_non_param"))) -# define MOZ_REQUIRED_BASE_METHOD \ - __attribute__((annotate("moz_required_base_method"))) -/* - * It turns out that clang doesn't like void func() __attribute__ {} without a - * warning, so use pragmas to disable the warning. This code won't work on GCC - * anyways, so the warning is safe to ignore. - */ -# define MOZ_HEAP_ALLOCATOR \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((annotate("moz_heap_allocator"))) \ - _Pragma("clang diagnostic pop") -#else -# define MOZ_MUST_OVERRIDE /* nothing */ -# define MOZ_STACK_CLASS /* nothing */ -# define MOZ_NONHEAP_CLASS /* nothing */ -# define MOZ_HEAP_CLASS /* nothing */ -# define MOZ_NON_TEMPORARY_CLASS /* nothing */ -# define MOZ_TRIVIAL_CTOR_DTOR /* nothing */ -# define MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS /* nothing */ -# define MOZ_IMPLICIT /* nothing */ -# define MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT /* nothing */ -# define MOZ_HEAP_ALLOCATOR /* nothing */ -# define MOZ_OWNING_REF /* nothing */ -# define MOZ_NON_OWNING_REF /* nothing */ -# define MOZ_UNSAFE_REF(reason) /* nothing */ -# define MOZ_NO_ADDREF_RELEASE_ON_RETURN /* nothing */ -# define MOZ_MUST_USE_TYPE /* nothing */ -# define MOZ_NEEDS_NO_VTABLE_TYPE /* nothing */ -# define MOZ_NON_MEMMOVABLE /* nothing */ -# define MOZ_NEEDS_MEMMOVABLE_TYPE /* nothing */ -# define MOZ_NEEDS_MEMMOVABLE_MEMBERS /* nothing */ -# define MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS /* nothing */ -# define MOZ_INIT_OUTSIDE_CTOR /* nothing */ -# define MOZ_IS_CLASS_INIT /* nothing */ -# define MOZ_NON_PARAM /* nothing */ -# define MOZ_NON_AUTOABLE /* nothing */ -# define MOZ_REQUIRED_BASE_METHOD /* nothing */ -#endif /* MOZ_CLANG_PLUGIN */ - -#define MOZ_RAII MOZ_NON_TEMPORARY_CLASS MOZ_STACK_CLASS - -/* - * MOZ_HAVE_REF_QUALIFIERS is defined for compilers that support C++11's rvalue - * qualifier, "&&". - */ -#if defined(_MSC_VER) && _MSC_VER >= 1900 -# define MOZ_HAVE_REF_QUALIFIERS -#elif defined(__clang__) -// All supported Clang versions -# define MOZ_HAVE_REF_QUALIFIERS -#elif defined(__GNUC__) -# include "mozilla/Compiler.h" -# if MOZ_GCC_VERSION_AT_LEAST(4, 8, 1) -# define MOZ_HAVE_REF_QUALIFIERS -# endif -#endif - -#endif /* __cplusplus */ - -/** - * Printf style formats. MOZ_FORMAT_PRINTF can be used to annotate a - * function or method that is "printf-like"; this will let (some) - * compilers check that the arguments match the template string. - * - * This macro takes two arguments. The first argument is the argument - * number of the template string. The second argument is the argument - * number of the '...' argument holding the arguments. - * - * Argument numbers start at 1. Note that the implicit "this" - * argument of a non-static member function counts as an argument. - * - * So, for a simple case like: - * void print_something (int whatever, const char *fmt, ...); - * The corresponding annotation would be - * MOZ_FORMAT_PRINTF(2, 3) - * However, if "print_something" were a non-static member function, - * then the annotation would be: - * MOZ_FORMAT_PRINTF(3, 4) - * - * Note that the checking is limited to standards-conforming - * printf-likes, and in particular this should not be used for - * PR_snprintf and friends, which are "printf-like" but which assign - * different meanings to the various formats. - */ -#ifdef __GNUC__ -#define MOZ_FORMAT_PRINTF(stringIndex, firstToCheck) \ - __attribute__ ((format (printf, stringIndex, firstToCheck))) -#else -#define MOZ_FORMAT_PRINTF(stringIndex, firstToCheck) -#endif - -#endif /* mozilla_Attributes_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/BinarySearch.h b/android/arm64-v8a/include/spidermonkey/mozilla/BinarySearch.h deleted file mode 100644 index 1bbe0566..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/BinarySearch.h +++ /dev/null @@ -1,139 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_BinarySearch_h -#define mozilla_BinarySearch_h - -#include "mozilla/Assertions.h" - -#include - -namespace mozilla { - -/* - * The BinarySearch() algorithm searches the given container |aContainer| over - * the sorted index range [aBegin, aEnd) for an index |i| where - * |aContainer[i] == aTarget|. - * If such an index |i| is found, BinarySearch returns |true| and the index is - * returned via the outparam |aMatchOrInsertionPoint|. If no index is found, - * BinarySearch returns |false| and the outparam returns the first index in - * [aBegin, aEnd] where |aTarget| can be inserted to maintain sorted order. - * - * Example: - * - * Vector sortedInts = ... - * - * size_t match; - * if (BinarySearch(sortedInts, 0, sortedInts.length(), 13, &match)) { - * printf("found 13 at %lu\n", match); - * } - * - * The BinarySearchIf() version behaves similarly, but takes |aComparator|, a - * functor to compare the values with, instead of a value to find. - * That functor should take one argument - the value to compare - and return an - * |int| with the comparison result: - * - * * 0, if the argument is equal to, - * * less than 0, if the argument is greater than, - * * greater than 0, if the argument is less than - * - * the value. - * - * Example: - * - * struct Comparator { - * int operator()(int aVal) const { - * if (mTarget < aVal) { return -1; } - * if (mTarget > aVal) { return 1; } - * return 0; - * } - * explicit Comparator(int aTarget) : mTarget(aTarget) {} - * const int mTarget; - * }; - * - * Vector sortedInts = ... - * - * size_t match; - * if (BinarySearchIf(sortedInts, 0, sortedInts.length(), Comparator(13), &match)) { - * printf("found 13 at %lu\n", match); - * } - * - */ - -template -bool -BinarySearchIf(const Container& aContainer, size_t aBegin, size_t aEnd, - const Comparator& aCompare, size_t* aMatchOrInsertionPoint) -{ - MOZ_ASSERT(aBegin <= aEnd); - - size_t low = aBegin; - size_t high = aEnd; - while (high != low) { - size_t middle = low + (high - low) / 2; - - // Allow any intermediate type so long as it provides a suitable ordering - // relation. - const int result = aCompare(aContainer[middle]); - - if (result == 0) { - *aMatchOrInsertionPoint = middle; - return true; - } - - if (result < 0) { - high = middle; - } else { - low = middle + 1; - } - } - - *aMatchOrInsertionPoint = low; - return false; -} - -namespace detail { - -template -class BinarySearchDefaultComparator -{ -public: - explicit BinarySearchDefaultComparator(const T& aTarget) - : mTarget(aTarget) - {} - - template - int operator()(const U& aVal) const { - if (mTarget == aVal) { - return 0; - } - - if (mTarget < aVal) { - return -1; - } - - return 1; - } - -private: - const T& mTarget; -}; - -} // namespace detail - -template -bool -BinarySearch(const Container& aContainer, size_t aBegin, size_t aEnd, - T aTarget, size_t* aMatchOrInsertionPoint) -{ - return BinarySearchIf(aContainer, aBegin, aEnd, - detail::BinarySearchDefaultComparator(aTarget), - aMatchOrInsertionPoint); -} - -} // namespace mozilla - -#endif // mozilla_BinarySearch_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/BloomFilter.h b/android/arm64-v8a/include/spidermonkey/mozilla/BloomFilter.h deleted file mode 100644 index 6757e411..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/BloomFilter.h +++ /dev/null @@ -1,256 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * A counting Bloom filter implementation. This allows consumers to - * do fast probabilistic "is item X in set Y?" testing which will - * never answer "no" when the correct answer is "yes" (but might - * incorrectly answer "yes" when the correct answer is "no"). - */ - -#ifndef mozilla_BloomFilter_h -#define mozilla_BloomFilter_h - -#include "mozilla/Assertions.h" -#include "mozilla/Likely.h" - -#include -#include - -namespace mozilla { - -/* - * This class implements a counting Bloom filter as described at - * , with - * 8-bit counters. This allows quick probabilistic answers to the - * question "is object X in set Y?" where the contents of Y might not - * be time-invariant. The probabilistic nature of the test means that - * sometimes the answer will be "yes" when it should be "no". If the - * answer is "no", then X is guaranteed not to be in Y. - * - * The filter is parametrized on KeySize, which is the size of the key - * generated by each of hash functions used by the filter, in bits, - * and the type of object T being added and removed. T must implement - * a |uint32_t hash() const| method which returns a uint32_t hash key - * that will be used to generate the two separate hash functions for - * the Bloom filter. This hash key MUST be well-distributed for good - * results! KeySize is not allowed to be larger than 16. - * - * The filter uses exactly 2**KeySize bytes of memory. From now on we - * will refer to the memory used by the filter as M. - * - * The expected rate of incorrect "yes" answers depends on M and on - * the number N of objects in set Y. As long as N is small compared - * to M, the rate of such answers is expected to be approximately - * 4*(N/M)**2 for this filter. In practice, if Y has a few hundred - * elements then using a KeySize of 12 gives a reasonably low - * incorrect answer rate. A KeySize of 12 has the additional benefit - * of using exactly one page for the filter in typical hardware - * configurations. - */ - -template -class BloomFilter -{ - /* - * A counting Bloom filter with 8-bit counters. For now we assume - * that having two hash functions is enough, but we may revisit that - * decision later. - * - * The filter uses an array with 2**KeySize entries. - * - * Assuming a well-distributed hash function, a Bloom filter with - * array size M containing N elements and - * using k hash function has expected false positive rate exactly - * - * $ (1 - (1 - 1/M)^{kN})^k $ - * - * because each array slot has a - * - * $ (1 - 1/M)^{kN} $ - * - * chance of being 0, and the expected false positive rate is the - * probability that all of the k hash functions will hit a nonzero - * slot. - * - * For reasonable assumptions (M large, kN large, which should both - * hold if we're worried about false positives) about M and kN this - * becomes approximately - * - * $$ (1 - \exp(-kN/M))^k $$ - * - * For our special case of k == 2, that's $(1 - \exp(-2N/M))^2$, - * or in other words - * - * $$ N/M = -0.5 * \ln(1 - \sqrt(r)) $$ - * - * where r is the false positive rate. This can be used to compute - * the desired KeySize for a given load N and false positive rate r. - * - * If N/M is assumed small, then the false positive rate can - * further be approximated as 4*N^2/M^2. So increasing KeySize by - * 1, which doubles M, reduces the false positive rate by about a - * factor of 4, and a false positive rate of 1% corresponds to - * about M/N == 20. - * - * What this means in practice is that for a few hundred keys using a - * KeySize of 12 gives false positive rates on the order of 0.25-4%. - * - * Similarly, using a KeySize of 10 would lead to a 4% false - * positive rate for N == 100 and to quite bad false positive - * rates for larger N. - */ -public: - BloomFilter() - { - static_assert(KeySize <= kKeyShift, "KeySize too big"); - - // Should we have a custom operator new using calloc instead and - // require that we're allocated via the operator? - clear(); - } - - /* - * Clear the filter. This should be done before reusing it, because - * just removing all items doesn't clear counters that hit the upper - * bound. - */ - void clear(); - - /* - * Add an item to the filter. - */ - void add(const T* aValue); - - /* - * Remove an item from the filter. - */ - void remove(const T* aValue); - - /* - * Check whether the filter might contain an item. This can - * sometimes return true even if the item is not in the filter, - * but will never return false for items that are actually in the - * filter. - */ - bool mightContain(const T* aValue) const; - - /* - * Methods for add/remove/contain when we already have a hash computed - */ - void add(uint32_t aHash); - void remove(uint32_t aHash); - bool mightContain(uint32_t aHash) const; - -private: - static const size_t kArraySize = (1 << KeySize); - static const uint32_t kKeyMask = (1 << KeySize) - 1; - static const uint32_t kKeyShift = 16; - - static uint32_t hash1(uint32_t aHash) - { - return aHash & kKeyMask; - } - static uint32_t hash2(uint32_t aHash) - { - return (aHash >> kKeyShift) & kKeyMask; - } - - uint8_t& firstSlot(uint32_t aHash) - { - return mCounters[hash1(aHash)]; - } - uint8_t& secondSlot(uint32_t aHash) - { - return mCounters[hash2(aHash)]; - } - - const uint8_t& firstSlot(uint32_t aHash) const - { - return mCounters[hash1(aHash)]; - } - const uint8_t& secondSlot(uint32_t aHash) const - { - return mCounters[hash2(aHash)]; - } - - static bool full(const uint8_t& aSlot) { return aSlot == UINT8_MAX; } - - uint8_t mCounters[kArraySize]; -}; - -template -inline void -BloomFilter::clear() -{ - memset(mCounters, 0, kArraySize); -} - -template -inline void -BloomFilter::add(uint32_t aHash) -{ - uint8_t& slot1 = firstSlot(aHash); - if (MOZ_LIKELY(!full(slot1))) { - ++slot1; - } - uint8_t& slot2 = secondSlot(aHash); - if (MOZ_LIKELY(!full(slot2))) { - ++slot2; - } -} - -template -MOZ_ALWAYS_INLINE void -BloomFilter::add(const T* aValue) -{ - uint32_t hash = aValue->hash(); - return add(hash); -} - -template -inline void -BloomFilter::remove(uint32_t aHash) -{ - // If the slots are full, we don't know whether we bumped them to be - // there when we added or not, so just leave them full. - uint8_t& slot1 = firstSlot(aHash); - if (MOZ_LIKELY(!full(slot1))) { - --slot1; - } - uint8_t& slot2 = secondSlot(aHash); - if (MOZ_LIKELY(!full(slot2))) { - --slot2; - } -} - -template -MOZ_ALWAYS_INLINE void -BloomFilter::remove(const T* aValue) -{ - uint32_t hash = aValue->hash(); - remove(hash); -} - -template -MOZ_ALWAYS_INLINE bool -BloomFilter::mightContain(uint32_t aHash) const -{ - // Check that all the slots for this hash contain something - return firstSlot(aHash) && secondSlot(aHash); -} - -template -MOZ_ALWAYS_INLINE bool -BloomFilter::mightContain(const T* aValue) const -{ - uint32_t hash = aValue->hash(); - return mightContain(hash); -} - -} // namespace mozilla - -#endif /* mozilla_BloomFilter_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/BufferList.h b/android/arm64-v8a/include/spidermonkey/mozilla/BufferList.h deleted file mode 100644 index 42aea12d..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/BufferList.h +++ /dev/null @@ -1,517 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_BufferList_h -#define mozilla_BufferList_h - -#include -#include "mozilla/AllocPolicy.h" -#include "mozilla/Move.h" -#include "mozilla/ScopeExit.h" -#include "mozilla/Types.h" -#include "mozilla/TypeTraits.h" -#include "mozilla/Vector.h" -#include - -// BufferList represents a sequence of buffers of data. A BufferList can choose -// to own its buffers or not. The class handles writing to the buffers, -// iterating over them, and reading data out. Unlike SegmentedVector, the -// buffers may be of unequal size. Like SegmentedVector, BufferList is a nice -// way to avoid large contiguous allocations (which can trigger OOMs). - -namespace mozilla { - -template -class BufferList : private AllocPolicy -{ - // Each buffer in a BufferList has a size and a capacity. The first mSize - // bytes are initialized and the remaining |mCapacity - mSize| bytes are free. - struct Segment - { - char* mData; - size_t mSize; - size_t mCapacity; - - Segment(char* aData, size_t aSize, size_t aCapacity) - : mData(aData), - mSize(aSize), - mCapacity(aCapacity) - { - } - - Segment(const Segment&) = delete; - Segment& operator=(const Segment&) = delete; - - Segment(Segment&&) = default; - Segment& operator=(Segment&&) = default; - - char* Start() const { return mData; } - char* End() const { return mData + mSize; } - }; - - template - friend class BufferList; - - public: - // For the convenience of callers, all segments are required to be a multiple - // of 8 bytes in capacity. Also, every buffer except the last one is required - // to be full (i.e., size == capacity). Therefore, a byte at offset N within - // the BufferList and stored in memory at an address A will satisfy - // (N % Align == A % Align) if Align == 2, 4, or 8. - static const size_t kSegmentAlignment = 8; - - // Allocate a BufferList. The BufferList will free all its buffers when it is - // destroyed. An initial buffer of size aInitialSize and capacity - // aInitialCapacity is allocated automatically. This data will be contiguous - // an can be accessed via |Start()|. Subsequent buffers will be allocated with - // capacity aStandardCapacity. - BufferList(size_t aInitialSize, - size_t aInitialCapacity, - size_t aStandardCapacity, - AllocPolicy aAP = AllocPolicy()) - : AllocPolicy(aAP), - mOwning(true), - mSegments(aAP), - mSize(0), - mStandardCapacity(aStandardCapacity) - { - MOZ_ASSERT(aInitialCapacity % kSegmentAlignment == 0); - MOZ_ASSERT(aStandardCapacity % kSegmentAlignment == 0); - - if (aInitialCapacity) { - AllocateSegment(aInitialSize, aInitialCapacity); - } - } - - BufferList(const BufferList& aOther) = delete; - - BufferList(BufferList&& aOther) - : mOwning(aOther.mOwning), - mSegments(Move(aOther.mSegments)), - mSize(aOther.mSize), - mStandardCapacity(aOther.mStandardCapacity) - { - aOther.mSegments.clear(); - aOther.mSize = 0; - } - - BufferList& operator=(const BufferList& aOther) = delete; - - BufferList& operator=(BufferList&& aOther) - { - Clear(); - - mOwning = aOther.mOwning; - mSegments = Move(aOther.mSegments); - mSize = aOther.mSize; - aOther.mSegments.clear(); - aOther.mSize = 0; - return *this; - } - - ~BufferList() { Clear(); } - - // Returns the sum of the sizes of all the buffers. - size_t Size() const { return mSize; } - - void Clear() - { - if (mOwning) { - for (Segment& segment : mSegments) { - this->free_(segment.mData); - } - } - mSegments.clear(); - - mSize = 0; - } - - // Iterates over bytes in the segments. You can advance it by as many bytes as - // you choose. - class IterImpl - { - // Invariants: - // (0) mSegment <= bufferList.mSegments.size() - // (1) mData <= mDataEnd - // (2) If mSegment is not the last segment, mData < mDataEnd - uintptr_t mSegment; - char* mData; - char* mDataEnd; - - friend class BufferList; - - public: - explicit IterImpl(const BufferList& aBuffers) - : mSegment(0), - mData(nullptr), - mDataEnd(nullptr) - { - if (!aBuffers.mSegments.empty()) { - mData = aBuffers.mSegments[0].Start(); - mDataEnd = aBuffers.mSegments[0].End(); - } - } - - // Returns a pointer to the raw data. It is valid to access up to - // RemainingInSegment bytes of this buffer. - char* Data() const - { - MOZ_RELEASE_ASSERT(!Done()); - return mData; - } - - // Returns true if the memory in the range [Data(), Data() + aBytes) is all - // part of one contiguous buffer. - bool HasRoomFor(size_t aBytes) const - { - MOZ_RELEASE_ASSERT(mData <= mDataEnd); - return size_t(mDataEnd - mData) >= aBytes; - } - - // Returns the maximum value aBytes for which HasRoomFor(aBytes) will be - // true. - size_t RemainingInSegment() const - { - MOZ_RELEASE_ASSERT(mData <= mDataEnd); - return mDataEnd - mData; - } - - // Advances the iterator by aBytes bytes. aBytes must be less than - // RemainingInSegment(). If advancing by aBytes takes the iterator to the - // end of a buffer, it will be moved to the beginning of the next buffer - // unless it is the last buffer. - void Advance(const BufferList& aBuffers, size_t aBytes) - { - const Segment& segment = aBuffers.mSegments[mSegment]; - MOZ_RELEASE_ASSERT(segment.Start() <= mData); - MOZ_RELEASE_ASSERT(mData <= mDataEnd); - MOZ_RELEASE_ASSERT(mDataEnd == segment.End()); - - MOZ_RELEASE_ASSERT(HasRoomFor(aBytes)); - mData += aBytes; - - if (mData == mDataEnd && mSegment + 1 < aBuffers.mSegments.length()) { - mSegment++; - const Segment& nextSegment = aBuffers.mSegments[mSegment]; - mData = nextSegment.Start(); - mDataEnd = nextSegment.End(); - MOZ_RELEASE_ASSERT(mData < mDataEnd); - } - } - - // Advance the iterator by aBytes, possibly crossing segments. This function - // returns false if it runs out of buffers to advance through. Otherwise it - // returns true. - bool AdvanceAcrossSegments(const BufferList& aBuffers, size_t aBytes) - { - size_t bytes = aBytes; - while (bytes) { - size_t toAdvance = std::min(bytes, RemainingInSegment()); - if (!toAdvance) { - return false; - } - Advance(aBuffers, toAdvance); - bytes -= toAdvance; - } - return true; - } - - // Returns true when the iterator reaches the end of the BufferList. - bool Done() const - { - return mData == mDataEnd; - } - - private: - - // Count the bytes we would need to advance in order to reach aTarget. - size_t BytesUntil(const BufferList& aBuffers, const IterImpl& aTarget) const { - size_t offset = 0; - - MOZ_ASSERT(aTarget.IsIn(aBuffers)); - - char* data = mData; - for (uintptr_t segment = mSegment; segment < aTarget.mSegment; segment++) { - offset += aBuffers.mSegments[segment].End() - data; - data = aBuffers.mSegments[segment].mData; - } - - MOZ_RELEASE_ASSERT(IsIn(aBuffers)); - MOZ_RELEASE_ASSERT(aTarget.mData >= data); - - offset += aTarget.mData - data; - return offset; - } - - bool IsIn(const BufferList& aBuffers) const { - return mSegment < aBuffers.mSegments.length() && - mData >= aBuffers.mSegments[mSegment].mData && - mData < aBuffers.mSegments[mSegment].End(); - } - }; - - // Special convenience method that returns Iter().Data(). - char* Start() { return mSegments[0].mData; } - const char* Start() const { return mSegments[0].mData; } - - IterImpl Iter() const { return IterImpl(*this); } - - // Copies aSize bytes from aData into the BufferList. The storage for these - // bytes may be split across multiple buffers. Size() is increased by aSize. - inline bool WriteBytes(const char* aData, size_t aSize); - - // Copies possibly non-contiguous byte range starting at aIter into - // aData. aIter is advanced by aSize bytes. Returns false if it runs out of - // data before aSize. - inline bool ReadBytes(IterImpl& aIter, char* aData, size_t aSize) const; - - // Return a new BufferList that shares storage with this BufferList. The new - // BufferList is read-only. It allows iteration over aSize bytes starting at - // aIter. Borrow can fail, in which case *aSuccess will be false upon - // return. The borrowed BufferList can use a different AllocPolicy than the - // original one. However, it is not responsible for freeing buffers, so the - // AllocPolicy is only used for the buffer vector. - template - BufferList Borrow(IterImpl& aIter, size_t aSize, bool* aSuccess, - BorrowingAllocPolicy aAP = BorrowingAllocPolicy()) const; - - // Return a new BufferList and move storage from this BufferList to it. The - // new BufferList owns the buffers. Move can fail, in which case *aSuccess - // will be false upon return. The new BufferList can use a different - // AllocPolicy than the original one. The new OtherAllocPolicy is responsible - // for freeing buffers, so the OtherAllocPolicy must use freeing method - // compatible to the original one. - template - BufferList MoveFallible(bool* aSuccess, OtherAllocPolicy aAP = OtherAllocPolicy()); - - // Return a new BufferList that adopts the byte range starting at Iter so that - // range [aIter, aIter + aSize) is transplanted to the returned BufferList. - // Contents of the buffer before aIter + aSize is left undefined. - // Extract can fail, in which case *aSuccess will be false upon return. The - // moved buffers are erased from the original BufferList. In case of extract - // fails, the original BufferList is intact. All other iterators except aIter - // are invalidated. - // This method requires aIter and aSize to be 8-byte aligned. - BufferList Extract(IterImpl& aIter, size_t aSize, bool* aSuccess); - - // Return the number of bytes from 'start' to 'end', two iterators within - // this BufferList. - size_t RangeLength(const IterImpl& start, const IterImpl& end) const { - MOZ_ASSERT(start.IsIn(*this) && end.IsIn(*this)); - return start.BytesUntil(*this, end); - } - -private: - explicit BufferList(AllocPolicy aAP) - : AllocPolicy(aAP), - mOwning(false), - mSize(0), - mStandardCapacity(0) - { - } - - void* AllocateSegment(size_t aSize, size_t aCapacity) - { - MOZ_RELEASE_ASSERT(mOwning); - - char* data = this->template pod_malloc(aCapacity); - if (!data) { - return nullptr; - } - if (!mSegments.append(Segment(data, aSize, aCapacity))) { - this->free_(data); - return nullptr; - } - mSize += aSize; - return data; - } - - bool mOwning; - Vector mSegments; - size_t mSize; - size_t mStandardCapacity; -}; - -template -bool -BufferList::WriteBytes(const char* aData, size_t aSize) -{ - MOZ_RELEASE_ASSERT(mOwning); - MOZ_RELEASE_ASSERT(mStandardCapacity); - - size_t copied = 0; - size_t remaining = aSize; - - if (!mSegments.empty()) { - Segment& lastSegment = mSegments.back(); - - size_t toCopy = std::min(aSize, lastSegment.mCapacity - lastSegment.mSize); - memcpy(lastSegment.mData + lastSegment.mSize, aData, toCopy); - lastSegment.mSize += toCopy; - mSize += toCopy; - - copied += toCopy; - remaining -= toCopy; - } - - while (remaining) { - size_t toCopy = std::min(remaining, mStandardCapacity); - - void* data = AllocateSegment(toCopy, mStandardCapacity); - if (!data) { - return false; - } - memcpy(data, aData + copied, toCopy); - - copied += toCopy; - remaining -= toCopy; - } - - return true; -} - -template -bool -BufferList::ReadBytes(IterImpl& aIter, char* aData, size_t aSize) const -{ - size_t copied = 0; - size_t remaining = aSize; - while (remaining) { - size_t toCopy = std::min(aIter.RemainingInSegment(), remaining); - if (!toCopy) { - // We've run out of data in the last segment. - return false; - } - memcpy(aData + copied, aIter.Data(), toCopy); - copied += toCopy; - remaining -= toCopy; - - aIter.Advance(*this, toCopy); - } - - return true; -} - -template template -BufferList -BufferList::Borrow(IterImpl& aIter, size_t aSize, bool* aSuccess, - BorrowingAllocPolicy aAP) const -{ - BufferList result(aAP); - - size_t size = aSize; - while (size) { - size_t toAdvance = std::min(size, aIter.RemainingInSegment()); - - if (!toAdvance || !result.mSegments.append(typename BufferList::Segment(aIter.mData, toAdvance, toAdvance))) { - *aSuccess = false; - return result; - } - aIter.Advance(*this, toAdvance); - size -= toAdvance; - } - - result.mSize = aSize; - *aSuccess = true; - return result; -} - -template template -BufferList -BufferList::MoveFallible(bool* aSuccess, OtherAllocPolicy aAP) -{ - BufferList result(0, 0, mStandardCapacity, aAP); - - IterImpl iter = Iter(); - while (!iter.Done()) { - size_t toAdvance = iter.RemainingInSegment(); - - if (!toAdvance || !result.mSegments.append(typename BufferList::Segment(iter.mData, toAdvance, toAdvance))) { - *aSuccess = false; - result.mSegments.clear(); - return result; - } - iter.Advance(*this, toAdvance); - } - - result.mSize = mSize; - mSegments.clear(); - mSize = 0; - *aSuccess = true; - return result; -} - -template -BufferList -BufferList::Extract(IterImpl& aIter, size_t aSize, bool* aSuccess) -{ - MOZ_RELEASE_ASSERT(aSize); - MOZ_RELEASE_ASSERT(mOwning); - MOZ_ASSERT(aSize % kSegmentAlignment == 0); - MOZ_ASSERT(intptr_t(aIter.mData) % kSegmentAlignment == 0); - - IterImpl iter = aIter; - size_t size = aSize; - size_t toCopy = std::min(size, aIter.RemainingInSegment()); - MOZ_ASSERT(toCopy % kSegmentAlignment == 0); - - BufferList result(0, toCopy, mStandardCapacity); - BufferList error(0, 0, mStandardCapacity); - - // Copy the head - if (!result.WriteBytes(aIter.mData, toCopy)) { - *aSuccess = false; - return error; - } - iter.Advance(*this, toCopy); - size -= toCopy; - - // Move segments to result - auto resultGuard = MakeScopeExit([&] { - *aSuccess = false; - result.mSegments.erase(result.mSegments.begin()+1, result.mSegments.end()); - }); - - size_t movedSize = 0; - uintptr_t toRemoveStart = iter.mSegment; - uintptr_t toRemoveEnd = iter.mSegment; - while (!iter.Done() && - !iter.HasRoomFor(size)) { - if (!result.mSegments.append(Segment(mSegments[iter.mSegment].mData, - mSegments[iter.mSegment].mSize, - mSegments[iter.mSegment].mCapacity))) { - return error; - } - movedSize += iter.RemainingInSegment(); - size -= iter.RemainingInSegment(); - toRemoveEnd++; - iter.Advance(*this, iter.RemainingInSegment()); - } - - if (size) { - if (!iter.HasRoomFor(size) || - !result.WriteBytes(iter.Data(), size)) { - return error; - } - iter.Advance(*this, size); - } - - mSegments.erase(mSegments.begin() + toRemoveStart, mSegments.begin() + toRemoveEnd); - mSize -= movedSize; - aIter.mSegment = iter.mSegment - (toRemoveEnd - toRemoveStart); - aIter.mData = iter.mData; - aIter.mDataEnd = iter.mDataEnd; - MOZ_ASSERT(aIter.mDataEnd == mSegments[aIter.mSegment].End()); - result.mSize = aSize; - - resultGuard.release(); - *aSuccess = true; - return result; -} - -} // namespace mozilla - -#endif /* mozilla_BufferList_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Casting.h b/android/arm64-v8a/include/spidermonkey/mozilla/Casting.h deleted file mode 100644 index a7d0fb50..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Casting.h +++ /dev/null @@ -1,243 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Cast operations to supplement the built-in casting operations. */ - -#ifndef mozilla_Casting_h -#define mozilla_Casting_h - -#include "mozilla/Assertions.h" -#include "mozilla/TypeTraits.h" - -#include - -namespace mozilla { - -/** - * Sets the outparam value of type |To| with the same underlying bit pattern of - * |aFrom|. - * - * |To| and |From| must be types of the same size; be careful of cross-platform - * size differences, or this might fail to compile on some but not all - * platforms. - * - * There is also a variant that returns the value directly. In most cases, the - * two variants should be identical. However, in the specific case of x86 - * chips, the behavior differs: returning floating-point values directly is done - * through the x87 stack, and x87 loads and stores turn signaling NaNs into - * quiet NaNs... silently. Returning floating-point values via outparam, - * however, is done entirely within the SSE registers when SSE2 floating-point - * is enabled in the compiler, which has semantics-preserving behavior you would - * expect. - * - * If preserving the distinction between signaling NaNs and quiet NaNs is - * important to you, you should use the outparam version. In all other cases, - * you should use the direct return version. - */ -template -inline void -BitwiseCast(const From aFrom, To* aResult) -{ - static_assert(sizeof(From) == sizeof(To), - "To and From must have the same size"); - union - { - From mFrom; - To mTo; - } u; - u.mFrom = aFrom; - *aResult = u.mTo; -} - -template -inline To -BitwiseCast(const From aFrom) -{ - To temp; - BitwiseCast(aFrom, &temp); - return temp; -} - -namespace detail { - -enum ToSignedness { ToIsSigned, ToIsUnsigned }; -enum FromSignedness { FromIsSigned, FromIsUnsigned }; - -template::value ? FromIsSigned : FromIsUnsigned, - ToSignedness = IsSigned::value ? ToIsSigned : ToIsUnsigned> -struct BoundsCheckImpl; - -// Implicit conversions on operands to binary operations make this all a bit -// hard to verify. Attempt to ease the pain below by *only* comparing values -// that are obviously the same type (and will undergo no further conversions), -// even when it's not strictly necessary, for explicitness. - -enum UUComparison { FromIsBigger, FromIsNotBigger }; - -// Unsigned-to-unsigned range check - -template sizeof(To)) - ? FromIsBigger - : FromIsNotBigger> -struct UnsignedUnsignedCheck; - -template -struct UnsignedUnsignedCheck -{ -public: - static bool checkBounds(const From aFrom) - { - return aFrom <= From(To(-1)); - } -}; - -template -struct UnsignedUnsignedCheck -{ -public: - static bool checkBounds(const From aFrom) - { - return true; - } -}; - -template -struct BoundsCheckImpl -{ -public: - static bool checkBounds(const From aFrom) - { - return UnsignedUnsignedCheck::checkBounds(aFrom); - } -}; - -// Signed-to-unsigned range check - -template -struct BoundsCheckImpl -{ -public: - static bool checkBounds(const From aFrom) - { - if (aFrom < 0) { - return false; - } - if (sizeof(To) >= sizeof(From)) { - return true; - } - return aFrom <= From(To(-1)); - } -}; - -// Unsigned-to-signed range check - -enum USComparison { FromIsSmaller, FromIsNotSmaller }; - -template -struct UnsignedSignedCheck; - -template -struct UnsignedSignedCheck -{ -public: - static bool checkBounds(const From aFrom) - { - return true; - } -}; - -template -struct UnsignedSignedCheck -{ -public: - static bool checkBounds(const From aFrom) - { - const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); - return aFrom <= From(MaxValue); - } -}; - -template -struct BoundsCheckImpl -{ -public: - static bool checkBounds(const From aFrom) - { - return UnsignedSignedCheck::checkBounds(aFrom); - } -}; - -// Signed-to-signed range check - -template -struct BoundsCheckImpl -{ -public: - static bool checkBounds(const From aFrom) - { - if (sizeof(From) <= sizeof(To)) { - return true; - } - const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); - const To MinValue = -MaxValue - To(1); - return From(MinValue) <= aFrom && - From(aFrom) <= From(MaxValue); - } -}; - -template::value && - IsIntegral::value> -class BoundsChecker; - -template -class BoundsChecker -{ -public: - static bool checkBounds(const From aFrom) { return true; } -}; - -template -class BoundsChecker -{ -public: - static bool checkBounds(const From aFrom) - { - return BoundsCheckImpl::checkBounds(aFrom); - } -}; - -template -inline bool -IsInBounds(const From aFrom) -{ - return BoundsChecker::checkBounds(aFrom); -} - -} // namespace detail - -/** - * Cast a value of integral type |From| to a value of integral type |To|, - * asserting that the cast will be a safe cast per C++ (that is, that |to| is in - * the range of values permitted for the type |From|). - */ -template -inline To -AssertedCast(const From aFrom) -{ - MOZ_ASSERT((detail::IsInBounds(aFrom))); - return static_cast(aFrom); -} - -} // namespace mozilla - -#endif /* mozilla_Casting_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/ChaosMode.h b/android/arm64-v8a/include/spidermonkey/mozilla/ChaosMode.h deleted file mode 100644 index 94833c39..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/ChaosMode.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_ChaosMode_h -#define mozilla_ChaosMode_h - -#include "mozilla/Atomics.h" -#include "mozilla/EnumSet.h" - -#include -#include - -namespace mozilla { - -enum ChaosFeature { - None = 0x0, - // Altering thread scheduling. - ThreadScheduling = 0x1, - // Altering network request scheduling. - NetworkScheduling = 0x2, - // Altering timer scheduling. - TimerScheduling = 0x4, - // Read and write less-than-requested amounts. - IOAmounts = 0x8, - // Iterate over hash tables in random order. - HashTableIteration = 0x10, - // Randomly refuse to use cached version of image (when allowed by spec). - ImageCache = 0x20, - Any = 0xffffffff, -}; - -namespace detail { -extern MFBT_DATA Atomic gChaosModeCounter; -extern MFBT_DATA ChaosFeature gChaosFeatures; -} // namespace detail - -/** - * When "chaos mode" is activated, code that makes implicitly nondeterministic - * choices is encouraged to make random and extreme choices, to test more - * code paths and uncover bugs. - */ -class ChaosMode -{ -public: - static void SetChaosFeature(ChaosFeature aChaosFeature) - { - detail::gChaosFeatures = aChaosFeature; - } - - static bool isActive(ChaosFeature aFeature) - { - if (detail::gChaosModeCounter > 0) { - return true; - } - return detail::gChaosFeatures & aFeature; - } - - /** - * Increase the chaos mode activation level. An equivalent number of - * calls to leaveChaosMode must be made in order to restore the original - * chaos mode state. If the activation level is nonzero all chaos mode - * features are activated. - */ - static void enterChaosMode() - { - detail::gChaosModeCounter++; - } - - /** - * Decrease the chaos mode activation level. See enterChaosMode(). - */ - static void leaveChaosMode() - { - MOZ_ASSERT(detail::gChaosModeCounter > 0); - detail::gChaosModeCounter--; - } - - /** - * Returns a somewhat (but not uniformly) random uint32_t < aBound. - * Not to be used for anything except ChaosMode, since it's not very random. - */ - static uint32_t randomUint32LessThan(uint32_t aBound) - { - MOZ_ASSERT(aBound != 0); - return uint32_t(rand()) % aBound; - } -}; - -} /* namespace mozilla */ - -#endif /* mozilla_ChaosMode_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Char16.h b/android/arm64-v8a/include/spidermonkey/mozilla/Char16.h deleted file mode 100644 index 3c2f254a..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Char16.h +++ /dev/null @@ -1,194 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implements a UTF-16 character type. */ - -#ifndef mozilla_Char16_h -#define mozilla_Char16_h - -#ifdef __cplusplus - -/* - * C++11 introduces a char16_t type and support for UTF-16 string and character - * literals. C++11's char16_t is a distinct builtin type. Technically, char16_t - * is a 16-bit code unit of a Unicode code point, not a "character". - */ - -#ifdef WIN32 -# define MOZ_USE_CHAR16_WRAPPER -# include - /** - * Win32 API extensively uses wchar_t, which is represented by a separated - * builtin type than char16_t per spec. It's not the case for MSVC prior to - * MSVC 2015, but other compilers follow the spec. We want to mix wchar_t and - * char16_t on Windows builds. This class is supposed to make it easier. It - * stores char16_t const pointer, but provides implicit casts for wchar_t as - * well. On other platforms, we simply use - * |typedef const char16_t* char16ptr_t|. Here, we want to make the class as - * similar to this typedef, including providing some casts that are allowed - * by the typedef. - */ -class char16ptr_t -{ -private: - const char16_t* mPtr; - static_assert(sizeof(char16_t) == sizeof(wchar_t), - "char16_t and wchar_t sizes differ"); - -public: - char16ptr_t(const char16_t* aPtr) : mPtr(aPtr) {} - char16ptr_t(const wchar_t* aPtr) : - mPtr(reinterpret_cast(aPtr)) - {} - - /* Without this, nullptr assignment would be ambiguous. */ - constexpr char16ptr_t(decltype(nullptr)) : mPtr(nullptr) {} - - operator const char16_t*() const - { - return mPtr; - } - operator const wchar_t*() const - { - return reinterpret_cast(mPtr); - } - operator const void*() const - { - return mPtr; - } - operator bool() const - { - return mPtr != nullptr; - } - - /* Explicit cast operators to allow things like (char16_t*)str. */ - explicit operator char16_t*() const - { - return const_cast(mPtr); - } - explicit operator wchar_t*() const - { - return const_cast(static_cast(*this)); - } - explicit operator int() const - { - return reinterpret_cast(mPtr); - } - explicit operator unsigned int() const - { - return reinterpret_cast(mPtr); - } - explicit operator long() const - { - return reinterpret_cast(mPtr); - } - explicit operator unsigned long() const - { - return reinterpret_cast(mPtr); - } - explicit operator long long() const - { - return reinterpret_cast(mPtr); - } - explicit operator unsigned long long() const - { - return reinterpret_cast(mPtr); - } - - /** - * Some Windows API calls accept BYTE* but require that data actually be - * WCHAR*. Supporting this requires explicit operators to support the - * requisite explicit casts. - */ - explicit operator const char*() const - { - return reinterpret_cast(mPtr); - } - explicit operator const unsigned char*() const - { - return reinterpret_cast(mPtr); - } - explicit operator unsigned char*() const - { - return - const_cast(reinterpret_cast(mPtr)); - } - explicit operator void*() const - { - return const_cast(mPtr); - } - - /* Some operators used on pointers. */ - char16_t operator[](size_t aIndex) const - { - return mPtr[aIndex]; - } - bool operator==(const char16ptr_t& aOther) const - { - return mPtr == aOther.mPtr; - } - bool operator==(decltype(nullptr)) const - { - return mPtr == nullptr; - } - bool operator!=(const char16ptr_t& aOther) const - { - return mPtr != aOther.mPtr; - } - bool operator!=(decltype(nullptr)) const - { - return mPtr != nullptr; - } - char16ptr_t operator+(int aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(unsigned int aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(long aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(unsigned long aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(long long aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(unsigned long long aValue) const - { - return char16ptr_t(mPtr + aValue); - } - ptrdiff_t operator-(const char16ptr_t& aOther) const - { - return mPtr - aOther.mPtr; - } -}; - -inline decltype((char*)0-(char*)0) -operator-(const char16_t* aX, const char16ptr_t aY) -{ - return aX - static_cast(aY); -} - -#else - -typedef const char16_t* char16ptr_t; - -#endif - -static_assert(sizeof(char16_t) == 2, "Is char16_t type 16 bits?"); -static_assert(char16_t(-1) > char16_t(0), "Is char16_t type unsigned?"); -static_assert(sizeof(u'A') == 2, "Is unicode char literal 16 bits?"); -static_assert(sizeof(u""[0]) == 2, "Is unicode string char 16 bits?"); - -#endif - -#endif /* mozilla_Char16_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/CheckedInt.h b/android/arm64-v8a/include/spidermonkey/mozilla/CheckedInt.h deleted file mode 100644 index 02ef8d5b..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/CheckedInt.h +++ /dev/null @@ -1,791 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Provides checked integers, detecting integer overflow and divide-by-0. */ - -#ifndef mozilla_CheckedInt_h -#define mozilla_CheckedInt_h - -#include -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/IntegerTypeTraits.h" - -namespace mozilla { - -template class CheckedInt; - -namespace detail { - -/* - * Step 1: manually record supported types - * - * What's nontrivial here is that there are different families of integer - * types: basic integer types and stdint types. It is merrily undefined which - * types from one family may be just typedefs for a type from another family. - * - * For example, on GCC 4.6, aside from the basic integer types, the only other - * type that isn't just a typedef for some of them, is int8_t. - */ - -struct UnsupportedType {}; - -template -struct IsSupportedPass2 -{ - static const bool value = false; -}; - -template -struct IsSupported -{ - static const bool value = IsSupportedPass2::value; -}; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -/* - * Step 2: Implement the actual validity checks. - * - * Ideas taken from IntegerLib, code different. - */ - -template -struct TwiceBiggerType -{ - typedef typename detail::StdintTypeForSizeAndSignedness< - sizeof(IntegerType) * 2, - IsSigned::value - >::Type Type; -}; - -template -struct TwiceBiggerType -{ - typedef UnsupportedType Type; -}; - -template -inline bool -HasSignBit(T aX) -{ - // In C++, right bit shifts on negative values is undefined by the standard. - // Notice that signed-to-unsigned conversions are always well-defined in the - // standard, as the value congruent modulo 2**n as expected. By contrast, - // unsigned-to-signed is only well-defined if the value is representable. - return bool(typename MakeUnsigned::Type(aX) >> - PositionOfSignBit::value); -} - -// Bitwise ops may return a larger type, so it's good to use this inline -// helper guaranteeing that the result is really of type T. -template -inline T -BinaryComplement(T aX) -{ - return ~aX; -} - -template::value, - bool IsUSigned = IsSigned::value> -struct DoesRangeContainRange -{ -}; - -template -struct DoesRangeContainRange -{ - static const bool value = sizeof(T) >= sizeof(U); -}; - -template -struct DoesRangeContainRange -{ - static const bool value = sizeof(T) > sizeof(U); -}; - -template -struct DoesRangeContainRange -{ - static const bool value = false; -}; - -template::value, - bool IsUSigned = IsSigned::value, - bool DoesTRangeContainURange = DoesRangeContainRange::value> -struct IsInRangeImpl {}; - -template -struct IsInRangeImpl -{ - static bool run(U) - { - return true; - } -}; - -template -struct IsInRangeImpl -{ - static bool run(U aX) - { - return aX <= MaxValue::value && aX >= MinValue::value; - } -}; - -template -struct IsInRangeImpl -{ - static bool run(U aX) - { - return aX <= MaxValue::value; - } -}; - -template -struct IsInRangeImpl -{ - static bool run(U aX) - { - return sizeof(T) > sizeof(U) || aX <= U(MaxValue::value); - } -}; - -template -struct IsInRangeImpl -{ - static bool run(U aX) - { - return sizeof(T) >= sizeof(U) - ? aX >= 0 - : aX >= 0 && aX <= U(MaxValue::value); - } -}; - -template -inline bool -IsInRange(U aX) -{ - return IsInRangeImpl::run(aX); -} - -template -inline bool -IsAddValid(T aX, T aY) -{ - // Addition is valid if the sign of aX+aY is equal to either that of aX or - // that of aY. Since the value of aX+aY is undefined if we have a signed - // type, we compute it using the unsigned type of the same size. Beware! - // These bitwise operations can return a larger integer type, if T was a - // small type like int8_t, so we explicitly cast to T. - - typename MakeUnsigned::Type ux = aX; - typename MakeUnsigned::Type uy = aY; - typename MakeUnsigned::Type result = ux + uy; - return IsSigned::value - ? HasSignBit(BinaryComplement(T((result ^ aX) & (result ^ aY)))) - : BinaryComplement(aX) >= aY; -} - -template -inline bool -IsSubValid(T aX, T aY) -{ - // Subtraction is valid if either aX and aY have same sign, or aX-aY and aX - // have same sign. Since the value of aX-aY is undefined if we have a signed - // type, we compute it using the unsigned type of the same size. - typename MakeUnsigned::Type ux = aX; - typename MakeUnsigned::Type uy = aY; - typename MakeUnsigned::Type result = ux - uy; - - return IsSigned::value - ? HasSignBit(BinaryComplement(T((result ^ aX) & (aX ^ aY)))) - : aX >= aY; -} - -template::value, - bool TwiceBiggerTypeIsSupported = - IsSupported::Type>::value> -struct IsMulValidImpl {}; - -template -struct IsMulValidImpl -{ - static bool run(T aX, T aY) - { - typedef typename TwiceBiggerType::Type TwiceBiggerType; - TwiceBiggerType product = TwiceBiggerType(aX) * TwiceBiggerType(aY); - return IsInRange(product); - } -}; - -template -struct IsMulValidImpl -{ - static bool run(T aX, T aY) - { - const T max = MaxValue::value; - const T min = MinValue::value; - - if (aX == 0 || aY == 0) { - return true; - } - if (aX > 0) { - return aY > 0 - ? aX <= max / aY - : aY >= min / aX; - } - - // If we reach this point, we know that aX < 0. - return aY > 0 - ? aX >= min / aY - : aY >= max / aX; - } -}; - -template -struct IsMulValidImpl -{ - static bool run(T aX, T aY) - { - return aY == 0 || aX <= MaxValue::value / aY; - } -}; - -template -inline bool -IsMulValid(T aX, T aY) -{ - return IsMulValidImpl::run(aX, aY); -} - -template -inline bool -IsDivValid(T aX, T aY) -{ - // Keep in mind that in the signed case, min/-1 is invalid because - // abs(min)>max. - return aY != 0 && - !(IsSigned::value && aX == MinValue::value && aY == T(-1)); -} - -template::value> -struct IsModValidImpl; - -template -inline bool -IsModValid(T aX, T aY) -{ - return IsModValidImpl::run(aX, aY); -} - -/* - * Mod is pretty simple. - * For now, let's just use the ANSI C definition: - * If aX or aY are negative, the results are implementation defined. - * Consider these invalid. - * Undefined for aY=0. - * The result will never exceed either aX or aY. - * - * Checking that aX>=0 is a warning when T is unsigned. - */ - -template -struct IsModValidImpl -{ - static inline bool run(T aX, T aY) - { - return aY >= 1; - } -}; - -template -struct IsModValidImpl -{ - static inline bool run(T aX, T aY) - { - if (aX < 0) { - return false; - } - return aY >= 1; - } -}; - -template::value> -struct NegateImpl; - -template -struct NegateImpl -{ - static CheckedInt negate(const CheckedInt& aVal) - { - // Handle negation separately for signed/unsigned, for simpler code and to - // avoid an MSVC warning negating an unsigned value. - return CheckedInt(0, aVal.isValid() && aVal.mValue == 0); - } -}; - -template -struct NegateImpl -{ - static CheckedInt negate(const CheckedInt& aVal) - { - // Watch out for the min-value, which (with twos-complement) can't be - // negated as -min-value is then (max-value + 1). - if (!aVal.isValid() || aVal.mValue == MinValue::value) { - return CheckedInt(aVal.mValue, false); - } - return CheckedInt(-aVal.mValue, true); - } -}; - -} // namespace detail - - -/* - * Step 3: Now define the CheckedInt class. - */ - -/** - * @class CheckedInt - * @brief Integer wrapper class checking for integer overflow and other errors - * @param T the integer type to wrap. Can be any type among the following: - * - any basic integer type such as |int| - * - any stdint type such as |int8_t| - * - * This class implements guarded integer arithmetic. Do a computation, check - * that isValid() returns true, you then have a guarantee that no problem, such - * as integer overflow, happened during this computation, and you can call - * value() to get the plain integer value. - * - * The arithmetic operators in this class are guaranteed not to raise a signal - * (e.g. in case of a division by zero). - * - * For example, suppose that you want to implement a function that computes - * (aX+aY)/aZ, that doesn't crash if aZ==0, and that reports on error (divide by - * zero or integer overflow). You could code it as follows: - @code - bool computeXPlusYOverZ(int aX, int aY, int aZ, int* aResult) - { - CheckedInt checkedResult = (CheckedInt(aX) + aY) / aZ; - if (checkedResult.isValid()) { - *aResult = checkedResult.value(); - return true; - } else { - return false; - } - } - @endcode - * - * Implicit conversion from plain integers to checked integers is allowed. The - * plain integer is checked to be in range before being casted to the - * destination type. This means that the following lines all compile, and the - * resulting CheckedInts are correctly detected as valid or invalid: - * @code - // 1 is of type int, is found to be in range for uint8_t, x is valid - CheckedInt x(1); - // -1 is of type int, is found not to be in range for uint8_t, x is invalid - CheckedInt x(-1); - // -1 is of type int, is found to be in range for int8_t, x is valid - CheckedInt x(-1); - // 1000 is of type int16_t, is found not to be in range for int8_t, - // x is invalid - CheckedInt x(int16_t(1000)); - // 3123456789 is of type uint32_t, is found not to be in range for int32_t, - // x is invalid - CheckedInt x(uint32_t(3123456789)); - * @endcode - * Implicit conversion from - * checked integers to plain integers is not allowed. As shown in the - * above example, to get the value of a checked integer as a normal integer, - * call value(). - * - * Arithmetic operations between checked and plain integers is allowed; the - * result type is the type of the checked integer. - * - * Checked integers of different types cannot be used in the same arithmetic - * expression. - * - * There are convenience typedefs for all stdint types, of the following form - * (these are just 2 examples): - @code - typedef CheckedInt CheckedInt32; - typedef CheckedInt CheckedUint16; - @endcode - */ -template -class CheckedInt -{ -protected: - T mValue; - bool mIsValid; - - template - CheckedInt(U aValue, bool aIsValid) : mValue(aValue), mIsValid(aIsValid) - { - static_assert(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); - } - - friend struct detail::NegateImpl; - -public: - /** - * Constructs a checked integer with given @a value. The checked integer is - * initialized as valid or invalid depending on whether the @a value - * is in range. - * - * This constructor is not explicit. Instead, the type of its argument is a - * separate template parameter, ensuring that no conversion is performed - * before this constructor is actually called. As explained in the above - * documentation for class CheckedInt, this constructor checks that its - * argument is valid. - */ - template - MOZ_IMPLICIT CheckedInt(U aValue) MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT - : mValue(T(aValue)), - mIsValid(detail::IsInRange(aValue)) - { - static_assert(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); - } - - template - friend class CheckedInt; - - template - CheckedInt toChecked() const - { - CheckedInt ret(mValue); - ret.mIsValid = ret.mIsValid && mIsValid; - return ret; - } - - /** Constructs a valid checked integer with initial value 0 */ - CheckedInt() : mValue(0), mIsValid(true) - { - static_assert(detail::IsSupported::value, - "This type is not supported by CheckedInt"); - } - - /** @returns the actual value */ - T value() const - { - MOZ_ASSERT(mIsValid, "Invalid checked integer (division by zero or integer overflow)"); - return mValue; - } - - /** - * @returns true if the checked integer is valid, i.e. is not the result - * of an invalid operation or of an operation involving an invalid checked - * integer - */ - bool isValid() const - { - return mIsValid; - } - - template - friend CheckedInt operator +(const CheckedInt& aLhs, - const CheckedInt& aRhs); - template - CheckedInt& operator +=(U aRhs); - CheckedInt& operator +=(const CheckedInt& aRhs); - - template - friend CheckedInt operator -(const CheckedInt& aLhs, - const CheckedInt& aRhs); - template - CheckedInt& operator -=(U aRhs); - CheckedInt& operator -=(const CheckedInt& aRhs); - - template - friend CheckedInt operator *(const CheckedInt& aLhs, - const CheckedInt& aRhs); - template - CheckedInt& operator *=(U aRhs); - CheckedInt& operator *=(const CheckedInt& aRhs); - - template - friend CheckedInt operator /(const CheckedInt& aLhs, - const CheckedInt& aRhs); - template - CheckedInt& operator /=(U aRhs); - CheckedInt& operator /=(const CheckedInt& aRhs); - - template - friend CheckedInt operator %(const CheckedInt& aLhs, - const CheckedInt& aRhs); - template - CheckedInt& operator %=(U aRhs); - CheckedInt& operator %=(const CheckedInt& aRhs); - - CheckedInt operator -() const - { - return detail::NegateImpl::negate(*this); - } - - /** - * @returns true if the left and right hand sides are valid - * and have the same value. - * - * Note that these semantics are the reason why we don't offer - * a operator!=. Indeed, we'd want to have a!=b be equivalent to !(a==b) - * but that would mean that whenever a or b is invalid, a!=b - * is always true, which would be very confusing. - * - * For similar reasons, operators <, >, <=, >= would be very tricky to - * specify, so we just avoid offering them. - * - * Notice that these == semantics are made more reasonable by these facts: - * 1. a==b implies equality at the raw data level - * (the converse is false, as a==b is never true among invalids) - * 2. This is similar to the behavior of IEEE floats, where a==b - * means that a and b have the same value *and* neither is NaN. - */ - bool operator ==(const CheckedInt& aOther) const - { - return mIsValid && aOther.mIsValid && mValue == aOther.mValue; - } - - /** prefix ++ */ - CheckedInt& operator++() - { - *this += 1; - return *this; - } - - /** postfix ++ */ - CheckedInt operator++(int) - { - CheckedInt tmp = *this; - *this += 1; - return tmp; - } - - /** prefix -- */ - CheckedInt& operator--() - { - *this -= 1; - return *this; - } - - /** postfix -- */ - CheckedInt operator--(int) - { - CheckedInt tmp = *this; - *this -= 1; - return tmp; - } - -private: - /** - * The !=, <, <=, >, >= operators are disabled: - * see the comment on operator==. - */ - template bool operator !=(U aOther) const = delete; - template bool operator < (U aOther) const = delete; - template bool operator <=(U aOther) const = delete; - template bool operator > (U aOther) const = delete; - template bool operator >=(U aOther) const = delete; -}; - -#define MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(NAME, OP) \ - template \ - inline CheckedInt \ - operator OP(const CheckedInt& aLhs, const CheckedInt& aRhs) \ - { \ - if (!detail::Is##NAME##Valid(aLhs.mValue, aRhs.mValue)) { \ - return CheckedInt(0, false); \ - } \ - return CheckedInt(aLhs.mValue OP aRhs.mValue, \ - aLhs.mIsValid && aRhs.mIsValid); \ - } - -MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Add, +) -MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Sub, -) -MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mul, *) -MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Div, /) -MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mod, %) - -#undef MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR - -// Implement castToCheckedInt(x), making sure that -// - it allows x to be either a CheckedInt or any integer type -// that can be casted to T -// - if x is already a CheckedInt, we just return a reference to it, -// instead of copying it (optimization) - -namespace detail { - -template -struct CastToCheckedIntImpl -{ - typedef CheckedInt ReturnType; - static CheckedInt run(U aU) { return aU; } -}; - -template -struct CastToCheckedIntImpl > -{ - typedef const CheckedInt& ReturnType; - static const CheckedInt& run(const CheckedInt& aU) { return aU; } -}; - -} // namespace detail - -template -inline typename detail::CastToCheckedIntImpl::ReturnType -castToCheckedInt(U aU) -{ - static_assert(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); - return detail::CastToCheckedIntImpl::run(aU); -} - -#define MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(OP, COMPOUND_OP) \ - template \ - template \ - CheckedInt& CheckedInt::operator COMPOUND_OP(U aRhs) \ - { \ - *this = *this OP castToCheckedInt(aRhs); \ - return *this; \ - } \ - template \ - CheckedInt& CheckedInt::operator COMPOUND_OP(const CheckedInt& aRhs) \ - { \ - *this = *this OP aRhs; \ - return *this; \ - } \ - template \ - inline CheckedInt operator OP(const CheckedInt& aLhs, U aRhs) \ - { \ - return aLhs OP castToCheckedInt(aRhs); \ - } \ - template \ - inline CheckedInt operator OP(U aLhs, const CheckedInt& aRhs) \ - { \ - return castToCheckedInt(aLhs) OP aRhs; \ - } - -MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(+, +=) -MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(*, *=) -MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(-, -=) -MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(/, /=) -MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(%, %=) - -#undef MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS - -template -inline bool -operator ==(const CheckedInt& aLhs, U aRhs) -{ - return aLhs == castToCheckedInt(aRhs); -} - -template -inline bool -operator ==(U aLhs, const CheckedInt& aRhs) -{ - return castToCheckedInt(aLhs) == aRhs; -} - -// Convenience typedefs. -typedef CheckedInt CheckedInt8; -typedef CheckedInt CheckedUint8; -typedef CheckedInt CheckedInt16; -typedef CheckedInt CheckedUint16; -typedef CheckedInt CheckedInt32; -typedef CheckedInt CheckedUint32; -typedef CheckedInt CheckedInt64; -typedef CheckedInt CheckedUint64; - -} // namespace mozilla - -#endif /* mozilla_CheckedInt_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Compiler.h b/android/arm64-v8a/include/spidermonkey/mozilla/Compiler.h deleted file mode 100644 index 1bd34d32..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Compiler.h +++ /dev/null @@ -1,113 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Various compiler checks. */ - -#ifndef mozilla_Compiler_h -#define mozilla_Compiler_h - -#define MOZ_IS_GCC 0 -#define MOZ_IS_MSVC 0 - -#if !defined(__clang__) && defined(__GNUC__) - -# undef MOZ_IS_GCC -# define MOZ_IS_GCC 1 - /* - * These macros should simplify gcc version checking. For example, to check - * for gcc 4.7.1 or later, check `#if MOZ_GCC_VERSION_AT_LEAST(4, 7, 1)`. - */ -# define MOZ_GCC_VERSION_AT_LEAST(major, minor, patchlevel) \ - ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) \ - >= ((major) * 10000 + (minor) * 100 + (patchlevel))) -# define MOZ_GCC_VERSION_AT_MOST(major, minor, patchlevel) \ - ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) \ - <= ((major) * 10000 + (minor) * 100 + (patchlevel))) -# if !MOZ_GCC_VERSION_AT_LEAST(4, 8, 0) -# error "mfbt (and Gecko) require at least gcc 4.8 to build." -# endif - -#elif defined(_MSC_VER) - -# undef MOZ_IS_MSVC -# define MOZ_IS_MSVC 1 - -#endif - -/* - * The situation with standard libraries is a lot worse than with compilers, - * particularly as clang and gcc could end up using one of three or so standard - * libraries, and they may not be up-to-snuff with newer C++11 versions. To - * detect the library, we're going to include cstddef (which is a small header - * which will be transitively included by everybody else at some point) to grab - * the version macros and deduce macros from there. - */ -#ifdef __cplusplus -# include -# ifdef _STLPORT_MAJOR -# define MOZ_USING_STLPORT 1 -# define MOZ_STLPORT_VERSION_AT_LEAST(major, minor, patch) \ - (_STLPORT_VERSION >= ((major) << 8 | (minor) << 4 | (patch))) -# elif defined(_LIBCPP_VERSION) - /* - * libc++, unfortunately, doesn't appear to have useful versioning macros. - * Hopefully, the recommendations of N3694 with respect to standard libraries - * will get applied instead and we won't need to worry about version numbers - * here. - */ -# define MOZ_USING_LIBCXX 1 -# elif defined(__GLIBCXX__) -# define MOZ_USING_LIBSTDCXX 1 - /* - * libstdc++ is also annoying and doesn't give us useful versioning macros - * for the library. If we're using gcc, then assume that libstdc++ matches - * the compiler version. If we're using clang, we're going to have to fake - * major/minor combinations by looking for newly-defined config macros. - */ -# if MOZ_IS_GCC -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - MOZ_GCC_VERSION_AT_LEAST(major, minor, patch) -# elif defined(_GLIBCXX_THROW_OR_ABORT) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 8)) -# elif defined(_GLIBCXX_NOEXCEPT) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 7)) -# elif defined(_GLIBCXX_USE_DEPRECATED) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 6)) -# elif defined(_GLIBCXX_PSEUDO_VISIBILITY) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 5)) -# elif defined(_GLIBCXX_BEGIN_EXTERN_C) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 4)) -# elif defined(_GLIBCXX_VISIBILITY_ATTR) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 3)) -# elif defined(_GLIBCXX_VISIBILITY) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 2)) -# else -# error "Your version of libstdc++ is unknown to us and is likely too old." -# endif -# endif - - // Flesh out the defines for everyone else -# ifndef MOZ_USING_STLPORT -# define MOZ_USING_STLPORT 0 -# define MOZ_STLPORT_VERSION_AT_LEAST(major, minor, patch) 0 -# endif -# ifndef MOZ_USING_LIBCXX -# define MOZ_USING_LIBCXX 0 -# endif -# ifndef MOZ_USING_LIBSTDCXX -# define MOZ_USING_LIBSTDCXX 0 -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) 0 -# endif -#endif /* __cplusplus */ - -#endif /* mozilla_Compiler_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Compression.h b/android/arm64-v8a/include/spidermonkey/mozilla/Compression.h deleted file mode 100644 index aa50211b..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Compression.h +++ /dev/null @@ -1,119 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Various simple compression/decompression functions. */ - -#ifndef mozilla_Compression_h_ -#define mozilla_Compression_h_ - -#include "mozilla/Assertions.h" -#include "mozilla/Types.h" - -namespace mozilla { -namespace Compression { - -/** - * LZ4 is a very fast byte-wise compression algorithm. - * - * Compared to Google's Snappy it is faster to compress and decompress and - * generally produces output of about the same size. - * - * Compared to zlib it compresses at about 10x the speed, decompresses at about - * 4x the speed and produces output of about 1.5x the size. - */ - -class LZ4 -{ -public: - /** - * Compresses |aInputSize| bytes from |aSource| into |aDest|. Destination - * buffer must be already allocated, and must be sized to handle worst cases - * situations (input data not compressible). Worst case size evaluation is - * provided by function maxCompressedSize() - * - * @param aInputSize is the input size. Max supported value is ~1.9GB - * @return the number of bytes written in buffer |aDest| - */ - static MFBT_API size_t - compress(const char* aSource, size_t aInputSize, char* aDest); - - /** - * Compress |aInputSize| bytes from |aSource| into an output buffer - * |aDest| of maximum size |aMaxOutputSize|. If it cannot achieve it, - * compression will stop, and result of the function will be zero, - * |aDest| will still be written to, but since the number of input - * bytes consumed is not returned the result is not usable. - * - * This function never writes outside of provided output buffer. - * - * @param aInputSize is the input size. Max supported value is ~1.9GB - * @param aMaxOutputSize is the size of the destination buffer (which must - * be already allocated) - * @return the number of bytes written in buffer |aDest| or 0 if the - * compression fails - */ - static MFBT_API size_t - compressLimitedOutput(const char* aSource, size_t aInputSize, char* aDest, - size_t aMaxOutputSize); - - /** - * If the source stream is malformed, the function will stop decoding - * and return false. - * - * This function never writes outside of provided buffers, and never - * modifies input buffer. - * - * Note: destination buffer must be already allocated, and its size must be a - * minimum of |aOutputSize| bytes. - * - * @param aOutputSize is the output size, therefore the original size - * @return true on success, false on failure - */ - static MFBT_API MOZ_MUST_USE bool - decompress(const char* aSource, char* aDest, size_t aOutputSize); - - /** - * If the source stream is malformed, the function will stop decoding - * and return false. - * - * This function never writes beyond aDest + aMaxOutputSize, and is - * therefore protected against malicious data packets. - * - * Note: Destination buffer must be already allocated. This version is - * slightly slower than the decompress without the aMaxOutputSize. - * - * @param aInputSize is the length of the input compressed data - * @param aMaxOutputSize is the size of the destination buffer (which must be - * already allocated) - * @param aOutputSize the actual number of bytes decoded in the destination - * buffer (necessarily <= aMaxOutputSize) - * @return true on success, false on failure - */ - static MFBT_API MOZ_MUST_USE bool - decompress(const char* aSource, size_t aInputSize, char* aDest, - size_t aMaxOutputSize, size_t* aOutputSize); - - /* - * Provides the maximum size that LZ4 may output in a "worst case" - * scenario (input data not compressible) primarily useful for memory - * allocation of output buffer. - * note : this function is limited by "int" range (2^31-1) - * - * @param aInputSize is the input size. Max supported value is ~1.9GB - * @return maximum output size in a "worst case" scenario - */ - static inline size_t maxCompressedSize(size_t aInputSize) - { - size_t max = (aInputSize + (aInputSize / 255) + 16); - MOZ_ASSERT(max > aInputSize); - return max; - } -}; - -} /* namespace Compression */ -} /* namespace mozilla */ - -#endif /* mozilla_Compression_h_ */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/DebugOnly.h b/android/arm64-v8a/include/spidermonkey/mozilla/DebugOnly.h deleted file mode 100644 index a1a669db..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/DebugOnly.h +++ /dev/null @@ -1,92 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Provides DebugOnly, a type for variables used only in debug builds (i.e. by - * assertions). - */ - -#ifndef mozilla_DebugOnly_h -#define mozilla_DebugOnly_h - -#include "mozilla/Attributes.h" - -namespace mozilla { - -/** - * DebugOnly contains a value of type T, but only in debug builds. In release - * builds, it does not contain a value. This helper is intended to be used with - * MOZ_ASSERT()-style macros, allowing one to write: - * - * DebugOnly check = func(); - * MOZ_ASSERT(check); - * - * more concisely than declaring |check| conditional on #ifdef DEBUG. - * - * DebugOnly instances can only be coerced to T in debug builds. In release - * builds they don't have a value, so type coercion is not well defined. - * - * NOTE: DebugOnly instances still take up one byte of space, plus padding, even - * in optimized, non-DEBUG builds (see bug 1253094 comment 37 for more info). - * For this reason the class is MOZ_STACK_CLASS to prevent consumers using - * DebugOnly for struct/class members and unwittingly inflating the size of - * their objects in release builds. - */ -template -class MOZ_STACK_CLASS DebugOnly -{ -public: -#ifdef DEBUG - T value; - - DebugOnly() { } - MOZ_IMPLICIT DebugOnly(const T& aOther) : value(aOther) { } - DebugOnly(const DebugOnly& aOther) : value(aOther.value) { } - DebugOnly& operator=(const T& aRhs) { - value = aRhs; - return *this; - } - - void operator++(int) { value++; } - void operator--(int) { value--; } - - // Do not define operator+=(), etc. here. These will coerce via the - // implicit cast and built-in operators. Defining explicit methods here - // will create ambiguity the compiler can't deal with. - - T* operator&() { return &value; } - - operator T&() { return value; } - operator const T&() const { return value; } - - T& operator->() { return value; } - const T& operator->() const { return value; } - -#else - DebugOnly() { } - MOZ_IMPLICIT DebugOnly(const T&) { } - DebugOnly(const DebugOnly&) { } - DebugOnly& operator=(const T&) { return *this; } - void operator++(int) { } - void operator--(int) { } - DebugOnly& operator+=(const T&) { return *this; } - DebugOnly& operator-=(const T&) { return *this; } - DebugOnly& operator&=(const T&) { return *this; } - DebugOnly& operator|=(const T&) { return *this; } - DebugOnly& operator^=(const T&) { return *this; } -#endif - - /* - * DebugOnly must always have a destructor or else it will - * generate "unused variable" warnings, exactly what it's intended - * to avoid! - */ - ~DebugOnly() {} -}; - -} // namespace mozilla - -#endif /* mozilla_DebugOnly_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Decimal.h b/android/arm64-v8a/include/spidermonkey/mozilla/Decimal.h deleted file mode 100644 index 10d0e2c7..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Decimal.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Imported from: - * https://chromium.googlesource.com/chromium/src.git/+/master/third_party/WebKit/Source/platform/Decimal.h - * Check UPSTREAM-GIT-SHA for the commit ID of the last update from Blink core. - */ - -#ifndef Decimal_h -#define Decimal_h - -#include "mozilla/Assertions.h" -#include -#include "mozilla/Types.h" - -#include - -#ifndef ASSERT -#define DEFINED_ASSERT_FOR_DECIMAL_H 1 -#define ASSERT MOZ_ASSERT -#endif - -#define PLATFORM_EXPORT - -// To use USING_FAST_MALLOC we'd need: -// https://chromium.googlesource.com/chromium/src.git/+/master/third_party/WebKit/Source/wtf/Allocator.h -// Since we don't allocate Decimal objects, no need. -#define USING_FAST_MALLOC(type) \ - void ignore_this_dummy_method() = delete - -#define DISALLOW_NEW() \ - private: \ - void* operator new(size_t) = delete; \ - void* operator new(size_t, void*) = delete; \ - public: - -namespace blink { - -namespace DecimalPrivate { -class SpecialValueHandler; -} - -// This class represents decimal base floating point number. -// -// FIXME: Once all C++ compiler support decimal type, we should replace this -// class to compiler supported one. See below URI for current status of decimal -// type for C++: // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1977.html -class PLATFORM_EXPORT Decimal { - USING_FAST_MALLOC(Decimal); -public: - enum Sign { - Positive, - Negative, - }; - - // You should not use EncodedData other than unit testing. - class EncodedData { - DISALLOW_NEW(); - // For accessing FormatClass. - friend class Decimal; - friend class DecimalPrivate::SpecialValueHandler; - public: - EncodedData(Sign, int exponent, uint64_t coefficient); - - bool operator==(const EncodedData&) const; - bool operator!=(const EncodedData& another) const { return !operator==(another); } - - uint64_t coefficient() const { return m_coefficient; } - int countDigits() const; - int exponent() const { return m_exponent; } - bool isFinite() const { return !isSpecial(); } - bool isInfinity() const { return m_formatClass == ClassInfinity; } - bool isNaN() const { return m_formatClass == ClassNaN; } - bool isSpecial() const { return m_formatClass == ClassInfinity || m_formatClass == ClassNaN; } - bool isZero() const { return m_formatClass == ClassZero; } - Sign sign() const { return m_sign; } - void setSign(Sign sign) { m_sign = sign; } - - private: - enum FormatClass { - ClassInfinity, - ClassNormal, - ClassNaN, - ClassZero, - }; - - EncodedData(Sign, FormatClass); - FormatClass formatClass() const { return m_formatClass; } - - uint64_t m_coefficient; - int16_t m_exponent; - FormatClass m_formatClass; - Sign m_sign; - }; - - MFBT_API explicit Decimal(int32_t = 0); - MFBT_API Decimal(Sign, int exponent, uint64_t coefficient); - MFBT_API Decimal(const Decimal&); - - MFBT_API Decimal& operator=(const Decimal&); - MFBT_API Decimal& operator+=(const Decimal&); - MFBT_API Decimal& operator-=(const Decimal&); - MFBT_API Decimal& operator*=(const Decimal&); - MFBT_API Decimal& operator/=(const Decimal&); - - MFBT_API Decimal operator-() const; - - MFBT_API bool operator==(const Decimal&) const; - MFBT_API bool operator!=(const Decimal&) const; - MFBT_API bool operator<(const Decimal&) const; - MFBT_API bool operator<=(const Decimal&) const; - MFBT_API bool operator>(const Decimal&) const; - MFBT_API bool operator>=(const Decimal&) const; - - MFBT_API Decimal operator+(const Decimal&) const; - MFBT_API Decimal operator-(const Decimal&) const; - MFBT_API Decimal operator*(const Decimal&) const; - MFBT_API Decimal operator/(const Decimal&) const; - - int exponent() const - { - ASSERT(isFinite()); - return m_data.exponent(); - } - - bool isFinite() const { return m_data.isFinite(); } - bool isInfinity() const { return m_data.isInfinity(); } - bool isNaN() const { return m_data.isNaN(); } - bool isNegative() const { return sign() == Negative; } - bool isPositive() const { return sign() == Positive; } - bool isSpecial() const { return m_data.isSpecial(); } - bool isZero() const { return m_data.isZero(); } - - MFBT_API Decimal abs() const; - MFBT_API Decimal ceil() const; - MFBT_API Decimal floor() const; - MFBT_API Decimal remainder(const Decimal&) const; - MFBT_API Decimal round() const; - - MFBT_API double toDouble() const; - // Note: toString method supports infinity and nan but fromString not. - MFBT_API std::string toString() const; - MFBT_API bool toString(char* strBuf, size_t bufLength) const; - - static MFBT_API Decimal fromDouble(double); - // fromString supports following syntax EBNF: - // number ::= sign? digit+ ('.' digit*) (exponent-marker sign? digit+)? - // | sign? '.' digit+ (exponent-marker sign? digit+)? - // sign ::= '+' | '-' - // exponent-marker ::= 'e' | 'E' - // digit ::= '0' | '1' | ... | '9' - // Note: fromString doesn't support "infinity" and "nan". - static MFBT_API Decimal fromString(const std::string& aValue); - static MFBT_API Decimal infinity(Sign); - static MFBT_API Decimal nan(); - static MFBT_API Decimal zero(Sign); - - // You should not use below methods. We expose them for unit testing. - MFBT_API explicit Decimal(const EncodedData&); - const EncodedData& value() const { return m_data; } - -private: - struct AlignedOperands { - uint64_t lhsCoefficient; - uint64_t rhsCoefficient; - int exponent; - }; - - MFBT_API explicit Decimal(double); - MFBT_API Decimal compareTo(const Decimal&) const; - - static MFBT_API AlignedOperands alignOperands(const Decimal& lhs, const Decimal& rhs); - static inline Sign invertSign(Sign sign) { return sign == Negative ? Positive : Negative; } - - Sign sign() const { return m_data.sign(); } - - EncodedData m_data; -}; - -} // namespace blink - -namespace mozilla { -typedef blink::Decimal Decimal; -} // namespace mozilla - -#undef USING_FAST_MALLOC - -#ifdef DEFINED_ASSERT_FOR_DECIMAL_H -#undef DEFINED_ASSERT_FOR_DECIMAL_H -#undef ASSERT -#endif - -#endif // Decimal_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/EndianUtils.h b/android/arm64-v8a/include/spidermonkey/mozilla/EndianUtils.h deleted file mode 100644 index 00815580..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/EndianUtils.h +++ /dev/null @@ -1,695 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Functions for reading and writing integers in various endiannesses. */ - -/* - * The classes LittleEndian and BigEndian expose static methods for - * reading and writing 16-, 32-, and 64-bit signed and unsigned integers - * in their respective endianness. The naming scheme is: - * - * {Little,Big}Endian::{read,write}{Uint,Int} - * - * For instance, LittleEndian::readInt32 will read a 32-bit signed - * integer from memory in little endian format. Similarly, - * BigEndian::writeUint16 will write a 16-bit unsigned integer to memory - * in big-endian format. - * - * The class NativeEndian exposes methods for conversion of existing - * data to and from the native endianness. These methods are intended - * for cases where data needs to be transferred, serialized, etc. - * swap{To,From}{Little,Big}Endian byteswap a single value if necessary. - * Bulk conversion functions are also provided which optimize the - * no-conversion-needed case: - * - * - copyAndSwap{To,From}{Little,Big}Endian; - * - swap{To,From}{Little,Big}EndianInPlace. - * - * The *From* variants are intended to be used for reading data and the - * *To* variants for writing data. - * - * Methods on NativeEndian work with integer data of any type. - * Floating-point data is not supported. - * - * For clarity in networking code, "Network" may be used as a synonym - * for "Big" in any of the above methods or class names. - * - * As an example, reading a file format header whose fields are stored - * in big-endian format might look like: - * - * class ExampleHeader - * { - * private: - * uint32_t mMagic; - * uint32_t mLength; - * uint32_t mTotalRecords; - * uint64_t mChecksum; - * - * public: - * ExampleHeader(const void* data) - * { - * const uint8_t* ptr = static_cast(data); - * mMagic = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); - * mLength = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); - * mTotalRecords = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); - * mChecksum = BigEndian::readUint64(ptr); - * } - * ... - * }; - */ - -#ifndef mozilla_EndianUtils_h -#define mozilla_EndianUtils_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Compiler.h" -#include "mozilla/DebugOnly.h" -#include "mozilla/TypeTraits.h" - -#include -#include - -#if defined(_MSC_VER) -# include -# pragma intrinsic(_byteswap_ushort) -# pragma intrinsic(_byteswap_ulong) -# pragma intrinsic(_byteswap_uint64) -#endif - -#if defined(_WIN64) -# if defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_) -# define MOZ_LITTLE_ENDIAN 1 -# else -# error "CPU type is unknown" -# endif -#elif defined(_WIN32) -# if defined(_M_IX86) -# define MOZ_LITTLE_ENDIAN 1 -# elif defined(_M_ARM) -# define MOZ_LITTLE_ENDIAN 1 -# else -# error "CPU type is unknown" -# endif -#elif defined(__APPLE__) || defined(__powerpc__) || defined(__ppc__) -# if __LITTLE_ENDIAN__ -# define MOZ_LITTLE_ENDIAN 1 -# elif __BIG_ENDIAN__ -# define MOZ_BIG_ENDIAN 1 -# endif -#elif defined(__GNUC__) && \ - defined(__BYTE_ORDER__) && \ - defined(__ORDER_LITTLE_ENDIAN__) && \ - defined(__ORDER_BIG_ENDIAN__) - /* - * Some versions of GCC provide architecture-independent macros for - * this. Yes, there are more than two values for __BYTE_ORDER__. - */ -# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -# define MOZ_LITTLE_ENDIAN 1 -# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -# define MOZ_BIG_ENDIAN 1 -# else -# error "Can't handle mixed-endian architectures" -# endif -/* - * We can't include useful headers like or - * here because they're not present on all platforms. Instead we have - * this big conditional that ideally will catch all the interesting - * cases. - */ -#elif defined(__sparc) || defined(__sparc__) || \ - defined(_POWER) || defined(__hppa) || \ - defined(_MIPSEB) || defined(__ARMEB__) || \ - defined(__s390__) || defined(__AARCH64EB__) || \ - (defined(__sh__) && defined(__LITTLE_ENDIAN__)) || \ - (defined(__ia64) && defined(__BIG_ENDIAN__)) -# define MOZ_BIG_ENDIAN 1 -#elif defined(__i386) || defined(__i386__) || \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_MIPSEL) || defined(__ARMEL__) || \ - defined(__alpha__) || defined(__AARCH64EL__) || \ - (defined(__sh__) && defined(__BIG_ENDIAN__)) || \ - (defined(__ia64) && !defined(__BIG_ENDIAN__)) -# define MOZ_LITTLE_ENDIAN 1 -#endif - -#if MOZ_BIG_ENDIAN -# define MOZ_LITTLE_ENDIAN 0 -#elif MOZ_LITTLE_ENDIAN -# define MOZ_BIG_ENDIAN 0 -#else -# error "Cannot determine endianness" -#endif - -#if defined(__clang__) -# if __has_builtin(__builtin_bswap16) -# define MOZ_HAVE_BUILTIN_BYTESWAP16 __builtin_bswap16 -# endif -#elif defined(__GNUC__) -# define MOZ_HAVE_BUILTIN_BYTESWAP16 __builtin_bswap16 -#elif defined(_MSC_VER) -# define MOZ_HAVE_BUILTIN_BYTESWAP16 _byteswap_ushort -#endif - -namespace mozilla { - -namespace detail { - -/* - * We need wrappers here because free functions with default template - * arguments and/or partial specialization of function templates are not - * supported by all the compilers we use. - */ -template -struct Swapper; - -template -struct Swapper -{ - static T swap(T aValue) - { -#if defined(MOZ_HAVE_BUILTIN_BYTESWAP16) - return MOZ_HAVE_BUILTIN_BYTESWAP16(aValue); -#else - return T(((aValue & 0x00ff) << 8) | ((aValue & 0xff00) >> 8)); -#endif - } -}; - -template -struct Swapper -{ - static T swap(T aValue) - { -#if defined(__clang__) || defined(__GNUC__) - return T(__builtin_bswap32(aValue)); -#elif defined(_MSC_VER) - return T(_byteswap_ulong(aValue)); -#else - return T(((aValue & 0x000000ffU) << 24) | - ((aValue & 0x0000ff00U) << 8) | - ((aValue & 0x00ff0000U) >> 8) | - ((aValue & 0xff000000U) >> 24)); -#endif - } -}; - -template -struct Swapper -{ - static inline T swap(T aValue) - { -#if defined(__clang__) || defined(__GNUC__) - return T(__builtin_bswap64(aValue)); -#elif defined(_MSC_VER) - return T(_byteswap_uint64(aValue)); -#else - return T(((aValue & 0x00000000000000ffULL) << 56) | - ((aValue & 0x000000000000ff00ULL) << 40) | - ((aValue & 0x0000000000ff0000ULL) << 24) | - ((aValue & 0x00000000ff000000ULL) << 8) | - ((aValue & 0x000000ff00000000ULL) >> 8) | - ((aValue & 0x0000ff0000000000ULL) >> 24) | - ((aValue & 0x00ff000000000000ULL) >> 40) | - ((aValue & 0xff00000000000000ULL) >> 56)); -#endif - } -}; - -enum Endianness { Little, Big }; - -#if MOZ_BIG_ENDIAN -# define MOZ_NATIVE_ENDIANNESS detail::Big -#else -# define MOZ_NATIVE_ENDIANNESS detail::Little -#endif - -class EndianUtils -{ - /** - * Assert that the memory regions [aDest, aDest+aCount) and - * [aSrc, aSrc+aCount] do not overlap. aCount is given in bytes. - */ - static void assertNoOverlap(const void* aDest, const void* aSrc, - size_t aCount) - { - DebugOnly byteDestPtr = static_cast(aDest); - DebugOnly byteSrcPtr = static_cast(aSrc); - MOZ_ASSERT((byteDestPtr <= byteSrcPtr && - byteDestPtr + aCount <= byteSrcPtr) || - (byteSrcPtr <= byteDestPtr && - byteSrcPtr + aCount <= byteDestPtr)); - } - - template - static void assertAligned(T* aPtr) - { - MOZ_ASSERT((uintptr_t(aPtr) % sizeof(T)) == 0, "Unaligned pointer!"); - } - -protected: - /** - * Return |aValue| converted from SourceEndian encoding to DestEndian - * encoding. - */ - template - static inline T maybeSwap(T aValue) - { - if (SourceEndian == DestEndian) { - return aValue; - } - return Swapper::swap(aValue); - } - - /** - * Convert |aCount| elements at |aPtr| from SourceEndian encoding to - * DestEndian encoding. - */ - template - static inline void maybeSwapInPlace(T* aPtr, size_t aCount) - { - assertAligned(aPtr); - - if (SourceEndian == DestEndian) { - return; - } - for (size_t i = 0; i < aCount; i++) { - aPtr[i] = Swapper::swap(aPtr[i]); - } - } - - /** - * Write |aCount| elements to the unaligned address |aDest| in DestEndian - * format, using elements found at |aSrc| in SourceEndian format. - */ - template - static void copyAndSwapTo(void* aDest, const T* aSrc, size_t aCount) - { - assertNoOverlap(aDest, aSrc, aCount * sizeof(T)); - assertAligned(aSrc); - - if (SourceEndian == DestEndian) { - memcpy(aDest, aSrc, aCount * sizeof(T)); - return; - } - - uint8_t* byteDestPtr = static_cast(aDest); - for (size_t i = 0; i < aCount; ++i) { - union - { - T mVal; - uint8_t mBuffer[sizeof(T)]; - } u; - u.mVal = maybeSwap(aSrc[i]); - memcpy(byteDestPtr, u.mBuffer, sizeof(T)); - byteDestPtr += sizeof(T); - } - } - - /** - * Write |aCount| elements to |aDest| in DestEndian format, using elements - * found at the unaligned address |aSrc| in SourceEndian format. - */ - template - static void copyAndSwapFrom(T* aDest, const void* aSrc, size_t aCount) - { - assertNoOverlap(aDest, aSrc, aCount * sizeof(T)); - assertAligned(aDest); - - if (SourceEndian == DestEndian) { - memcpy(aDest, aSrc, aCount * sizeof(T)); - return; - } - - const uint8_t* byteSrcPtr = static_cast(aSrc); - for (size_t i = 0; i < aCount; ++i) { - union - { - T mVal; - uint8_t mBuffer[sizeof(T)]; - } u; - memcpy(u.mBuffer, byteSrcPtr, sizeof(T)); - aDest[i] = maybeSwap(u.mVal); - byteSrcPtr += sizeof(T); - } - } -}; - -template -class Endian : private EndianUtils -{ -protected: - /** Read a uint16_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE uint16_t readUint16(const void* aPtr) - { - return read(aPtr); - } - - /** Read a uint32_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE uint32_t readUint32(const void* aPtr) - { - return read(aPtr); - } - - /** Read a uint64_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE uint64_t readUint64(const void* aPtr) - { - return read(aPtr); - } - - /** Read an int16_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE int16_t readInt16(const void* aPtr) - { - return read(aPtr); - } - - /** Read an int32_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE int32_t readInt32(const void* aPtr) - { - return read(aPtr); - } - - /** Read an int64_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE int64_t readInt64(const void* aPtr) - { - return read(aPtr); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeUint16(void* aPtr, uint16_t aValue) - { - write(aPtr, aValue); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeUint32(void* aPtr, uint32_t aValue) - { - write(aPtr, aValue); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeUint64(void* aPtr, uint64_t aValue) - { - write(aPtr, aValue); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeInt16(void* aPtr, int16_t aValue) - { - write(aPtr, aValue); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeInt32(void* aPtr, int32_t aValue) - { - write(aPtr, aValue); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeInt64(void* aPtr, int64_t aValue) - { - write(aPtr, aValue); - } - - /* - * Converts a value of type T to little-endian format. - * - * This function is intended for cases where you have data in your - * native-endian format and you need it to appear in little-endian - * format for transmission. - */ - template - MOZ_MUST_USE static T swapToLittleEndian(T aValue) - { - return maybeSwap(aValue); - } - - /* - * Copies |aCount| values of type T starting at |aSrc| to |aDest|, converting - * them to little-endian format if ThisEndian is Big. - * As with memcpy, |aDest| and |aSrc| must not overlap. - */ - template - static void copyAndSwapToLittleEndian(void* aDest, const T* aSrc, - size_t aCount) - { - copyAndSwapTo(aDest, aSrc, aCount); - } - - /* - * Likewise, but converts values in place. - */ - template - static void swapToLittleEndianInPlace(T* aPtr, size_t aCount) - { - maybeSwapInPlace(aPtr, aCount); - } - - /* - * Converts a value of type T to big-endian format. - */ - template - MOZ_MUST_USE static T swapToBigEndian(T aValue) - { - return maybeSwap(aValue); - } - - /* - * Copies |aCount| values of type T starting at |aSrc| to |aDest|, converting - * them to big-endian format if ThisEndian is Little. - * As with memcpy, |aDest| and |aSrc| must not overlap. - */ - template - static void copyAndSwapToBigEndian(void* aDest, const T* aSrc, - size_t aCount) - { - copyAndSwapTo(aDest, aSrc, aCount); - } - - /* - * Likewise, but converts values in place. - */ - template - static void swapToBigEndianInPlace(T* aPtr, size_t aCount) - { - maybeSwapInPlace(aPtr, aCount); - } - - /* - * Synonyms for the big-endian functions, for better readability - * in network code. - */ - - template - MOZ_MUST_USE static T swapToNetworkOrder(T aValue) - { - return swapToBigEndian(aValue); - } - - template - static void - copyAndSwapToNetworkOrder(void* aDest, const T* aSrc, size_t aCount) - { - copyAndSwapToBigEndian(aDest, aSrc, aCount); - } - - template - static void - swapToNetworkOrderInPlace(T* aPtr, size_t aCount) - { - swapToBigEndianInPlace(aPtr, aCount); - } - - /* - * Converts a value of type T from little-endian format. - */ - template - MOZ_MUST_USE static T swapFromLittleEndian(T aValue) - { - return maybeSwap(aValue); - } - - /* - * Copies |aCount| values of type T starting at |aSrc| to |aDest|, converting - * them to little-endian format if ThisEndian is Big. - * As with memcpy, |aDest| and |aSrc| must not overlap. - */ - template - static void copyAndSwapFromLittleEndian(T* aDest, const void* aSrc, - size_t aCount) - { - copyAndSwapFrom(aDest, aSrc, aCount); - } - - /* - * Likewise, but converts values in place. - */ - template - static void swapFromLittleEndianInPlace(T* aPtr, size_t aCount) - { - maybeSwapInPlace(aPtr, aCount); - } - - /* - * Converts a value of type T from big-endian format. - */ - template - MOZ_MUST_USE static T swapFromBigEndian(T aValue) - { - return maybeSwap(aValue); - } - - /* - * Copies |aCount| values of type T starting at |aSrc| to |aDest|, converting - * them to big-endian format if ThisEndian is Little. - * As with memcpy, |aDest| and |aSrc| must not overlap. - */ - template - static void copyAndSwapFromBigEndian(T* aDest, const void* aSrc, - size_t aCount) - { - copyAndSwapFrom(aDest, aSrc, aCount); - } - - /* - * Likewise, but converts values in place. - */ - template - static void swapFromBigEndianInPlace(T* aPtr, size_t aCount) - { - maybeSwapInPlace(aPtr, aCount); - } - - /* - * Synonyms for the big-endian functions, for better readability - * in network code. - */ - template - MOZ_MUST_USE static T swapFromNetworkOrder(T aValue) - { - return swapFromBigEndian(aValue); - } - - template - static void copyAndSwapFromNetworkOrder(T* aDest, const void* aSrc, - size_t aCount) - { - copyAndSwapFromBigEndian(aDest, aSrc, aCount); - } - - template - static void swapFromNetworkOrderInPlace(T* aPtr, size_t aCount) - { - swapFromBigEndianInPlace(aPtr, aCount); - } - -private: - /** - * Read a value of type T, encoded in endianness ThisEndian from |aPtr|. - * Return that value encoded in native endianness. - */ - template - static T read(const void* aPtr) - { - union - { - T mVal; - uint8_t mBuffer[sizeof(T)]; - } u; - memcpy(u.mBuffer, aPtr, sizeof(T)); - return maybeSwap(u.mVal); - } - - /** - * Write a value of type T, in native endianness, to |aPtr|, in ThisEndian - * endianness. - */ - template - static void write(void* aPtr, T aValue) - { - T tmp = maybeSwap(aValue); - memcpy(aPtr, &tmp, sizeof(T)); - } - - Endian() = delete; - Endian(const Endian& aTther) = delete; - void operator=(const Endian& aOther) = delete; -}; - -template -class EndianReadWrite : public Endian -{ -private: - typedef Endian super; - -public: - using super::readUint16; - using super::readUint32; - using super::readUint64; - using super::readInt16; - using super::readInt32; - using super::readInt64; - using super::writeUint16; - using super::writeUint32; - using super::writeUint64; - using super::writeInt16; - using super::writeInt32; - using super::writeInt64; -}; - -} /* namespace detail */ - -class LittleEndian final : public detail::EndianReadWrite -{}; - -class BigEndian final : public detail::EndianReadWrite -{}; - -typedef BigEndian NetworkEndian; - -class NativeEndian final : public detail::Endian -{ -private: - typedef detail::Endian super; - -public: - /* - * These functions are intended for cases where you have data in your - * native-endian format and you need the data to appear in the appropriate - * endianness for transmission, serialization, etc. - */ - using super::swapToLittleEndian; - using super::copyAndSwapToLittleEndian; - using super::swapToLittleEndianInPlace; - using super::swapToBigEndian; - using super::copyAndSwapToBigEndian; - using super::swapToBigEndianInPlace; - using super::swapToNetworkOrder; - using super::copyAndSwapToNetworkOrder; - using super::swapToNetworkOrderInPlace; - - /* - * These functions are intended for cases where you have data in the - * given endianness (e.g. reading from disk or a file-format) and you - * need the data to appear in native-endian format for processing. - */ - using super::swapFromLittleEndian; - using super::copyAndSwapFromLittleEndian; - using super::swapFromLittleEndianInPlace; - using super::swapFromBigEndian; - using super::copyAndSwapFromBigEndian; - using super::swapFromBigEndianInPlace; - using super::swapFromNetworkOrder; - using super::copyAndSwapFromNetworkOrder; - using super::swapFromNetworkOrderInPlace; -}; - -#undef MOZ_NATIVE_ENDIANNESS - -} /* namespace mozilla */ - -#endif /* mozilla_EndianUtils_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/EnumSet.h b/android/arm64-v8a/include/spidermonkey/mozilla/EnumSet.h deleted file mode 100644 index 5282ab30..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/EnumSet.h +++ /dev/null @@ -1,344 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A set abstraction for enumeration values. */ - -#ifndef mozilla_EnumSet_h -#define mozilla_EnumSet_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -#include - -#include - -namespace mozilla { - -/** - * EnumSet is a set of values defined by an enumeration. It is implemented - * using a 32 bit mask for each value so it will only work for enums with an int - * representation less than 32. It works both for enum and enum class types. - */ -template -class EnumSet -{ -public: - EnumSet() - : mBitField(0) - { - initVersion(); - } - - MOZ_IMPLICIT EnumSet(T aEnum) - : mBitField(bitFor(aEnum)) - { } - - EnumSet(T aEnum1, T aEnum2) - : mBitField(bitFor(aEnum1) | - bitFor(aEnum2)) - { - initVersion(); - } - - EnumSet(T aEnum1, T aEnum2, T aEnum3) - : mBitField(bitFor(aEnum1) | - bitFor(aEnum2) | - bitFor(aEnum3)) - { - initVersion(); - } - - EnumSet(T aEnum1, T aEnum2, T aEnum3, T aEnum4) - : mBitField(bitFor(aEnum1) | - bitFor(aEnum2) | - bitFor(aEnum3) | - bitFor(aEnum4)) - { - initVersion(); - } - - MOZ_IMPLICIT EnumSet(std::initializer_list list) - : mBitField(0) - { - for (auto value : list) { - (*this) += value; - } - initVersion(); - } - - EnumSet(const EnumSet& aEnumSet) - : mBitField(aEnumSet.mBitField) - { - initVersion(); - } - - /** - * Add an element - */ - void operator+=(T aEnum) - { - incVersion(); - mBitField |= bitFor(aEnum); - } - - /** - * Add an element - */ - EnumSet operator+(T aEnum) const - { - EnumSet result(*this); - result += aEnum; - return result; - } - - /** - * Union - */ - void operator+=(const EnumSet aEnumSet) - { - incVersion(); - mBitField |= aEnumSet.mBitField; - } - - /** - * Union - */ - EnumSet operator+(const EnumSet aEnumSet) const - { - EnumSet result(*this); - result += aEnumSet; - return result; - } - - /** - * Remove an element - */ - void operator-=(T aEnum) - { - incVersion(); - mBitField &= ~(bitFor(aEnum)); - } - - /** - * Remove an element - */ - EnumSet operator-(T aEnum) const - { - EnumSet result(*this); - result -= aEnum; - return result; - } - - /** - * Remove a set of elements - */ - void operator-=(const EnumSet aEnumSet) - { - incVersion(); - mBitField &= ~(aEnumSet.mBitField); - } - - /** - * Remove a set of elements - */ - EnumSet operator-(const EnumSet aEnumSet) const - { - EnumSet result(*this); - result -= aEnumSet; - return result; - } - - /** - * Clear - */ - void clear() - { - incVersion(); - mBitField = 0; - } - - /** - * Intersection - */ - void operator&=(const EnumSet aEnumSet) - { - incVersion(); - mBitField &= aEnumSet.mBitField; - } - - /** - * Intersection - */ - EnumSet operator&(const EnumSet aEnumSet) const - { - EnumSet result(*this); - result &= aEnumSet; - return result; - } - - /** - * Equality - */ - bool operator==(const EnumSet aEnumSet) const - { - return mBitField == aEnumSet.mBitField; - } - - /** - * Test is an element is contained in the set. - */ - bool contains(T aEnum) const - { - return mBitField & bitFor(aEnum); - } - - /** - * Return the number of elements in the set. - */ - uint8_t size() const - { - uint8_t count = 0; - for (uint32_t bitField = mBitField; bitField; bitField >>= 1) { - if (bitField & 1) { - count++; - } - } - return count; - } - - bool isEmpty() const - { - return mBitField == 0; - } - - uint32_t serialize() const - { - return mBitField; - } - - void deserialize(uint32_t aValue) - { - incVersion(); - mBitField = aValue; - } - - class ConstIterator - { - const EnumSet* mSet; - uint32_t mPos; -#ifdef DEBUG - uint64_t mVersion; -#endif - - void checkVersion() { - // Check that the set has not been modified while being iterated. - MOZ_ASSERT_IF(mSet, mSet->mVersion == mVersion); - } - - public: - ConstIterator(const EnumSet& aSet, uint32_t aPos) - : mSet(&aSet), mPos(aPos) - { -#ifdef DEBUG - mVersion = mSet->mVersion; -#endif - MOZ_ASSERT(aPos <= kMaxBits); - if (aPos != kMaxBits && !mSet->contains(T(mPos))) - ++*this; - } - - ConstIterator(const ConstIterator& aOther) - : mSet(aOther.mSet), mPos(aOther.mPos) - { -#ifdef DEBUG - mVersion = aOther.mVersion; - checkVersion(); -#endif - } - - ConstIterator(ConstIterator&& aOther) - : mSet(aOther.mSet), mPos(aOther.mPos) - { -#ifdef DEBUG - mVersion = aOther.mVersion; - checkVersion(); -#endif - aOther.mSet = nullptr; - } - - ~ConstIterator() { - checkVersion(); - } - - bool operator==(const ConstIterator& other) { - MOZ_ASSERT(mSet == other.mSet); - checkVersion(); - return mPos == other.mPos; - } - - bool operator!=(const ConstIterator& other) { - return !(*this == other); - } - - T operator*() { - MOZ_ASSERT(mSet); - MOZ_ASSERT(mPos < kMaxBits); - MOZ_ASSERT(mSet->contains(T(mPos))); - checkVersion(); - return T(mPos); - } - - ConstIterator& operator++() { - MOZ_ASSERT(mSet); - MOZ_ASSERT(mPos < kMaxBits); - checkVersion(); - do { - mPos++; - } while (mPos < kMaxBits && !mSet->contains(T(mPos))); - return *this; - } - }; - - ConstIterator begin() const { - return ConstIterator(*this, 0); - } - - ConstIterator end() const { - return ConstIterator(*this, kMaxBits); - } - -private: - static uint32_t bitFor(T aEnum) - { - uint32_t bitNumber = (uint32_t)aEnum; - MOZ_ASSERT(bitNumber < kMaxBits); - return 1U << bitNumber; - } - - void initVersion() { -#ifdef DEBUG - mVersion = 0; -#endif - } - - void incVersion() { -#ifdef DEBUG - mVersion++; -#endif - } - - static const size_t kMaxBits = 32; - uint32_t mBitField; - -#ifdef DEBUG - uint64_t mVersion; -#endif -}; - -} // namespace mozilla - -#endif /* mozilla_EnumSet_h_*/ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/EnumTypeTraits.h b/android/arm64-v8a/include/spidermonkey/mozilla/EnumTypeTraits.h deleted file mode 100644 index 223eaf8c..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/EnumTypeTraits.h +++ /dev/null @@ -1,70 +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/. */ - -/* Type traits for enums. */ - -#ifndef mozilla_EnumTypeTraits_h -#define mozilla_EnumTypeTraits_h - -#include - -namespace mozilla { - -namespace detail { - -template -struct EnumFitsWithinHelper; - -// Signed enum, signed storage. -template -struct EnumFitsWithinHelper - : public std::integral_constant -{}; - -// Signed enum, unsigned storage. -template -struct EnumFitsWithinHelper - : public std::integral_constant -{}; - -// Unsigned enum, signed storage. -template -struct EnumFitsWithinHelper - : public std::integral_constant -{}; - -// Unsigned enum, unsigned storage. -template -struct EnumFitsWithinHelper - : public std::integral_constant -{}; - -} // namespace detail - -/* - * Type trait that determines whether the enum type T can fit within the - * integral type Storage without data loss. This trait should be used with - * caution with an enum type whose underlying type has not been explicitly - * specified: for such enums, the C++ implementation is free to choose a type - * no smaller than int whose range encompasses all possible values of the enum. - * So for an enum with only small non-negative values, the underlying type may - * be either int or unsigned int, depending on the whims of the implementation. - */ -template -struct EnumTypeFitsWithin - : public detail::EnumFitsWithinHelper< - sizeof(T), - std::is_signed::type>::value, - sizeof(Storage), - std::is_signed::value - > -{ - static_assert(std::is_enum::value, "must provide an enum type"); - static_assert(std::is_integral::value, "must provide an integral type"); -}; - -} // namespace mozilla - -#endif /* mozilla_EnumTypeTraits_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/EnumeratedArray.h b/android/arm64-v8a/include/spidermonkey/mozilla/EnumeratedArray.h deleted file mode 100644 index 9e74b772..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/EnumeratedArray.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* EnumeratedArray is like Array, but indexed by a typed enum. */ - -#ifndef mozilla_EnumeratedArray_h -#define mozilla_EnumeratedArray_h - -#include "mozilla/Array.h" -#include "mozilla/Move.h" - -namespace mozilla { - -/** - * EnumeratedArray is a fixed-size array container for use when an - * array is indexed by a specific enum class. - * - * This provides type safety by guarding at compile time against accidentally - * indexing such arrays with unrelated values. This also removes the need - * for manual casting when using a typed enum value to index arrays. - * - * Aside from the typing of indices, EnumeratedArray is similar to Array. - * - * Example: - * - * enum class AnimalSpecies { - * Cow, - * Sheep, - * Count - * }; - * - * EnumeratedArray headCount; - * - * headCount[AnimalSpecies::Cow] = 17; - * headCount[AnimalSpecies::Sheep] = 30; - * - */ -template -class EnumeratedArray -{ -public: - static const size_t kSize = size_t(SizeAsEnumValue); - -private: - typedef Array ArrayType; - - ArrayType mArray; - -public: - EnumeratedArray() {} - - template - MOZ_IMPLICIT EnumeratedArray(Args&&... aArgs) - : mArray{mozilla::Forward(aArgs)...} - {} - - explicit EnumeratedArray(const EnumeratedArray& aOther) - { - for (size_t i = 0; i < kSize; i++) { - mArray[i] = aOther.mArray[i]; - } - } - - EnumeratedArray(EnumeratedArray&& aOther) - { - for (size_t i = 0; i < kSize; i++) { - mArray[i] = Move(aOther.mArray[i]); - } - } - - ValueType& operator[](IndexType aIndex) - { - return mArray[size_t(aIndex)]; - } - - const ValueType& operator[](IndexType aIndex) const - { - return mArray[size_t(aIndex)]; - } - - typedef typename ArrayType::iterator iterator; - typedef typename ArrayType::const_iterator const_iterator; - typedef typename ArrayType::reverse_iterator reverse_iterator; - typedef typename ArrayType::const_reverse_iterator const_reverse_iterator; - - // Methods for range-based for loops. - iterator begin() { return mArray.begin(); } - const_iterator begin() const { return mArray.begin(); } - const_iterator cbegin() const { return mArray.cbegin(); } - iterator end() { return mArray.end(); } - const_iterator end() const { return mArray.end(); } - const_iterator cend() const { return mArray.cend(); } - - // Methods for reverse iterating. - reverse_iterator rbegin() { return mArray.rbegin(); } - const_reverse_iterator rbegin() const { return mArray.rbegin(); } - const_reverse_iterator crbegin() const { return mArray.crbegin(); } - reverse_iterator rend() { return mArray.rend(); } - const_reverse_iterator rend() const { return mArray.rend(); } - const_reverse_iterator crend() const { return mArray.crend(); } -}; - -} // namespace mozilla - -#endif // mozilla_EnumeratedArray_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/EnumeratedRange.h b/android/arm64-v8a/include/spidermonkey/mozilla/EnumeratedRange.h deleted file mode 100644 index b158f8a3..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/EnumeratedRange.h +++ /dev/null @@ -1,201 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Iterator over contiguous enum values */ - -/* - * Implements generator functions that create a range to iterate over the values - * of a scoped or unscoped enum. Unlike IntegerRange, which can only function on - * the underlying integral type, the elements of the generated sequence will - * have the type of the enum in question. - * - * Note that the enum values should be contiguous in the iterated range; - * unfortunately there exists no way for EnumeratedRange to enforce this - * either dynamically or at compile time. - */ - -#ifndef mozilla_EnumeratedRange_h -#define mozilla_EnumeratedRange_h - -#include - -#include "mozilla/ReverseIterator.h" - -namespace mozilla { - -namespace detail { - -template -class EnumeratedIterator -{ -public: - typedef typename std::underlying_type::type IntTypeT; - - template - explicit EnumeratedIterator(EnumType aCurrent) - : mCurrent(aCurrent) { } - - template - explicit EnumeratedIterator(const EnumeratedIterator& aOther) - : mCurrent(aOther.mCurrent) { } - - EnumTypeT operator*() const { return mCurrent; } - - /* Increment and decrement operators */ - - EnumeratedIterator& operator++() - { - mCurrent = EnumTypeT(IntTypeT(mCurrent) + IntTypeT(1)); - return *this; - } - EnumeratedIterator& operator--() - { - mCurrent = EnumTypeT(IntTypeT(mCurrent) - IntTypeT(1)); - return *this; - } - EnumeratedIterator operator++(int) - { - auto ret = *this; - mCurrent = EnumTypeT(IntTypeT(mCurrent) + IntTypeT(1)); - return ret; - } - EnumeratedIterator operator--(int) - { - auto ret = *this; - mCurrent = EnumTypeT(IntTypeT(mCurrent) - IntTypeT(1)); - return ret; - } - - /* Comparison operators */ - - template - friend bool operator==(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - template - friend bool operator!=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - template - friend bool operator<(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - template - friend bool operator<=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - template - friend bool operator>(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - template - friend bool operator>=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - -private: - EnumTypeT mCurrent; -}; - -template -bool operator==(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent == aIter2.mCurrent; -} - -template -bool operator!=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent != aIter2.mCurrent; -} - -template -bool operator<(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent < aIter2.mCurrent; -} - -template -bool operator<=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent <= aIter2.mCurrent; -} - -template -bool operator>(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent > aIter2.mCurrent; -} - -template -bool operator>=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent >= aIter2.mCurrent; -} - -template -class EnumeratedRange -{ -public: - typedef EnumeratedIterator iterator; - typedef EnumeratedIterator const_iterator; - typedef ReverseIterator reverse_iterator; - typedef ReverseIterator const_reverse_iterator; - - template - EnumeratedRange(EnumType aBegin, EnumType aEnd) - : mBegin(aBegin), mEnd(aEnd) { } - - iterator begin() const { return iterator(mBegin); } - const_iterator cbegin() const { return begin(); } - iterator end() const { return iterator(mEnd); } - const_iterator cend() const { return end(); } - reverse_iterator rbegin() const { return reverse_iterator(mEnd); } - const_reverse_iterator crbegin() const { return rbegin(); } - reverse_iterator rend() const { return reverse_iterator(mBegin); } - const_reverse_iterator crend() const { return rend(); } - -private: - EnumTypeT mBegin; - EnumTypeT mEnd; -}; - -} // namespace detail - -#ifdef __GNUC__ -// Enums can have an unsigned underlying type, which makes some of the -// comparisons below always true or always false. Temporarily disable -// -Wtype-limits to avoid breaking -Werror builds. -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wtype-limits" -#endif - -// Create a range to iterate from aBegin to aEnd, exclusive. -template -inline detail::EnumeratedRange -MakeEnumeratedRange(EnumType aBegin, EnumType aEnd) -{ - MOZ_ASSERT(aBegin <= aEnd, "Cannot generate invalid, unbounded range!"); - return detail::EnumeratedRange(aBegin, aEnd); -} - -// Create a range to iterate from EnumType(0) to aEnd, exclusive. EnumType(0) -// should exist, but note that there is no way for us to ensure that it does! -template -inline detail::EnumeratedRange -MakeEnumeratedRange(EnumType aEnd) -{ - return MakeEnumeratedRange(EnumType(0), aEnd); -} - -#ifdef __GNUC__ -# pragma GCC diagnostic pop -#endif - -} // namespace mozilla - -#endif // mozilla_EnumeratedRange_h - diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/FastBernoulliTrial.h b/android/arm64-v8a/include/spidermonkey/mozilla/FastBernoulliTrial.h deleted file mode 100644 index 7e38b70a..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/FastBernoulliTrial.h +++ /dev/null @@ -1,379 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_FastBernoulliTrial_h -#define mozilla_FastBernoulliTrial_h - -#include "mozilla/Assertions.h" -#include "mozilla/XorShift128PlusRNG.h" - -#include -#include - -namespace mozilla { - -/** - * class FastBernoulliTrial: Efficient sampling with uniform probability - * - * When gathering statistics about a program's behavior, we may be observing - * events that occur very frequently (e.g., function calls or memory - * allocations) and we may be gathering information that is somewhat expensive - * to produce (e.g., call stacks). Sampling all the events could have a - * significant impact on the program's performance. - * - * Why not just sample every N'th event? This technique is called "systematic - * sampling"; it's simple and efficient, and it's fine if we imagine a - * patternless stream of events. But what if we're sampling allocations, and the - * program happens to have a loop where each iteration does exactly N - * allocations? You would end up sampling the same allocation every time through - * the loop; the entire rest of the loop becomes invisible to your measurements! - * More generally, if each iteration does M allocations, and M and N have any - * common divisor at all, most allocation sites will never be sampled. If - * they're both even, say, the odd-numbered allocations disappear from your - * results. - * - * Ideally, we'd like each event to have some probability P of being sampled, - * independent of its neighbors and of its position in the sequence. This is - * called "Bernoulli sampling", and it doesn't suffer from any of the problems - * mentioned above. - * - * One disadvantage of Bernoulli sampling is that you can't be sure exactly how - * many samples you'll get: technically, it's possible that you might sample - * none of them, or all of them. But if the number of events N is large, these - * aren't likely outcomes; you can generally expect somewhere around P * N - * events to be sampled. - * - * The other disadvantage of Bernoulli sampling is that you have to generate a - * random number for every event, which can be slow. - * - * [significant pause] - * - * BUT NOT WITH THIS CLASS! FastBernoulliTrial lets you do true Bernoulli - * sampling, while generating a fresh random number only when we do decide to - * sample an event, not on every trial. When it decides not to sample, a call to - * |FastBernoulliTrial::trial| is nothing but decrementing a counter and - * comparing it to zero. So the lower your sampling probability is, the less - * overhead FastBernoulliTrial imposes. - * - * Probabilities of 0 and 1 are handled efficiently. (In neither case need we - * ever generate a random number at all.) - * - * The essential API: - * - * - FastBernoulliTrial(double P) - * Construct an instance that selects events with probability P. - * - * - FastBernoulliTrial::trial() - * Return true with probability P. Call this each time an event occurs, to - * decide whether to sample it or not. - * - * - FastBernoulliTrial::trial(size_t n) - * Equivalent to calling trial() |n| times, and returning true if any of those - * calls do. However, like trial, this runs in fast constant time. - * - * What is this good for? In some applications, some events are "bigger" than - * others. For example, large allocations are more significant than small - * allocations. Perhaps we'd like to imagine that we're drawing allocations - * from a stream of bytes, and performing a separate Bernoulli trial on every - * byte from the stream. We can accomplish this by calling |t.trial(S)| for - * the number of bytes S, and sampling the event if that returns true. - * - * Of course, this style of sampling needs to be paired with analysis and - * presentation that makes the size of the event apparent, lest trials with - * large values for |n| appear to be indistinguishable from those with small - * values for |n|. - */ -class FastBernoulliTrial { - /* - * This comment should just read, "Generate skip counts with a geometric - * distribution", and leave everyone to go look that up and see why it's the - * right thing to do, if they don't know already. - * - * BUT IF YOU'RE CURIOUS, COMMENTS ARE FREE... - * - * Instead of generating a fresh random number for every trial, we can - * randomly generate a count of how many times we should return false before - * the next time we return true. We call this a "skip count". Once we've - * returned true, we generate a fresh skip count, and begin counting down - * again. - * - * Here's an awesome fact: by exercising a little care in the way we generate - * skip counts, we can produce results indistinguishable from those we would - * get "rolling the dice" afresh for every trial. - * - * In short, skip counts in Bernoulli trials of probability P obey a geometric - * distribution. If a random variable X is uniformly distributed from [0..1), - * then std::floor(std::log(X) / std::log(1-P)) has the appropriate geometric - * distribution for the skip counts. - * - * Why that formula? - * - * Suppose we're to return |true| with some probability P, say, 0.3. Spread - * all possible futures along a line segment of length 1. In portion P of - * those cases, we'll return true on the next call to |trial|; the skip count - * is 0. For the remaining portion 1-P of cases, the skip count is 1 or more. - * - * skip: 0 1 or more - * |------------------^-----------------------------------------| - * portion: 0.3 0.7 - * P 1-P - * - * But the "1 or more" section of the line is subdivided the same way: *within - * that section*, in portion P the second call to |trial()| returns true, and in - * portion 1-P it returns false a second time; the skip count is two or more. - * So we return true on the second call in proportion 0.7 * 0.3, and skip at - * least the first two in proportion 0.7 * 0.7. - * - * skip: 0 1 2 or more - * |------------------^------------^----------------------------| - * portion: 0.3 0.7 * 0.3 0.7 * 0.7 - * P (1-P)*P (1-P)^2 - * - * We can continue to subdivide: - * - * skip >= 0: |------------------------------------------------- (1-P)^0 --| - * skip >= 1: | ------------------------------- (1-P)^1 --| - * skip >= 2: | ------------------ (1-P)^2 --| - * skip >= 3: | ^ ---------- (1-P)^3 --| - * skip >= 4: | . --- (1-P)^4 --| - * . - * ^X, see below - * - * In other words, the likelihood of the next n calls to |trial| returning - * false is (1-P)^n. The longer a run we require, the more the likelihood - * drops. Further calls may return false too, but this is the probability - * we'll skip at least n. - * - * This is interesting, because we can pick a point along this line segment - * and see which skip count's range it falls within; the point X above, for - * example, is within the ">= 2" range, but not within the ">= 3" range, so it - * designates a skip count of 2. So if we pick points on the line at random - * and use the skip counts they fall under, that will be indistinguishable - * from generating a fresh random number between 0 and 1 for each trial and - * comparing it to P. - * - * So to find the skip count for a point X, we must ask: To what whole power - * must we raise 1-P such that we include X, but the next power would exclude - * it? This is exactly std::floor(std::log(X) / std::log(1-P)). - * - * Our algorithm is then, simply: When constructed, compute an initial skip - * count. Return false from |trial| that many times, and then compute a new skip - * count. - * - * For a call to |trial(n)|, if the skip count is greater than n, return false - * and subtract n from the skip count. If the skip count is less than n, - * return true and compute a new skip count. Since each trial is independent, - * it doesn't matter by how much n overshoots the skip count; we can actually - * compute a new skip count at *any* time without affecting the distribution. - * This is really beautiful. - */ - public: - /** - * Construct a fast Bernoulli trial generator. Calls to |trial()| return true - * with probability |aProbability|. Use |aState0| and |aState1| to seed the - * random number generator; both may not be zero. - */ - FastBernoulliTrial(double aProbability, uint64_t aState0, uint64_t aState1) - : mProbability(0) - , mInvLogNotProbability(0) - , mGenerator(aState0, aState1) - , mSkipCount(0) - { - setProbability(aProbability); - } - - /** - * Return true with probability |mProbability|. Call this each time an event - * occurs, to decide whether to sample it or not. The lower |mProbability| is, - * the faster this function runs. - */ - bool trial() { - if (mSkipCount) { - mSkipCount--; - return false; - } - - return chooseSkipCount(); - } - - /** - * Equivalent to calling trial() |n| times, and returning true if any of those - * calls do. However, like trial, this runs in fast constant time. - * - * What is this good for? In some applications, some events are "bigger" than - * others. For example, large allocations are more significant than small - * allocations. Perhaps we'd like to imagine that we're drawing allocations - * from a stream of bytes, and performing a separate Bernoulli trial on every - * byte from the stream. We can accomplish this by calling |t.trial(S)| for - * the number of bytes S, and sampling the event if that returns true. - * - * Of course, this style of sampling needs to be paired with analysis and - * presentation that makes the "size" of the event apparent, lest trials with - * large values for |n| appear to be indistinguishable from those with small - * values for |n|, despite being potentially much more likely to be sampled. - */ - bool trial(size_t aCount) { - if (mSkipCount > aCount) { - mSkipCount -= aCount; - return false; - } - - return chooseSkipCount(); - } - - void setRandomState(uint64_t aState0, uint64_t aState1) { - mGenerator.setState(aState0, aState1); - } - - void setProbability(double aProbability) { - MOZ_ASSERT(0 <= aProbability && aProbability <= 1); - mProbability = aProbability; - if (0 < mProbability && mProbability < 1) { - /* - * Let's look carefully at how this calculation plays out in floating- - * point arithmetic. We'll assume IEEE, but the final C++ code we arrive - * at would still be fine if our numbers were mathematically perfect. So, - * while we've considered IEEE's edge cases, we haven't done anything that - * should be actively bad when using other representations. - * - * (In the below, read comparisons as exact mathematical comparisons: when - * we say something "equals 1", that means it's exactly equal to 1. We - * treat approximation using intervals with open boundaries: saying a - * value is in (0,1) doesn't specify how close to 0 or 1 the value gets. - * When we use closed boundaries like [2**-53, 1], we're careful to ensure - * the boundary values are actually representable.) - * - * - After the comparison above, we know mProbability is in (0,1). - * - * - The gaps below 1 are 2**-53, so that interval is (0, 1-2**-53]. - * - * - Because the floating-point gaps near 1 are wider than those near - * zero, there are many small positive doubles ε such that 1-ε rounds to - * exactly 1. However, 2**-53 can be represented exactly. So - * 1-mProbability is in [2**-53, 1]. - * - * - log(1 - mProbability) is thus in (-37, 0]. - * - * That range includes zero, but when we use mInvLogNotProbability, it - * would be helpful if we could trust that it's negative. So when log(1 - * - mProbability) is 0, we'll just set mProbability to 0, so that - * mInvLogNotProbability is not used in chooseSkipCount. - * - * - How much of the range of mProbability does this cause us to ignore? - * The only value for which log returns 0 is exactly 1; the slope of log - * at 1 is 1, so for small ε such that 1 - ε != 1, log(1 - ε) is -ε, - * never 0. The gaps near one are larger than the gaps near zero, so if - * 1 - ε wasn't 1, then -ε is representable. So if log(1 - mProbability) - * isn't 0, then 1 - mProbability isn't 1, which means that mProbability - * is at least 2**-53, as discussed earlier. This is a sampling - * likelihood of roughly one in ten trillion, which is unlikely to be - * distinguishable from zero in practice. - * - * So by forbidding zero, we've tightened our range to (-37, -2**-53]. - * - * - Finally, 1 / log(1 - mProbability) is in [-2**53, -1/37). This all - * falls readily within the range of an IEEE double. - * - * ALL THAT HAVING BEEN SAID: here are the five lines of actual code: - */ - double logNotProbability = std::log(1 - mProbability); - if (logNotProbability == 0.0) - mProbability = 0.0; - else - mInvLogNotProbability = 1 / logNotProbability; - } - - chooseSkipCount(); - } - - private: - /* The likelihood that any given call to |trial| should return true. */ - double mProbability; - - /* - * The value of 1/std::log(1 - mProbability), cached for repeated use. - * - * If mProbability is exactly 0 or exactly 1, we don't use this value. - * Otherwise, we guarantee this value is in the range [-2**53, -1/37), i.e. - * definitely negative, as required by chooseSkipCount. See setProbability for - * the details. - */ - double mInvLogNotProbability; - - /* Our random number generator. */ - non_crypto::XorShift128PlusRNG mGenerator; - - /* The number of times |trial| should return false before next returning true. */ - size_t mSkipCount; - - /* - * Choose the next skip count. This also returns the value that |trial| should - * return, since we have to check for the extreme values for mProbability - * anyway, and |trial| should never return true at all when mProbability is 0. - */ - bool chooseSkipCount() { - /* - * If the probability is 1.0, every call to |trial| returns true. Make sure - * mSkipCount is 0. - */ - if (mProbability == 1.0) { - mSkipCount = 0; - return true; - } - - /* - * If the probabilility is zero, |trial| never returns true. Don't bother us - * for a while. - */ - if (mProbability == 0.0) { - mSkipCount = SIZE_MAX; - return false; - } - - /* - * What sorts of values can this call to std::floor produce? - * - * Since mGenerator.nextDouble returns a value in [0, 1-2**-53], std::log - * returns a value in the range [-infinity, -2**-53], all negative. Since - * mInvLogNotProbability is negative (see its comments), the product is - * positive and possibly infinite. std::floor returns +infinity unchanged. - * So the result will always be positive. - * - * Converting a double to an integer that is out of range for that integer - * is undefined behavior, so we must clamp our result to SIZE_MAX, to ensure - * we get an acceptable value for mSkipCount. - * - * The clamp is written carefully. Note that if we had said: - * - * if (skipCount > SIZE_MAX) - * skipCount = SIZE_MAX; - * - * that leads to undefined behavior 64-bit machines: SIZE_MAX coerced to - * double is 2^64, not 2^64-1, so this doesn't actually set skipCount to a - * value that can be safely assigned to mSkipCount. - * - * Jakub Oleson cleverly suggested flipping the sense of the comparison: if - * we require that skipCount < SIZE_MAX, then because of the gaps (2048) - * between doubles at that magnitude, the highest double less than 2^64 is - * 2^64 - 2048, which is fine to store in a size_t. - * - * (On 32-bit machines, all size_t values can be represented exactly in - * double, so all is well.) - */ - double skipCount = std::floor(std::log(mGenerator.nextDouble()) - * mInvLogNotProbability); - if (skipCount < SIZE_MAX) - mSkipCount = skipCount; - else - mSkipCount = SIZE_MAX; - - return true; - } -}; - -} /* namespace mozilla */ - -#endif /* mozilla_FastBernoulliTrial_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/FloatingPoint.h b/android/arm64-v8a/include/spidermonkey/mozilla/FloatingPoint.h deleted file mode 100644 index 59afccd1..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/FloatingPoint.h +++ /dev/null @@ -1,479 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Various predicates and operations on IEEE-754 floating point types. */ - -#ifndef mozilla_FloatingPoint_h -#define mozilla_FloatingPoint_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Casting.h" -#include "mozilla/MathAlgorithms.h" -#include "mozilla/Types.h" - -#include - -namespace mozilla { - -/* - * It's reasonable to ask why we have this header at all. Don't isnan, - * copysign, the built-in comparison operators, and the like solve these - * problems? Unfortunately, they don't. We've found that various compilers - * (MSVC, MSVC when compiling with PGO, and GCC on OS X, at least) miscompile - * the standard methods in various situations, so we can't use them. Some of - * these compilers even have problems compiling seemingly reasonable bitwise - * algorithms! But with some care we've found algorithms that seem to not - * trigger those compiler bugs. - * - * For the aforementioned reasons, be very wary of making changes to any of - * these algorithms. If you must make changes, keep a careful eye out for - * compiler bustage, particularly PGO-specific bustage. - */ - -struct FloatTypeTraits -{ - typedef uint32_t Bits; - - static const unsigned kExponentBias = 127; - static const unsigned kExponentShift = 23; - - static const Bits kSignBit = 0x80000000UL; - static const Bits kExponentBits = 0x7F800000UL; - static const Bits kSignificandBits = 0x007FFFFFUL; -}; - -struct DoubleTypeTraits -{ - typedef uint64_t Bits; - - static const unsigned kExponentBias = 1023; - static const unsigned kExponentShift = 52; - - static const Bits kSignBit = 0x8000000000000000ULL; - static const Bits kExponentBits = 0x7ff0000000000000ULL; - static const Bits kSignificandBits = 0x000fffffffffffffULL; -}; - -template struct SelectTrait; -template<> struct SelectTrait : public FloatTypeTraits {}; -template<> struct SelectTrait : public DoubleTypeTraits {}; - -/* - * This struct contains details regarding the encoding of floating-point - * numbers that can be useful for direct bit manipulation. As of now, the - * template parameter has to be float or double. - * - * The nested typedef |Bits| is the unsigned integral type with the same size - * as T: uint32_t for float and uint64_t for double (static assertions - * double-check these assumptions). - * - * kExponentBias is the offset that is subtracted from the exponent when - * computing the value, i.e. one plus the opposite of the mininum possible - * exponent. - * kExponentShift is the shift that one needs to apply to retrieve the - * exponent component of the value. - * - * kSignBit contains a bits mask. Bit-and-ing with this mask will result in - * obtaining the sign bit. - * kExponentBits contains the mask needed for obtaining the exponent bits and - * kSignificandBits contains the mask needed for obtaining the significand - * bits. - * - * Full details of how floating point number formats are encoded are beyond - * the scope of this comment. For more information, see - * http://en.wikipedia.org/wiki/IEEE_floating_point - * http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers - */ -template -struct FloatingPoint : public SelectTrait -{ - typedef SelectTrait Base; - typedef typename Base::Bits Bits; - - static_assert((Base::kSignBit & Base::kExponentBits) == 0, - "sign bit shouldn't overlap exponent bits"); - static_assert((Base::kSignBit & Base::kSignificandBits) == 0, - "sign bit shouldn't overlap significand bits"); - static_assert((Base::kExponentBits & Base::kSignificandBits) == 0, - "exponent bits shouldn't overlap significand bits"); - - static_assert((Base::kSignBit | Base::kExponentBits | Base::kSignificandBits) == - ~Bits(0), - "all bits accounted for"); - - /* - * These implementations assume float/double are 32/64-bit single/double - * format number types compatible with the IEEE-754 standard. C++ don't - * require this to be the case. But we required this in implementations of - * these algorithms that preceded this header, so we shouldn't break anything - * if we keep doing so. - */ - static_assert(sizeof(T) == sizeof(Bits), "Bits must be same size as T"); -}; - -/** Determines whether a float/double is NaN. */ -template -static MOZ_ALWAYS_INLINE bool -IsNaN(T aValue) -{ - /* - * A float/double is NaN if all exponent bits are 1 and the significand - * contains at least one non-zero bit. - */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - return (BitwiseCast(aValue) & Traits::kExponentBits) == Traits::kExponentBits && - (BitwiseCast(aValue) & Traits::kSignificandBits) != 0; -} - -/** Determines whether a float/double is +Infinity or -Infinity. */ -template -static MOZ_ALWAYS_INLINE bool -IsInfinite(T aValue) -{ - /* Infinities have all exponent bits set to 1 and an all-0 significand. */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return (bits & ~Traits::kSignBit) == Traits::kExponentBits; -} - -/** Determines whether a float/double is not NaN or infinite. */ -template -static MOZ_ALWAYS_INLINE bool -IsFinite(T aValue) -{ - /* - * NaN and Infinities are the only non-finite floats/doubles, and both have - * all exponent bits set to 1. - */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return (bits & Traits::kExponentBits) != Traits::kExponentBits; -} - -/** - * Determines whether a float/double is negative or -0. It is an error - * to call this method on a float/double which is NaN. - */ -template -static MOZ_ALWAYS_INLINE bool -IsNegative(T aValue) -{ - MOZ_ASSERT(!IsNaN(aValue), "NaN does not have a sign"); - - /* The sign bit is set if the double is negative. */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return (bits & Traits::kSignBit) != 0; -} - -/** Determines whether a float/double represents -0. */ -template -static MOZ_ALWAYS_INLINE bool -IsNegativeZero(T aValue) -{ - /* Only the sign bit is set if the value is -0. */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return bits == Traits::kSignBit; -} - -/** Determines wether a float/double represents +0. */ -template -static MOZ_ALWAYS_INLINE bool -IsPositiveZero(T aValue) -{ - /* All bits are zero if the value is +0. */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return bits == 0; -} - -/** - * Returns 0 if a float/double is NaN or infinite; - * otherwise, the float/double is returned. - */ -template -static MOZ_ALWAYS_INLINE T -ToZeroIfNonfinite(T aValue) -{ - return IsFinite(aValue) ? aValue : 0; -} - -/** - * Returns the exponent portion of the float/double. - * - * Zero is not special-cased, so ExponentComponent(0.0) is - * -int_fast16_t(Traits::kExponentBias). - */ -template -static MOZ_ALWAYS_INLINE int_fast16_t -ExponentComponent(T aValue) -{ - /* - * The exponent component of a float/double is an unsigned number, biased - * from its actual value. Subtract the bias to retrieve the actual exponent. - */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return int_fast16_t((bits & Traits::kExponentBits) >> Traits::kExponentShift) - - int_fast16_t(Traits::kExponentBias); -} - -/** Returns +Infinity. */ -template -static MOZ_ALWAYS_INLINE T -PositiveInfinity() -{ - /* - * Positive infinity has all exponent bits set, sign bit set to 0, and no - * significand. - */ - typedef FloatingPoint Traits; - return BitwiseCast(Traits::kExponentBits); -} - -/** Returns -Infinity. */ -template -static MOZ_ALWAYS_INLINE T -NegativeInfinity() -{ - /* - * Negative infinity has all exponent bits set, sign bit set to 1, and no - * significand. - */ - typedef FloatingPoint Traits; - return BitwiseCast(Traits::kSignBit | Traits::kExponentBits); -} - -/** - * Computes the bit pattern for a NaN with the specified sign bit and - * significand bits. - */ -template::Bits Significand> -struct SpecificNaNBits -{ - using Traits = FloatingPoint; - - static_assert(SignBit == 0 || SignBit == 1, "bad sign bit"); - static_assert((Significand & ~Traits::kSignificandBits) == 0, - "significand must only have significand bits set"); - static_assert(Significand & Traits::kSignificandBits, - "significand must be nonzero"); - - static constexpr typename Traits::Bits value = - (SignBit * Traits::kSignBit) | Traits::kExponentBits | Significand; -}; - -/** - * Constructs a NaN value with the specified sign bit and significand bits. - * - * There is also a variant that returns the value directly. In most cases, the - * two variants should be identical. However, in the specific case of x86 - * chips, the behavior differs: returning floating-point values directly is done - * through the x87 stack, and x87 loads and stores turn signaling NaNs into - * quiet NaNs... silently. Returning floating-point values via outparam, - * however, is done entirely within the SSE registers when SSE2 floating-point - * is enabled in the compiler, which has semantics-preserving behavior you would - * expect. - * - * If preserving the distinction between signaling NaNs and quiet NaNs is - * important to you, you should use the outparam version. In all other cases, - * you should use the direct return version. - */ -template -static MOZ_ALWAYS_INLINE void -SpecificNaN(int signbit, typename FloatingPoint::Bits significand, T* result) -{ - typedef FloatingPoint Traits; - MOZ_ASSERT(signbit == 0 || signbit == 1); - MOZ_ASSERT((significand & ~Traits::kSignificandBits) == 0); - MOZ_ASSERT(significand & Traits::kSignificandBits); - - BitwiseCast((signbit ? Traits::kSignBit : 0) | - Traits::kExponentBits | - significand, - result); - MOZ_ASSERT(IsNaN(*result)); -} - -template -static MOZ_ALWAYS_INLINE T -SpecificNaN(int signbit, typename FloatingPoint::Bits significand) -{ - T t; - SpecificNaN(signbit, significand, &t); - return t; -} - -/** Computes the smallest non-zero positive float/double value. */ -template -static MOZ_ALWAYS_INLINE T -MinNumberValue() -{ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - return BitwiseCast(Bits(1)); -} - -/** - * If aValue is equal to some int32_t value, set *aInt32 to that value and - * return true; otherwise return false. - * - * Note that negative zero is "equal" to zero here. To test whether a value can - * be losslessly converted to int32_t and back, use NumberIsInt32 instead. - */ -template -static MOZ_ALWAYS_INLINE bool -NumberEqualsInt32(T aValue, int32_t* aInt32) -{ - /* - * XXX Casting a floating-point value that doesn't truncate to int32_t, to - * int32_t, induces undefined behavior. We should definitely fix this - * (bug 744965), but as apparently it "works" in practice, it's not a - * pressing concern now. - */ - return aValue == (*aInt32 = int32_t(aValue)); -} - -/** - * If d can be converted to int32_t and back to an identical double value, - * set *aInt32 to that value and return true; otherwise return false. - * - * The difference between this and NumberEqualsInt32 is that this method returns - * false for negative zero. - */ -template -static MOZ_ALWAYS_INLINE bool -NumberIsInt32(T aValue, int32_t* aInt32) -{ - return !IsNegativeZero(aValue) && NumberEqualsInt32(aValue, aInt32); -} - -/** - * Computes a NaN value. Do not use this method if you depend upon a particular - * NaN value being returned. - */ -template -static MOZ_ALWAYS_INLINE T -UnspecifiedNaN() -{ - /* - * If we can use any quiet NaN, we might as well use the all-ones NaN, - * since it's cheap to materialize on common platforms (such as x64, where - * this value can be represented in a 32-bit signed immediate field, allowing - * it to be stored to memory in a single instruction). - */ - typedef FloatingPoint Traits; - return SpecificNaN(1, Traits::kSignificandBits); -} - -/** - * Compare two doubles for equality, *without* equating -0 to +0, and equating - * any NaN value to any other NaN value. (The normal equality operators equate - * -0 with +0, and they equate NaN to no other value.) - */ -template -static inline bool -NumbersAreIdentical(T aValue1, T aValue2) -{ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - if (IsNaN(aValue1)) { - return IsNaN(aValue2); - } - return BitwiseCast(aValue1) == BitwiseCast(aValue2); -} - -namespace detail { - -template -struct FuzzyEqualsEpsilon; - -template<> -struct FuzzyEqualsEpsilon -{ - // A number near 1e-5 that is exactly representable in a float. - static float value() { return 1.0f / (1 << 17); } -}; - -template<> -struct FuzzyEqualsEpsilon -{ - // A number near 1e-12 that is exactly representable in a double. - static double value() { return 1.0 / (1LL << 40); } -}; - -} // namespace detail - -/** - * Compare two floating point values for equality, modulo rounding error. That - * is, the two values are considered equal if they are both not NaN and if they - * are less than or equal to aEpsilon apart. The default value of aEpsilon is - * near 1e-5. - * - * For most scenarios you will want to use FuzzyEqualsMultiplicative instead, - * as it is more reasonable over the entire range of floating point numbers. - * This additive version should only be used if you know the range of the - * numbers you are dealing with is bounded and stays around the same order of - * magnitude. - */ -template -static MOZ_ALWAYS_INLINE bool -FuzzyEqualsAdditive(T aValue1, T aValue2, - T aEpsilon = detail::FuzzyEqualsEpsilon::value()) -{ - static_assert(IsFloatingPoint::value, "floating point type required"); - return Abs(aValue1 - aValue2) <= aEpsilon; -} - -/** - * Compare two floating point values for equality, allowing for rounding error - * relative to the magnitude of the values. That is, the two values are - * considered equal if they are both not NaN and they are less than or equal to - * some aEpsilon apart, where the aEpsilon is scaled by the smaller of the two - * argument values. - * - * In most cases you will want to use this rather than FuzzyEqualsAdditive, as - * this function effectively masks out differences in the bottom few bits of - * the floating point numbers being compared, regardless of what order of - * magnitude those numbers are at. - */ -template -static MOZ_ALWAYS_INLINE bool -FuzzyEqualsMultiplicative(T aValue1, T aValue2, - T aEpsilon = detail::FuzzyEqualsEpsilon::value()) -{ - static_assert(IsFloatingPoint::value, "floating point type required"); - // can't use std::min because of bug 965340 - T smaller = Abs(aValue1) < Abs(aValue2) ? Abs(aValue1) : Abs(aValue2); - return Abs(aValue1 - aValue2) <= aEpsilon * smaller; -} - -/** - * Returns true if the given value can be losslessly represented as an IEEE-754 - * single format number, false otherwise. All NaN values are considered - * representable (notwithstanding that the exact bit pattern of a double format - * NaN value can't be exactly represented in single format). - * - * This function isn't inlined to avoid buggy optimizations by MSVC. - */ -MOZ_MUST_USE -extern MFBT_API bool -IsFloat32Representable(double aFloat32); - -} /* namespace mozilla */ - -#endif /* mozilla_FloatingPoint_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Function.h b/android/arm64-v8a/include/spidermonkey/mozilla/Function.h deleted file mode 100644 index d6de9c83..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Function.h +++ /dev/null @@ -1,223 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A type-erased callable wrapper. */ - -#ifndef mozilla_Function_h -#define mozilla_Function_h - -#include "mozilla/Attributes.h" // for MOZ_IMPLICIT -#include "mozilla/Move.h" -#include "mozilla/RefCounted.h" -#include "mozilla/RefPtr.h" - -// |function| is a wrapper that can hold any type of callable -// object that can be invoked in a way that's compatible with |Signature|. -// The standard "type erasure" technique is used to avoid the type of the -// wrapper depending on the concrete type of the wrapped callable. -// -// Supported callable types include non-member functions, static member -// functions, and function objects (that is to say, objects with an overloaded -// call operator; this includes C++11 lambdas). Member functions aren't -// directly supported; they first need to be wrapped into a function object -// using |std::mem_fn()| or an equivalent. -// -// |Signature| is a type of the form |ReturnType(Arguments...)|. Syntactically, -// this is a function type; it's not used in any way other than serving as a -// vehicle to encode the return and argument types into a single type. -// -// |function| is default-constructible. A default-constructed instance is -// considered "empty". Invoking an empty instance is undefined behaviour. -// An empty instance can be populated with a callable by assigning to it. -// -// This class is intended to provide functionality similar to the C++11 -// standard library class |std::function|. - -namespace mozilla { - -namespace detail { - -template -class FunctionImplBase : public mozilla::RefCounted> -{ -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(FunctionImplBase) - - virtual ~FunctionImplBase() {} - virtual ReturnType call(Arguments... aArguments) = 0; -}; - -// Normal Callable Object. -template -class FunctionImpl : public FunctionImplBase -{ - public: - explicit FunctionImpl(const Callable& aCallable) - : mCallable(aCallable) {} - - ReturnType call(Arguments... aArguments) override - { - return mCallable(Forward(aArguments)...); - } - private: - Callable mCallable; -}; - -// Base class for passing pointer to member function. -template -class MemberFunctionImplBase : public FunctionImplBase -{ -public: - explicit MemberFunctionImplBase(const Callable& aCallable) - : mCallable(aCallable) {} - - ReturnType call(Arguments... aArguments) override - { - return callInternal(Forward(aArguments)...); - } -private: - template - ReturnType callInternal(ThisType* aThis, Args&&... aArguments) - { - return (aThis->*mCallable)(Forward(aArguments)...); - } - - template - ReturnType callInternal(ThisType&& aThis, Args&&... aArguments) - { - return (aThis.*mCallable)(Forward(aArguments)...); - } - Callable mCallable; -}; - -// For non-const member function specialization of FunctionImpl. -template -class FunctionImpl - : public MemberFunctionImplBase -{ -public: - explicit FunctionImpl(ReturnType(ThisType::*aMemberFunc)(Args...)) - : MemberFunctionImplBase(aMemberFunc) - {} -}; - -// For const member function specialization of FunctionImpl. -template -class FunctionImpl - : public MemberFunctionImplBase -{ -public: - explicit FunctionImpl(ReturnType(ThisType::*aConstMemberFunc)(Args...) const) - : MemberFunctionImplBase(aConstMemberFunc) - {} -}; - -} // namespace detail - -// The primary template is never defined. As |Signature| is required to be -// of the form |ReturnType(Arguments...)|, we only define a partial -// specialization that matches this form. This allows us to use |ReturnType| -// and |Arguments| in the definition of the specialization without having to -// introspect |Signature|. -template -class function; - -template -class function -{ -public: - function() {} - - // This constructor is implicit to match the interface of |std::function|. - template - MOZ_IMPLICIT function(const Callable& aCallable) - : mImpl(new detail::FunctionImpl(aCallable)) - {} - MOZ_IMPLICIT function(const function& aFunction) - : mImpl(aFunction.mImpl) - {} - MOZ_IMPLICIT function(decltype(nullptr)) - {} - - // Move constructor and move assingment operator. - // These should be generated automatically, but MSVC doesn't do that yet. - function(function&& aOther) : mImpl(Move(aOther.mImpl)) {} - function& operator=(function&& aOther) { - mImpl = Move(aOther.mImpl); - return *this; - } - - template - function& operator=(const Callable& aCallable) - { - mImpl = new detail::FunctionImpl(aCallable); - return *this; - } - function& operator=(const function& aFunction) - { - mImpl = aFunction.mImpl; - return *this; - } - function& operator=(decltype(nullptr)) - { - mImpl = nullptr; - return *this; - } - - template - ReturnType operator()(Args&&... aArguments) const - { - MOZ_ASSERT(mImpl); - return mImpl->call(Forward(aArguments)...); - } - - explicit operator bool() const - { - return bool(mImpl); - } - -private: - // TODO: Consider implementing a small object optimization. - RefPtr> mImpl; -}; - -template -bool -operator==(const function& aX, decltype(nullptr)) -{ - return !aX; -} - -template -bool -operator==(decltype(nullptr), const function& aX) -{ - return !aX; -} - -template -bool -operator!=(const function& aX, decltype(nullptr)) -{ - return bool(aX); -} - -template -bool -operator!=(decltype(nullptr), const function& aX) -{ - return bool(aX); -} - -} // namespace mozilla - -#endif /* mozilla_Function_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/GuardObjects.h b/android/arm64-v8a/include/spidermonkey/mozilla/GuardObjects.h deleted file mode 100644 index 9440c71c..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/GuardObjects.h +++ /dev/null @@ -1,167 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implementation of macros to ensure correct use of RAII Auto* objects. */ - -#ifndef mozilla_GuardObjects_h -#define mozilla_GuardObjects_h - -#include "mozilla/Assertions.h" -#include "mozilla/Move.h" -#include "mozilla/Types.h" - -#ifdef __cplusplus - -#ifdef DEBUG - -/** - * A custom define is used rather than |mozPoisonValue()| due to cascading - * build failures relating to how mfbt is linked on different operating - * systems. See bug 1160253. - */ -#define MOZ_POISON uintptr_t(-1) - -namespace mozilla { -namespace detail { - -/* - * The following classes are designed to cause assertions to detect - * inadvertent use of guard objects as temporaries. In other words, - * when we have a guard object whose only purpose is its constructor and - * destructor (and is never otherwise referenced), the intended use - * might be: - * - * AutoRestore savePainting(mIsPainting); - * - * but is is easy to accidentally write: - * - * AutoRestore(mIsPainting); - * - * which compiles just fine, but runs the destructor well before the - * intended time. - * - * They work by adding (#ifdef DEBUG) an additional parameter to the - * guard object's constructor, with a default value, so that users of - * the guard object's API do not need to do anything. The default value - * of this parameter is a temporary object. C++ (ISO/IEC 14882:1998), - * section 12.2 [class.temporary], clauses 4 and 5 seem to assume a - * guarantee that temporaries are destroyed in the reverse of their - * construction order, but I actually can't find a statement that that - * is true in the general case (beyond the two specific cases mentioned - * there). However, it seems to be true. - * - * These classes are intended to be used only via the macros immediately - * below them: - * - * MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER declares (ifdef DEBUG) a member - * variable, and should be put where a declaration of a private - * member variable would be placed. - * MOZ_GUARD_OBJECT_NOTIFIER_PARAM should be placed at the end of the - * parameters to each constructor of the guard object; it declares - * (ifdef DEBUG) an additional parameter. (But use the *_ONLY_PARAM - * variant for constructors that take no other parameters.) - * MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL should likewise be used in - * the implementation of such constructors when they are not inline. - * MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT should be used in - * the implementation of such constructors to pass the parameter to - * a base class that also uses these macros - * MOZ_GUARD_OBJECT_NOTIFIER_INIT is a statement that belongs in each - * constructor. It uses the parameter declared by - * MOZ_GUARD_OBJECT_NOTIFIER_PARAM. - * - * For more details, and examples of using these macros, see - * https://developer.mozilla.org/en/Using_RAII_classes_in_Mozilla - */ -class GuardObjectNotifier -{ -private: - bool* mStatementDone; - -public: - GuardObjectNotifier() - : mStatementDone(reinterpret_cast(MOZ_POISON)) - { - } - - ~GuardObjectNotifier() - { - // Assert that the GuardObjectNotifier has been properly initialized by - // using the |MOZ_GUARD_OBJECT_NOTIFIER_INIT| macro. A poison value is - // used rather than a null check to appease static analyzers that were - // (incorrectly) detecting null pointer dereferences. - MOZ_ASSERT(mStatementDone != reinterpret_cast(MOZ_POISON)); - *mStatementDone = true; - } - - void setStatementDone(bool* aStatementIsDone) - { - mStatementDone = aStatementIsDone; - } -}; - -class GuardObjectNotificationReceiver -{ -private: - bool mStatementDone; - -public: - GuardObjectNotificationReceiver() : mStatementDone(false) { } - - ~GuardObjectNotificationReceiver() { - /* - * Assert that the guard object was not used as a temporary. (Note that - * this assert might also fire if init is not called because the guard - * object's implementation is not using the above macros correctly.) - */ - MOZ_ASSERT(mStatementDone); - } - - void init(GuardObjectNotifier& aNotifier) - { - aNotifier.setStatementDone(&mStatementDone); - } -}; - -} /* namespace detail */ -} /* namespace mozilla */ - -#undef MOZ_POISON - -#endif /* DEBUG */ - -#ifdef DEBUG -# define MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER \ - mozilla::detail::GuardObjectNotificationReceiver _mCheckNotUsedAsTemporary; -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM \ - , mozilla::detail::GuardObjectNotifier&& _notifier = \ - mozilla::detail::GuardObjectNotifier() -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM \ - mozilla::detail::GuardObjectNotifier&& _notifier = \ - mozilla::detail::GuardObjectNotifier() -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL \ - , mozilla::detail::GuardObjectNotifier&& _notifier -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL \ - mozilla::detail::GuardObjectNotifier&& _notifier -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT \ - , mozilla::Move(_notifier) -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT \ - mozilla::Move(_notifier) -# define MOZ_GUARD_OBJECT_NOTIFIER_INIT \ - do { _mCheckNotUsedAsTemporary.init(_notifier); } while (0) -#else -# define MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT -# define MOZ_GUARD_OBJECT_NOTIFIER_INIT do { } while (0) -#endif - -#endif /* __cplusplus */ - -#endif /* mozilla_GuardObjects_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/HashFunctions.h b/android/arm64-v8a/include/spidermonkey/mozilla/HashFunctions.h deleted file mode 100644 index eeb192c3..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/HashFunctions.h +++ /dev/null @@ -1,389 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Utilities for hashing. */ - -/* - * This file exports functions for hashing data down to a 32-bit value, - * including: - * - * - HashString Hash a char* or char16_t/wchar_t* of known or unknown - * length. - * - * - HashBytes Hash a byte array of known length. - * - * - HashGeneric Hash one or more values. Currently, we support uint32_t, - * types which can be implicitly cast to uint32_t, data - * pointers, and function pointers. - * - * - AddToHash Add one or more values to the given hash. This supports the - * same list of types as HashGeneric. - * - * - * You can chain these functions together to hash complex objects. For example: - * - * class ComplexObject - * { - * char* mStr; - * uint32_t mUint1, mUint2; - * void (*mCallbackFn)(); - * - * public: - * uint32_t hash() - * { - * uint32_t hash = HashString(mStr); - * hash = AddToHash(hash, mUint1, mUint2); - * return AddToHash(hash, mCallbackFn); - * } - * }; - * - * If you want to hash an nsAString or nsACString, use the HashString functions - * in nsHashKeys.h. - */ - -#ifndef mozilla_HashFunctions_h -#define mozilla_HashFunctions_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Char16.h" -#include "mozilla/MathAlgorithms.h" -#include "mozilla/Types.h" - -#include - -#ifdef __cplusplus -namespace mozilla { - -/** - * The golden ratio as a 32-bit fixed-point value. - */ -static const uint32_t kGoldenRatioU32 = 0x9E3779B9U; - -inline uint32_t -RotateBitsLeft32(uint32_t aValue, uint8_t aBits) -{ - MOZ_ASSERT(aBits < 32); - return (aValue << aBits) | (aValue >> (32 - aBits)); -} - -namespace detail { - -inline uint32_t -AddU32ToHash(uint32_t aHash, uint32_t aValue) -{ - /* - * This is the meat of all our hash routines. This hash function is not - * particularly sophisticated, but it seems to work well for our mostly - * plain-text inputs. Implementation notes follow. - * - * Our use of the golden ratio here is arbitrary; we could pick almost any - * number which: - * - * * is odd (because otherwise, all our hash values will be even) - * - * * has a reasonably-even mix of 1's and 0's (consider the extreme case - * where we multiply by 0x3 or 0xeffffff -- this will not produce good - * mixing across all bits of the hash). - * - * The rotation length of 5 is also arbitrary, although an odd number is again - * preferable so our hash explores the whole universe of possible rotations. - * - * Finally, we multiply by the golden ratio *after* xor'ing, not before. - * Otherwise, if |aHash| is 0 (as it often is for the beginning of a - * message), the expression - * - * (kGoldenRatioU32 * RotateBitsLeft(aHash, 5)) |xor| aValue - * - * evaluates to |aValue|. - * - * (Number-theoretic aside: Because any odd number |m| is relatively prime to - * our modulus (2^32), the list - * - * [x * m (mod 2^32) for 0 <= x < 2^32] - * - * has no duplicate elements. This means that multiplying by |m| does not - * cause us to skip any possible hash values. - * - * It's also nice if |m| has large-ish order mod 2^32 -- that is, if the - * smallest k such that m^k == 1 (mod 2^32) is large -- so we can safely - * multiply our hash value by |m| a few times without negating the - * multiplicative effect. Our golden ratio constant has order 2^29, which is - * more than enough for our purposes.) - */ - return kGoldenRatioU32 * (RotateBitsLeft32(aHash, 5) ^ aValue); -} - -/** - * AddUintptrToHash takes sizeof(uintptr_t) as a template parameter. - */ -template -inline uint32_t -AddUintptrToHash(uint32_t aHash, uintptr_t aValue); - -template<> -inline uint32_t -AddUintptrToHash<4>(uint32_t aHash, uintptr_t aValue) -{ - return AddU32ToHash(aHash, static_cast(aValue)); -} - -template<> -inline uint32_t -AddUintptrToHash<8>(uint32_t aHash, uintptr_t aValue) -{ - /* - * The static cast to uint64_t below is necessary because this function - * sometimes gets compiled on 32-bit platforms (yes, even though it's a - * template and we never call this particular override in a 32-bit build). If - * we do aValue >> 32 on a 32-bit machine, we're shifting a 32-bit uintptr_t - * right 32 bits, and the compiler throws an error. - */ - uint32_t v1 = static_cast(aValue); - uint32_t v2 = static_cast(static_cast(aValue) >> 32); - return AddU32ToHash(AddU32ToHash(aHash, v1), v2); -} - -} /* namespace detail */ - -/** - * AddToHash takes a hash and some values and returns a new hash based on the - * inputs. - * - * Currently, we support hashing uint32_t's, values which we can implicitly - * convert to uint32_t, data pointers, and function pointers. - */ -template -MOZ_MUST_USE inline uint32_t -AddToHash(uint32_t aHash, A aA) -{ - /* - * Try to convert |A| to uint32_t implicitly. If this works, great. If not, - * we'll error out. - */ - return detail::AddU32ToHash(aHash, aA); -} - -template -MOZ_MUST_USE inline uint32_t -AddToHash(uint32_t aHash, A* aA) -{ - /* - * You might think this function should just take a void*. But then we'd only - * catch data pointers and couldn't handle function pointers. - */ - - static_assert(sizeof(aA) == sizeof(uintptr_t), "Strange pointer!"); - - return detail::AddUintptrToHash(aHash, uintptr_t(aA)); -} - -template<> -MOZ_MUST_USE inline uint32_t -AddToHash(uint32_t aHash, uintptr_t aA) -{ - return detail::AddUintptrToHash(aHash, aA); -} - -template -MOZ_MUST_USE uint32_t -AddToHash(uint32_t aHash, A aArg, Args... aArgs) -{ - return AddToHash(AddToHash(aHash, aArg), aArgs...); -} - -/** - * The HashGeneric class of functions let you hash one or more values. - * - * If you want to hash together two values x and y, calling HashGeneric(x, y) is - * much better than calling AddToHash(x, y), because AddToHash(x, y) assumes - * that x has already been hashed. - */ -template -MOZ_MUST_USE inline uint32_t -HashGeneric(Args... aArgs) -{ - return AddToHash(0, aArgs...); -} - -namespace detail { - -template -uint32_t -HashUntilZero(const T* aStr) -{ - uint32_t hash = 0; - for (T c; (c = *aStr); aStr++) { - hash = AddToHash(hash, c); - } - return hash; -} - -template -uint32_t -HashKnownLength(const T* aStr, size_t aLength) -{ - uint32_t hash = 0; - for (size_t i = 0; i < aLength; i++) { - hash = AddToHash(hash, aStr[i]); - } - return hash; -} - -} /* namespace detail */ - -/** - * The HashString overloads below do just what you'd expect. - * - * If you have the string's length, you might as well call the overload which - * includes the length. It may be marginally faster. - */ -MOZ_MUST_USE inline uint32_t -HashString(const char* aStr) -{ - return detail::HashUntilZero(reinterpret_cast(aStr)); -} - -MOZ_MUST_USE inline uint32_t -HashString(const char* aStr, size_t aLength) -{ - return detail::HashKnownLength(reinterpret_cast(aStr), aLength); -} - -MOZ_MUST_USE -inline uint32_t -HashString(const unsigned char* aStr, size_t aLength) -{ - return detail::HashKnownLength(aStr, aLength); -} - -MOZ_MUST_USE inline uint32_t -HashString(const char16_t* aStr) -{ - return detail::HashUntilZero(aStr); -} - -MOZ_MUST_USE inline uint32_t -HashString(const char16_t* aStr, size_t aLength) -{ - return detail::HashKnownLength(aStr, aLength); -} - -/* - * On Windows, wchar_t is not the same as char16_t, even though it's - * the same width! - */ -#ifdef WIN32 -MOZ_MUST_USE inline uint32_t -HashString(const wchar_t* aStr) -{ - return detail::HashUntilZero(aStr); -} - -MOZ_MUST_USE inline uint32_t -HashString(const wchar_t* aStr, size_t aLength) -{ - return detail::HashKnownLength(aStr, aLength); -} -#endif - -/** - * Hash some number of bytes. - * - * This hash walks word-by-word, rather than byte-by-byte, so you won't get the - * same result out of HashBytes as you would out of HashString. - */ -MOZ_MUST_USE extern MFBT_API uint32_t -HashBytes(const void* bytes, size_t aLength); - -/** - * A pseudorandom function mapping 32-bit integers to 32-bit integers. - * - * This is for when you're feeding private data (like pointer values or credit - * card numbers) to a non-crypto hash function (like HashBytes) and then using - * the hash code for something that untrusted parties could observe (like a JS - * Map). Plug in a HashCodeScrambler before that last step to avoid leaking the - * private data. - * - * By itself, this does not prevent hash-flooding DoS attacks, because an - * attacker can still generate many values with exactly equal hash codes by - * attacking the non-crypto hash function alone. Equal hash codes will, of - * course, still be equal however much you scramble them. - * - * The algorithm is SipHash-1-3. See . - */ -class HashCodeScrambler -{ - struct SipHasher; - - uint64_t mK0, mK1; - -public: - /** Creates a new scrambler with the given 128-bit key. */ - constexpr HashCodeScrambler(uint64_t aK0, uint64_t aK1) : mK0(aK0), mK1(aK1) {} - - /** - * Scramble a hash code. Always produces the same result for the same - * combination of key and hash code. - */ - uint32_t scramble(uint32_t aHashCode) const - { - SipHasher hasher(mK0, mK1); - return uint32_t(hasher.sipHash(aHashCode)); - } - -private: - struct SipHasher - { - SipHasher(uint64_t aK0, uint64_t aK1) - { - // 1. Initialization. - mV0 = aK0 ^ UINT64_C(0x736f6d6570736575); - mV1 = aK1 ^ UINT64_C(0x646f72616e646f6d); - mV2 = aK0 ^ UINT64_C(0x6c7967656e657261); - mV3 = aK1 ^ UINT64_C(0x7465646279746573); - } - - uint64_t sipHash(uint64_t aM) - { - // 2. Compression. - mV3 ^= aM; - sipRound(); - mV0 ^= aM; - - // 3. Finalization. - mV2 ^= 0xff; - for (int i = 0; i < 3; i++) - sipRound(); - return mV0 ^ mV1 ^ mV2 ^ mV3; - } - - void sipRound() - { - mV0 += mV1; - mV1 = RotateLeft(mV1, 13); - mV1 ^= mV0; - mV0 = RotateLeft(mV0, 32); - mV2 += mV3; - mV3 = RotateLeft(mV3, 16); - mV3 ^= mV2; - mV0 += mV3; - mV3 = RotateLeft(mV3, 21); - mV3 ^= mV0; - mV2 += mV1; - mV1 = RotateLeft(mV1, 17); - mV1 ^= mV2; - mV2 = RotateLeft(mV2, 32); - } - - uint64_t mV0, mV1, mV2, mV3; - }; -}; - -} /* namespace mozilla */ -#endif /* __cplusplus */ - -#endif /* mozilla_HashFunctions_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/IndexSequence.h b/android/arm64-v8a/include/spidermonkey/mozilla/IndexSequence.h deleted file mode 100644 index 1ccace02..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/IndexSequence.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A utility for expanding a tuple into a variadic argument list. - * Based on std::index_sequence. */ - -/** - * Example usage: - * - * Problem: - * - * You have a variadic function Foo: - * - * template void Foo(Args...); - * - * And a variadic function Bar, which contains a tuple: - * - * template - * void Bar() { - * // ... - * Tuple t; - * } - * - * And inside Bar, you want to call Foo with the elements of the tuple as - * arguments to Foo. - * - * You want to write: - * - * Foo(Get<0>(t), Get<1>(t), ..., Get(t)) - * - * but you can't literally write that, because N is different for different - * instantiations of Bar. - * - * Solution: - * - * Write a helper function which takes the tuple, and an index sequence - * containing indices corresponding to the tuple indices. - * - * template - * void Helper(const Tuple& t, IndexSequence) - * { - * Foo(Get(t)...); - * } - * - * Assuming 'Indices...' are 0, 1, ..., N - 1, where N is the size of the - * tuple, pack expansion will expand the pack 'Get(t)...' to - * 'Get<0>(t), Get<1>(t), ..., Get(t)'. - * - * Finally, call the helper, creating the index sequence to pass in like so: - * - * template - * void Bar() { - * // ... - * Tuple t; - * Helper(t, typename IndexSequenceFor::Type()); - * } - */ - -#ifndef mozilla_IndexSequence_h -#define mozilla_IndexSequence_h - -#include "mozilla/Attributes.h" - -#include - -namespace mozilla { - -/** - * Represents a compile-time sequence of integer indices. - */ -template -struct IndexSequence -{ - static constexpr size_t Size() { return sizeof...(Indices); } -}; - -namespace detail { - -// Helpers used by MakeIndexSequence. - -template -struct IndexTuple -{ - typedef IndexTuple Next; -}; - -// Builds IndexTuple<0, 1, ..., N - 1>. -template -struct BuildIndexTuple -{ - typedef typename BuildIndexTuple::Type::Next Type; -}; - -template<> -struct BuildIndexTuple<0> -{ - typedef IndexTuple<> Type; -}; - -template -struct MakeIndexSequenceImpl; - -template -struct MakeIndexSequenceImpl> -{ - typedef IndexSequence Type; -}; - -} // namespace detail - -/** - * A utility for building an IndexSequence of consecutive indices. - * MakeIndexSequence::Type evaluates to IndexSequence<0, 1, .., N - 1>. - * Note: unlike std::make_index_sequence, this is not an alias template - * to work around bugs in MSVC 2013. - */ -template -struct MakeIndexSequence -{ - typedef typename detail::MakeIndexSequenceImpl::Type>::Type Type; -}; - -/** - * A utility for building an IndexSequence of consecutive indices - * corresponding to a variadic argument list. - * IndexSequenceFor evaluates to IndexSequence<0, 1, ..., N - 1> - * where N is the number of types in Types. - * Note: unlike std::index_sequence_for, this is not an alias template - * to work around bugs in MSVC 2013. - */ -template -struct IndexSequenceFor -{ - typedef typename MakeIndexSequence::Type Type; -}; - -} // namespace mozilla - -#endif /* mozilla_IndexSequence_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/IntegerPrintfMacros.h b/android/arm64-v8a/include/spidermonkey/mozilla/IntegerPrintfMacros.h deleted file mode 100644 index c534a0ba..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/IntegerPrintfMacros.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implements the C99 interface. */ - -#ifndef mozilla_IntegerPrintfMacros_h_ -#define mozilla_IntegerPrintfMacros_h_ - -/* - * These macros should not be used with the NSPR printf-like functions or their - * users, e.g. mozilla/Logging.h. If you need to use NSPR's facilities, see the - * comment on supported formats at the top of nsprpub/pr/include/prprf.h. - */ - -/* - * scanf is a footgun: if the input number exceeds the bounds of the target - * type, behavior is undefined (in the compiler sense: that is, this code - * could overwrite your hard drive with zeroes): - * - * uint8_t u; - * sscanf("256", "%" SCNu8, &u); // BAD - * - * For this reason, *never* use the SCN* macros provided by this header! - */ - -#include - -/* - * Fix up Android's broken [u]intptr_t inttype macros. Android's PRI*PTR - * macros are defined as "ld", but sizeof(long) is 8 and sizeof(intptr_t) - * is 4 on 32-bit Android. TestTypeTraits.cpp asserts that these new macro - * definitions match the actual type sizes seen at compile time. - */ -#if defined(ANDROID) && !defined(__LP64__) -# undef PRIdPTR /* intptr_t */ -# define PRIdPTR "d" /* intptr_t */ -# undef PRIiPTR /* intptr_t */ -# define PRIiPTR "i" /* intptr_t */ -# undef PRIoPTR /* uintptr_t */ -# define PRIoPTR "o" /* uintptr_t */ -# undef PRIuPTR /* uintptr_t */ -# define PRIuPTR "u" /* uintptr_t */ -# undef PRIxPTR /* uintptr_t */ -# define PRIxPTR "x" /* uintptr_t */ -# undef PRIXPTR /* uintptr_t */ -# define PRIXPTR "X" /* uintptr_t */ -#endif - -#endif /* mozilla_IntegerPrintfMacros_h_ */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/IntegerRange.h b/android/arm64-v8a/include/spidermonkey/mozilla/IntegerRange.h deleted file mode 100644 index 8d5d2e4d..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/IntegerRange.h +++ /dev/null @@ -1,181 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Iterator over ranges of integers */ - -#ifndef mozilla_IntegerRange_h -#define mozilla_IntegerRange_h - -#include "mozilla/Assertions.h" -#include "mozilla/ReverseIterator.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -namespace detail { - -template -class IntegerIterator -{ -public: - template - explicit IntegerIterator(IntType aCurrent) - : mCurrent(aCurrent) { } - - template - explicit IntegerIterator(const IntegerIterator& aOther) - : mCurrent(aOther.mCurrent) { } - - IntTypeT operator*() const { return mCurrent; } - - /* Increment and decrement operators */ - - IntegerIterator& operator++() { ++mCurrent; return *this; } - IntegerIterator& operator--() { --mCurrent; return *this; } - IntegerIterator operator++(int) { auto ret = *this; ++mCurrent; return ret; } - IntegerIterator operator--(int) { auto ret = *this; --mCurrent; return ret; } - - /* Comparison operators */ - - template - friend bool operator==(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - template - friend bool operator!=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - template - friend bool operator<(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - template - friend bool operator<=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - template - friend bool operator>(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - template - friend bool operator>=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - -private: - IntTypeT mCurrent; -}; - -template -bool operator==(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent == aIter2.mCurrent; -} - -template -bool operator!=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent != aIter2.mCurrent; -} - -template -bool operator<(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent < aIter2.mCurrent; -} - -template -bool operator<=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent <= aIter2.mCurrent; -} - -template -bool operator>(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent > aIter2.mCurrent; -} - -template -bool operator>=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent >= aIter2.mCurrent; -} - -template -class IntegerRange -{ -public: - typedef IntegerIterator iterator; - typedef IntegerIterator const_iterator; - typedef ReverseIterator> reverse_iterator; - typedef ReverseIterator> const_reverse_iterator; - - template - explicit IntegerRange(IntType aEnd) - : mBegin(0), mEnd(aEnd) { } - - template - IntegerRange(IntType1 aBegin, IntType2 aEnd) - : mBegin(aBegin), mEnd(aEnd) { } - - iterator begin() const { return iterator(mBegin); } - const_iterator cbegin() const { return begin(); } - iterator end() const { return iterator(mEnd); } - const_iterator cend() const { return end(); } - reverse_iterator rbegin() const { return reverse_iterator(mEnd); } - const_reverse_iterator crbegin() const { return rbegin(); } - reverse_iterator rend() const { return reverse_iterator(mBegin); } - const_reverse_iterator crend() const { return rend(); } - -private: - IntTypeT mBegin; - IntTypeT mEnd; -}; - -template::value> -struct GeqZero -{ - static bool check(T t) { - return t >= 0; - } -}; - -template -struct GeqZero -{ - static bool check(T t) { - return true; - } -}; - -} // namespace detail - -template -detail::IntegerRange -MakeRange(IntType aEnd) -{ - static_assert(IsIntegral::value, "value must be integral"); - MOZ_ASSERT(detail::GeqZero::check(aEnd), - "Should never have negative value here"); - return detail::IntegerRange(aEnd); -} - -template -detail::IntegerRange -MakeRange(IntType1 aBegin, IntType2 aEnd) -{ - static_assert(IsIntegral::value && IsIntegral::value, - "values must both be integral"); - static_assert(IsSigned::value == IsSigned::value, - "signed/unsigned mismatch"); - MOZ_ASSERT(aEnd >= aBegin, "End value should be larger than begin value"); - return detail::IntegerRange(aBegin, aEnd); -} - -} // namespace mozilla - -#endif // mozilla_IntegerRange_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/IntegerTypeTraits.h b/android/arm64-v8a/include/spidermonkey/mozilla/IntegerTypeTraits.h deleted file mode 100644 index 6144d208..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/IntegerTypeTraits.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Helpers to manipulate integer types that don't fit in TypeTraits.h */ - -#ifndef mozilla_IntegerTypeTraits_h -#define mozilla_IntegerTypeTraits_h - -#include "mozilla/TypeTraits.h" -#include - -namespace mozilla { - -namespace detail { - -/** - * StdintTypeForSizeAndSignedness returns the stdint integer type - * of given size (can be 1, 2, 4 or 8) and given signedness - * (false means unsigned, true means signed). - */ -template -struct StdintTypeForSizeAndSignedness; - -template<> -struct StdintTypeForSizeAndSignedness<1, true> -{ - typedef int8_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<1, false> -{ - typedef uint8_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<2, true> -{ - typedef int16_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<2, false> -{ - typedef uint16_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<4, true> -{ - typedef int32_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<4, false> -{ - typedef uint32_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<8, true> -{ - typedef int64_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<8, false> -{ - typedef uint64_t Type; -}; - -} // namespace detail - -template -struct UnsignedStdintTypeForSize - : detail::StdintTypeForSizeAndSignedness -{}; - -template -struct SignedStdintTypeForSize - : detail::StdintTypeForSizeAndSignedness -{}; - -template -struct PositionOfSignBit -{ - static_assert(IsIntegral::value, - "PositionOfSignBit is only for integral types"); - // 8 here should be CHAR_BIT from limits.h, but the world has moved on. - static const size_t value = 8 * sizeof(IntegerType) - 1; -}; - -/** - * MinValue returns the minimum value of the given integer type as a - * compile-time constant, which std::numeric_limits::min() - * cannot do in c++98. - */ -template -struct MinValue -{ -private: - static_assert(IsIntegral::value, - "MinValue is only for integral types"); - - typedef typename MakeUnsigned::Type UnsignedIntegerType; - static const size_t PosOfSignBit = PositionOfSignBit::value; - -public: - // Bitwise ops may return a larger type, that's why we cast explicitly. - // In C++, left bit shifts on signed values is undefined by the standard - // unless the shifted value is representable. - // Notice that signed-to-unsigned conversions are always well-defined in - // the standard as the value congruent to 2**n, as expected. By contrast, - // unsigned-to-signed is only well-defined if the value is representable. - static const IntegerType value = - IsSigned::value - ? IntegerType(UnsignedIntegerType(1) << PosOfSignBit) - : IntegerType(0); -}; - -/** - * MaxValue returns the maximum value of the given integer type as a - * compile-time constant, which std::numeric_limits::max() - * cannot do in c++98. - */ -template -struct MaxValue -{ - static_assert(IsIntegral::value, - "MaxValue is only for integral types"); - - // Tricksy, but covered by the CheckedInt unit test. - // Relies on the type of MinValue::value - // being IntegerType. - static const IntegerType value = ~MinValue::value; -}; - -} // namespace mozilla - -#endif // mozilla_IntegerTypeTraits_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/JSONWriter.h b/android/arm64-v8a/include/spidermonkey/mozilla/JSONWriter.h deleted file mode 100644 index 7d44dc7f..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/JSONWriter.h +++ /dev/null @@ -1,460 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A JSON pretty-printer class. */ - -// A typical JSON-writing library requires you to first build up a data -// structure that represents a JSON object and then serialize it (to file, or -// somewhere else). This approach makes for a clean API, but building the data -// structure takes up memory. Sometimes that isn't desirable, such as when the -// JSON data is produced for memory reporting. -// -// The JSONWriter class instead allows JSON data to be written out -// incrementally without building up large data structures. -// -// The API is slightly uglier than you would see in a typical JSON-writing -// library, but still fairly easy to use. It's possible to generate invalid -// JSON with JSONWriter, but typically the most basic testing will identify any -// such problems. -// -// Similarly, there are no RAII facilities for automatically closing objects -// and arrays. These would be nice if you are generating all your code within -// nested functions, but in other cases you'd have to maintain an explicit -// stack of RAII objects and manually unwind it, which is no better than just -// calling "end" functions. Furthermore, the consequences of forgetting to -// close an object or array are obvious and, again, will be identified via -// basic testing, unlike other cases where RAII is typically used (e.g. smart -// pointers) and the consequences of defects are more subtle. -// -// Importantly, the class does solve the two hard problems of JSON -// pretty-printing, which are (a) correctly escaping strings, and (b) adding -// appropriate indentation and commas between items. -// -// By default, every property is placed on its own line. However, it is -// possible to request that objects and arrays be placed entirely on a single -// line, which can reduce output size significantly in some cases. -// -// Strings used (for property names and string property values) are |const -// char*| throughout, and can be ASCII or UTF-8. -// -// EXAMPLE -// ------- -// Assume that |MyWriteFunc| is a class that implements |JSONWriteFunc|. The -// following code: -// -// JSONWriter w(MakeUnique()); -// w.Start(); -// { -// w.NullProperty("null"); -// w.BoolProperty("bool", true); -// w.IntProperty("int", 1); -// w.StartArrayProperty("array"); -// { -// w.StringElement("string"); -// w.StartObjectElement(); -// { -// w.DoubleProperty("double", 3.4); -// w.StartArrayProperty("single-line array", w.SingleLineStyle); -// { -// w.IntElement(1); -// w.StartObjectElement(); // SingleLineStyle is inherited from -// w.EndObjectElement(); // above for this collection -// } -// w.EndArray(); -// } -// w.EndObjectElement(); -// } -// w.EndArrayProperty(); -// } -// w.End(); -// -// will produce pretty-printed output for the following JSON object: -// -// { -// "null": null, -// "bool": true, -// "int": 1, -// "array": [ -// "string", -// { -// "double": 3.4, -// "single-line array": [1, {}] -// } -// ] -// } -// -// The nesting in the example code is obviously optional, but can aid -// readability. - -#ifndef mozilla_JSONWriter_h -#define mozilla_JSONWriter_h - -#include "mozilla/double-conversion.h" -#include "mozilla/IntegerPrintfMacros.h" -#include "mozilla/PodOperations.h" -#include "mozilla/Sprintf.h" -#include "mozilla/UniquePtr.h" -#include "mozilla/Vector.h" - -#include - -namespace mozilla { - -// A quasi-functor for JSONWriter. We don't use a true functor because that -// requires templatizing JSONWriter, and the templatization seeps to lots of -// places we don't want it to. -class JSONWriteFunc -{ -public: - virtual void Write(const char* aStr) = 0; - virtual ~JSONWriteFunc() {} -}; - -// Ideally this would be within |EscapedString| but when compiling with GCC -// on Linux that caused link errors, whereas this formulation didn't. -namespace detail { -extern MFBT_DATA const char gTwoCharEscapes[256]; -} // namespace detail - -class JSONWriter -{ - // From http://www.ietf.org/rfc/rfc4627.txt: - // - // "All Unicode characters may be placed within the quotation marks except - // for the characters that must be escaped: quotation mark, reverse - // solidus, and the control characters (U+0000 through U+001F)." - // - // This implementation uses two-char escape sequences where possible, namely: - // - // \", \\, \b, \f, \n, \r, \t - // - // All control characters not in the above list are represented with a - // six-char escape sequence, e.g. '\u000b' (a.k.a. '\v'). - // - class EscapedString - { - // Only one of |mUnownedStr| and |mOwnedStr| are ever non-null. |mIsOwned| - // indicates which one is in use. They're not within a union because that - // wouldn't work with UniquePtr. - bool mIsOwned; - const char* mUnownedStr; - UniquePtr mOwnedStr; - - void SanityCheck() const - { - MOZ_ASSERT_IF( mIsOwned, mOwnedStr.get() && !mUnownedStr); - MOZ_ASSERT_IF(!mIsOwned, !mOwnedStr.get() && mUnownedStr); - } - - static char hexDigitToAsciiChar(uint8_t u) - { - u = u & 0xf; - return u < 10 ? '0' + u : 'a' + (u - 10); - } - - public: - explicit EscapedString(const char* aStr) - : mUnownedStr(nullptr) - , mOwnedStr(nullptr) - { - const char* p; - - // First, see if we need to modify the string. - size_t nExtra = 0; - p = aStr; - while (true) { - uint8_t u = *p; // ensure it can't be interpreted as negative - if (u == 0) { - break; - } - if (detail::gTwoCharEscapes[u]) { - nExtra += 1; - } else if (u <= 0x1f) { - nExtra += 5; - } - p++; - } - - if (nExtra == 0) { - // No escapes needed. Easy. - mIsOwned = false; - mUnownedStr = aStr; - return; - } - - // Escapes are needed. We'll create a new string. - mIsOwned = true; - size_t len = (p - aStr) + nExtra; - mOwnedStr = MakeUnique(len + 1); - - p = aStr; - size_t i = 0; - - while (true) { - uint8_t u = *p; // ensure it can't be interpreted as negative - if (u == 0) { - mOwnedStr[i] = 0; - break; - } - if (detail::gTwoCharEscapes[u]) { - mOwnedStr[i++] = '\\'; - mOwnedStr[i++] = detail::gTwoCharEscapes[u]; - } else if (u <= 0x1f) { - mOwnedStr[i++] = '\\'; - mOwnedStr[i++] = 'u'; - mOwnedStr[i++] = '0'; - mOwnedStr[i++] = '0'; - mOwnedStr[i++] = hexDigitToAsciiChar((u & 0x00f0) >> 4); - mOwnedStr[i++] = hexDigitToAsciiChar(u & 0x000f); - } else { - mOwnedStr[i++] = u; - } - p++; - } - } - - ~EscapedString() - { - SanityCheck(); - } - - const char* get() const - { - SanityCheck(); - return mIsOwned ? mOwnedStr.get() : mUnownedStr; - } - }; - -public: - // Collections (objects and arrays) are printed in a multi-line style by - // default. This can be changed to a single-line style if SingleLineStyle is - // specified. If a collection is printed in single-line style, every nested - // collection within it is also printed in single-line style, even if - // multi-line style is requested. - enum CollectionStyle { - MultiLineStyle, // the default - SingleLineStyle - }; - -protected: - const UniquePtr mWriter; - Vector mNeedComma; // do we need a comma at depth N? - Vector mNeedNewlines; // do we need newlines at depth N? - size_t mDepth; // the current nesting depth - - void Indent() - { - for (size_t i = 0; i < mDepth; i++) { - mWriter->Write(" "); - } - } - - // Adds whatever is necessary (maybe a comma, and then a newline and - // whitespace) to separate an item (property or element) from what's come - // before. - void Separator() - { - if (mNeedComma[mDepth]) { - mWriter->Write(","); - } - if (mDepth > 0 && mNeedNewlines[mDepth]) { - mWriter->Write("\n"); - Indent(); - } else if (mNeedComma[mDepth]) { - mWriter->Write(" "); - } - } - - void PropertyNameAndColon(const char* aName) - { - EscapedString escapedName(aName); - mWriter->Write("\""); - mWriter->Write(escapedName.get()); - mWriter->Write("\": "); - } - - void Scalar(const char* aMaybePropertyName, const char* aStringValue) - { - Separator(); - if (aMaybePropertyName) { - PropertyNameAndColon(aMaybePropertyName); - } - mWriter->Write(aStringValue); - mNeedComma[mDepth] = true; - } - - void QuotedScalar(const char* aMaybePropertyName, const char* aStringValue) - { - Separator(); - if (aMaybePropertyName) { - PropertyNameAndColon(aMaybePropertyName); - } - mWriter->Write("\""); - mWriter->Write(aStringValue); - mWriter->Write("\""); - mNeedComma[mDepth] = true; - } - - void NewVectorEntries() - { - // If these tiny allocations OOM we might as well just crash because we - // must be in serious memory trouble. - MOZ_RELEASE_ASSERT(mNeedComma.resizeUninitialized(mDepth + 1)); - MOZ_RELEASE_ASSERT(mNeedNewlines.resizeUninitialized(mDepth + 1)); - mNeedComma[mDepth] = false; - mNeedNewlines[mDepth] = true; - } - - void StartCollection(const char* aMaybePropertyName, const char* aStartChar, - CollectionStyle aStyle = MultiLineStyle) - { - Separator(); - if (aMaybePropertyName) { - mWriter->Write("\""); - mWriter->Write(aMaybePropertyName); - mWriter->Write("\": "); - } - mWriter->Write(aStartChar); - mNeedComma[mDepth] = true; - mDepth++; - NewVectorEntries(); - mNeedNewlines[mDepth] = - mNeedNewlines[mDepth - 1] && aStyle == MultiLineStyle; - } - - // Adds the whitespace and closing char necessary to end a collection. - void EndCollection(const char* aEndChar) - { - if (mNeedNewlines[mDepth]) { - mWriter->Write("\n"); - mDepth--; - Indent(); - } else { - mDepth--; - } - mWriter->Write(aEndChar); - } - -public: - explicit JSONWriter(UniquePtr aWriter) - : mWriter(Move(aWriter)) - , mNeedComma() - , mNeedNewlines() - , mDepth(0) - { - NewVectorEntries(); - } - - // Returns the JSONWriteFunc passed in at creation, for temporary use. The - // JSONWriter object still owns the JSONWriteFunc. - JSONWriteFunc* WriteFunc() const { return mWriter.get(); } - - // For all the following functions, the "Prints:" comment indicates what the - // basic output looks like. However, it doesn't indicate the whitespace and - // trailing commas, which are automatically added as required. - // - // All property names and string properties are escaped as necessary. - - // Prints: { - void Start(CollectionStyle aStyle = MultiLineStyle) - { - StartCollection(nullptr, "{", aStyle); - } - - // Prints: } - void End() { EndCollection("}\n"); } - - // Prints: "": null - void NullProperty(const char* aName) - { - Scalar(aName, "null"); - } - - // Prints: null - void NullElement() { NullProperty(nullptr); } - - // Prints: "": - void BoolProperty(const char* aName, bool aBool) - { - Scalar(aName, aBool ? "true" : "false"); - } - - // Prints: - void BoolElement(bool aBool) { BoolProperty(nullptr, aBool); } - - // Prints: "": - void IntProperty(const char* aName, int64_t aInt) - { - char buf[64]; - SprintfLiteral(buf, "%" PRId64, aInt); - Scalar(aName, buf); - } - - // Prints: - void IntElement(int64_t aInt) { IntProperty(nullptr, aInt); } - - // Prints: "": - void DoubleProperty(const char* aName, double aDouble) - { - static const size_t buflen = 64; - char buf[buflen]; - const double_conversion::DoubleToStringConverter &converter = - double_conversion::DoubleToStringConverter::EcmaScriptConverter(); - double_conversion::StringBuilder builder(buf, buflen); - converter.ToShortest(aDouble, &builder); - Scalar(aName, builder.Finalize()); - } - - // Prints: - void DoubleElement(double aDouble) { DoubleProperty(nullptr, aDouble); } - - // Prints: "": "" - void StringProperty(const char* aName, const char* aStr) - { - EscapedString escapedStr(aStr); - QuotedScalar(aName, escapedStr.get()); - } - - // Prints: "" - void StringElement(const char* aStr) { StringProperty(nullptr, aStr); } - - // Prints: "": [ - void StartArrayProperty(const char* aName, - CollectionStyle aStyle = MultiLineStyle) - { - StartCollection(aName, "[", aStyle); - } - - // Prints: [ - void StartArrayElement(CollectionStyle aStyle = MultiLineStyle) - { - StartArrayProperty(nullptr, aStyle); - } - - // Prints: ] - void EndArray() { EndCollection("]"); } - - // Prints: "": { - void StartObjectProperty(const char* aName, - CollectionStyle aStyle = MultiLineStyle) - { - StartCollection(aName, "{", aStyle); - } - - // Prints: { - void StartObjectElement(CollectionStyle aStyle = MultiLineStyle) - { - StartObjectProperty(nullptr, aStyle); - } - - // Prints: } - void EndObject() { EndCollection("}"); } -}; - -} // namespace mozilla - -#endif /* mozilla_JSONWriter_h */ - diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Likely.h b/android/arm64-v8a/include/spidermonkey/mozilla/Likely.h deleted file mode 100644 index 4f216092..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Likely.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * MOZ_LIKELY and MOZ_UNLIKELY macros to hint to the compiler how a - * boolean predicate should be branch-predicted. - */ - -#ifndef mozilla_Likely_h -#define mozilla_Likely_h - -#if defined(__clang__) || defined(__GNUC__) -# define MOZ_LIKELY(x) (__builtin_expect(!!(x), 1)) -# define MOZ_UNLIKELY(x) (__builtin_expect(!!(x), 0)) -#else -# define MOZ_LIKELY(x) (!!(x)) -# define MOZ_UNLIKELY(x) (!!(x)) -#endif - -#endif /* mozilla_Likely_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/LinkedList.h b/android/arm64-v8a/include/spidermonkey/mozilla/LinkedList.h deleted file mode 100644 index 6e14aa16..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/LinkedList.h +++ /dev/null @@ -1,659 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A type-safe doubly-linked list class. */ - -/* - * The classes LinkedList and LinkedListElement together form a - * convenient, type-safe doubly-linked list implementation. - * - * The class T which will be inserted into the linked list must inherit from - * LinkedListElement. A given object may be in only one linked list at a - * time. - * - * A LinkedListElement automatically removes itself from the list upon - * destruction, and a LinkedList will fatally assert in debug builds if it's - * non-empty when it's destructed. - * - * For example, you might use LinkedList in a simple observer list class as - * follows. - * - * class Observer : public LinkedListElement - * { - * public: - * void observe(char* aTopic) { ... } - * }; - * - * class ObserverContainer - * { - * private: - * LinkedList list; - * - * public: - * void addObserver(Observer* aObserver) - * { - * // Will assert if |aObserver| is part of another list. - * list.insertBack(aObserver); - * } - * - * void removeObserver(Observer* aObserver) - * { - * // Will assert if |aObserver| is not part of some list. - * aObserver.remove(); - * // Or, will assert if |aObserver| is not part of |list| specifically. - * // aObserver.removeFrom(list); - * } - * - * void notifyObservers(char* aTopic) - * { - * for (Observer* o = list.getFirst(); o != nullptr; o = o->getNext()) { - * o->observe(aTopic); - * } - * } - * }; - * - * Additionally, the class AutoCleanLinkedList is a LinkedList that will - * remove and delete each element still within itself upon destruction. Note - * that because each element is deleted, elements must have been allocated - * using |new|. - */ - -#ifndef mozilla_LinkedList_h -#define mozilla_LinkedList_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" -#include "mozilla/RefPtr.h" - -#ifdef __cplusplus - -namespace mozilla { - -template -class LinkedListElement; - -namespace detail { - -/** - * LinkedList supports refcounted elements using this adapter class. Clients - * using LinkedList> will get a data structure that holds a strong - * reference to T as long as T is in the list. - */ -template -struct LinkedListElementTraits -{ - typedef T* RawType; - typedef const T* ConstRawType; - typedef T* ClientType; - typedef const T* ConstClientType; - - // These static methods are called when an element is added to or removed from - // a linked list. It can be used to keep track ownership in lists that are - // supposed to own their elements. If elements are transferred from one list - // to another, no enter or exit calls happen since the elements still belong - // to a list. - static void enterList(LinkedListElement* elt) {} - static void exitList(LinkedListElement* elt) {} -}; - -template -struct LinkedListElementTraits> -{ - typedef T* RawType; - typedef const T* ConstRawType; - typedef RefPtr ClientType; - typedef RefPtr ConstClientType; - - static void enterList(LinkedListElement>* elt) { elt->asT()->AddRef(); } - static void exitList(LinkedListElement>* elt) { elt->asT()->Release(); } -}; - -} /* namespace detail */ - -template -class LinkedList; - -template -class LinkedListElement -{ - typedef typename detail::LinkedListElementTraits Traits; - typedef typename Traits::RawType RawType; - typedef typename Traits::ConstRawType ConstRawType; - typedef typename Traits::ClientType ClientType; - typedef typename Traits::ConstClientType ConstClientType; - - /* - * It's convenient that we return nullptr when getNext() or getPrevious() - * hits the end of the list, but doing so costs an extra word of storage in - * each linked list node (to keep track of whether |this| is the sentinel - * node) and a branch on this value in getNext/getPrevious. - * - * We could get rid of the extra word of storage by shoving the "is - * sentinel" bit into one of the pointers, although this would, of course, - * have performance implications of its own. - * - * But the goal here isn't to win an award for the fastest or slimmest - * linked list; rather, we want a *convenient* linked list. So we won't - * waste time guessing which micro-optimization strategy is best. - * - * - * Speaking of unnecessary work, it's worth addressing here why we wrote - * mozilla::LinkedList in the first place, instead of using stl::list. - * - * The key difference between mozilla::LinkedList and stl::list is that - * mozilla::LinkedList stores the mPrev/mNext pointers in the object itself, - * while stl::list stores the mPrev/mNext pointers in a list element which - * itself points to the object being stored. - * - * mozilla::LinkedList's approach makes it harder to store an object in more - * than one list. But the upside is that you can call next() / prev() / - * remove() directly on the object. With stl::list, you'd need to store a - * pointer to its iterator in the object in order to accomplish this. Not - * only would this waste space, but you'd have to remember to update that - * pointer every time you added or removed the object from a list. - * - * In-place, constant-time removal is a killer feature of doubly-linked - * lists, and supporting this painlessly was a key design criterion. - */ - -private: - LinkedListElement* mNext; - LinkedListElement* mPrev; - const bool mIsSentinel; - -public: - LinkedListElement() - : mNext(this), - mPrev(this), - mIsSentinel(false) - { } - - /* - * Moves |aOther| into |*this|. If |aOther| is already in a list, then - * |aOther| is removed from the list and replaced by |*this|. - */ - LinkedListElement(LinkedListElement&& aOther) - : mIsSentinel(aOther.mIsSentinel) - { - adjustLinkForMove(Move(aOther)); - } - - LinkedListElement& operator=(LinkedListElement&& aOther) - { - MOZ_ASSERT(mIsSentinel == aOther.mIsSentinel, "Mismatch NodeKind!"); - MOZ_ASSERT(!isInList(), - "Assigning to an element in a list messes up that list!"); - adjustLinkForMove(Move(aOther)); - return *this; - } - - ~LinkedListElement() - { - if (!mIsSentinel && isInList()) { - remove(); - } - } - - /* - * Get the next element in the list, or nullptr if this is the last element - * in the list. - */ - RawType getNext() { return mNext->asT(); } - ConstRawType getNext() const { return mNext->asT(); } - - /* - * Get the previous element in the list, or nullptr if this is the first - * element in the list. - */ - RawType getPrevious() { return mPrev->asT(); } - ConstRawType getPrevious() const { return mPrev->asT(); } - - /* - * Insert aElem after this element in the list. |this| must be part of a - * linked list when you call setNext(); otherwise, this method will assert. - */ - void setNext(RawType aElem) - { - MOZ_ASSERT(isInList()); - setNextUnsafe(aElem); - } - - /* - * Insert aElem before this element in the list. |this| must be part of a - * linked list when you call setPrevious(); otherwise, this method will - * assert. - */ - void setPrevious(RawType aElem) - { - MOZ_ASSERT(isInList()); - setPreviousUnsafe(aElem); - } - - /* - * Remove this element from the list which contains it. If this element is - * not currently part of a linked list, this method asserts. - */ - void remove() - { - MOZ_ASSERT(isInList()); - - mPrev->mNext = mNext; - mNext->mPrev = mPrev; - mNext = this; - mPrev = this; - - Traits::exitList(this); - } - - /* - * Remove this element from the list containing it. Returns a pointer to the - * element that follows this element (before it was removed). This method - * asserts if the element does not belong to a list. - */ - ClientType removeAndGetNext() - { - ClientType r = getNext(); - remove(); - return r; - } - - /* - * Remove this element from the list containing it. Returns a pointer to the - * previous element in the containing list (before the removal). This method - * asserts if the element does not belong to a list. - */ - ClientType removeAndGetPrevious() - { - ClientType r = getPrevious(); - remove(); - return r; - } - - /* - * Identical to remove(), but also asserts in debug builds that this element - * is in aList. - */ - void removeFrom(const LinkedList& aList) - { - aList.assertContains(asT()); - remove(); - } - - /* - * Return true if |this| part is of a linked list, and false otherwise. - */ - bool isInList() const - { - MOZ_ASSERT((mNext == this) == (mPrev == this)); - return mNext != this; - } - -private: - friend class LinkedList; - friend struct detail::LinkedListElementTraits; - - enum class NodeKind { - Normal, - Sentinel - }; - - explicit LinkedListElement(NodeKind nodeKind) - : mNext(this), - mPrev(this), - mIsSentinel(nodeKind == NodeKind::Sentinel) - { } - - /* - * Return |this| cast to T* if we're a normal node, or return nullptr if - * we're a sentinel node. - */ - RawType asT() - { - return mIsSentinel ? nullptr : static_cast(this); - } - ConstRawType asT() const - { - return mIsSentinel ? nullptr : static_cast(this); - } - - /* - * Insert aElem after this element, but don't check that this element is in - * the list. This is called by LinkedList::insertFront(). - */ - void setNextUnsafe(RawType aElem) - { - LinkedListElement *listElem = static_cast(aElem); - MOZ_ASSERT(!listElem->isInList()); - - listElem->mNext = this->mNext; - listElem->mPrev = this; - this->mNext->mPrev = listElem; - this->mNext = listElem; - - Traits::enterList(aElem); - } - - /* - * Insert aElem before this element, but don't check that this element is in - * the list. This is called by LinkedList::insertBack(). - */ - void setPreviousUnsafe(RawType aElem) - { - LinkedListElement* listElem = static_cast*>(aElem); - MOZ_ASSERT(!listElem->isInList()); - - listElem->mNext = this; - listElem->mPrev = this->mPrev; - this->mPrev->mNext = listElem; - this->mPrev = listElem; - - Traits::enterList(aElem); - } - - /* - * Adjust mNext and mPrev for implementing move constructor and move - * assignment. - */ - void adjustLinkForMove(LinkedListElement&& aOther) - { - if (!aOther.isInList()) { - mNext = this; - mPrev = this; - return; - } - - if (!mIsSentinel) { - Traits::enterList(this); - } - - MOZ_ASSERT(aOther.mNext->mPrev == &aOther); - MOZ_ASSERT(aOther.mPrev->mNext == &aOther); - - /* - * Initialize |this| with |aOther|'s mPrev/mNext pointers, and adjust those - * element to point to this one. - */ - mNext = aOther.mNext; - mPrev = aOther.mPrev; - - mNext->mPrev = this; - mPrev->mNext = this; - - /* - * Adjust |aOther| so it doesn't think it's in a list. This makes it - * safely destructable. - */ - aOther.mNext = &aOther; - aOther.mPrev = &aOther; - - if (!mIsSentinel) { - Traits::exitList(&aOther); - } - } - - LinkedListElement& operator=(const LinkedListElement& aOther) = delete; - LinkedListElement(const LinkedListElement& aOther) = delete; -}; - -template -class LinkedList -{ -private: - typedef typename detail::LinkedListElementTraits Traits; - typedef typename Traits::RawType RawType; - typedef typename Traits::ConstRawType ConstRawType; - typedef typename Traits::ClientType ClientType; - typedef typename Traits::ConstClientType ConstClientType; - - LinkedListElement sentinel; - -public: - class Iterator { - RawType mCurrent; - - public: - explicit Iterator(RawType aCurrent) : mCurrent(aCurrent) {} - - RawType operator *() const { - return mCurrent; - } - - const Iterator& operator++() { - mCurrent = mCurrent->getNext(); - return *this; - } - - bool operator!=(Iterator& aOther) const { - return mCurrent != aOther.mCurrent; - } - }; - - LinkedList() : sentinel(LinkedListElement::NodeKind::Sentinel) { } - - LinkedList(LinkedList&& aOther) - : sentinel(mozilla::Move(aOther.sentinel)) - { } - - LinkedList& operator=(LinkedList&& aOther) - { - MOZ_ASSERT(isEmpty(), "Assigning to a non-empty list leaks elements in that list!"); - sentinel = mozilla::Move(aOther.sentinel); - return *this; - } - - ~LinkedList() { - MOZ_ASSERT(isEmpty(), - "failing this assertion means this LinkedList's creator is " - "buggy: it should have removed all this list's elements before " - "the list's destruction"); - } - - /* - * Add aElem to the front of the list. - */ - void insertFront(RawType aElem) - { - /* Bypass setNext()'s this->isInList() assertion. */ - sentinel.setNextUnsafe(aElem); - } - - /* - * Add aElem to the back of the list. - */ - void insertBack(RawType aElem) - { - sentinel.setPreviousUnsafe(aElem); - } - - /* - * Get the first element of the list, or nullptr if the list is empty. - */ - RawType getFirst() { return sentinel.getNext(); } - ConstRawType getFirst() const { return sentinel.getNext(); } - - /* - * Get the last element of the list, or nullptr if the list is empty. - */ - RawType getLast() { return sentinel.getPrevious(); } - ConstRawType getLast() const { return sentinel.getPrevious(); } - - /* - * Get and remove the first element of the list. If the list is empty, - * return nullptr. - */ - ClientType popFirst() - { - ClientType ret = sentinel.getNext(); - if (ret) { - static_cast*>(RawType(ret))->remove(); - } - return ret; - } - - /* - * Get and remove the last element of the list. If the list is empty, - * return nullptr. - */ - ClientType popLast() - { - ClientType ret = sentinel.getPrevious(); - if (ret) { - static_cast*>(RawType(ret))->remove(); - } - return ret; - } - - /* - * Return true if the list is empty, or false otherwise. - */ - bool isEmpty() const - { - return !sentinel.isInList(); - } - - /* - * Remove all the elements from the list. - * - * This runs in time linear to the list's length, because we have to mark - * each element as not in the list. - */ - void clear() - { - while (popFirst()) { - continue; - } - } - - /* - * Allow range-based iteration: - * - * for (MyElementType* elt : myList) { ... } - */ - Iterator begin() { - return Iterator(getFirst()); - } - Iterator end() { - return Iterator(nullptr); - } - - /* - * Measures the memory consumption of the list excluding |this|. Note that - * it only measures the list elements themselves. If the list elements - * contain pointers to other memory blocks, those blocks must be measured - * separately during a subsequent iteration over the list. - */ - size_t sizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const - { - size_t n = 0; - for (const T* t = getFirst(); t; t = t->getNext()) { - n += aMallocSizeOf(t); - } - return n; - } - - /* - * Like sizeOfExcludingThis(), but measures |this| as well. - */ - size_t sizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const - { - return aMallocSizeOf(this) + sizeOfExcludingThis(aMallocSizeOf); - } - - /* - * In a debug build, make sure that the list is sane (no cycles, consistent - * mNext/mPrev pointers, only one sentinel). Has no effect in release builds. - */ - void debugAssertIsSane() const - { -#ifdef DEBUG - const LinkedListElement* slow; - const LinkedListElement* fast1; - const LinkedListElement* fast2; - - /* - * Check for cycles in the forward singly-linked list using the - * tortoise/hare algorithm. - */ - for (slow = sentinel.mNext, - fast1 = sentinel.mNext->mNext, - fast2 = sentinel.mNext->mNext->mNext; - slow != &sentinel && fast1 != &sentinel && fast2 != &sentinel; - slow = slow->mNext, fast1 = fast2->mNext, fast2 = fast1->mNext) { - MOZ_ASSERT(slow != fast1); - MOZ_ASSERT(slow != fast2); - } - - /* Check for cycles in the backward singly-linked list. */ - for (slow = sentinel.mPrev, - fast1 = sentinel.mPrev->mPrev, - fast2 = sentinel.mPrev->mPrev->mPrev; - slow != &sentinel && fast1 != &sentinel && fast2 != &sentinel; - slow = slow->mPrev, fast1 = fast2->mPrev, fast2 = fast1->mPrev) { - MOZ_ASSERT(slow != fast1); - MOZ_ASSERT(slow != fast2); - } - - /* - * Check that |sentinel| is the only node in the list with - * mIsSentinel == true. - */ - for (const LinkedListElement* elem = sentinel.mNext; - elem != &sentinel; - elem = elem->mNext) { - MOZ_ASSERT(!elem->mIsSentinel); - } - - /* Check that the mNext/mPrev pointers match up. */ - const LinkedListElement* prev = &sentinel; - const LinkedListElement* cur = sentinel.mNext; - do { - MOZ_ASSERT(cur->mPrev == prev); - MOZ_ASSERT(prev->mNext == cur); - - prev = cur; - cur = cur->mNext; - } while (cur != &sentinel); -#endif /* ifdef DEBUG */ - } - -private: - friend class LinkedListElement; - - void assertContains(const RawType aValue) const - { -#ifdef DEBUG - for (ConstRawType elem = getFirst(); elem; elem = elem->getNext()) { - if (elem == aValue) { - return; - } - } - MOZ_CRASH("element wasn't found in this list!"); -#endif - } - - LinkedList& operator=(const LinkedList& aOther) = delete; - LinkedList(const LinkedList& aOther) = delete; -}; - -template -class AutoCleanLinkedList : public LinkedList -{ -public: - ~AutoCleanLinkedList() - { - while (T* element = this->popFirst()) { - delete element; - } - } -}; - -} /* namespace mozilla */ - -#endif /* __cplusplus */ - -#endif /* mozilla_LinkedList_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/LinuxSignal.h b/android/arm64-v8a/include/spidermonkey/mozilla/LinuxSignal.h deleted file mode 100644 index 83c2bf81..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/LinuxSignal.h +++ /dev/null @@ -1,45 +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/. */ - -#ifndef mozilla_LinuxSignal_h -#define mozilla_LinuxSignal_h - -namespace mozilla { - -#if defined(__arm__) - -// Some (old) Linux kernels on ARM have a bug where a signal handler -// can be called without clearing the IT bits in CPSR first. The result -// is that the first few instructions of the handler could be skipped, -// ultimately resulting in crashes. To workaround this bug, the handler -// on ARM is a trampoline that starts with enough NOP instructions, so -// that even if the IT bits are not cleared, only the NOP instructions -// will be skipped over. - -template -__attribute__((naked)) void -SignalTrampoline(int aSignal, siginfo_t* aInfo, void* aContext) -{ - asm volatile ( - "nop; nop; nop; nop" - : : : "memory"); - - asm volatile ( - "b %0" - : - : "X"(H) - : "memory"); -} - -# define MOZ_SIGNAL_TRAMPOLINE(h) (mozilla::SignalTrampoline) - -#else // __arm__ - -# define MOZ_SIGNAL_TRAMPOLINE(h) (h) - -#endif // __arm__ - -} // namespace mozilla - -#endif // mozilla_LinuxSignal_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/MacroArgs.h b/android/arm64-v8a/include/spidermonkey/mozilla/MacroArgs.h deleted file mode 100644 index 52ed1e82..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/MacroArgs.h +++ /dev/null @@ -1,109 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Implements various macros meant to ease the use of variadic macros. - */ - -#ifndef mozilla_MacroArgs_h -#define mozilla_MacroArgs_h - -// Concatenates pre-processor tokens in a way that can be used with __LINE__. -#define MOZ_CONCAT2(x, y) x ## y -#define MOZ_CONCAT(x, y) MOZ_CONCAT2(x, y) - -/* - * MOZ_PASTE_PREFIX_AND_ARG_COUNT(aPrefix, ...) counts the number of variadic - * arguments and prefixes it with |aPrefix|. For example: - * - * MOZ_PASTE_PREFIX_AND_ARG_COUNT(, foo, 42) expands to 2 - * MOZ_PASTE_PREFIX_AND_ARG_COUNT(A, foo, 42, bar) expands to A3 - * - * You must pass in between 1 and 50 (inclusive) variadic arguments, past - * |aPrefix|. It is not legal to do - * - * MOZ_PASTE_PREFIX_AND_ARG_COUNT(prefix) - * - * (that is, pass in 0 variadic arguments). To ensure that a compile-time - * error occurs when these constraints are violated, use the - * MOZ_STATIC_ASSERT_VALID_ARG_COUNT macro with the same variaidc arguments - * wherever this macro is used. - * - * Passing (__VA_ARGS__, ) rather than simply calling - * MOZ_MACROARGS_ARG_COUNT_HELPER2(__VA_ARGS__, ) very - * carefully tiptoes around a MSVC bug where it improperly expands __VA_ARGS__ - * as a single token in argument lists. For details, see: - * - * http://connect.microsoft.com/VisualStudio/feedback/details/380090/variadic-macro-replacement - * http://cplusplus.co.il/2010/07/17/variadic-macro-to-count-number-of-arguments/#comment-644 - */ -#define MOZ_PASTE_PREFIX_AND_ARG_COUNT(aPrefix, ...) \ - MOZ_MACROARGS_ARG_COUNT_HELPER((__VA_ARGS__, \ - aPrefix##50, aPrefix##49, aPrefix##48, aPrefix##47, aPrefix##46, \ - aPrefix##45, aPrefix##44, aPrefix##43, aPrefix##42, aPrefix##41, \ - aPrefix##40, aPrefix##39, aPrefix##38, aPrefix##37, aPrefix##36, \ - aPrefix##35, aPrefix##34, aPrefix##33, aPrefix##32, aPrefix##31, \ - aPrefix##30, aPrefix##29, aPrefix##28, aPrefix##27, aPrefix##26, \ - aPrefix##25, aPrefix##24, aPrefix##23, aPrefix##22, aPrefix##21, \ - aPrefix##20, aPrefix##19, aPrefix##18, aPrefix##17, aPrefix##16, \ - aPrefix##15, aPrefix##14, aPrefix##13, aPrefix##12, aPrefix##11, \ - aPrefix##10, aPrefix##9, aPrefix##8, aPrefix##7, aPrefix##6, \ - aPrefix##5, aPrefix##4, aPrefix##3, aPrefix##2, aPrefix##1, aPrefix##0)) - -#define MOZ_MACROARGS_ARG_COUNT_HELPER(aArgs) \ - MOZ_MACROARGS_ARG_COUNT_HELPER2 aArgs - -#define MOZ_MACROARGS_ARG_COUNT_HELPER2( \ - a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, \ - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, \ - a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, \ - a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, \ - a41, a42, a43, a44, a45, a46, a47, a48, a49, a50, \ - a51, ...) a51 - -/* - * MOZ_STATIC_ASSERT_VALID_ARG_COUNT ensures that a compile-time error occurs - * when the argument count constraints of MOZ_PASTE_PREFIX_AND_ARG_COUNT are - * violated. Use this macro wherever MOZ_PASTE_PREFIX_AND_ARG_COUNT is used - * and pass it the same variadic arguments. - * - * This macro employs a few dirty tricks to function. To detect the zero - * argument case, |(__VA_ARGS__)| is stringified, sizeof-ed, and compared to - * what it should be in the absence of arguments. - * - * Detecting too many arguments is a little trickier. With a valid argument - * count and a prefix of 1, MOZ_PASTE_PREFIX_AND_ARG_COUNT expands to e.g. 14. - * With a prefix of 0.0, it expands to e.g. 0.04. If there are too many - * arguments, it expands to the first argument over the limit. If this - * exceeding argument is a number, the assertion will fail as there is no - * number than can simultaneously be both > 10 and == 0. If the exceeding - * argument is not a number, a compile-time error should still occur due to - * the operations performed on it. - */ -#define MOZ_MACROARGS_STRINGIFY_HELPER(x) #x -#define MOZ_STATIC_ASSERT_VALID_ARG_COUNT(...) \ - static_assert( \ - sizeof(MOZ_MACROARGS_STRINGIFY_HELPER((__VA_ARGS__))) != sizeof("()") && \ - (MOZ_PASTE_PREFIX_AND_ARG_COUNT(1, __VA_ARGS__)) > 10 && \ - (int)(MOZ_PASTE_PREFIX_AND_ARG_COUNT(0.0, __VA_ARGS__)) == 0, \ - "MOZ_STATIC_ASSERT_VALID_ARG_COUNT requires 1 to 50 arguments") /* ; */ - -/* - * MOZ_ARGS_AFTER_N expands to its arguments excluding the first |N| - * arguments. For example: - * - * MOZ_ARGS_AFTER_2(a, b, c, d) expands to: c, d - */ -#define MOZ_ARGS_AFTER_1(a1, ...) __VA_ARGS__ -#define MOZ_ARGS_AFTER_2(a1, a2, ...) __VA_ARGS__ - -/* - * MOZ_ARG_N expands to its |N|th argument. - */ -#define MOZ_ARG_1(a1, ...) a1 -#define MOZ_ARG_2(a1, a2, ...) a2 - -#endif /* mozilla_MacroArgs_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/MacroForEach.h b/android/arm64-v8a/include/spidermonkey/mozilla/MacroForEach.h deleted file mode 100644 index 7c0e3cfb..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/MacroForEach.h +++ /dev/null @@ -1,158 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Implements a higher-order macro for iteratively calling another macro with - * fixed leading arguments, plus a trailing element picked from a second list - * of arguments. - */ - -#ifndef mozilla_MacroForEach_h -#define mozilla_MacroForEach_h - -#include "mozilla/MacroArgs.h" - -/* - * MOZ_FOR_EACH(aMacro, aFixedArgs, aArgs) expands to N calls to the macro - * |aMacro| where N is equal the number of items in the list |aArgs|. The - * arguments for each |aMacro| call are composed of *all* arguments in the list - * |aFixedArgs| as well as a single argument in the list |aArgs|. For example: - * - * #define MACRO_A(x) x + - * int a = MOZ_FOR_EACH(MACRO_A, (), (1, 2, 3)) 0; - * // Expands to: MACRO_A(1) MACRO_A(2) MACRO_A(3) 0; - * // And further to: 1 + 2 + 3 + 0; - * - * #define MACRO_B(k, x) (k + x) + - * int b = MOZ_FOR_EACH(MACRO_B, (5,), (1, 2)) 0; - * // Expands to: MACRO_B(5, 1) MACRO_B(5, 2) 0; - * - * #define MACRO_C(k1, k2, x) (k1 + k2 + x) + - * int c = MOZ_FOR_EACH(MACRO_C, (5, 8,), (1, 2)) 0; - * // Expands to: MACRO_B(5, 8, 1) MACRO_B(5, 8, 2) 0; - * - * If the |aFixedArgs| list is not empty, a trailing comma must be included. - * - * The |aArgs| list must be not be empty and may be up to 50 items long. Use - * MOZ_STATIC_ASSERT_VALID_ARG_COUNT to ensure that violating this constraint - * results in a compile-time error. - */ -#define MOZ_FOR_EACH_EXPAND_HELPER(...) __VA_ARGS__ -#define MOZ_FOR_EACH_GLUE(a, b) a b -#define MOZ_FOR_EACH(aMacro, aFixedArgs, aArgs) \ - MOZ_FOR_EACH_GLUE( \ - MOZ_PASTE_PREFIX_AND_ARG_COUNT(MOZ_FOR_EACH_, \ - MOZ_FOR_EACH_EXPAND_HELPER aArgs), \ - (aMacro, aFixedArgs, aArgs)) - -#define MOZ_FOR_EACH_HELPER_GLUE(a, b) a b -#define MOZ_FOR_EACH_HELPER(aMacro, aFixedArgs, aArgs) \ - MOZ_FOR_EACH_HELPER_GLUE( \ - aMacro, \ - (MOZ_FOR_EACH_EXPAND_HELPER aFixedArgs MOZ_ARG_1 aArgs)) - -#define MOZ_FOR_EACH_1(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) -#define MOZ_FOR_EACH_2(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_1(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_3(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_2(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_4(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_3(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_5(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_4(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_6(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_5(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_7(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_6(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_8(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_7(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_9(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_8(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_10(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_9(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_11(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_10(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_12(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_11(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_13(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_12(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_14(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_13(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_15(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_14(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_16(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_15(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_17(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_16(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_18(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_17(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_19(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_18(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_20(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_19(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_21(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_20(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_22(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_21(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_23(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_22(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_24(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_23(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_25(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_24(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_26(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_25(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_27(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_26(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_28(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_27(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_29(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_28(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_30(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_29(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_31(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_30(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_32(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_31(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_33(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_32(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_34(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_33(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_35(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_34(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_36(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_35(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_37(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_36(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_38(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_37(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_39(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_38(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_40(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_39(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_41(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_40(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_42(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_41(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_43(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_42(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_44(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_43(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_45(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_44(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_46(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_45(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_47(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_46(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_48(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_47(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_49(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_48(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_50(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_49(m, fa, (MOZ_ARGS_AFTER_1 a)) - -#endif /* mozilla_MacroForEach_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/MathAlgorithms.h b/android/arm64-v8a/include/spidermonkey/mozilla/MathAlgorithms.h deleted file mode 100644 index 4db6de49..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/MathAlgorithms.h +++ /dev/null @@ -1,547 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* mfbt maths algorithms. */ - -#ifndef mozilla_MathAlgorithms_h -#define mozilla_MathAlgorithms_h - -#include "mozilla/Assertions.h" -#include "mozilla/TypeTraits.h" - -#include -#include -#include - -namespace mozilla { - -// Greatest Common Divisor -template -MOZ_ALWAYS_INLINE IntegerType -EuclidGCD(IntegerType aA, IntegerType aB) -{ - // Euclid's algorithm; O(N) in the worst case. (There are better - // ways, but we don't need them for the current use of this algo.) - MOZ_ASSERT(aA > IntegerType(0)); - MOZ_ASSERT(aB > IntegerType(0)); - - while (aA != aB) { - if (aA > aB) { - aA = aA - aB; - } else { - aB = aB - aA; - } - } - - return aA; -} - -// Least Common Multiple -template -MOZ_ALWAYS_INLINE IntegerType -EuclidLCM(IntegerType aA, IntegerType aB) -{ - // Divide first to reduce overflow risk. - return (aA / EuclidGCD(aA, aB)) * aB; -} - -namespace detail { - -template -struct AllowDeprecatedAbsFixed : FalseType {}; - -template<> struct AllowDeprecatedAbsFixed : TrueType {}; -template<> struct AllowDeprecatedAbsFixed : TrueType {}; - -template -struct AllowDeprecatedAbs : AllowDeprecatedAbsFixed {}; - -template<> struct AllowDeprecatedAbs : TrueType {}; -template<> struct AllowDeprecatedAbs : TrueType {}; - -} // namespace detail - -// DO NOT USE DeprecatedAbs. It exists only until its callers can be converted -// to Abs below, and it will be removed when all callers have been changed. -template -inline typename mozilla::EnableIf::value, T>::Type -DeprecatedAbs(const T aValue) -{ - // The absolute value of the smallest possible value of a signed-integer type - // won't fit in that type (on twos-complement systems -- and we're blithely - // assuming we're on such systems, for the non- types listed above), - // so assert that the input isn't that value. - // - // This is the case if: the value is non-negative; or if adding one (giving a - // value in the range [-maxvalue, 0]), then negating (giving a value in the - // range [0, maxvalue]), doesn't produce maxvalue (because in twos-complement, - // (minvalue + 1) == -maxvalue). - MOZ_ASSERT(aValue >= 0 || - -(aValue + 1) != T((1ULL << (CHAR_BIT * sizeof(T) - 1)) - 1), - "You can't negate the smallest possible negative integer!"); - return aValue >= 0 ? aValue : -aValue; -} - -namespace detail { - -// For now mozilla::Abs only takes intN_T, the signed natural types, and -// float/double/long double. Feel free to add overloads for other standard, -// signed types if you need them. - -template -struct AbsReturnTypeFixed; - -template<> struct AbsReturnTypeFixed { typedef uint8_t Type; }; -template<> struct AbsReturnTypeFixed { typedef uint16_t Type; }; -template<> struct AbsReturnTypeFixed { typedef uint32_t Type; }; -template<> struct AbsReturnTypeFixed { typedef uint64_t Type; }; - -template -struct AbsReturnType : AbsReturnTypeFixed {}; - -template<> struct AbsReturnType : - EnableIf {}; -template<> struct AbsReturnType { typedef unsigned char Type; }; -template<> struct AbsReturnType { typedef unsigned short Type; }; -template<> struct AbsReturnType { typedef unsigned int Type; }; -template<> struct AbsReturnType { typedef unsigned long Type; }; -template<> struct AbsReturnType { typedef unsigned long long Type; }; -template<> struct AbsReturnType { typedef float Type; }; -template<> struct AbsReturnType { typedef double Type; }; -template<> struct AbsReturnType { typedef long double Type; }; - -} // namespace detail - -template -inline typename detail::AbsReturnType::Type -Abs(const T aValue) -{ - typedef typename detail::AbsReturnType::Type ReturnType; - return aValue >= 0 ? ReturnType(aValue) : ~ReturnType(aValue) + 1; -} - -template<> -inline float -Abs(const float aFloat) -{ - return std::fabs(aFloat); -} - -template<> -inline double -Abs(const double aDouble) -{ - return std::fabs(aDouble); -} - -template<> -inline long double -Abs(const long double aLongDouble) -{ - return std::fabs(aLongDouble); -} - -} // namespace mozilla - -#if defined(_MSC_VER) && \ - (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) -# define MOZ_BITSCAN_WINDOWS - -# include -# pragma intrinsic(_BitScanForward, _BitScanReverse) - -# if defined(_M_AMD64) || defined(_M_X64) -# define MOZ_BITSCAN_WINDOWS64 -# pragma intrinsic(_BitScanForward64, _BitScanReverse64) -# endif - -#endif - -namespace mozilla { - -namespace detail { - -#if defined(MOZ_BITSCAN_WINDOWS) - -inline uint_fast8_t -CountLeadingZeroes32(uint32_t aValue) -{ - unsigned long index; - if (!_BitScanReverse(&index, static_cast(aValue))) - return 32; - return uint_fast8_t(31 - index); -} - - -inline uint_fast8_t -CountTrailingZeroes32(uint32_t aValue) -{ - unsigned long index; - if (!_BitScanForward(&index, static_cast(aValue))) - return 32; - return uint_fast8_t(index); -} - -inline uint_fast8_t -CountPopulation32(uint32_t aValue) -{ - uint32_t x = aValue - ((aValue >> 1) & 0x55555555); - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - return (((x + (x >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24; -} -inline uint_fast8_t -CountPopulation64(uint64_t aValue) -{ - return uint_fast8_t(CountPopulation32(aValue & 0xffffffff) + - CountPopulation32(aValue >> 32)); -} - -inline uint_fast8_t -CountLeadingZeroes64(uint64_t aValue) -{ -#if defined(MOZ_BITSCAN_WINDOWS64) - unsigned long index; - if (!_BitScanReverse64(&index, static_cast(aValue))) - return 64; - return uint_fast8_t(63 - index); -#else - uint32_t hi = uint32_t(aValue >> 32); - if (hi != 0) { - return CountLeadingZeroes32(hi); - } - return 32u + CountLeadingZeroes32(uint32_t(aValue)); -#endif -} - -inline uint_fast8_t -CountTrailingZeroes64(uint64_t aValue) -{ -#if defined(MOZ_BITSCAN_WINDOWS64) - unsigned long index; - if (!_BitScanForward64(&index, static_cast(aValue))) - return 64; - return uint_fast8_t(index); -#else - uint32_t lo = uint32_t(aValue); - if (lo != 0) { - return CountTrailingZeroes32(lo); - } - return 32u + CountTrailingZeroes32(uint32_t(aValue >> 32)); -#endif -} - -# ifdef MOZ_HAVE_BITSCAN64 -# undef MOZ_HAVE_BITSCAN64 -# endif - -#elif defined(__clang__) || defined(__GNUC__) - -# if defined(__clang__) -# if !__has_builtin(__builtin_ctz) || !__has_builtin(__builtin_clz) -# error "A clang providing __builtin_c[lt]z is required to build" -# endif -# else - // gcc has had __builtin_clz and friends since 3.4: no need to check. -# endif - -inline uint_fast8_t -CountLeadingZeroes32(uint32_t aValue) -{ - return __builtin_clz(aValue); -} - -inline uint_fast8_t -CountTrailingZeroes32(uint32_t aValue) -{ - return __builtin_ctz(aValue); -} - -inline uint_fast8_t -CountPopulation32(uint32_t aValue) -{ - return __builtin_popcount(aValue); -} - -inline uint_fast8_t -CountPopulation64(uint64_t aValue) -{ - return __builtin_popcountll(aValue); -} - -inline uint_fast8_t -CountLeadingZeroes64(uint64_t aValue) -{ - return __builtin_clzll(aValue); -} - -inline uint_fast8_t -CountTrailingZeroes64(uint64_t aValue) -{ - return __builtin_ctzll(aValue); -} - -#else -# error "Implement these!" -inline uint_fast8_t CountLeadingZeroes32(uint32_t aValue) = delete; -inline uint_fast8_t CountTrailingZeroes32(uint32_t aValue) = delete; -inline uint_fast8_t CountPopulation32(uint32_t aValue) = delete; -inline uint_fast8_t CountPopulation64(uint64_t aValue) = delete; -inline uint_fast8_t CountLeadingZeroes64(uint64_t aValue) = delete; -inline uint_fast8_t CountTrailingZeroes64(uint64_t aValue) = delete; -#endif - -} // namespace detail - -/** - * Compute the number of high-order zero bits in the NON-ZERO number |aValue|. - * That is, looking at the bitwise representation of the number, with the - * highest- valued bits at the start, return the number of zeroes before the - * first one is observed. - * - * CountLeadingZeroes32(0xF0FF1000) is 0; - * CountLeadingZeroes32(0x7F8F0001) is 1; - * CountLeadingZeroes32(0x3FFF0100) is 2; - * CountLeadingZeroes32(0x1FF50010) is 3; and so on. - */ -inline uint_fast8_t -CountLeadingZeroes32(uint32_t aValue) -{ - MOZ_ASSERT(aValue != 0); - return detail::CountLeadingZeroes32(aValue); -} - -/** - * Compute the number of low-order zero bits in the NON-ZERO number |aValue|. - * That is, looking at the bitwise representation of the number, with the - * lowest- valued bits at the start, return the number of zeroes before the - * first one is observed. - * - * CountTrailingZeroes32(0x0100FFFF) is 0; - * CountTrailingZeroes32(0x7000FFFE) is 1; - * CountTrailingZeroes32(0x0080FFFC) is 2; - * CountTrailingZeroes32(0x0080FFF8) is 3; and so on. - */ -inline uint_fast8_t -CountTrailingZeroes32(uint32_t aValue) -{ - MOZ_ASSERT(aValue != 0); - return detail::CountTrailingZeroes32(aValue); -} - -/** - * Compute the number of one bits in the number |aValue|, - */ -inline uint_fast8_t -CountPopulation32(uint32_t aValue) -{ - return detail::CountPopulation32(aValue); -} - -/** Analogous to CountPopulation32, but for 64-bit numbers */ -inline uint_fast8_t -CountPopulation64(uint64_t aValue) -{ - return detail::CountPopulation64(aValue); -} - -/** Analogous to CountLeadingZeroes32, but for 64-bit numbers. */ -inline uint_fast8_t -CountLeadingZeroes64(uint64_t aValue) -{ - MOZ_ASSERT(aValue != 0); - return detail::CountLeadingZeroes64(aValue); -} - -/** Analogous to CountTrailingZeroes32, but for 64-bit numbers. */ -inline uint_fast8_t -CountTrailingZeroes64(uint64_t aValue) -{ - MOZ_ASSERT(aValue != 0); - return detail::CountTrailingZeroes64(aValue); -} - -namespace detail { - -template -class CeilingLog2; - -template -class CeilingLog2 -{ -public: - static uint_fast8_t compute(const T aValue) - { - // Check for <= 1 to avoid the == 0 undefined case. - return aValue <= 1 ? 0u : 32u - CountLeadingZeroes32(aValue - 1); - } -}; - -template -class CeilingLog2 -{ -public: - static uint_fast8_t compute(const T aValue) - { - // Check for <= 1 to avoid the == 0 undefined case. - return aValue <= 1 ? 0u : 64u - CountLeadingZeroes64(aValue - 1); - } -}; - -} // namespace detail - -/** - * Compute the log of the least power of 2 greater than or equal to |aValue|. - * - * CeilingLog2(0..1) is 0; - * CeilingLog2(2) is 1; - * CeilingLog2(3..4) is 2; - * CeilingLog2(5..8) is 3; - * CeilingLog2(9..16) is 4; and so on. - */ -template -inline uint_fast8_t -CeilingLog2(const T aValue) -{ - return detail::CeilingLog2::compute(aValue); -} - -/** A CeilingLog2 variant that accepts only size_t. */ -inline uint_fast8_t -CeilingLog2Size(size_t aValue) -{ - return CeilingLog2(aValue); -} - -namespace detail { - -template -class FloorLog2; - -template -class FloorLog2 -{ -public: - static uint_fast8_t compute(const T aValue) - { - return 31u - CountLeadingZeroes32(aValue | 1); - } -}; - -template -class FloorLog2 -{ -public: - static uint_fast8_t compute(const T aValue) - { - return 63u - CountLeadingZeroes64(aValue | 1); - } -}; - -} // namespace detail - -/** - * Compute the log of the greatest power of 2 less than or equal to |aValue|. - * - * FloorLog2(0..1) is 0; - * FloorLog2(2..3) is 1; - * FloorLog2(4..7) is 2; - * FloorLog2(8..15) is 3; and so on. - */ -template -inline uint_fast8_t -FloorLog2(const T aValue) -{ - return detail::FloorLog2::compute(aValue); -} - -/** A FloorLog2 variant that accepts only size_t. */ -inline uint_fast8_t -FloorLog2Size(size_t aValue) -{ - return FloorLog2(aValue); -} - -/* - * Compute the smallest power of 2 greater than or equal to |x|. |x| must not - * be so great that the computed value would overflow |size_t|. - */ -inline size_t -RoundUpPow2(size_t aValue) -{ - MOZ_ASSERT(aValue <= (size_t(1) << (sizeof(size_t) * CHAR_BIT - 1)), - "can't round up -- will overflow!"); - return size_t(1) << CeilingLog2(aValue); -} - -/** - * Rotates the bits of the given value left by the amount of the shift width. - */ -template -inline T -RotateLeft(const T aValue, uint_fast8_t aShift) -{ - MOZ_ASSERT(aShift < sizeof(T) * CHAR_BIT, "Shift value is too large!"); - MOZ_ASSERT(aShift > 0, - "Rotation by value length is undefined behavior, but compilers " - "do not currently fold a test into the rotate instruction. " - "Please remove this restriction when compilers optimize the " - "zero case (http://blog.regehr.org/archives/1063)."); - static_assert(IsUnsigned::value, "Rotates require unsigned values"); - return (aValue << aShift) | (aValue >> (sizeof(T) * CHAR_BIT - aShift)); -} - -/** - * Rotates the bits of the given value right by the amount of the shift width. - */ -template -inline T -RotateRight(const T aValue, uint_fast8_t aShift) -{ - MOZ_ASSERT(aShift < sizeof(T) * CHAR_BIT, "Shift value is too large!"); - MOZ_ASSERT(aShift > 0, - "Rotation by value length is undefined behavior, but compilers " - "do not currently fold a test into the rotate instruction. " - "Please remove this restriction when compilers optimize the " - "zero case (http://blog.regehr.org/archives/1063)."); - static_assert(IsUnsigned::value, "Rotates require unsigned values"); - return (aValue >> aShift) | (aValue << (sizeof(T) * CHAR_BIT - aShift)); -} - -/** - * Returns true if |x| is a power of two. - * Zero is not an integer power of two. (-Inf is not an integer) - */ -template -constexpr bool -IsPowerOfTwo(T x) -{ - static_assert(IsUnsigned::value, - "IsPowerOfTwo requires unsigned values"); - return x && (x & (x - 1)) == 0; -} - -template -inline T -Clamp(const T aValue, const T aMin, const T aMax) -{ - static_assert(IsIntegral::value, - "Clamp accepts only integral types, so that it doesn't have" - " to distinguish differently-signed zeroes (which users may" - " or may not care to distinguish, likely at a perf cost) or" - " to decide how to clamp NaN or a range with a NaN" - " endpoint."); - MOZ_ASSERT(aMin <= aMax); - - if (aValue <= aMin) - return aMin; - if (aValue >= aMax) - return aMax; - return aValue; -} - -} /* namespace mozilla */ - -#endif /* mozilla_MathAlgorithms_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Maybe.h b/android/arm64-v8a/include/spidermonkey/mozilla/Maybe.h deleted file mode 100644 index 2a601ac4..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Maybe.h +++ /dev/null @@ -1,551 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A class for optional values and in-place lazy construction. */ - -#ifndef mozilla_Maybe_h -#define mozilla_Maybe_h - -#include "mozilla/Alignment.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -#include // for placement new -#include - -namespace mozilla { - -struct Nothing { }; - -/* - * Maybe is a container class which contains either zero or one elements. It - * serves two roles. It can represent values which are *semantically* optional, - * augmenting a type with an explicit 'Nothing' value. In this role, it provides - * methods that make it easy to work with values that may be missing, along with - * equality and comparison operators so that Maybe values can be stored in - * containers. Maybe values can be constructed conveniently in expressions using - * type inference, as follows: - * - * void doSomething(Maybe aFoo) { - * if (aFoo) // Make sure that aFoo contains a value... - * aFoo->takeAction(); // and then use |aFoo->| to access it. - * } // |*aFoo| also works! - * - * doSomething(Nothing()); // Passes a Maybe containing no value. - * doSomething(Some(Foo(100))); // Passes a Maybe containing |Foo(100)|. - * - * You'll note that it's important to check whether a Maybe contains a value - * before using it, using conversion to bool, |isSome()|, or |isNothing()|. You - * can avoid these checks, and sometimes write more readable code, using - * |valueOr()|, |ptrOr()|, and |refOr()|, which allow you to retrieve the value - * in the Maybe and provide a default for the 'Nothing' case. You can also use - * |apply()| to call a function only if the Maybe holds a value, and |map()| to - * transform the value in the Maybe, returning another Maybe with a possibly - * different type. - * - * Maybe's other role is to support lazily constructing objects without using - * dynamic storage. A Maybe directly contains storage for a value, but it's - * empty by default. |emplace()|, as mentioned above, can be used to construct a - * value in Maybe's storage. The value a Maybe contains can be destroyed by - * calling |reset()|; this will happen automatically if a Maybe is destroyed - * while holding a value. - * - * It's a common idiom in C++ to use a pointer as a 'Maybe' type, with a null - * value meaning 'Nothing' and any other value meaning 'Some'. You can convert - * from such a pointer to a Maybe value using 'ToMaybe()'. - * - * Maybe is inspired by similar types in the standard library of many other - * languages (e.g. Haskell's Maybe and Rust's Option). In the C++ world it's - * very similar to std::optional, which was proposed for C++14 and originated in - * Boost. The most important differences between Maybe and std::optional are: - * - * - std::optional may be compared with T. We deliberately forbid that. - * - std::optional allows in-place construction without a separate call to - * |emplace()| by using a dummy |in_place_t| value to tag the appropriate - * constructor. - * - std::optional has |valueOr()|, equivalent to Maybe's |valueOr()|, but - * lacks corresponding methods for |refOr()| and |ptrOr()|. - * - std::optional lacks |map()| and |apply()|, making it less suitable for - * functional-style code. - * - std::optional lacks many convenience functions that Maybe has. Most - * unfortunately, it lacks equivalents of the type-inferred constructor - * functions |Some()| and |Nothing()|. - * - * N.B. GCC has missed optimizations with Maybe in the past and may generate - * extra branches/loads/stores. Use with caution on hot paths; it's not known - * whether or not this is still a problem. - */ -template -class Maybe -{ - bool mIsSome; - AlignedStorage2 mStorage; - -public: - typedef T ValueType; - - Maybe() : mIsSome(false) { } - ~Maybe() { reset(); } - - MOZ_IMPLICIT Maybe(Nothing) : mIsSome(false) { } - - Maybe(const Maybe& aOther) - : mIsSome(false) - { - if (aOther.mIsSome) { - emplace(*aOther); - } - } - - /** - * Maybe can be copy-constructed from a Maybe if U* and T* are - * compatible, or from Maybe. - */ - template::value && - (std::is_same::value || - (std::is_pointer::value && - std::is_base_of::type, - typename std::remove_pointer::type>::value))>::type> - MOZ_IMPLICIT - Maybe(const Maybe& aOther) - : mIsSome(false) - { - if (aOther.isSome()) { - emplace(*aOther); - } - } - - Maybe(Maybe&& aOther) - : mIsSome(false) - { - if (aOther.mIsSome) { - emplace(Move(*aOther)); - aOther.reset(); - } - } - - /** - * Maybe can be move-constructed from a Maybe if U* and T* are - * compatible, or from Maybe. - */ - template::value && - (std::is_same::value || - (std::is_pointer::value && - std::is_base_of::type, - typename std::remove_pointer::type>::value))>::type> - MOZ_IMPLICIT - Maybe(Maybe&& aOther) - : mIsSome(false) - { - if (aOther.isSome()) { - emplace(Move(*aOther)); - aOther.reset(); - } - } - - Maybe& operator=(const Maybe& aOther) - { - if (&aOther != this) { - if (aOther.mIsSome) { - if (mIsSome) { - // XXX(seth): The correct code for this branch, below, can't be used - // due to a bug in Visual Studio 2010. See bug 1052940. - /* - ref() = aOther.ref(); - */ - reset(); - emplace(*aOther); - } else { - emplace(*aOther); - } - } else { - reset(); - } - } - return *this; - } - - Maybe& operator=(Maybe&& aOther) - { - MOZ_ASSERT(this != &aOther, "Self-moves are prohibited"); - - if (aOther.mIsSome) { - if (mIsSome) { - ref() = Move(aOther.ref()); - } else { - emplace(Move(*aOther)); - } - aOther.reset(); - } else { - reset(); - } - - return *this; - } - - /* Methods that check whether this Maybe contains a value */ - explicit operator bool() const { return isSome(); } - bool isSome() const { return mIsSome; } - bool isNothing() const { return !mIsSome; } - - /* Returns the contents of this Maybe by value. Unsafe unless |isSome()|. */ - T value() const - { - MOZ_ASSERT(mIsSome); - return ref(); - } - - /* - * Returns the contents of this Maybe by value. If |isNothing()|, returns - * the default value provided. - */ - template - T valueOr(V&& aDefault) const - { - if (isSome()) { - return ref(); - } - return Forward(aDefault); - } - - /* - * Returns the contents of this Maybe by value. If |isNothing()|, returns - * the value returned from the function or functor provided. - */ - template - T valueOrFrom(F&& aFunc) const - { - if (isSome()) { - return ref(); - } - return aFunc(); - } - - /* Returns the contents of this Maybe by pointer. Unsafe unless |isSome()|. */ - T* ptr() - { - MOZ_ASSERT(mIsSome); - return &ref(); - } - - const T* ptr() const - { - MOZ_ASSERT(mIsSome); - return &ref(); - } - - /* - * Returns the contents of this Maybe by pointer. If |isNothing()|, - * returns the default value provided. - */ - T* ptrOr(T* aDefault) - { - if (isSome()) { - return ptr(); - } - return aDefault; - } - - const T* ptrOr(const T* aDefault) const - { - if (isSome()) { - return ptr(); - } - return aDefault; - } - - /* - * Returns the contents of this Maybe by pointer. If |isNothing()|, - * returns the value returned from the function or functor provided. - */ - template - T* ptrOrFrom(F&& aFunc) - { - if (isSome()) { - return ptr(); - } - return aFunc(); - } - - template - const T* ptrOrFrom(F&& aFunc) const - { - if (isSome()) { - return ptr(); - } - return aFunc(); - } - - T* operator->() - { - MOZ_ASSERT(mIsSome); - return ptr(); - } - - const T* operator->() const - { - MOZ_ASSERT(mIsSome); - return ptr(); - } - - /* Returns the contents of this Maybe by ref. Unsafe unless |isSome()|. */ - T& ref() - { - MOZ_ASSERT(mIsSome); - return *mStorage.addr(); - } - - const T& ref() const - { - MOZ_ASSERT(mIsSome); - return *mStorage.addr(); - } - - /* - * Returns the contents of this Maybe by ref. If |isNothing()|, returns - * the default value provided. - */ - T& refOr(T& aDefault) - { - if (isSome()) { - return ref(); - } - return aDefault; - } - - const T& refOr(const T& aDefault) const - { - if (isSome()) { - return ref(); - } - return aDefault; - } - - /* - * Returns the contents of this Maybe by ref. If |isNothing()|, returns the - * value returned from the function or functor provided. - */ - template - T& refOrFrom(F&& aFunc) - { - if (isSome()) { - return ref(); - } - return aFunc(); - } - - template - const T& refOrFrom(F&& aFunc) const - { - if (isSome()) { - return ref(); - } - return aFunc(); - } - - T& operator*() - { - MOZ_ASSERT(mIsSome); - return ref(); - } - - const T& operator*() const - { - MOZ_ASSERT(mIsSome); - return ref(); - } - - /* If |isSome()|, runs the provided function or functor on the contents of - * this Maybe. */ - template - Maybe& apply(Func aFunc) - { - if (isSome()) { - aFunc(ref()); - } - return *this; - } - - template - const Maybe& apply(Func aFunc) const - { - if (isSome()) { - aFunc(ref()); - } - return *this; - } - - /* - * If |isSome()|, runs the provided function and returns the result wrapped - * in a Maybe. If |isNothing()|, returns an empty Maybe value. - */ - template - auto map(Func aFunc) -> Maybe>().ref()))> - { - using ReturnType = decltype(aFunc(ref())); - if (isSome()) { - Maybe val; - val.emplace(aFunc(ref())); - return val; - } - return Maybe(); - } - - template - auto map(Func aFunc) const -> Maybe>().ref()))> - { - using ReturnType = decltype(aFunc(ref())); - if (isSome()) { - Maybe val; - val.emplace(aFunc(ref())); - return val; - } - return Maybe(); - } - - /* If |isSome()|, empties this Maybe and destroys its contents. */ - void reset() - { - if (isSome()) { - ref().T::~T(); - mIsSome = false; - } - } - - /* - * Constructs a T value in-place in this empty Maybe's storage. The - * arguments to |emplace()| are the parameters to T's constructor. - */ - template - void emplace(Args&&... aArgs) - { - MOZ_ASSERT(!mIsSome); - ::new (mStorage.addr()) T(Forward(aArgs)...); - mIsSome = true; - } -}; - -/* - * Some() creates a Maybe value containing the provided T value. If T has a - * move constructor, it's used to make this as efficient as possible. - * - * Some() selects the type of Maybe it returns by removing any const, volatile, - * or reference qualifiers from the type of the value you pass to it. This gives - * it more intuitive behavior when used in expressions, but it also means that - * if you need to construct a Maybe value that holds a const, volatile, or - * reference value, you need to use emplace() instead. - */ -template -Maybe::Type>::Type> -Some(T&& aValue) -{ - typedef typename RemoveCV::Type>::Type U; - Maybe value; - value.emplace(Forward(aValue)); - return value; -} - -template -Maybe::Type>::Type> -ToMaybe(T* aPtr) -{ - if (aPtr) { - return Some(*aPtr); - } - return Nothing(); -} - -/* - * Two Maybe values are equal if - * - both are Nothing, or - * - both are Some, and the values they contain are equal. - */ -template bool -operator==(const Maybe& aLHS, const Maybe& aRHS) -{ - if (aLHS.isNothing() != aRHS.isNothing()) { - return false; - } - return aLHS.isNothing() || *aLHS == *aRHS; -} - -template bool -operator!=(const Maybe& aLHS, const Maybe& aRHS) -{ - return !(aLHS == aRHS); -} - -/* - * We support comparison to Nothing to allow reasonable expressions like: - * if (maybeValue == Nothing()) { ... } - */ -template bool -operator==(const Maybe& aLHS, const Nothing& aRHS) -{ - return aLHS.isNothing(); -} - -template bool -operator!=(const Maybe& aLHS, const Nothing& aRHS) -{ - return !(aLHS == aRHS); -} - -template bool -operator==(const Nothing& aLHS, const Maybe& aRHS) -{ - return aRHS.isNothing(); -} - -template bool -operator!=(const Nothing& aLHS, const Maybe& aRHS) -{ - return !(aLHS == aRHS); -} - -/* - * Maybe values are ordered in the same way T values are ordered, except that - * Nothing comes before anything else. - */ -template bool -operator<(const Maybe& aLHS, const Maybe& aRHS) -{ - if (aLHS.isNothing()) { - return aRHS.isSome(); - } - if (aRHS.isNothing()) { - return false; - } - return *aLHS < *aRHS; -} - -template bool -operator>(const Maybe& aLHS, const Maybe& aRHS) -{ - return !(aLHS < aRHS || aLHS == aRHS); -} - -template bool -operator<=(const Maybe& aLHS, const Maybe& aRHS) -{ - return aLHS < aRHS || aLHS == aRHS; -} - -template bool -operator>=(const Maybe& aLHS, const Maybe& aRHS) -{ - return !(aLHS < aRHS); -} - -} // namespace mozilla - -#endif /* mozilla_Maybe_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/MaybeOneOf.h b/android/arm64-v8a/include/spidermonkey/mozilla/MaybeOneOf.h deleted file mode 100644 index 9c38ff8b..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/MaybeOneOf.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_MaybeOneOf_h -#define mozilla_MaybeOneOf_h - -#include "mozilla/Alignment.h" -#include "mozilla/Assertions.h" -#include "mozilla/Move.h" -#include "mozilla/TemplateLib.h" - -#include // For placement new - -namespace mozilla { - -/* - * MaybeOneOf is like Maybe, but it supports constructing either T1 - * or T2. When a MaybeOneOf is constructed, it is |empty()|, i.e., - * no value has been constructed and no destructor will be called when the - * MaybeOneOf is destroyed. Upon calling |construct()| or - * |construct()|, a T1 or T2 object will be constructed with the given - * arguments and that object will be destroyed when the owning MaybeOneOf is - * destroyed. - */ -template -class MaybeOneOf -{ - AlignedStorage::value> storage; - - enum State { None, SomeT1, SomeT2 } state; - template struct Type2State {}; - - template - T& as() - { - MOZ_ASSERT(state == Type2State::result); - return *(T*)storage.addr(); - } - - template - const T& as() const - { - MOZ_ASSERT(state == Type2State::result); - return *(T*)storage.addr(); - } - -public: - MaybeOneOf() : state(None) {} - ~MaybeOneOf() { destroyIfConstructed(); } - - MaybeOneOf(MaybeOneOf&& rhs) - : state(None) - { - if (!rhs.empty()) { - if (rhs.constructed()) { - construct(Move(rhs.as())); - rhs.as().~T1(); - } else { - construct(Move(rhs.as())); - rhs.as().~T2(); - } - rhs.state = None; - } - } - - MaybeOneOf &operator=(MaybeOneOf&& rhs) - { - MOZ_ASSERT(this != &rhs, "Self-move is prohibited"); - this->~MaybeOneOf(); - new(this) MaybeOneOf(Move(rhs)); - return *this; - } - - bool empty() const { return state == None; } - - template - bool constructed() const { return state == Type2State::result; } - - template - void construct(Args&&... aArgs) - { - MOZ_ASSERT(state == None); - state = Type2State::result; - ::new (storage.addr()) T(Forward(aArgs)...); - } - - template - T& ref() - { - return as(); - } - - template - const T& ref() const - { - return as(); - } - - void destroy() - { - MOZ_ASSERT(state == SomeT1 || state == SomeT2); - if (state == SomeT1) { - as().~T1(); - } else if (state == SomeT2) { - as().~T2(); - } - state = None; - } - - void destroyIfConstructed() - { - if (!empty()) { - destroy(); - } - } - -private: - MaybeOneOf(const MaybeOneOf& aOther) = delete; - const MaybeOneOf& operator=(const MaybeOneOf& aOther) = delete; -}; - -template -template -struct MaybeOneOf::Type2State -{ - typedef MaybeOneOf Enclosing; - static const typename Enclosing::State result = Enclosing::SomeT1; -}; - -template -template -struct MaybeOneOf::Type2State -{ - typedef MaybeOneOf Enclosing; - static const typename Enclosing::State result = Enclosing::SomeT2; -}; - -} // namespace mozilla - -#endif /* mozilla_MaybeOneOf_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/MemoryChecking.h b/android/arm64-v8a/include/spidermonkey/mozilla/MemoryChecking.h deleted file mode 100644 index ff42d7f1..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/MemoryChecking.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Provides a common interface to the ASan (AddressSanitizer) and Valgrind - * functions used to mark memory in certain ways. In detail, the following - * three macros are provided: - * - * MOZ_MAKE_MEM_NOACCESS - Mark memory as unsafe to access (e.g. freed) - * MOZ_MAKE_MEM_UNDEFINED - Mark memory as accessible, with content undefined - * MOZ_MAKE_MEM_DEFINED - Mark memory as accessible, with content defined - * - * With Valgrind in use, these directly map to the three respective Valgrind - * macros. With ASan in use, the NOACCESS macro maps to poisoning the memory, - * while the UNDEFINED/DEFINED macros unpoison memory. - * - * With no memory checker available, all macros expand to the empty statement. - */ - -#ifndef mozilla_MemoryChecking_h -#define mozilla_MemoryChecking_h - -#if defined(MOZ_VALGRIND) -#include "valgrind/memcheck.h" -#endif - -#if defined(MOZ_ASAN) || defined(MOZ_VALGRIND) -#define MOZ_HAVE_MEM_CHECKS 1 -#endif - -#if defined(MOZ_ASAN) -#include - -#include "mozilla/Attributes.h" -#include "mozilla/Types.h" - -#ifdef _MSC_VER -// In clang-cl based ASAN, we link against the memory poisoning functions -// statically. -#define MOZ_ASAN_VISIBILITY -#else -#define MOZ_ASAN_VISIBILITY MOZ_EXPORT -#endif - -extern "C" { -/* These definitions are usually provided through the - * sanitizer/asan_interface.h header installed by ASan. - */ -void MOZ_ASAN_VISIBILITY -__asan_poison_memory_region(void const volatile *addr, size_t size); -void MOZ_ASAN_VISIBILITY -__asan_unpoison_memory_region(void const volatile *addr, size_t size); - -#define MOZ_MAKE_MEM_NOACCESS(addr, size) \ - __asan_poison_memory_region((addr), (size)) - -#define MOZ_MAKE_MEM_UNDEFINED(addr, size) \ - __asan_unpoison_memory_region((addr), (size)) - -#define MOZ_MAKE_MEM_DEFINED(addr, size) \ - __asan_unpoison_memory_region((addr), (size)) - -/* - * These definitions are usually provided through the - * sanitizer/lsan_interface.h header installed by LSan. - */ -void MOZ_EXPORT -__lsan_ignore_object(const void *p); - -} -#elif defined(MOZ_MSAN) -#include - -#include "mozilla/Types.h" - -extern "C" { -/* These definitions are usually provided through the - * sanitizer/msan_interface.h header installed by MSan. - */ -void MOZ_EXPORT -__msan_poison(void const volatile *addr, size_t size); -void MOZ_EXPORT -__msan_unpoison(void const volatile *addr, size_t size); - -#define MOZ_MAKE_MEM_NOACCESS(addr, size) \ - __msan_poison((addr), (size)) - -#define MOZ_MAKE_MEM_UNDEFINED(addr, size) \ - __msan_poison((addr), (size)) - -#define MOZ_MAKE_MEM_DEFINED(addr, size) \ - __msan_unpoison((addr), (size)) -} -#elif defined(MOZ_VALGRIND) -#define MOZ_MAKE_MEM_NOACCESS(addr, size) \ - VALGRIND_MAKE_MEM_NOACCESS((addr), (size)) - -#define MOZ_MAKE_MEM_UNDEFINED(addr, size) \ - VALGRIND_MAKE_MEM_UNDEFINED((addr), (size)) - -#define MOZ_MAKE_MEM_DEFINED(addr, size) \ - VALGRIND_MAKE_MEM_DEFINED((addr), (size)) -#else - -#define MOZ_MAKE_MEM_NOACCESS(addr, size) do {} while (0) -#define MOZ_MAKE_MEM_UNDEFINED(addr, size) do {} while (0) -#define MOZ_MAKE_MEM_DEFINED(addr, size) do {} while (0) - -#endif - -/* - * MOZ_LSAN_INTENTIONAL_LEAK(X) is a macro to tell LeakSanitizer that X - * points to a value that will intentionally never be deallocated during - * the execution of the process. - * - * Additional uses of this macro should be reviewed by people - * conversant in leak-checking and/or MFBT peers. - */ -#if defined(MOZ_ASAN) -# define MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(X) __lsan_ignore_object(X) -#else -# define MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(X) /* nothing */ -#endif // defined(MOZ_ASAN) - - -#endif /* mozilla_MemoryChecking_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/MemoryReporting.h b/android/arm64-v8a/include/spidermonkey/mozilla/MemoryReporting.h deleted file mode 100644 index d2340ecf..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/MemoryReporting.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Memory reporting infrastructure. */ - -#ifndef mozilla_MemoryReporting_h -#define mozilla_MemoryReporting_h - -#include - -#ifdef __cplusplus - -namespace mozilla { - -/* - * This is for functions that are like malloc_usable_size. Such functions are - * used for measuring the size of data structures. - */ -typedef size_t (*MallocSizeOf)(const void* p); - -} /* namespace mozilla */ - -#endif /* __cplusplus */ - -typedef size_t (*MozMallocSizeOf)(const void* p); - -#endif /* mozilla_MemoryReporting_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Move.h b/android/arm64-v8a/include/spidermonkey/mozilla/Move.h deleted file mode 100644 index f6d0bfc1..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Move.h +++ /dev/null @@ -1,238 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* C++11-style, but C++98-usable, "move references" implementation. */ - -#ifndef mozilla_Move_h -#define mozilla_Move_h - -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -/* - * "Move" References - * - * Some types can be copied much more efficiently if we know the original's - * value need not be preserved --- that is, if we are doing a "move", not a - * "copy". For example, if we have: - * - * Vector u; - * Vector v(u); - * - * the constructor for v must apply a copy constructor to each element of u --- - * taking time linear in the length of u. However, if we know we will not need u - * any more once v has been initialized, then we could initialize v very - * efficiently simply by stealing u's dynamically allocated buffer and giving it - * to v --- a constant-time operation, regardless of the size of u. - * - * Moves often appear in container implementations. For example, when we append - * to a vector, we may need to resize its buffer. This entails moving each of - * its extant elements from the old, smaller buffer to the new, larger buffer. - * But once the elements have been migrated, we're just going to throw away the - * old buffer; we don't care if they still have their values. So if the vector's - * element type can implement "move" more efficiently than "copy", the vector - * resizing should by all means use a "move" operation. Hash tables should also - * use moves when resizing their internal array as entries are added and - * removed. - * - * The details of the optimization, and whether it's worth applying, vary - * from one type to the next: copying an 'int' is as cheap as moving it, so - * there's no benefit in distinguishing 'int' moves from copies. And while - * some constructor calls for complex types are moves, many really have to - * be copies, and can't be optimized this way. So we need: - * - * 1) a way for a type (like Vector) to announce that it can be moved more - * efficiently than it can be copied, and provide an implementation of that - * move operation; and - * - * 2) a way for a particular invocation of a copy constructor to say that it's - * really a move, not a copy, and that the value of the original isn't - * important afterwards (although it must still be safe to destroy). - * - * If a constructor has a single argument of type 'T&&' (an 'rvalue reference - * to T'), that indicates that it is a 'move constructor'. That's 1). It should - * move, not copy, its argument into the object being constructed. It may leave - * the original in any safely-destructible state. - * - * If a constructor's argument is an rvalue, as in 'C(f(x))' or 'C(x + y)', as - * opposed to an lvalue, as in 'C(x)', then overload resolution will prefer the - * move constructor, if there is one. The 'mozilla::Move' function, defined in - * this file, is an identity function you can use in a constructor invocation to - * make any argument into an rvalue, like this: C(Move(x)). That's 2). (You - * could use any function that works, but 'Move' indicates your intention - * clearly.) - * - * Where we might define a copy constructor for a class C like this: - * - * C(const C& rhs) { ... copy rhs to this ... } - * - * we would declare a move constructor like this: - * - * C(C&& rhs) { .. move rhs to this ... } - * - * And where we might perform a copy like this: - * - * C c2(c1); - * - * we would perform a move like this: - * - * C c2(Move(c1)); - * - * Note that 'T&&' implicitly converts to 'T&'. So you can pass a 'T&&' to an - * ordinary copy constructor for a type that doesn't support a special move - * constructor, and you'll just get a copy. This means that templates can use - * Move whenever they know they won't use the original value any more, even if - * they're not sure whether the type at hand has a specialized move constructor. - * If it doesn't, the 'T&&' will just convert to a 'T&', and the ordinary copy - * constructor will apply. - * - * A class with a move constructor can also provide a move assignment operator. - * A generic definition would run this's destructor, and then apply the move - * constructor to *this's memory. A typical definition: - * - * C& operator=(C&& rhs) { - * MOZ_ASSERT(&rhs != this, "self-moves are prohibited"); - * this->~C(); - * new(this) C(Move(rhs)); - * return *this; - * } - * - * With that in place, one can write move assignments like this: - * - * c2 = Move(c1); - * - * This destroys c2, moves c1's value to c2, and leaves c1 in an undefined but - * destructible state. - * - * As we say, a move must leave the original in a "destructible" state. The - * original's destructor will still be called, so if a move doesn't - * actually steal all its resources, that's fine. We require only that the - * move destination must take on the original's value; and that destructing - * the original must not break the move destination. - * - * (Opinions differ on whether move assignment operators should deal with move - * assignment of an object onto itself. It seems wise to either handle that - * case, or assert that it does not occur.) - * - * Forwarding: - * - * Sometimes we want copy construction or assignment if we're passed an ordinary - * value, but move construction if passed an rvalue reference. For example, if - * our constructor takes two arguments and either could usefully be a move, it - * seems silly to write out all four combinations: - * - * C::C(X& x, Y& y) : x(x), y(y) { } - * C::C(X& x, Y&& y) : x(x), y(Move(y)) { } - * C::C(X&& x, Y& y) : x(Move(x)), y(y) { } - * C::C(X&& x, Y&& y) : x(Move(x)), y(Move(y)) { } - * - * To avoid this, C++11 has tweaks to make it possible to write what you mean. - * The four constructor overloads above can be written as one constructor - * template like so[0]: - * - * template - * C::C(XArg&& x, YArg&& y) : x(Forward(x)), y(Forward(y)) { } - * - * ("'Don't Repeat Yourself'? What's that?") - * - * This takes advantage of two new rules in C++11: - * - * - First, when a function template takes an argument that is an rvalue - * reference to a template argument (like 'XArg&& x' and 'YArg&& y' above), - * then when the argument is applied to an lvalue, the template argument - * resolves to 'T&'; and when it is applied to an rvalue, the template - * argument resolves to 'T'. Thus, in a call to C::C like: - * - * X foo(int); - * Y yy; - * - * C(foo(5), yy) - * - * XArg would resolve to 'X', and YArg would resolve to 'Y&'. - * - * - Second, Whereas C++ used to forbid references to references, C++11 defines - * 'collapsing rules': 'T& &', 'T&& &', and 'T& &&' (that is, any combination - * involving an lvalue reference) now collapse to simply 'T&'; and 'T&& &&' - * collapses to 'T&&'. - * - * Thus, in the call above, 'XArg&&' is 'X&&'; and 'YArg&&' is 'Y& &&', which - * collapses to 'Y&'. Because the arguments are declared as rvalue references - * to template arguments, the lvalue-ness "shines through" where present. - * - * Then, the 'Forward' function --- you must invoke 'Forward' with its type - * argument --- returns an lvalue reference or an rvalue reference to its - * argument, depending on what T is. In our unified constructor definition, that - * means that we'll invoke either the copy or move constructors for x and y, - * depending on what we gave C's constructor. In our call, we'll move 'foo()' - * into 'x', but copy 'yy' into 'y'. - * - * This header file defines Move and Forward in the mozilla namespace. It's up - * to individual containers to annotate moves as such, by calling Move; and it's - * up to individual types to define move constructors and assignment operators - * when valuable. - * - * (C++11 says that the header file should define 'std::move' and - * 'std::forward', which are just like our 'Move' and 'Forward'; but those - * definitions aren't available in that header on all our platforms, so we - * define them ourselves here.) - * - * 0. This pattern is known as "perfect forwarding". Interestingly, it is not - * actually perfect, and it can't forward all possible argument expressions! - * There is a C++11 issue: you can't form a reference to a bit-field. As a - * workaround, assign the bit-field to a local variable and use that: - * - * // C is as above - * struct S { int x : 1; } s; - * C(s.x, 0); // BAD: s.x is a reference to a bit-field, can't form those - * int tmp = s.x; - * C(tmp, 0); // OK: tmp not a bit-field - */ - -/** - * Identical to std::Move(); this is necessary until our stlport supports - * std::move(). - */ -template -inline typename RemoveReference::Type&& -Move(T&& aX) -{ - return static_cast::Type&&>(aX); -} - -/** - * These two overloads are identical to std::forward(); they are necessary until - * our stlport supports std::forward(). - */ -template -inline T&& -Forward(typename RemoveReference::Type& aX) -{ - return static_cast(aX); -} - -template -inline T&& -Forward(typename RemoveReference::Type&& aX) -{ - static_assert(!IsLvalueReference::value, - "misuse of Forward detected! try the other overload"); - return static_cast(aX); -} - -/** Swap |aX| and |aY| using move-construction if possible. */ -template -inline void -Swap(T& aX, T& aY) -{ - T tmp(Move(aX)); - aX = Move(aY); - aY = Move(tmp); -} - -} // namespace mozilla - -#endif /* mozilla_Move_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/NotNull.h b/android/arm64-v8a/include/spidermonkey/mozilla/NotNull.h deleted file mode 100644 index 0c3c333e..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/NotNull.h +++ /dev/null @@ -1,209 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_NotNull_h -#define mozilla_NotNull_h - -// It's often unclear if a particular pointer, be it raw (T*) or smart -// (RefPtr, nsCOMPtr, etc.) can be null. This leads to missing null -// checks (which can cause crashes) and unnecessary null checks (which clutter -// the code). -// -// C++ has a built-in alternative that avoids these problems: references. This -// module defines another alternative, NotNull, which can be used in cases -// where references are not suitable. -// -// In the comments below we use the word "handle" to cover all varieties of -// pointers and references. -// -// References -// ---------- -// References are always non-null. (You can do |T& r = *p;| where |p| is null, -// but that's undefined behaviour. C++ doesn't provide any built-in, ironclad -// guarantee of non-nullness.) -// -// A reference works well when you need a temporary handle to an existing -// single object, e.g. for passing a handle to a function, or as a local handle -// within another object. (In Rust parlance, this is a "borrow".) -// -// A reference is less appropriate in the following cases. -// -// - As a primary handle to an object. E.g. code such as this is possible but -// strange: |T& t = *new T(); ...; delete &t;| -// -// - As a handle to an array. It's common for |T*| to refer to either a single -// |T| or an array of |T|, but |T&| cannot refer to an array of |T| because -// you can't index off a reference (at least, not without first converting it -// to a pointer). -// -// - When the handle identity is meaningful, e.g. if you have a hashtable of -// handles, because you have to use |&| on the reference to convert it to a -// pointer. -// -// - Some people don't like using non-const references as function parameters, -// because it is not clear at the call site that the argument might be -// modified. -// -// - When you need "smart" behaviour. E.g. we lack reference equivalents to -// RefPtr and nsCOMPtr. -// -// - When interfacing with code that uses pointers a lot, sometimes using a -// reference just feels like an odd fit. -// -// Furthermore, a reference is impossible in the following cases. -// -// - When the handle is rebound to another object. References don't allow this. -// -// - When the handle has type |void|. |void&| is not allowed. -// -// NotNull is an alternative that can be used in any of the above cases except -// for the last one, where the handle type is |void|. See below. - -#include "mozilla/Assertions.h" - -namespace mozilla { - -// NotNull can be used to wrap a "base" pointer (raw or smart) to indicate it -// is not null. Some examples: -// -// - NotNull -// - NotNull> -// - NotNull> -// -// NotNull has the following notable properties. -// -// - It has zero space overhead. -// -// - It must be initialized explicitly. There is no default initialization. -// -// - It auto-converts to the base pointer type. -// -// - It does not auto-convert from a base pointer. Implicit conversion from a -// less-constrained type (e.g. T*) to a more-constrained type (e.g. -// NotNull) is dangerous. Creation and assignment from a base pointer can -// only be done with WrapNotNull(), which makes them impossible to overlook, -// both when writing and reading code. -// -// - When initialized (or assigned) it is checked, and if it is null we abort. -// This guarantees that it cannot be null. -// -// - |operator bool()| is deleted. This means you cannot check a NotNull in a -// boolean context, which eliminates the possibility of unnecessary null -// checks. -// -// NotNull currently doesn't work with UniquePtr. See -// https://github.com/Microsoft/GSL/issues/89 for some discussion. -// -template -class NotNull -{ - template friend NotNull WrapNotNull(U aBasePtr); - - T mBasePtr; - - // This constructor is only used by WrapNotNull(). - template - explicit NotNull(U aBasePtr) : mBasePtr(aBasePtr) {} - -public: - // Disallow default construction. - NotNull() = delete; - - // Construct/assign from another NotNull with a compatible base pointer type. - template - MOZ_IMPLICIT NotNull(const NotNull& aOther) : mBasePtr(aOther.get()) {} - - // Default copy/move construction and assignment. - NotNull(const NotNull&) = default; - NotNull& operator=(const NotNull&) = default; - NotNull(NotNull&&) = default; - NotNull& operator=(NotNull&&) = default; - - // Disallow null checks, which are unnecessary for this type. - explicit operator bool() const = delete; - - // Explicit conversion to a base pointer. Use only to resolve ambiguity or to - // get a castable pointer. - const T& get() const { return mBasePtr; } - - // Implicit conversion to a base pointer. Preferable to get(). - operator const T&() const { return get(); } - - // Dereference operators. - const T& operator->() const { return get(); } - decltype(*mBasePtr) operator*() const { return *mBasePtr; } -}; - -template -NotNull -WrapNotNull(const T aBasePtr) -{ - NotNull notNull(aBasePtr); - MOZ_RELEASE_ASSERT(aBasePtr); - return notNull; -} - -// Compare two NotNulls. -template -inline bool -operator==(const NotNull& aLhs, const NotNull& aRhs) -{ - return aLhs.get() == aRhs.get(); -} -template -inline bool -operator!=(const NotNull& aLhs, const NotNull& aRhs) -{ - return aLhs.get() != aRhs.get(); -} - -// Compare a NotNull to a base pointer. -template -inline bool -operator==(const NotNull& aLhs, const U& aRhs) -{ - return aLhs.get() == aRhs; -} -template -inline bool -operator!=(const NotNull& aLhs, const U& aRhs) -{ - return aLhs.get() != aRhs; -} - -// Compare a base pointer to a NotNull. -template -inline bool -operator==(const T& aLhs, const NotNull& aRhs) -{ - return aLhs == aRhs.get(); -} -template -inline bool -operator!=(const T& aLhs, const NotNull& aRhs) -{ - return aLhs != aRhs.get(); -} - -// Disallow comparing a NotNull to a nullptr. -template -bool -operator==(const NotNull&, decltype(nullptr)) = delete; -template -bool -operator!=(const NotNull&, decltype(nullptr)) = delete; - -// Disallow comparing a nullptr to a NotNull. -template -bool -operator==(decltype(nullptr), const NotNull&) = delete; -template -bool -operator!=(decltype(nullptr), const NotNull&) = delete; - -} // namespace mozilla - -#endif /* mozilla_NotNull_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/NullPtr.h b/android/arm64-v8a/include/spidermonkey/mozilla/NullPtr.h deleted file mode 100644 index d2248f4b..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/NullPtr.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implements a mozilla::IsNullPointer type trait. */ - -#ifndef mozilla_NullPtr_h -#define mozilla_NullPtr_h - -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -/** - * IsNullPointer::value is true iff T is decltype(nullptr). - * - * Ideally this would be in TypeTraits.h, but C++11 omitted std::is_null_pointer - * (fixed in C++14), so in the interests of easing a switch to , - * this trait lives elsewhere. - */ -template -struct IsNullPointer : FalseType {}; - -template<> -struct IsNullPointer : TrueType {}; - -} // namespace mozilla - -#endif /* mozilla_NullPtr_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Opaque.h b/android/arm64-v8a/include/spidermonkey/mozilla/Opaque.h deleted file mode 100644 index d7239ee7..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Opaque.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* An opaque integral type supporting only comparison operators. */ - -#ifndef mozilla_Opaque_h -#define mozilla_Opaque_h - -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -/** - * Opaque is a replacement for integral T in cases where only comparisons - * must be supported, and it's desirable to prevent accidental dependency on - * exact values. - */ -template -class Opaque final -{ - static_assert(mozilla::IsIntegral::value, - "mozilla::Opaque only supports integral types"); - - T mValue; - -public: - Opaque() {} - explicit Opaque(T aValue) : mValue(aValue) {} - - bool operator==(const Opaque& aOther) const { - return mValue == aOther.mValue; - } - - bool operator!=(const Opaque& aOther) const { - return !(*this == aOther); - } -}; - -} // namespace mozilla - -#endif /* mozilla_Opaque_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/OperatorNewExtensions.h b/android/arm64-v8a/include/spidermonkey/mozilla/OperatorNewExtensions.h deleted file mode 100644 index 52fd88a6..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/OperatorNewExtensions.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A version of |operator new| that eschews mandatory null-checks. */ - -#ifndef mozilla_OperatorNewExtensions_h -#define mozilla_OperatorNewExtensions_h - -#include "mozilla/Assertions.h" - -// Credit goes to WebKit for this implementation, cf. -// https://bugs.webkit.org/show_bug.cgi?id=74676 -namespace mozilla { -enum NotNullTag { - KnownNotNull, -}; -} // namespace mozilla - -/* - * The logic here is a little subtle. [expr.new] states that if the allocation - * function being called returns null, then object initialization must not be - * done, and the entirety of the new expression must return null. Non-throwing - * (noexcept) functions are defined to return null to indicate failure. The - * standard placement operator new is defined in such a way, and so it requires - * a null check, even when that null check would be extraneous. Functions - * declared without such a specification are defined to throw std::bad_alloc if - * they fail, and return a non-null pointer otherwise. We compile without - * exceptions, so any placement new overload we define that doesn't declare - * itself as noexcept must therefore avoid generating a null check. Below is - * just such an overload. - * - * You might think that MOZ_NONNULL might perform the same function, but - * MOZ_NONNULL isn't supported on all of our compilers, and even when it is - * supported, doesn't work on all the versions we support. And even keeping - * those limitations in mind, we can't put MOZ_NONNULL on the global, - * standardized placement new function in any event. - * - * We deliberately don't add MOZ_NONNULL(3) to tag |p| as non-null, to benefit - * hypothetical static analyzers. Doing so makes |MOZ_ASSERT(p)|'s internal - * test vacuous, and some compilers warn about such vacuous tests. - */ -inline void* -operator new(size_t, mozilla::NotNullTag, void* p) -{ - MOZ_ASSERT(p); - return p; -} - -#endif // mozilla_OperatorNewExtensions_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Pair.h b/android/arm64-v8a/include/spidermonkey/mozilla/Pair.h deleted file mode 100644 index ad7b86a2..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Pair.h +++ /dev/null @@ -1,219 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A class holding a pair of objects that tries to conserve storage space. */ - -#ifndef mozilla_Pair_h -#define mozilla_Pair_h - -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -namespace detail { - -enum StorageType { AsBase, AsMember }; - -// Optimize storage using the Empty Base Optimization -- that empty base classes -// don't take up space -- to optimize size when one or the other class is -// stateless and can be used as a base class. -// -// The extra conditions on storage for B are necessary so that PairHelper won't -// ambiguously inherit from either A or B, such that one or the other base class -// would be inaccessible. -template::value ? detail::AsBase : detail::AsMember, - detail::StorageType = - IsEmpty::value && !IsBaseOf::value && !IsBaseOf::value - ? detail::AsBase - : detail::AsMember> -struct PairHelper; - -template -struct PairHelper -{ -protected: - template - PairHelper(AArg&& aA, BArg&& aB) - : mFirstA(Forward(aA)), - mSecondB(Forward(aB)) - {} - - A& first() { return mFirstA; } - const A& first() const { return mFirstA; } - B& second() { return mSecondB; } - const B& second() const { return mSecondB; } - - void swap(PairHelper& aOther) - { - Swap(mFirstA, aOther.mFirstA); - Swap(mSecondB, aOther.mSecondB); - } - -private: - A mFirstA; - B mSecondB; -}; - -template -struct PairHelper : private B -{ -protected: - template - PairHelper(AArg&& aA, BArg&& aB) - : B(Forward(aB)), - mFirstA(Forward(aA)) - {} - - A& first() { return mFirstA; } - const A& first() const { return mFirstA; } - B& second() { return *this; } - const B& second() const { return *this; } - - void swap(PairHelper& aOther) - { - Swap(mFirstA, aOther.mFirstA); - Swap(static_cast(*this), static_cast(aOther)); - } - -private: - A mFirstA; -}; - -template -struct PairHelper : private A -{ -protected: - template - PairHelper(AArg&& aA, BArg&& aB) - : A(Forward(aA)), - mSecondB(Forward(aB)) - {} - - A& first() { return *this; } - const A& first() const { return *this; } - B& second() { return mSecondB; } - const B& second() const { return mSecondB; } - - void swap(PairHelper& aOther) - { - Swap(static_cast(*this), static_cast(aOther)); - Swap(mSecondB, aOther.mSecondB); - } - -private: - B mSecondB; -}; - -template -struct PairHelper : private A, private B -{ -protected: - template - PairHelper(AArg&& aA, BArg&& aB) - : A(Forward(aA)), - B(Forward(aB)) - {} - - A& first() { return static_cast(*this); } - const A& first() const { return static_cast(*this); } - B& second() { return static_cast(*this); } - const B& second() const { return static_cast(*this); } - - void swap(PairHelper& aOther) - { - Swap(static_cast(*this), static_cast(aOther)); - Swap(static_cast(*this), static_cast(aOther)); - } -}; - -} // namespace detail - -/** - * Pair is the logical concatenation of an instance of A with an instance B. - * Space is conserved when possible. Neither A nor B may be a final class. - * - * It's typically clearer to have individual A and B member fields. Except if - * you want the space-conserving qualities of Pair, you're probably better off - * not using this! - * - * No guarantees are provided about the memory layout of A and B, the order of - * initialization or destruction of A and B, and so on. (This is approximately - * required to optimize space usage.) The first/second names are merely - * conceptual! - */ -template -struct Pair - : private detail::PairHelper -{ - typedef typename detail::PairHelper Base; - -public: - template - Pair(AArg&& aA, BArg&& aB) - : Base(Forward(aA), Forward(aB)) - {} - - Pair(Pair&& aOther) - : Base(Move(aOther.first()), Move(aOther.second())) - { } - - Pair(const Pair& aOther) = default; - - Pair& operator=(Pair&& aOther) - { - MOZ_ASSERT(this != &aOther, "Self-moves are prohibited"); - - first() = Move(aOther.first()); - second() = Move(aOther.second()); - - return *this; - } - - Pair& operator=(const Pair& aOther) = default; - - /** The A instance. */ - using Base::first; - /** The B instance. */ - using Base::second; - - /** Swap this pair with another pair. */ - void swap(Pair& aOther) { Base::swap(aOther); } -}; - -template -void -Swap(Pair& aX, Pair& aY) -{ - aX.swap(aY); -} - -/** - * MakePair allows you to construct a Pair instance using type inference. A call - * like this: - * - * MakePair(Foo(), Bar()) - * - * will return a Pair. - */ -template -Pair::Type>::Type, - typename RemoveCV::Type>::Type> -MakePair(A&& aA, B&& aB) -{ - return - Pair::Type>::Type, - typename RemoveCV::Type>::Type>( - Forward(aA), - Forward(aB)); -} - -} // namespace mozilla - -#endif /* mozilla_Pair_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/PodOperations.h b/android/arm64-v8a/include/spidermonkey/mozilla/PodOperations.h deleted file mode 100644 index e6f4df21..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/PodOperations.h +++ /dev/null @@ -1,196 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Operations for zeroing POD types, arrays, and so on. - * - * These operations are preferable to memset, memcmp, and the like because they - * don't require remembering to multiply by sizeof(T), array lengths, and so on - * everywhere. - */ - -#ifndef mozilla_PodOperations_h -#define mozilla_PodOperations_h - -#include "mozilla/Array.h" -#include "mozilla/ArrayUtils.h" -#include "mozilla/Attributes.h" - -#include -#include - -namespace mozilla { - -/** Set the contents of |aT| to 0. */ -template -static MOZ_ALWAYS_INLINE void -PodZero(T* aT) -{ - memset(aT, 0, sizeof(T)); -} - -/** Set the contents of |aNElem| elements starting at |aT| to 0. */ -template -static MOZ_ALWAYS_INLINE void -PodZero(T* aT, size_t aNElem) -{ - /* - * This function is often called with 'aNElem' small; we use an inline loop - * instead of calling 'memset' with a non-constant length. The compiler - * should inline the memset call with constant size, though. - */ - for (T* end = aT + aNElem; aT < end; aT++) { - memset(aT, 0, sizeof(T)); - } -} - -/* - * Arrays implicitly convert to pointers to their first element, which is - * dangerous when combined with the above PodZero definitions. Adding an - * overload for arrays is ambiguous, so we need another identifier. The - * ambiguous overload is left to catch mistaken uses of PodZero; if you get a - * compile error involving PodZero and array types, use PodArrayZero instead. - */ -template -static void PodZero(T (&aT)[N]) = delete; -template -static void PodZero(T (&aT)[N], size_t aNElem) = delete; - -/** Set the contents of the array |aT| to zero. */ -template -static MOZ_ALWAYS_INLINE void -PodArrayZero(T (&aT)[N]) -{ - memset(aT, 0, N * sizeof(T)); -} - -template -static MOZ_ALWAYS_INLINE void -PodArrayZero(Array& aArr) -{ - memset(&aArr[0], 0, N * sizeof(T)); -} - -/** - * Assign |*aSrc| to |*aDst|. The locations must not be the same and must not - * overlap. - */ -template -static MOZ_ALWAYS_INLINE void -PodAssign(T* aDst, const T* aSrc) -{ - MOZ_ASSERT(aDst + 1 <= aSrc || aSrc + 1 <= aDst, - "destination and source must not overlap"); - memcpy(reinterpret_cast(aDst), reinterpret_cast(aSrc), - sizeof(T)); -} - -/** - * Copy |aNElem| T elements from |aSrc| to |aDst|. The two memory ranges must - * not overlap! - */ -template -static MOZ_ALWAYS_INLINE void -PodCopy(T* aDst, const T* aSrc, size_t aNElem) -{ - MOZ_ASSERT(aDst + aNElem <= aSrc || aSrc + aNElem <= aDst, - "destination and source must not overlap"); - if (aNElem < 128) { - /* - * Avoid using operator= in this loop, as it may have been - * intentionally deleted by the POD type. - */ - for (const T* srcend = aSrc + aNElem; aSrc < srcend; aSrc++, aDst++) { - PodAssign(aDst, aSrc); - } - } else { - memcpy(aDst, aSrc, aNElem * sizeof(T)); - } -} - -template -static MOZ_ALWAYS_INLINE void -PodCopy(volatile T* aDst, const volatile T* aSrc, size_t aNElem) -{ - MOZ_ASSERT(aDst + aNElem <= aSrc || aSrc + aNElem <= aDst, - "destination and source must not overlap"); - - /* - * Volatile |aDst| requires extra work, because it's undefined behavior to - * modify volatile objects using the mem* functions. Just write out the - * loops manually, using operator= rather than memcpy for the same reason, - * and let the compiler optimize to the extent it can. - */ - for (const volatile T* srcend = aSrc + aNElem; - aSrc < srcend; - aSrc++, aDst++) { - *aDst = *aSrc; - } -} - -/* - * Copy the contents of the array |aSrc| into the array |aDst|, both of size N. - * The arrays must not overlap! - */ -template -static MOZ_ALWAYS_INLINE void -PodArrayCopy(T (&aDst)[N], const T (&aSrc)[N]) -{ - PodCopy(aDst, aSrc, N); -} - -/** - * Copy the memory for |aNElem| T elements from |aSrc| to |aDst|. If the two - * memory ranges overlap, then the effect is as if the |aNElem| elements are - * first copied from |aSrc| to a temporary array, and then from the temporary - * array to |aDst|. - */ -template -static MOZ_ALWAYS_INLINE void -PodMove(T* aDst, const T* aSrc, size_t aNElem) -{ - MOZ_ASSERT(aNElem <= SIZE_MAX / sizeof(T), - "trying to move an impossible number of elements"); - memmove(aDst, aSrc, aNElem * sizeof(T)); -} - -/** - * Determine whether the |len| elements at |one| are memory-identical to the - * |len| elements at |two|. - */ -template -static MOZ_ALWAYS_INLINE bool -PodEqual(const T* one, const T* two, size_t len) -{ - if (len < 128) { - const T* p1end = one + len; - const T* p1 = one; - const T* p2 = two; - for (; p1 < p1end; p1++, p2++) { - if (*p1 != *p2) { - return false; - } - } - return true; - } - - return !memcmp(one, two, len * sizeof(T)); -} - -/* - * Determine whether the |N| elements at |one| are memory-identical to the - * |N| elements at |two|. - */ -template -static MOZ_ALWAYS_INLINE bool -PodEqual(const T (&one)[N], const T (&two)[N]) -{ - return PodEqual(one, two, N); -} - -} // namespace mozilla - -#endif /* mozilla_PodOperations_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Poison.h b/android/arm64-v8a/include/spidermonkey/mozilla/Poison.h deleted file mode 100644 index aae56765..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Poison.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * A poison value that can be used to fill a memory space with - * an address that leads to a safe crash when dereferenced. - */ - -#ifndef mozilla_Poison_h -#define mozilla_Poison_h - -#include "mozilla/Assertions.h" -#include "mozilla/Types.h" - -#include - -MOZ_BEGIN_EXTERN_C - -extern MFBT_DATA uintptr_t gMozillaPoisonValue; - -/** - * @return the poison value. - */ -inline uintptr_t mozPoisonValue() -{ - return gMozillaPoisonValue; -} - -/** - * Overwrite the memory block of aSize bytes at aPtr with the poison value. - * aPtr MUST be aligned at a sizeof(uintptr_t) boundary. - * Only an even number of sizeof(uintptr_t) bytes are overwritten, the last - * few bytes (if any) is not overwritten. - */ -inline void mozWritePoison(void* aPtr, size_t aSize) -{ - const uintptr_t POISON = mozPoisonValue(); - char* p = (char*)aPtr; - char* limit = p + aSize; - MOZ_ASSERT((uintptr_t)aPtr % sizeof(uintptr_t) == 0, "bad alignment"); - MOZ_ASSERT(aSize >= sizeof(uintptr_t), "poisoning this object has no effect"); - for (; p < limit; p += sizeof(uintptr_t)) { - *((uintptr_t*)p) = POISON; - } -} - -/** - * Initialize the poison value. - * This should only be called once. - */ -extern MFBT_API void mozPoisonValueInit(); - -/* Values annotated by CrashReporter */ -extern MFBT_DATA uintptr_t gMozillaPoisonBase; -extern MFBT_DATA uintptr_t gMozillaPoisonSize; - -MOZ_END_EXTERN_C - -#if defined(__cplusplus) - -namespace mozilla { - -/** - * This class is designed to cause crashes when various kinds of memory - * corruption are observed. For instance, let's say we have a class C where we - * suspect out-of-bounds writes to some members. We can insert a member of type - * Poison near the members we suspect are being corrupted by out-of-bounds - * writes. Or perhaps we have a class K we suspect is subject to use-after-free - * violations, in which case it doesn't particularly matter where in the class - * we add the member of type Poison. - * - * In either case, we then insert calls to Check() throughout the code. Doing - * so enables us to narrow down the location where the corruption is occurring. - * A pleasant side-effect of these additional Check() calls is that crash - * signatures may become more regular, as crashes will ideally occur - * consolidated at the point of a Check(), rather than scattered about at - * various uses of the corrupted memory. - */ -class CorruptionCanary { -public: - CorruptionCanary() { - mValue = kCanarySet; - } - - ~CorruptionCanary() { - Check(); - mValue = mozPoisonValue(); - } - - void Check() const { - if (mValue != kCanarySet) { - MOZ_CRASH("Canary check failed, check lifetime"); - } - } - -private: - static const uintptr_t kCanarySet = 0x0f0b0f0b; - uintptr_t mValue; -}; - -} // mozilla - -#endif - -#endif /* mozilla_Poison_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Range.h b/android/arm64-v8a/include/spidermonkey/mozilla/Range.h deleted file mode 100644 index 47d91bb0..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Range.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_Range_h -#define mozilla_Range_h - -#include "mozilla/RangedPtr.h" -#include "mozilla/TypeTraits.h" - -#include - -namespace mozilla { - -// Range is a tuple containing a pointer and a length. -template -class Range -{ - const RangedPtr mStart; - const RangedPtr mEnd; - -public: - Range() : mStart(nullptr, 0), mEnd(nullptr, 0) {} - Range(T* aPtr, size_t aLength) - : mStart(aPtr, aPtr, aPtr + aLength), - mEnd(aPtr + aLength, aPtr, aPtr + aLength) - {} - Range(const RangedPtr& aStart, const RangedPtr& aEnd) - : mStart(aStart.get(), aStart.get(), aEnd.get()), - mEnd(aEnd.get(), aStart.get(), aEnd.get()) - { - // Only accept two RangedPtrs within the same range. - aStart.checkIdenticalRange(aEnd); - MOZ_ASSERT(aStart <= aEnd); - } - - template::value, - int>::Type> - MOZ_IMPLICIT Range(const Range& aOther) - : mStart(aOther.mStart), - mEnd(aOther.mEnd) - {} - - RangedPtr begin() const { return mStart; } - RangedPtr end() const { return mEnd; } - size_t length() const { return mEnd - mStart; } - - T& operator[](size_t aOffset) const { return mStart[aOffset]; } - - explicit operator bool() const { return mStart != nullptr; } -}; - -} // namespace mozilla - -#endif /* mozilla_Range_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/RangedArray.h b/android/arm64-v8a/include/spidermonkey/mozilla/RangedArray.h deleted file mode 100644 index afe6267f..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/RangedArray.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * A compile-time constant-length array, with bounds-checking assertions -- but - * unlike mozilla::Array, with indexes biased by a constant. - * - * Thus where mozilla::Array is a three-element array indexed by [0, 3), - * mozilla::RangedArray is a three-element array indexed by [8, 11). - */ - -#ifndef mozilla_RangedArray_h -#define mozilla_RangedArray_h - -#include "mozilla/Array.h" - -namespace mozilla { - -template -class RangedArray -{ -private: - typedef Array ArrayType; - ArrayType mArr; - -public: - T& operator[](size_t aIndex) - { - MOZ_ASSERT(aIndex == MinIndex || aIndex > MinIndex); - return mArr[aIndex - MinIndex]; - } - - const T& operator[](size_t aIndex) const - { - MOZ_ASSERT(aIndex == MinIndex || aIndex > MinIndex); - return mArr[aIndex - MinIndex]; - } - - typedef typename ArrayType::iterator iterator; - typedef typename ArrayType::const_iterator const_iterator; - typedef typename ArrayType::reverse_iterator reverse_iterator; - typedef typename ArrayType::const_reverse_iterator const_reverse_iterator; - - // Methods for range-based for loops. - iterator begin() { return mArr.begin(); } - const_iterator begin() const { return mArr.begin(); } - const_iterator cbegin() const { return mArr.cbegin(); } - iterator end() { return mArr.end(); } - const_iterator end() const { return mArr.end(); } - const_iterator cend() const { return mArr.cend(); } - - // Methods for reverse iterating. - reverse_iterator rbegin() { return mArr.rbegin(); } - const_reverse_iterator rbegin() const { return mArr.rbegin(); } - const_reverse_iterator crbegin() const { return mArr.crbegin(); } - reverse_iterator rend() { return mArr.rend(); } - const_reverse_iterator rend() const { return mArr.rend(); } - const_reverse_iterator crend() const { return mArr.crend(); } -}; - -} // namespace mozilla - -#endif // mozilla_RangedArray_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/RangedPtr.h b/android/arm64-v8a/include/spidermonkey/mozilla/RangedPtr.h deleted file mode 100644 index a07c1f4f..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/RangedPtr.h +++ /dev/null @@ -1,292 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Implements a smart pointer asserted to remain within a range specified at - * construction. - */ - -#ifndef mozilla_RangedPtr_h -#define mozilla_RangedPtr_h - -#include "mozilla/ArrayUtils.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -#include - -namespace mozilla { - -/* - * RangedPtr is a smart pointer restricted to an address range specified at - * creation. The pointer (and any smart pointers derived from it) must remain - * within the range [start, end] (inclusive of end to facilitate use as - * sentinels). Dereferencing or indexing into the pointer (or pointers derived - * from it) must remain within the range [start, end). All the standard pointer - * operators are defined on it; in debug builds these operations assert that the - * range specified at construction is respected. - * - * In theory passing a smart pointer instance as an argument can be slightly - * slower than passing a T* (due to ABI requirements for passing structs versus - * passing pointers), if the method being called isn't inlined. If you are in - * extremely performance-critical code, you may want to be careful using this - * smart pointer as an argument type. - * - * RangedPtr intentionally does not implicitly convert to T*. Use get() to - * explicitly convert to T*. Keep in mind that the raw pointer of course won't - * implement bounds checking in debug builds. - */ -template -class RangedPtr -{ - T* mPtr; - -#ifdef DEBUG - T* const mRangeStart; - T* const mRangeEnd; -#endif - - void checkSanity() - { - MOZ_ASSERT(mRangeStart <= mPtr); - MOZ_ASSERT(mPtr <= mRangeEnd); - } - - /* Creates a new pointer for |aPtr|, restricted to this pointer's range. */ - RangedPtr create(T* aPtr) const - { -#ifdef DEBUG - return RangedPtr(aPtr, mRangeStart, mRangeEnd); -#else - return RangedPtr(aPtr, nullptr, size_t(0)); -#endif - } - - uintptr_t asUintptr() const { return reinterpret_cast(mPtr); } - -public: - RangedPtr(T* aPtr, T* aStart, T* aEnd) - : mPtr(aPtr) -#ifdef DEBUG - , mRangeStart(aStart), mRangeEnd(aEnd) -#endif - { - MOZ_ASSERT(mRangeStart <= mRangeEnd); - checkSanity(); - } - RangedPtr(T* aPtr, T* aStart, size_t aLength) - : mPtr(aPtr) -#ifdef DEBUG - , mRangeStart(aStart), mRangeEnd(aStart + aLength) -#endif - { - MOZ_ASSERT(aLength <= size_t(-1) / sizeof(T)); - MOZ_ASSERT(reinterpret_cast(mRangeStart) + aLength * sizeof(T) >= - reinterpret_cast(mRangeStart)); - checkSanity(); - } - - /* Equivalent to RangedPtr(aPtr, aPtr, aLength). */ - RangedPtr(T* aPtr, size_t aLength) - : mPtr(aPtr) -#ifdef DEBUG - , mRangeStart(aPtr), mRangeEnd(aPtr + aLength) -#endif - { - MOZ_ASSERT(aLength <= size_t(-1) / sizeof(T)); - MOZ_ASSERT(reinterpret_cast(mRangeStart) + aLength * sizeof(T) >= - reinterpret_cast(mRangeStart)); - checkSanity(); - } - - /* Equivalent to RangedPtr(aArr, aArr, N). */ - template - explicit RangedPtr(T (&aArr)[N]) - : mPtr(aArr) -#ifdef DEBUG - , mRangeStart(aArr), mRangeEnd(aArr + N) -#endif - { - checkSanity(); - } - - T* get() const { return mPtr; } - - explicit operator bool() const { return mPtr != nullptr; } - - void checkIdenticalRange(const RangedPtr& aOther) const - { - MOZ_ASSERT(mRangeStart == aOther.mRangeStart); - MOZ_ASSERT(mRangeEnd == aOther.mRangeEnd); - } - - /* - * You can only assign one RangedPtr into another if the two pointers have - * the same valid range: - * - * char arr1[] = "hi"; - * char arr2[] = "bye"; - * RangedPtr p1(arr1, 2); - * p1 = RangedPtr(arr1 + 1, arr1, arr1 + 2); // works - * p1 = RangedPtr(arr2, 3); // asserts - */ - RangedPtr& operator=(const RangedPtr& aOther) - { - checkIdenticalRange(aOther); - mPtr = aOther.mPtr; - checkSanity(); - return *this; - } - - RangedPtr operator+(size_t aInc) const - { - MOZ_ASSERT(aInc <= size_t(-1) / sizeof(T)); - MOZ_ASSERT(asUintptr() + aInc * sizeof(T) >= asUintptr()); - return create(mPtr + aInc); - } - - RangedPtr operator-(size_t aDec) const - { - MOZ_ASSERT(aDec <= size_t(-1) / sizeof(T)); - MOZ_ASSERT(asUintptr() - aDec * sizeof(T) <= asUintptr()); - return create(mPtr - aDec); - } - - /* - * You can assign a raw pointer into a RangedPtr if the raw pointer is - * within the range specified at creation. - */ - template - RangedPtr& operator=(U* aPtr) - { - *this = create(aPtr); - return *this; - } - - template - RangedPtr& operator=(const RangedPtr& aPtr) - { - MOZ_ASSERT(mRangeStart <= aPtr.mPtr); - MOZ_ASSERT(aPtr.mPtr <= mRangeEnd); - mPtr = aPtr.mPtr; - checkSanity(); - return *this; - } - - RangedPtr& operator++() - { - return (*this += 1); - } - - RangedPtr operator++(int) - { - RangedPtr rcp = *this; - ++*this; - return rcp; - } - - RangedPtr& operator--() - { - return (*this -= 1); - } - - RangedPtr operator--(int) - { - RangedPtr rcp = *this; - --*this; - return rcp; - } - - RangedPtr& operator+=(size_t aInc) - { - *this = *this + aInc; - return *this; - } - - RangedPtr& operator-=(size_t aDec) - { - *this = *this - aDec; - return *this; - } - - T& operator[](int aIndex) const - { - MOZ_ASSERT(size_t(aIndex > 0 ? aIndex : -aIndex) <= size_t(-1) / sizeof(T)); - return *create(mPtr + aIndex); - } - - T& operator*() const - { - MOZ_ASSERT(mPtr >= mRangeStart); - MOZ_ASSERT(mPtr < mRangeEnd); - return *mPtr; - } - - T* operator->() const - { - MOZ_ASSERT(mPtr >= mRangeStart); - MOZ_ASSERT(mPtr < mRangeEnd); - return mPtr; - } - - template - bool operator==(const RangedPtr& aOther) const - { - return mPtr == aOther.mPtr; - } - template - bool operator!=(const RangedPtr& aOther) const - { - return !(*this == aOther); - } - - template - bool operator==(const U* u) const - { - return mPtr == u; - } - template - bool operator!=(const U* u) const - { - return !(*this == u); - } - - template - bool operator<(const RangedPtr& aOther) const - { - return mPtr < aOther.mPtr; - } - template - bool operator<=(const RangedPtr& aOther) const - { - return mPtr <= aOther.mPtr; - } - - template - bool operator>(const RangedPtr& aOther) const - { - return mPtr > aOther.mPtr; - } - template - bool operator>=(const RangedPtr& aOther) const - { - return mPtr >= aOther.mPtr; - } - - size_t operator-(const RangedPtr& aOther) const - { - MOZ_ASSERT(mPtr >= aOther.mPtr); - return PointerRangeSize(aOther.mPtr, mPtr); - } - -private: - RangedPtr() = delete; - T* operator&() = delete; -}; - -} /* namespace mozilla */ - -#endif /* mozilla_RangedPtr_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/ReentrancyGuard.h b/android/arm64-v8a/include/spidermonkey/mozilla/ReentrancyGuard.h deleted file mode 100644 index 9963974e..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/ReentrancyGuard.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Small helper class for asserting uses of a class are non-reentrant. */ - -#ifndef mozilla_ReentrancyGuard_h -#define mozilla_ReentrancyGuard_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/GuardObjects.h" - -namespace mozilla { - -/* Useful for implementing containers that assert non-reentrancy */ -class MOZ_RAII ReentrancyGuard -{ - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -#ifdef DEBUG - bool& mEntered; -#endif - -public: - template -#ifdef DEBUG - explicit ReentrancyGuard(T& aObj - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mEntered(aObj.mEntered) -#else - explicit ReentrancyGuard(T& - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) -#endif - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; -#ifdef DEBUG - MOZ_ASSERT(!mEntered); - mEntered = true; -#endif - } - ~ReentrancyGuard() - { -#ifdef DEBUG - mEntered = false; -#endif - } - -private: - ReentrancyGuard(const ReentrancyGuard&) = delete; - void operator=(const ReentrancyGuard&) = delete; -}; - -} // namespace mozilla - -#endif /* mozilla_ReentrancyGuard_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/RefCountType.h b/android/arm64-v8a/include/spidermonkey/mozilla/RefCountType.h deleted file mode 100644 index e95a22a0..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/RefCountType.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_RefCountType_h -#define mozilla_RefCountType_h - -#include - -/** - * MozRefCountType is Mozilla's reference count type. - * - * We use the same type to represent the refcount of RefCounted objects - * as well, in order to be able to use the leak detection facilities - * that are implemented by XPCOM. - * - * Note that this type is not in the mozilla namespace so that it is - * usable for both C and C++ code. - */ -typedef uintptr_t MozRefCountType; - -/* - * This is the return type for AddRef() and Release() in nsISupports. - * IUnknown of COM returns an unsigned long from equivalent functions. - * - * The following ifdef exists to maintain binary compatibility with - * IUnknown, the base interface in Microsoft COM. - */ -#ifdef XP_WIN -typedef unsigned long MozExternalRefCountType; -#else -typedef uint32_t MozExternalRefCountType; -#endif - -#endif diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/RefCounted.h b/android/arm64-v8a/include/spidermonkey/mozilla/RefCounted.h deleted file mode 100644 index ae05f1e0..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/RefCounted.h +++ /dev/null @@ -1,210 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* CRTP refcounting templates. Do not use unless you are an Expert. */ - -#ifndef mozilla_RefCounted_h -#define mozilla_RefCounted_h - -#include "mozilla/AlreadyAddRefed.h" -#include "mozilla/Assertions.h" -#include "mozilla/Atomics.h" -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" -#include "mozilla/RefCountType.h" -#include "mozilla/TypeTraits.h" - -#if defined(MOZILLA_INTERNAL_API) -#include "nsXPCOM.h" -#endif - -#if defined(MOZILLA_INTERNAL_API) && \ - (defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING)) -#define MOZ_REFCOUNTED_LEAK_CHECKING -#endif - -namespace mozilla { - -/** - * RefCounted is a sort of a "mixin" for a class T. RefCounted - * manages, well, refcounting for T, and because RefCounted is - * parameterized on T, RefCounted can call T's destructor directly. - * This means T doesn't need to have a virtual dtor and so doesn't - * need a vtable. - * - * RefCounted is created with refcount == 0. Newly-allocated - * RefCounted must immediately be assigned to a RefPtr to make the - * refcount > 0. It's an error to allocate and free a bare - * RefCounted, i.e. outside of the RefPtr machinery. Attempts to - * do so will abort DEBUG builds. - * - * Live RefCounted have refcount > 0. The lifetime (refcounts) of - * live RefCounted are controlled by RefPtr and - * RefPtr. Upon a transition from refcounted==1 - * to 0, the RefCounted "dies" and is destroyed. The "destroyed" - * state is represented in DEBUG builds by refcount==0xffffdead. This - * state distinguishes use-before-ref (refcount==0) from - * use-after-destroy (refcount==0xffffdead). - * - * Note that when deriving from RefCounted or AtomicRefCounted, you - * should add MOZ_DECLARE_REFCOUNTED_TYPENAME(ClassName) to the public - * section of your class, where ClassName is the name of your class. - */ -namespace detail { -const MozRefCountType DEAD = 0xffffdead; - -// When building code that gets compiled into Gecko, try to use the -// trace-refcount leak logging facilities. -#ifdef MOZ_REFCOUNTED_LEAK_CHECKING -class RefCountLogger -{ -public: - static void logAddRef(const void* aPointer, MozRefCountType aRefCount, - const char* aTypeName, uint32_t aInstanceSize) - { - MOZ_ASSERT(aRefCount != DEAD); - NS_LogAddRef(const_cast(aPointer), aRefCount, aTypeName, - aInstanceSize); - } - - static void logRelease(const void* aPointer, MozRefCountType aRefCount, - const char* aTypeName) - { - MOZ_ASSERT(aRefCount != DEAD); - NS_LogRelease(const_cast(aPointer), aRefCount, aTypeName); - } -}; -#endif - -// This is used WeakPtr.h as well as this file. -enum RefCountAtomicity -{ - AtomicRefCount, - NonAtomicRefCount -}; - -template -class RefCounted -{ -protected: - RefCounted() : mRefCnt(0) {} - ~RefCounted() { MOZ_ASSERT(mRefCnt == detail::DEAD); } - -public: - // Compatibility with nsRefPtr. - void AddRef() const - { - // Note: this method must be thread safe for AtomicRefCounted. - MOZ_ASSERT(int32_t(mRefCnt) >= 0); -#ifndef MOZ_REFCOUNTED_LEAK_CHECKING - ++mRefCnt; -#else - const char* type = static_cast(this)->typeName(); - uint32_t size = static_cast(this)->typeSize(); - const void* ptr = static_cast(this); - MozRefCountType cnt = ++mRefCnt; - detail::RefCountLogger::logAddRef(ptr, cnt, type, size); -#endif - } - - void Release() const - { - // Note: this method must be thread safe for AtomicRefCounted. - MOZ_ASSERT(int32_t(mRefCnt) > 0); -#ifndef MOZ_REFCOUNTED_LEAK_CHECKING - MozRefCountType cnt = --mRefCnt; -#else - const char* type = static_cast(this)->typeName(); - const void* ptr = static_cast(this); - MozRefCountType cnt = --mRefCnt; - // Note: it's not safe to touch |this| after decrementing the refcount, - // except for below. - detail::RefCountLogger::logRelease(ptr, cnt, type); -#endif - if (0 == cnt) { - // Because we have atomically decremented the refcount above, only - // one thread can get a 0 count here, so as long as we can assume that - // everything else in the system is accessing this object through - // RefPtrs, it's safe to access |this| here. -#ifdef DEBUG - mRefCnt = detail::DEAD; -#endif - delete static_cast(this); - } - } - - // Compatibility with wtf::RefPtr. - void ref() { AddRef(); } - void deref() { Release(); } - MozRefCountType refCount() const { return mRefCnt; } - bool hasOneRef() const - { - MOZ_ASSERT(mRefCnt > 0); - return mRefCnt == 1; - } - -private: - mutable typename Conditional, - MozRefCountType>::Type mRefCnt; -}; - -#ifdef MOZ_REFCOUNTED_LEAK_CHECKING -// Passing override for the optional argument marks the typeName and -// typeSize functions defined by this macro as overrides. -#define MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(T, ...) \ - virtual const char* typeName() const __VA_ARGS__ { return #T; } \ - virtual size_t typeSize() const __VA_ARGS__ { return sizeof(*this); } -#else -#define MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(T, ...) -#endif - -// Note that this macro is expanded unconditionally because it declares only -// two small inline functions which will hopefully get eliminated by the linker -// in non-leak-checking builds. -#define MOZ_DECLARE_REFCOUNTED_TYPENAME(T) \ - const char* typeName() const { return #T; } \ - size_t typeSize() const { return sizeof(*this); } - -} // namespace detail - -template -class RefCounted : public detail::RefCounted -{ -public: - ~RefCounted() - { - static_assert(IsBaseOf::value, - "T must derive from RefCounted"); - } -}; - -namespace external { - -/** - * AtomicRefCounted is like RefCounted, with an atomically updated - * reference counter. - * - * NOTE: Please do not use this class, use NS_INLINE_DECL_THREADSAFE_REFCOUNTING - * instead. - */ -template -class AtomicRefCounted : - public mozilla::detail::RefCounted -{ -public: - ~AtomicRefCounted() - { - static_assert(IsBaseOf::value, - "T must derive from AtomicRefCounted"); - } -}; - -} // namespace external - -} // namespace mozilla - -#endif // mozilla_RefCounted_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/RefPtr.h b/android/arm64-v8a/include/spidermonkey/mozilla/RefPtr.h deleted file mode 100644 index bfa8f6e0..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/RefPtr.h +++ /dev/null @@ -1,656 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_RefPtr_h -#define mozilla_RefPtr_h - -#include "mozilla/AlreadyAddRefed.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -/*****************************************************************************/ - -// template class RefPtrGetterAddRefs; - -class nsCOMPtr_helper; - -namespace mozilla { -template class OwningNonNull; -template class StaticRefPtr; - -// Traditionally, RefPtr supports automatic refcounting of any pointer type -// with AddRef() and Release() methods that follow the traditional semantics. -// -// This traits class can be specialized to operate on other pointer types. For -// example, we specialize this trait for opaque FFI types that represent -// refcounted objects in Rust. -// -// Given the use of ConstRemovingRefPtrTraits below, U should not be a const- -// qualified type. -template -struct RefPtrTraits -{ - static void AddRef(U* aPtr) { - aPtr->AddRef(); - } - static void Release(U* aPtr) { - aPtr->Release(); - } -}; - -} // namespace mozilla - -template -class RefPtr -{ -private: - void - assign_with_AddRef(T* aRawPtr) - { - if (aRawPtr) { - ConstRemovingRefPtrTraits::AddRef(aRawPtr); - } - assign_assuming_AddRef(aRawPtr); - } - - void - assign_assuming_AddRef(T* aNewPtr) - { - T* oldPtr = mRawPtr; - mRawPtr = aNewPtr; - if (oldPtr) { - ConstRemovingRefPtrTraits::Release(oldPtr); - } - } - -private: - T* MOZ_OWNING_REF mRawPtr; - -public: - typedef T element_type; - - ~RefPtr() - { - if (mRawPtr) { - ConstRemovingRefPtrTraits::Release(mRawPtr); - } - } - - // Constructors - - RefPtr() - : mRawPtr(nullptr) - // default constructor - { - } - - RefPtr(const RefPtr& aSmartPtr) - : mRawPtr(aSmartPtr.mRawPtr) - // copy-constructor - { - if (mRawPtr) { - ConstRemovingRefPtrTraits::AddRef(mRawPtr); - } - } - - RefPtr(RefPtr&& aRefPtr) - : mRawPtr(aRefPtr.mRawPtr) - { - aRefPtr.mRawPtr = nullptr; - } - - // construct from a raw pointer (of the right type) - - MOZ_IMPLICIT RefPtr(T* aRawPtr) - : mRawPtr(aRawPtr) - { - if (mRawPtr) { - ConstRemovingRefPtrTraits::AddRef(mRawPtr); - } - } - - MOZ_IMPLICIT RefPtr(decltype(nullptr)) - : mRawPtr(nullptr) - { - } - - template - MOZ_IMPLICIT RefPtr(already_AddRefed& aSmartPtr) - : mRawPtr(aSmartPtr.take()) - // construct from |already_AddRefed| - { - } - - template - MOZ_IMPLICIT RefPtr(already_AddRefed&& aSmartPtr) - : mRawPtr(aSmartPtr.take()) - // construct from |otherRefPtr.forget()| - { - } - - template - MOZ_IMPLICIT RefPtr(const RefPtr& aSmartPtr) - : mRawPtr(aSmartPtr.get()) - // copy-construct from a smart pointer with a related pointer type - { - if (mRawPtr) { - ConstRemovingRefPtrTraits::AddRef(mRawPtr); - } - } - - template - MOZ_IMPLICIT RefPtr(RefPtr&& aSmartPtr) - : mRawPtr(aSmartPtr.forget().take()) - // construct from |Move(RefPtr)|. - { - } - - MOZ_IMPLICIT RefPtr(const nsCOMPtr_helper& aHelper); - - // Defined in OwningNonNull.h - template - MOZ_IMPLICIT RefPtr(const mozilla::OwningNonNull& aOther); - - // Defined in StaticPtr.h - template - MOZ_IMPLICIT RefPtr(const mozilla::StaticRefPtr& aOther); - - // Assignment operators - - RefPtr& - operator=(decltype(nullptr)) - { - assign_assuming_AddRef(nullptr); - return *this; - } - - RefPtr& - operator=(const RefPtr& aRhs) - // copy assignment operator - { - assign_with_AddRef(aRhs.mRawPtr); - return *this; - } - - template - RefPtr& - operator=(const RefPtr& aRhs) - // assign from an RefPtr of a related pointer type - { - assign_with_AddRef(aRhs.get()); - return *this; - } - - RefPtr& - operator=(T* aRhs) - // assign from a raw pointer (of the right type) - { - assign_with_AddRef(aRhs); - return *this; - } - - template - RefPtr& - operator=(already_AddRefed& aRhs) - // assign from |already_AddRefed| - { - assign_assuming_AddRef(aRhs.take()); - return *this; - } - - template - RefPtr& - operator=(already_AddRefed && aRhs) - // assign from |otherRefPtr.forget()| - { - assign_assuming_AddRef(aRhs.take()); - return *this; - } - - RefPtr& operator=(const nsCOMPtr_helper& aHelper); - - RefPtr& - operator=(RefPtr && aRefPtr) - { - assign_assuming_AddRef(aRefPtr.mRawPtr); - aRefPtr.mRawPtr = nullptr; - return *this; - } - - // Defined in OwningNonNull.h - template - RefPtr& - operator=(const mozilla::OwningNonNull& aOther); - - // Defined in StaticPtr.h - template - RefPtr& - operator=(const mozilla::StaticRefPtr& aOther); - - // Other pointer operators - - void - swap(RefPtr& aRhs) - // ...exchange ownership with |aRhs|; can save a pair of refcount operations - { - T* temp = aRhs.mRawPtr; - aRhs.mRawPtr = mRawPtr; - mRawPtr = temp; - } - - void - swap(T*& aRhs) - // ...exchange ownership with |aRhs|; can save a pair of refcount operations - { - T* temp = aRhs; - aRhs = mRawPtr; - mRawPtr = temp; - } - - already_AddRefed - forget() - // return the value of mRawPtr and null out mRawPtr. Useful for - // already_AddRefed return values. - { - T* temp = nullptr; - swap(temp); - return already_AddRefed(temp); - } - - template - void - forget(I** aRhs) - // Set the target of aRhs to the value of mRawPtr and null out mRawPtr. - // Useful to avoid unnecessary AddRef/Release pairs with "out" - // parameters where aRhs bay be a T** or an I** where I is a base class - // of T. - { - MOZ_ASSERT(aRhs, "Null pointer passed to forget!"); - *aRhs = mRawPtr; - mRawPtr = nullptr; - } - - T* - get() const - /* - Prefer the implicit conversion provided automatically by |operator T*() const|. - Use |get()| to resolve ambiguity or to get a castable pointer. - */ - { - return const_cast(mRawPtr); - } - - operator T*() const -#ifdef MOZ_HAVE_REF_QUALIFIERS - & -#endif - /* - ...makes an |RefPtr| act like its underlying raw pointer type whenever it - is used in a context where a raw pointer is expected. It is this operator - that makes an |RefPtr| substitutable for a raw pointer. - - Prefer the implicit use of this operator to calling |get()|, except where - necessary to resolve ambiguity. - */ - { - return get(); - } - -#ifdef MOZ_HAVE_REF_QUALIFIERS - // Don't allow implicit conversion of temporary RefPtr to raw pointer, - // because the refcount might be one and the pointer will immediately become - // invalid. - operator T*() const && = delete; - - // These are needed to avoid the deleted operator above. XXX Why is operator! - // needed separately? Shouldn't the compiler prefer using the non-deleted - // operator bool instead of the deleted operator T*? - explicit operator bool() const { return !!mRawPtr; } - bool operator!() const { return !mRawPtr; } -#endif - - T* - operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN - { - MOZ_ASSERT(mRawPtr != nullptr, - "You can't dereference a NULL RefPtr with operator->()."); - return get(); - } - - template - class Proxy - { - typedef R (T::*member_function)(Args...); - T* mRawPtr; - member_function mFunction; - public: - Proxy(T* aRawPtr, member_function aFunction) - : mRawPtr(aRawPtr), - mFunction(aFunction) - { - } - template - R operator()(ActualArgs&&... aArgs) - { - return ((*mRawPtr).*mFunction)(mozilla::Forward(aArgs)...); - } - }; - - template - Proxy operator->*(R (T::*aFptr)(Args...)) const - { - MOZ_ASSERT(mRawPtr != nullptr, - "You can't dereference a NULL RefPtr with operator->*()."); - return Proxy(get(), aFptr); - } - - RefPtr* - get_address() - // This is not intended to be used by clients. See |address_of| - // below. - { - return this; - } - - const RefPtr* - get_address() const - // This is not intended to be used by clients. See |address_of| - // below. - { - return this; - } - -public: - T& - operator*() const - { - MOZ_ASSERT(mRawPtr != nullptr, - "You can't dereference a NULL RefPtr with operator*()."); - return *get(); - } - - T** - StartAssignment() - { - assign_assuming_AddRef(nullptr); - return reinterpret_cast(&mRawPtr); - } -private: - // This helper class makes |RefPtr| possible by casting away - // the constness from the pointer when calling AddRef() and Release(). - // - // This is necessary because AddRef() and Release() implementations can't - // generally expected to be const themselves (without heavy use of |mutable| - // and |const_cast| in their own implementations). - // - // This should be sound because while |RefPtr| provides a - // const view of an object, the object itself should not be const (it - // would have to be allocated as |new const T| or similar to be const). - template - struct ConstRemovingRefPtrTraits - { - static void AddRef(U* aPtr) { - mozilla::RefPtrTraits::AddRef(aPtr); - } - static void Release(U* aPtr) { - mozilla::RefPtrTraits::Release(aPtr); - } - }; - template - struct ConstRemovingRefPtrTraits - { - static void AddRef(const U* aPtr) { - mozilla::RefPtrTraits::AddRef(const_cast(aPtr)); - } - static void Release(const U* aPtr) { - mozilla::RefPtrTraits::Release(const_cast(aPtr)); - } - }; -}; - -class nsCycleCollectionTraversalCallback; -template -void -CycleCollectionNoteChild(nsCycleCollectionTraversalCallback& aCallback, - T* aChild, const char* aName, uint32_t aFlags); - -template -inline void -ImplCycleCollectionUnlink(RefPtr& aField) -{ - aField = nullptr; -} - -template -inline void -ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, - RefPtr& aField, - const char* aName, - uint32_t aFlags = 0) -{ - CycleCollectionNoteChild(aCallback, aField.get(), aName, aFlags); -} - -template -inline RefPtr* -address_of(RefPtr& aPtr) -{ - return aPtr.get_address(); -} - -template -inline const RefPtr* -address_of(const RefPtr& aPtr) -{ - return aPtr.get_address(); -} - -template -class RefPtrGetterAddRefs -/* - ... - - This class is designed to be used for anonymous temporary objects in the - argument list of calls that return COM interface pointers, e.g., - - RefPtr fooP; - ...->GetAddRefedPointer(getter_AddRefs(fooP)) - - DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_AddRefs()| instead. - - When initialized with a |RefPtr|, as in the example above, it returns - a |void**|, a |T**|, or an |nsISupports**| as needed, that the - outer call (|GetAddRefedPointer| in this case) can fill in. - - This type should be a nested class inside |RefPtr|. -*/ -{ -public: - explicit - RefPtrGetterAddRefs(RefPtr& aSmartPtr) - : mTargetSmartPtr(aSmartPtr) - { - // nothing else to do - } - - operator void**() - { - return reinterpret_cast(mTargetSmartPtr.StartAssignment()); - } - - operator T**() - { - return mTargetSmartPtr.StartAssignment(); - } - - T*& - operator*() - { - return *(mTargetSmartPtr.StartAssignment()); - } - -private: - RefPtr& mTargetSmartPtr; -}; - -template -inline RefPtrGetterAddRefs -getter_AddRefs(RefPtr& aSmartPtr) -/* - Used around a |RefPtr| when - ...makes the class |RefPtrGetterAddRefs| invisible. -*/ -{ - return RefPtrGetterAddRefs(aSmartPtr); -} - - -// Comparing two |RefPtr|s - -template -inline bool -operator==(const RefPtr& aLhs, const RefPtr& aRhs) -{ - return static_cast(aLhs.get()) == static_cast(aRhs.get()); -} - - -template -inline bool -operator!=(const RefPtr& aLhs, const RefPtr& aRhs) -{ - return static_cast(aLhs.get()) != static_cast(aRhs.get()); -} - - -// Comparing an |RefPtr| to a raw pointer - -template -inline bool -operator==(const RefPtr& aLhs, const U* aRhs) -{ - return static_cast(aLhs.get()) == static_cast(aRhs); -} - -template -inline bool -operator==(const U* aLhs, const RefPtr& aRhs) -{ - return static_cast(aLhs) == static_cast(aRhs.get()); -} - -template -inline bool -operator!=(const RefPtr& aLhs, const U* aRhs) -{ - return static_cast(aLhs.get()) != static_cast(aRhs); -} - -template -inline bool -operator!=(const U* aLhs, const RefPtr& aRhs) -{ - return static_cast(aLhs) != static_cast(aRhs.get()); -} - -template -inline bool -operator==(const RefPtr& aLhs, U* aRhs) -{ - return static_cast(aLhs.get()) == const_cast(aRhs); -} - -template -inline bool -operator==(U* aLhs, const RefPtr& aRhs) -{ - return const_cast(aLhs) == static_cast(aRhs.get()); -} - -template -inline bool -operator!=(const RefPtr& aLhs, U* aRhs) -{ - return static_cast(aLhs.get()) != const_cast(aRhs); -} - -template -inline bool -operator!=(U* aLhs, const RefPtr& aRhs) -{ - return const_cast(aLhs) != static_cast(aRhs.get()); -} - -// Comparing an |RefPtr| to |nullptr| - -template -inline bool -operator==(const RefPtr& aLhs, decltype(nullptr)) -{ - return aLhs.get() == nullptr; -} - -template -inline bool -operator==(decltype(nullptr), const RefPtr& aRhs) -{ - return nullptr == aRhs.get(); -} - -template -inline bool -operator!=(const RefPtr& aLhs, decltype(nullptr)) -{ - return aLhs.get() != nullptr; -} - -template -inline bool -operator!=(decltype(nullptr), const RefPtr& aRhs) -{ - return nullptr != aRhs.get(); -} - -/*****************************************************************************/ - -template -inline already_AddRefed -do_AddRef(T* aObj) -{ - RefPtr ref(aObj); - return ref.forget(); -} - -template -inline already_AddRefed -do_AddRef(const RefPtr& aObj) -{ - RefPtr ref(aObj); - return ref.forget(); -} - -namespace mozilla { - -/** - * Helper function to be able to conveniently write things like: - * - * already_AddRefed - * f(...) - * { - * return MakeAndAddRef(...); - * } - */ -template -already_AddRefed -MakeAndAddRef(Args&&... aArgs) -{ - RefPtr p(new T(Forward(aArgs)...)); - return p.forget(); -} - -} // namespace mozilla - -#endif /* mozilla_RefPtr_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/ReverseIterator.h b/android/arm64-v8a/include/spidermonkey/mozilla/ReverseIterator.h deleted file mode 100644 index 49c2e279..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/ReverseIterator.h +++ /dev/null @@ -1,168 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* An iterator that acts like another iterator, but iterating in - * the negative direction. (Note that not all iterators can iterate - * in the negative direction.) */ - -#ifndef mozilla_ReverseIterator_h -#define mozilla_ReverseIterator_h - -#include "mozilla/Attributes.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -template -class ReverseIterator -{ -public: - template - explicit ReverseIterator(Iterator aIter) - : mCurrent(aIter) { } - - template - MOZ_IMPLICIT ReverseIterator(const ReverseIterator& aOther) - : mCurrent(aOther.mCurrent) { } - - decltype(*DeclVal()) operator*() const - { - IteratorT tmp = mCurrent; - return *--tmp; - } - - /* Increments and decrements operators */ - - ReverseIterator& operator++() { --mCurrent; return *this; } - ReverseIterator& operator--() { ++mCurrent; return *this; } - ReverseIterator operator++(int) { auto ret = *this; mCurrent--; return ret; } - ReverseIterator operator--(int) { auto ret = *this; mCurrent++; return ret; } - - /* Comparison operators */ - - template - friend bool operator==(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - template - friend bool operator!=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - template - friend bool operator<(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - template - friend bool operator<=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - template - friend bool operator>(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - template - friend bool operator>=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - -private: - IteratorT mCurrent; -}; - -template -bool -operator==(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent == aIter2.mCurrent; -} - -template -bool -operator!=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent != aIter2.mCurrent; -} - -template -bool -operator<(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent > aIter2.mCurrent; -} - -template -bool -operator<=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent >= aIter2.mCurrent; -} - -template -bool -operator>(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent < aIter2.mCurrent; -} - -template -bool -operator>=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent <= aIter2.mCurrent; -} - -namespace detail { - -template -class IteratorRange -{ -public: - typedef IteratorT iterator; - typedef IteratorT const_iterator; - typedef ReverseIterator reverse_iterator; - typedef ReverseIterator const_reverse_iterator; - - template - MOZ_IMPLICIT IteratorRange(Iterator1 aIterBegin, Iterator2 aIterEnd) - : mIterBegin(aIterBegin), mIterEnd(aIterEnd) { } - - template - MOZ_IMPLICIT IteratorRange(const IteratorRange& aOther) - : mIterBegin(aOther.mIterBegin), mIterEnd(aOther.mIterEnd) { } - - iterator begin() const { return mIterBegin; } - const_iterator cbegin() const { return begin(); } - iterator end() const { return mIterEnd; } - const_iterator cend() const { return end(); } - reverse_iterator rbegin() const { return reverse_iterator(mIterEnd); } - const_reverse_iterator crbegin() const { return rbegin(); } - reverse_iterator rend() const { return reverse_iterator(mIterBegin); } - const_reverse_iterator crend() const { return rend(); } - -private: - IteratorT mIterBegin; - IteratorT mIterEnd; -}; - -} // namespace detail - -template -detail::IteratorRange -Reversed(Range& aRange) -{ - return {aRange.rbegin(), aRange.rend()}; -} - -template -detail::IteratorRange -Reversed(const Range& aRange) -{ - return {aRange.rbegin(), aRange.rend()}; -} - -} // namespace mozilla - -#endif // mozilla_ReverseIterator_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/RollingMean.h b/android/arm64-v8a/include/spidermonkey/mozilla/RollingMean.h deleted file mode 100644 index 8cc3148e..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/RollingMean.h +++ /dev/null @@ -1,115 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A set abstraction for enumeration values. */ - -#ifndef mozilla_RollingMean_h_ -#define mozilla_RollingMean_h_ - -#include "mozilla/Assertions.h" -#include "mozilla/TypeTraits.h" -#include "mozilla/Vector.h" - -#include - -namespace mozilla { - -/** - * RollingMean calculates a rolling mean of the values it is given. It - * accumulates the total as values are added and removed. The second type - * argument S specifies the type of the total. This may need to be a bigger - * type in order to maintain that the sum of all values in the average doesn't - * exceed the maximum input value. - * - * WARNING: Float types are not supported due to rounding errors. - */ -template -class RollingMean -{ -private: - size_t mInsertIndex; - size_t mMaxValues; - Vector mValues; - S mTotal; - -public: - static_assert(!IsFloatingPoint::value, - "floating-point types are unsupported due to rounding " - "errors"); - - explicit RollingMean(size_t aMaxValues) - : mInsertIndex(0), - mMaxValues(aMaxValues), - mTotal(0) - { - MOZ_ASSERT(aMaxValues > 0); - } - - RollingMean& operator=(RollingMean&& aOther) - { - MOZ_ASSERT(this != &aOther, "self-assignment is forbidden"); - this->~RollingMean(); - new(this) RollingMean(aOther.mMaxValues); - mInsertIndex = aOther.mInsertIndex; - mTotal = aOther.mTotal; - mValues.swap(aOther.mValues); - return *this; - } - - /** - * Insert a value into the rolling mean. - */ - bool insert(T aValue) - { - MOZ_ASSERT(mValues.length() <= mMaxValues); - - if (mValues.length() == mMaxValues) { - mTotal = mTotal - mValues[mInsertIndex] + aValue; - mValues[mInsertIndex] = aValue; - } else { - if (!mValues.append(aValue)) { - return false; - } - mTotal = mTotal + aValue; - } - - mInsertIndex = (mInsertIndex + 1) % mMaxValues; - return true; - } - - /** - * Calculate the rolling mean. - */ - T mean() - { - MOZ_ASSERT(!empty()); - return T(mTotal / int64_t(mValues.length())); - } - - bool empty() - { - return mValues.empty(); - } - - /** - * Remove all values from the rolling mean. - */ - void clear() - { - mValues.clear(); - mInsertIndex = 0; - mTotal = T(0); - } - - size_t maxValues() - { - return mMaxValues; - } -}; - -} // namespace mozilla - -#endif // mozilla_RollingMean_h_ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/SHA1.h b/android/arm64-v8a/include/spidermonkey/mozilla/SHA1.h deleted file mode 100644 index ddccaa67..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/SHA1.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Simple class for computing SHA1. */ - -#ifndef mozilla_SHA1_h -#define mozilla_SHA1_h - -#include "mozilla/Types.h" - -#include -#include - -namespace mozilla { - -/** - * This class computes the SHA1 hash of a byte sequence, or of the concatenation - * of multiple sequences. For example, computing the SHA1 of two sequences of - * bytes could be done as follows: - * - * void SHA1(const uint8_t* buf1, uint32_t size1, - * const uint8_t* buf2, uint32_t size2, - * SHA1Sum::Hash& hash) - * { - * SHA1Sum s; - * s.update(buf1, size1); - * s.update(buf2, size2); - * s.finish(hash); - * } - * - * The finish method may only be called once and cannot be followed by calls - * to update. - */ -class SHA1Sum -{ - union - { - uint32_t mW[16]; /* input buffer */ - uint8_t mB[64]; - } mU; - uint64_t mSize; /* count of hashed bytes. */ - unsigned mH[22]; /* 5 state variables, 16 tmp values, 1 extra */ - bool mDone; - -public: - MFBT_API SHA1Sum(); - - static const size_t kHashSize = 20; - typedef uint8_t Hash[kHashSize]; - - /* Add len bytes of dataIn to the data sequence being hashed. */ - MFBT_API void update(const void* aData, uint32_t aLength); - - /* Compute the final hash of all data into hashOut. */ - MFBT_API void finish(SHA1Sum::Hash& aHashOut); -}; - -} /* namespace mozilla */ - -#endif /* mozilla_SHA1_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Saturate.h b/android/arm64-v8a/include/spidermonkey/mozilla/Saturate.h deleted file mode 100644 index b79364d2..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Saturate.h +++ /dev/null @@ -1,288 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Provides saturation arithmetics for scalar types. */ - -#ifndef mozilla_Saturate_h -#define mozilla_Saturate_h - -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -#include - -namespace mozilla { -namespace detail { - -/** - * |SaturateOp| wraps scalar values for saturation arithmetics. Usage: - * - * uint32_t value = 1; - * - * ++SaturateOp(value); // value is 2 - * --SaturateOp(value); // value is 1 - * --SaturateOp(value); // value is 0 - * --SaturateOp(value); // value is still 0 - * - * Please add new operators when required. - * - * |SaturateOp| will saturate at the minimum and maximum values of - * type T. If you need other bounds, implement a clamped-type class and - * specialize the type traits accordingly. - */ -template -class SaturateOp -{ -public: - explicit SaturateOp(T& aValue) - : mValue(aValue) - { - // We should actually check for |std::is_scalar::value| to be - // true, but this type trait is not available everywhere. Relax - // this assertion if you want to use floating point values as well. - static_assert(IsIntegral::value, - "Integral type required in instantiation"); - } - - // Add and subtract operators - - T operator+(const T& aRhs) const - { - return T(mValue) += aRhs; - } - - T operator-(const T& aRhs) const - { - return T(mValue) -= aRhs; - } - - // Compound operators - - const T& operator+=(const T& aRhs) const - { - const T min = std::numeric_limits::min(); - const T max = std::numeric_limits::max(); - - if (aRhs > static_cast(0)) { - mValue = (max - aRhs) < mValue ? max : mValue + aRhs; - } else { - mValue = (min - aRhs) > mValue ? min : mValue + aRhs; - } - return mValue; - } - - const T& operator-=(const T& aRhs) const - { - const T min = std::numeric_limits::min(); - const T max = std::numeric_limits::max(); - - if (aRhs > static_cast(0)) { - mValue = (min + aRhs) > mValue ? min : mValue - aRhs; - } else { - mValue = (max + aRhs) < mValue ? max : mValue - aRhs; - } - return mValue; - } - - // Increment and decrement operators - - const T& operator++() const // prefix - { - return operator+=(static_cast(1)); - } - - T operator++(int) const // postfix - { - const T value(mValue); - operator++(); - return value; - } - - const T& operator--() const // prefix - { - return operator-=(static_cast(1)); - } - - T operator--(int) const // postfix - { - const T value(mValue); - operator--(); - return value; - } - -private: - SaturateOp(const SaturateOp&) = delete; - SaturateOp(SaturateOp&&) = delete; - SaturateOp& operator=(const SaturateOp&) = delete; - SaturateOp& operator=(SaturateOp&&) = delete; - - T& mValue; -}; - -/** - * |Saturate| is a value type for saturation arithmetics. It's - * build on top of |SaturateOp|. - */ -template -class Saturate -{ -public: - Saturate() = default; - MOZ_IMPLICIT Saturate(const Saturate&) = default; - - MOZ_IMPLICIT Saturate(Saturate&& aValue) - { - mValue = Move(aValue.mValue); - } - - explicit Saturate(const T& aValue) - : mValue(aValue) - { } - - const T& value() const - { - return mValue; - } - - // Compare operators - - bool operator==(const Saturate& aRhs) const - { - return mValue == aRhs.mValue; - } - - bool operator!=(const Saturate& aRhs) const - { - return !operator==(aRhs); - } - - bool operator==(const T& aRhs) const - { - return mValue == aRhs; - } - - bool operator!=(const T& aRhs) const - { - return !operator==(aRhs); - } - - // Assignment operators - - Saturate& operator=(const Saturate&) = default; - - Saturate& operator=(Saturate&& aRhs) - { - mValue = Move(aRhs.mValue); - return *this; - } - - // Add and subtract operators - - Saturate operator+(const Saturate& aRhs) const - { - Saturate lhs(mValue); - return lhs += aRhs.mValue; - } - - Saturate operator+(const T& aRhs) const - { - Saturate lhs(mValue); - return lhs += aRhs; - } - - Saturate operator-(const Saturate& aRhs) const - { - Saturate lhs(mValue); - return lhs -= aRhs.mValue; - } - - Saturate operator-(const T& aRhs) const - { - Saturate lhs(mValue); - return lhs -= aRhs; - } - - // Compound operators - - Saturate& operator+=(const Saturate& aRhs) - { - SaturateOp(mValue) += aRhs.mValue; - return *this; - } - - Saturate& operator+=(const T& aRhs) - { - SaturateOp(mValue) += aRhs; - return *this; - } - - Saturate& operator-=(const Saturate& aRhs) - { - SaturateOp(mValue) -= aRhs.mValue; - return *this; - } - - Saturate& operator-=(const T& aRhs) - { - SaturateOp(mValue) -= aRhs; - return *this; - } - - // Increment and decrement operators - - Saturate& operator++() // prefix - { - ++SaturateOp(mValue); - return *this; - } - - Saturate operator++(int) // postfix - { - return Saturate(SaturateOp(mValue)++); - } - - Saturate& operator--() // prefix - { - --SaturateOp(mValue); - return *this; - } - - Saturate operator--(int) // postfix - { - return Saturate(SaturateOp(mValue)--); - } - -private: - T mValue; -}; - -} // namespace detail - -typedef detail::Saturate SaturateInt8; -typedef detail::Saturate SaturateInt16; -typedef detail::Saturate SaturateInt32; -typedef detail::Saturate SaturateUint8; -typedef detail::Saturate SaturateUint16; -typedef detail::Saturate SaturateUint32; - -} // namespace mozilla - -template -bool -operator==(LhsT aLhs, const mozilla::detail::Saturate& aRhs) -{ - return aRhs.operator==(static_cast(aLhs)); -} - -template -bool -operator!=(LhsT aLhs, const mozilla::detail::Saturate& aRhs) -{ - return !(aLhs == aRhs); -} - -#endif // mozilla_Saturate_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/ScopeExit.h b/android/arm64-v8a/include/spidermonkey/mozilla/ScopeExit.h deleted file mode 100644 index 7aff82d8..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/ScopeExit.h +++ /dev/null @@ -1,135 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* RAII class for executing arbitrary actions at scope end. */ - -#ifndef mozilla_ScopeExit_h -#define mozilla_ScopeExit_h - -/* - * See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4189.pdf for a - * standards-track version of this. - * - * Error handling can be complex when various actions need to be performed that - * need to be undone if an error occurs midway. This can be handled with a - * collection of boolean state variables and gotos, which can get clunky and - * error-prone: - * - * { - * if (!a.setup()) - * goto fail; - * isASetup = true; - * - * if (!b.setup()) - * goto fail; - * isBSetup = true; - * - * ... - * return true; - * - * fail: - * if (isASetup) - * a.teardown(); - * if (isBSetup) - * b.teardown(); - * return false; - * } - * - * ScopeExit is a mechanism to simplify this pattern by keeping an RAII guard - * class that will perform the teardown on destruction, unless released. So the - * above would become: - * - * { - * if (!a.setup()) { - * return false; - * } - * auto guardA = MakeScopeExit([&] { - * a.teardown(); - * }); - * - * if (!b.setup()) { - * return false; - * } - * auto guardB = MakeScopeExit([&] { - * b.teardown(); - * }); - * - * ... - * guardA.release(); - * guardB.release(); - * return true; - * } - * - * This header provides: - * - * - |ScopeExit| - a container for a cleanup call, automically called at the - * end of the scope; - * - |MakeScopeExit| - a convenience function for constructing a |ScopeExit| - * with a given cleanup routine, commonly used with a lambda function. - * - * Note that the RAII classes defined in this header do _not_ perform any form - * of reference-counting or garbage-collection. These classes have exactly two - * behaviors: - * - * - if |release()| has not been called, the cleanup is always performed at - * the end of the scope; - * - if |release()| has been called, nothing will happen at the end of the - * scope. - */ - -#include "mozilla/GuardObjects.h" -#include "mozilla/Move.h" - -namespace mozilla { - -template -class MOZ_STACK_CLASS ScopeExit { - ExitFunction mExitFunction; - bool mExecuteOnDestruction; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - -public: - explicit ScopeExit(ExitFunction&& cleanup - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mExitFunction(cleanup) - , mExecuteOnDestruction(true) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - ScopeExit(ScopeExit&& rhs) - : mExitFunction(mozilla::Move(rhs.mExitFunction)) - , mExecuteOnDestruction(rhs.mExecuteOnDestruction) - { - rhs.release(); - } - - ~ScopeExit() { - if (mExecuteOnDestruction) { - mExitFunction(); - } - } - - void release() { - mExecuteOnDestruction = false; - } - -private: - explicit ScopeExit(const ScopeExit&) = delete; - ScopeExit& operator=(const ScopeExit&) = delete; - ScopeExit& operator=(ScopeExit&&) = delete; -}; - -template -ScopeExit -MakeScopeExit(ExitFunction&& exitFunction) -{ - return ScopeExit(mozilla::Move(exitFunction)); -} - -} /* namespace mozilla */ - -#endif /* mozilla_ScopeExit_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Scoped.h b/android/arm64-v8a/include/spidermonkey/mozilla/Scoped.h deleted file mode 100644 index c935434a..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Scoped.h +++ /dev/null @@ -1,255 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* DEPRECATED: Use UniquePtr.h instead. */ - -#ifndef mozilla_Scoped_h -#define mozilla_Scoped_h - -/* - * DEPRECATED: Use UniquePtr.h instead. - * - * Resource Acquisition Is Initialization is a programming idiom used - * to write robust code that is able to deallocate resources properly, - * even in presence of execution errors or exceptions that need to be - * propagated. The Scoped* classes defined via the |SCOPED_TEMPLATE| - * and |MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLTE| macros perform the - * deallocation of the resource they hold once program execution - * reaches the end of the scope for which they have been defined. - * These macros have been used to automatically close file - * descriptors/file handles when reaching the end of the scope, - * graphics contexts, etc. - * - * The general scenario for RAII classes created by the above macros - * is the following: - * - * ScopedClass foo(create_value()); - * // ... In this scope, |foo| is defined. Use |foo.get()| or |foo.rwget()| - * to access the value. - * // ... In case of |return| or |throw|, |foo| is deallocated automatically. - * // ... If |foo| needs to be returned or stored, use |foo.forget()| - * - * Note that the RAII classes defined in this header do _not_ perform any form - * of reference-counting or garbage-collection. These classes have exactly two - * behaviors: - * - * - if |forget()| has not been called, the resource is always deallocated at - * the end of the scope; - * - if |forget()| has been called, any control on the resource is unbound - * and the resource is not deallocated by the class. - */ - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/GuardObjects.h" -#include "mozilla/Move.h" - -namespace mozilla { - -/* - * Scoped is a helper to create RAII wrappers - * Type argument |Traits| is expected to have the following structure: - * - * struct Traits - * { - * // Define the type of the value stored in the wrapper - * typedef value_type type; - * // Returns the value corresponding to the uninitialized or freed state - * const static type empty(); - * // Release resources corresponding to the wrapped value - * // This function is responsible for not releasing an |empty| value - * const static void release(type); - * } - */ -template -class MOZ_NON_TEMPORARY_CLASS Scoped -{ -public: - typedef typename Traits::type Resource; - - explicit Scoped(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) - : mValue(Traits::empty()) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - explicit Scoped(const Resource& aValue - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mValue(aValue) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - /* Move constructor. */ - Scoped(Scoped&& aOther - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mValue(Move(aOther.mValue)) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - aOther.mValue = Traits::empty(); - } - - ~Scoped() { Traits::release(mValue); } - - // Constant getter - operator const Resource&() const { return mValue; } - const Resource& operator->() const { return mValue; } - const Resource& get() const { return mValue; } - // Non-constant getter. - Resource& rwget() { return mValue; } - - /* - * Forget the resource. - * - * Once |forget| has been called, the |Scoped| is neutralized, i.e. it will - * have no effect at destruction (unless it is reset to another resource by - * |operator=|). - * - * @return The original resource. - */ - Resource forget() - { - Resource tmp = mValue; - mValue = Traits::empty(); - return tmp; - } - - /* - * Perform immediate clean-up of this |Scoped|. - * - * If this |Scoped| is currently empty, this method has no effect. - */ - void dispose() - { - Traits::release(mValue); - mValue = Traits::empty(); - } - - bool operator==(const Resource& aOther) const { return mValue == aOther; } - - /* - * Replace the resource with another resource. - * - * Calling |operator=| has the side-effect of triggering clean-up. If you do - * not want to trigger clean-up, you should first invoke |forget|. - * - * @return this - */ - Scoped& operator=(const Resource& aOther) { return reset(aOther); } - - Scoped& reset(const Resource& aOther) - { - Traits::release(mValue); - mValue = aOther; - return *this; - } - - /* Move assignment operator. */ - Scoped& operator=(Scoped&& aRhs) - { - MOZ_ASSERT(&aRhs != this, "self-move-assignment not allowed"); - this->~Scoped(); - new(this) Scoped(Move(aRhs)); - return *this; - } - -private: - explicit Scoped(const Scoped& aValue) = delete; - Scoped& operator=(const Scoped& aValue) = delete; - -private: - Resource mValue; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -/* - * SCOPED_TEMPLATE defines a templated class derived from Scoped - * This allows to implement templates such as ScopedFreePtr. - * - * @param name The name of the class to define. - * @param Traits A struct implementing clean-up. See the implementations - * for more details. - */ -#define SCOPED_TEMPLATE(name, Traits) \ -template \ -struct MOZ_NON_TEMPORARY_CLASS name : public mozilla::Scoped > \ -{ \ - typedef mozilla::Scoped > Super; \ - typedef typename Super::Resource Resource; \ - name& operator=(Resource aRhs) \ - { \ - Super::operator=(aRhs); \ - return *this; \ - } \ - name& operator=(name&& aRhs) \ - { \ - Super::operator=(Move(aRhs)); \ - return *this; \ - } \ - explicit name(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) \ - : Super(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT) \ - {} \ - explicit name(Resource aRhs \ - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \ - : Super(aRhs \ - MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \ - {} \ - name(name&& aRhs \ - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \ - : Super(Move(aRhs) \ - MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \ - {} \ -private: \ - explicit name(name&) = delete; \ - name& operator=(name&) = delete; \ -}; - -/* - * MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE makes it easy to create scoped - * pointers for types with custom deleters; just overload - * TypeSpecificDelete(T*) in the same namespace as T to call the deleter for - * type T. - * - * @param name The name of the class to define. - * @param Type A struct implementing clean-up. See the implementations - * for more details. - * *param Deleter The function that is used to delete/destroy/free a - * non-null value of Type*. - * - * Example: - * - * MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRFileDesc, PRFileDesc, \ - * PR_Close) - * ... - * { - * ScopedPRFileDesc file(PR_OpenFile(...)); - * ... - * } // file is closed with PR_Close here - */ -#define MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(name, Type, Deleter) \ -template <> inline void TypeSpecificDelete(Type* aValue) { Deleter(aValue); } \ -typedef ::mozilla::TypeSpecificScopedPointer name; - -template void TypeSpecificDelete(T* aValue); - -template -struct TypeSpecificScopedPointerTraits -{ - typedef T* type; - static type empty() { return nullptr; } - static void release(type aValue) - { - if (aValue) { - TypeSpecificDelete(aValue); - } - } -}; - -SCOPED_TEMPLATE(TypeSpecificScopedPointer, TypeSpecificScopedPointerTraits) - -} /* namespace mozilla */ - -#endif /* mozilla_Scoped_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/SegmentedVector.h b/android/arm64-v8a/include/spidermonkey/mozilla/SegmentedVector.h deleted file mode 100644 index 1bf60e46..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/SegmentedVector.h +++ /dev/null @@ -1,339 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -// A simple segmented vector class. -// -// This class should be used in preference to mozilla::Vector or nsTArray when -// you are simply gathering items in order to later iterate over them. -// -// - In the case where you don't know the final size in advance, using -// SegmentedVector avoids the need to repeatedly allocate increasingly large -// buffers and copy the data into them. -// -// - In the case where you know the final size in advance and so can set the -// capacity appropriately, using SegmentedVector still avoids the need for -// large allocations (which can trigger OOMs). - -#ifndef mozilla_SegmentedVector_h -#define mozilla_SegmentedVector_h - -#include "mozilla/Alignment.h" -#include "mozilla/AllocPolicy.h" -#include "mozilla/Array.h" -#include "mozilla/LinkedList.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -#include // for placement new - -namespace mozilla { - -// |IdealSegmentSize| specifies how big each segment will be in bytes (or as -// close as is possible). Use the following guidelines to choose a size. -// -// - It should be a power-of-two, to avoid slop. -// -// - It should not be too small, so that segment allocations are infrequent, -// and so that per-segment bookkeeping overhead is low. Typically each -// segment should be able to hold hundreds of elements, at least. -// -// - It should not be too large, so that OOMs are unlikely when allocating -// segments, and so that not too much space is wasted when the final segment -// is not full. -// -// The ideal size depends on how the SegmentedVector is used and the size of -// |T|, but reasonable sizes include 1024, 4096 (the default), 8192, and 16384. -// -template -class SegmentedVector : private AllocPolicy -{ - template - struct SegmentImpl - : public mozilla::LinkedListElement> - { - SegmentImpl() : mLength(0) {} - - ~SegmentImpl() - { - for (uint32_t i = 0; i < mLength; i++) { - (*this)[i].~T(); - } - } - - uint32_t Length() const { return mLength; } - - T* Elems() { return reinterpret_cast(&mStorage.mBuf); } - - T& operator[](size_t aIndex) - { - MOZ_ASSERT(aIndex < mLength); - return Elems()[aIndex]; - } - - const T& operator[](size_t aIndex) const - { - MOZ_ASSERT(aIndex < mLength); - return Elems()[aIndex]; - } - - template - void Append(U&& aU) - { - MOZ_ASSERT(mLength < SegmentCapacity); - // Pre-increment mLength so that the bounds-check in operator[] passes. - mLength++; - T* elem = &(*this)[mLength - 1]; - new (elem) T(mozilla::Forward(aU)); - } - - void PopLast() - { - MOZ_ASSERT(mLength > 0); - (*this)[mLength - 1].~T(); - mLength--; - } - - uint32_t mLength; - - // The union ensures that the elements are appropriately aligned. - union Storage - { - char mBuf[sizeof(T) * SegmentCapacity]; - mozilla::AlignedElem mAlign; - } mStorage; - - static_assert(MOZ_ALIGNOF(T) == MOZ_ALIGNOF(Storage), - "SegmentedVector provides incorrect alignment"); - }; - - // See how many we elements we can fit in a segment of IdealSegmentSize. If - // IdealSegmentSize is too small, it'll be just one. The +1 is because - // kSingleElementSegmentSize already accounts for one element. - static const size_t kSingleElementSegmentSize = sizeof(SegmentImpl<1>); - static const size_t kSegmentCapacity = - kSingleElementSegmentSize <= IdealSegmentSize - ? (IdealSegmentSize - kSingleElementSegmentSize) / sizeof(T) + 1 - : 1; - - typedef SegmentImpl Segment; - -public: - // The |aIdealSegmentSize| is only for sanity checking. If it's specified, we - // check that the actual segment size is as close as possible to it. This - // serves as a sanity check for SegmentedVectorCapacity's capacity - // computation. - explicit SegmentedVector(size_t aIdealSegmentSize = 0) - { - // The difference between the actual segment size and the ideal segment - // size should be less than the size of a single element... unless the - // ideal size was too small, in which case the capacity should be one. - MOZ_ASSERT_IF( - aIdealSegmentSize != 0, - (sizeof(Segment) > aIdealSegmentSize && kSegmentCapacity == 1) || - aIdealSegmentSize - sizeof(Segment) < sizeof(T)); - } - - ~SegmentedVector() { Clear(); } - - bool IsEmpty() const { return !mSegments.getFirst(); } - - // Note that this is O(n) rather than O(1), but the constant factor is very - // small because it only has to do one addition per segment. - size_t Length() const - { - size_t n = 0; - for (auto segment = mSegments.getFirst(); - segment; - segment = segment->getNext()) { - n += segment->Length(); - } - return n; - } - - // Returns false if the allocation failed. (If you are using an infallible - // allocation policy, use InfallibleAppend() instead.) - template - MOZ_MUST_USE bool Append(U&& aU) - { - Segment* last = mSegments.getLast(); - if (!last || last->Length() == kSegmentCapacity) { - last = this->template pod_malloc(1); - if (!last) { - return false; - } - new (last) Segment(); - mSegments.insertBack(last); - } - last->Append(mozilla::Forward(aU)); - return true; - } - - // You should probably only use this instead of Append() if you are using an - // infallible allocation policy. It will crash if the allocation fails. - template - void InfallibleAppend(U&& aU) - { - bool ok = Append(mozilla::Forward(aU)); - MOZ_RELEASE_ASSERT(ok); - } - - void Clear() - { - Segment* segment; - while ((segment = mSegments.popFirst())) { - segment->~Segment(); - this->free_(segment); - } - } - - T& GetLast() - { - MOZ_ASSERT(!IsEmpty()); - Segment* last = mSegments.getLast(); - return (*last)[last->Length() - 1]; - } - - const T& GetLast() const - { - MOZ_ASSERT(!IsEmpty()); - Segment* last = mSegments.getLast(); - return (*last)[last->Length() - 1]; - } - - void PopLast() - { - MOZ_ASSERT(!IsEmpty()); - Segment* last = mSegments.getLast(); - last->PopLast(); - if (!last->Length()) { - mSegments.popLast(); - last->~Segment(); - this->free_(last); - } - } - - // Equivalent to calling |PopLast| |aNumElements| times, but potentially - // more efficient. - void PopLastN(uint32_t aNumElements) - { - MOZ_ASSERT(aNumElements <= Length()); - - Segment* last; - - // Pop full segments for as long as we can. Note that this loop - // cleanly handles the case when the initial last segment is not - // full and we are popping more elements than said segment contains. - do { - last = mSegments.getLast(); - - // The list is empty. We're all done. - if (!last) { - return; - } - - // Check to see if the list contains too many elements. Handle - // that in the epilogue. - uint32_t segmentLen = last->Length(); - if (segmentLen > aNumElements) { - break; - } - - // Destroying the segment destroys all elements contained therein. - mSegments.popLast(); - last->~Segment(); - this->free_(last); - - MOZ_ASSERT(aNumElements >= segmentLen); - aNumElements -= segmentLen; - if (aNumElements == 0) { - return; - } - } while (true); - - // Handle the case where the last segment contains more elements - // than we want to pop. - MOZ_ASSERT(last); - MOZ_ASSERT(last == mSegments.getLast()); - MOZ_ASSERT(aNumElements != 0); - MOZ_ASSERT(aNumElements < last->Length()); - for (uint32_t i = 0; i < aNumElements; ++i) { - last->PopLast(); - } - MOZ_ASSERT(last->Length() != 0); - } - - // Use this class to iterate over a SegmentedVector, like so: - // - // for (auto iter = v.Iter(); !iter.Done(); iter.Next()) { - // MyElem& elem = iter.Get(); - // f(elem); - // } - // - class IterImpl - { - friend class SegmentedVector; - - Segment* mSegment; - size_t mIndex; - - explicit IterImpl(SegmentedVector* aVector) - : mSegment(aVector->mSegments.getFirst()) - , mIndex(0) - {} - - public: - bool Done() const { return !mSegment; } - - T& Get() - { - MOZ_ASSERT(!Done()); - return (*mSegment)[mIndex]; - } - - const T& Get() const - { - MOZ_ASSERT(!Done()); - return (*mSegment)[mIndex]; - } - - void Next() - { - MOZ_ASSERT(!Done()); - mIndex++; - if (mIndex == mSegment->Length()) { - mSegment = mSegment->getNext(); - mIndex = 0; - } - } - }; - - IterImpl Iter() { return IterImpl(this); } - - // Measure the memory consumption of the vector excluding |this|. Note that - // it only measures the vector itself. If the vector elements contain - // pointers to other memory blocks, those blocks must be measured separately - // during a subsequent iteration over the vector. - size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const - { - return mSegments.sizeOfExcludingThis(aMallocSizeOf); - } - - // Like sizeOfExcludingThis(), but measures |this| as well. - size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const - { - return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); - } - -private: - mozilla::LinkedList mSegments; -}; - -} // namespace mozilla - -#endif /* mozilla_SegmentedVector_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/SizePrintfMacros.h b/android/arm64-v8a/include/spidermonkey/mozilla/SizePrintfMacros.h deleted file mode 100644 index ec55c62c..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/SizePrintfMacros.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implements (nonstandard) PRI{ouxX}SIZE format macros for size_t types. */ - -#ifndef mozilla_SizePrintfMacros_h_ -#define mozilla_SizePrintfMacros_h_ - -/* - * MSVC's libc does not support C99's %z format length modifier for size_t - * types. Instead, we use Microsoft's nonstandard %I modifier for size_t, which - * is unsigned __int32 on 32-bit platforms and unsigned __int64 on 64-bit - * platforms: - * - * http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx - */ - -#if defined(XP_WIN) -# define PRIoSIZE "Io" -# define PRIuSIZE "Iu" -# define PRIxSIZE "Ix" -# define PRIXSIZE "IX" -#else -# define PRIoSIZE "zo" -# define PRIuSIZE "zu" -# define PRIxSIZE "zx" -# define PRIXSIZE "zX" -#endif - -#endif /* mozilla_SizePrintfMacros_h_ */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/SplayTree.h b/android/arm64-v8a/include/spidermonkey/mozilla/SplayTree.h deleted file mode 100644 index 2b3b838b..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/SplayTree.h +++ /dev/null @@ -1,330 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/** - * A sorted tree with optimal access times, where recently-accessed elements - * are faster to access again. - */ - -#ifndef mozilla_SplayTree_h -#define mozilla_SplayTree_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -namespace mozilla { - -template -class SplayTree; - -template -class SplayTreeNode -{ -public: - template - friend class SplayTree; - - SplayTreeNode() - : mLeft(nullptr) - , mRight(nullptr) - , mParent(nullptr) - {} - -private: - T* mLeft; - T* mRight; - T* mParent; -}; - - -/** - * Class which represents a splay tree. - * Splay trees are balanced binary search trees for which search, insert and - * remove are all amortized O(log n), but where accessing a node makes it - * faster to access that node in the future. - * - * T indicates the type of tree elements, Comparator must have a static - * compare(const T&, const T&) method ordering the elements. The compare - * method must be free from side effects. - */ -template -class SplayTree -{ - T* mRoot; - -public: - constexpr SplayTree() - : mRoot(nullptr) - {} - - bool empty() const - { - return !mRoot; - } - - T* find(const T& aValue) - { - if (empty()) { - return nullptr; - } - - T* last = lookup(aValue); - splay(last); - return Comparator::compare(aValue, *last) == 0 ? last : nullptr; - } - - void insert(T* aValue) - { - MOZ_ASSERT(!find(*aValue), "Duplicate elements are not allowed."); - - if (!mRoot) { - mRoot = aValue; - return; - } - T* last = lookup(*aValue); - int cmp = Comparator::compare(*aValue, *last); - - finishInsertion(last, cmp, aValue); - return; - } - - T* findOrInsert(const T& aValue); - - T* remove(const T& aValue) - { - T* last = lookup(aValue); - MOZ_ASSERT(last, "This tree must contain the element being removed."); - MOZ_ASSERT(Comparator::compare(aValue, *last) == 0); - - // Splay the tree so that the item to remove is the root. - splay(last); - MOZ_ASSERT(last == mRoot); - - // Find another node which can be swapped in for the root: either the - // rightmost child of the root's left, or the leftmost child of the - // root's right. - T* swap; - T* swapChild; - if (mRoot->mLeft) { - swap = mRoot->mLeft; - while (swap->mRight) { - swap = swap->mRight; - } - swapChild = swap->mLeft; - } else if (mRoot->mRight) { - swap = mRoot->mRight; - while (swap->mLeft) { - swap = swap->mLeft; - } - swapChild = swap->mRight; - } else { - T* result = mRoot; - mRoot = nullptr; - return result; - } - - // The selected node has at most one child, in swapChild. Detach it - // from the subtree by replacing it with that child. - if (swap == swap->mParent->mLeft) { - swap->mParent->mLeft = swapChild; - } else { - swap->mParent->mRight = swapChild; - } - if (swapChild) { - swapChild->mParent = swap->mParent; - } - - // Make the selected node the new root. - mRoot = swap; - mRoot->mParent = nullptr; - mRoot->mLeft = last->mLeft; - mRoot->mRight = last->mRight; - if (mRoot->mLeft) { - mRoot->mLeft->mParent = mRoot; - } - if (mRoot->mRight) { - mRoot->mRight->mParent = mRoot; - } - - return last; - } - - T* removeMin() - { - MOZ_ASSERT(mRoot, "No min to remove!"); - - T* min = mRoot; - while (min->mLeft) { - min = min->mLeft; - } - return remove(*min); - } - - // For testing purposes only. - void checkCoherency() - { - checkCoherency(mRoot, nullptr); - } - -private: - /** - * Returns the node in this comparing equal to |aValue|, or a node just - * greater or just less than |aValue| if there is no such node. - */ - T* lookup(const T& aValue) - { - MOZ_ASSERT(!empty()); - - T* node = mRoot; - T* parent; - do { - parent = node; - int c = Comparator::compare(aValue, *node); - if (c == 0) { - return node; - } else if (c < 0) { - node = node->mLeft; - } else { - node = node->mRight; - } - } while (node); - return parent; - } - - void finishInsertion(T* aLast, int32_t aCmp, T* aNew) - { - MOZ_ASSERT(aCmp, "Nodes shouldn't be equal!"); - - T** parentPointer = (aCmp < 0) ? &aLast->mLeft : &aLast->mRight; - MOZ_ASSERT(!*parentPointer); - *parentPointer = aNew; - aNew->mParent = aLast; - - splay(aNew); - } - - /** - * Rotate the tree until |node| is at the root of the tree. Performing - * the rotations in this fashion preserves the amortized balancing of - * the tree. - */ - void splay(T* aNode) - { - MOZ_ASSERT(aNode); - - while (aNode != mRoot) { - T* parent = aNode->mParent; - if (parent == mRoot) { - // Zig rotation. - rotate(aNode); - MOZ_ASSERT(aNode == mRoot); - return; - } - T* grandparent = parent->mParent; - if ((parent->mLeft == aNode) == (grandparent->mLeft == parent)) { - // Zig-zig rotation. - rotate(parent); - rotate(aNode); - } else { - // Zig-zag rotation. - rotate(aNode); - rotate(aNode); - } - } - } - - void rotate(T* aNode) - { - // Rearrange nodes so that aNode becomes the parent of its current - // parent, while preserving the sortedness of the tree. - T* parent = aNode->mParent; - if (parent->mLeft == aNode) { - // x y - // y c ==> a x - // a b b c - parent->mLeft = aNode->mRight; - if (aNode->mRight) { - aNode->mRight->mParent = parent; - } - aNode->mRight = parent; - } else { - MOZ_ASSERT(parent->mRight == aNode); - // x y - // a y ==> x c - // b c a b - parent->mRight = aNode->mLeft; - if (aNode->mLeft) { - aNode->mLeft->mParent = parent; - } - aNode->mLeft = parent; - } - aNode->mParent = parent->mParent; - parent->mParent = aNode; - if (T* grandparent = aNode->mParent) { - if (grandparent->mLeft == parent) { - grandparent->mLeft = aNode; - } else { - grandparent->mRight = aNode; - } - } else { - mRoot = aNode; - } - } - - T* checkCoherency(T* aNode, T* aMinimum) - { - if (mRoot) { - MOZ_RELEASE_ASSERT(!mRoot->mParent); - } - if (!aNode) { - MOZ_RELEASE_ASSERT(!mRoot); - return nullptr; - } - if (!aNode->mParent) { - MOZ_RELEASE_ASSERT(aNode == mRoot); - } - if (aMinimum) { - MOZ_RELEASE_ASSERT(Comparator::compare(*aMinimum, *aNode) < 0); - } - if (aNode->mLeft) { - MOZ_RELEASE_ASSERT(aNode->mLeft->mParent == aNode); - T* leftMaximum = checkCoherency(aNode->mLeft, aMinimum); - MOZ_RELEASE_ASSERT(Comparator::compare(*leftMaximum, *aNode) < 0); - } - if (aNode->mRight) { - MOZ_RELEASE_ASSERT(aNode->mRight->mParent == aNode); - return checkCoherency(aNode->mRight, aNode); - } - return aNode; - } - - SplayTree(const SplayTree&) = delete; - void operator=(const SplayTree&) = delete; -}; - -template -T* -SplayTree::findOrInsert(const T& aValue) -{ - if (!mRoot) { - mRoot = new T(aValue); - return mRoot; - } - - T* last = lookup(aValue); - int cmp = Comparator::compare(aValue, *last); - if (!cmp) { - return last; - } - - T* t = new T(aValue); - finishInsertion(last, cmp, t); - return t; -} - -} /* namespace mozilla */ - -#endif /* mozilla_SplayTree_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Sprintf.h b/android/arm64-v8a/include/spidermonkey/mozilla/Sprintf.h deleted file mode 100644 index e0be271e..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Sprintf.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Provides a safer sprintf for printing to fixed-size character arrays. */ - -#ifndef mozilla_Sprintf_h_ -#define mozilla_Sprintf_h_ - -#include -#include - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -#ifdef __cplusplus - -template -int VsprintfLiteral(char (&buffer)[N], const char* format, va_list args) -{ - MOZ_ASSERT(format != buffer); - int result = vsnprintf(buffer, N, format, args); - buffer[N - 1] = '\0'; - return result; -} - -template -MOZ_FORMAT_PRINTF(2, 3) -int SprintfLiteral(char (&buffer)[N], const char* format, ...) -{ - va_list args; - va_start(args, format); - int result = VsprintfLiteral(buffer, format, args); - va_end(args); - return result; -} - -#endif -#endif /* mozilla_Sprintf_h_ */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/StackWalk.h b/android/arm64-v8a/include/spidermonkey/mozilla/StackWalk.h deleted file mode 100644 index 534c0bd8..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/StackWalk.h +++ /dev/null @@ -1,163 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* API for getting a stack trace of the C/C++ stack on the current thread */ - -#ifndef mozilla_StackWalk_h -#define mozilla_StackWalk_h - -/* WARNING: This file is intended to be included from C or C++ files. */ - -#include "mozilla/Types.h" -#include - -/** - * The callback for MozStackWalk. - * - * @param aFrameNumber The frame number (starts at 1, not 0). - * @param aPC The program counter value. - * @param aSP The best approximation possible of what the stack - * pointer will be pointing to when the execution returns - * to executing that at aPC. If no approximation can - * be made it will be nullptr. - * @param aClosure Extra data passed in via MozStackWalk(). - */ -typedef void -(*MozWalkStackCallback)(uint32_t aFrameNumber, void* aPC, void* aSP, - void* aClosure); - -/** - * Call aCallback for the C/C++ stack frames on the current thread, from - * the caller of MozStackWalk to main (or above). - * - * @param aCallback Callback function, called once per frame. - * @param aSkipFrames Number of initial frames to skip. 0 means that - * the first callback will be for the caller of - * MozStackWalk. - * @param aMaxFrames Maximum number of frames to trace. 0 means no limit. - * @param aClosure Caller-supplied data passed through to aCallback. - * @param aThread The thread for which the stack is to be retrieved. - * Passing null causes us to walk the stack of the - * current thread. On Windows, this is a thread HANDLE. - * It is currently not supported on any other platform. - * @param aPlatformData Platform specific data that can help in walking the - * stack, this should be nullptr unless you really know - * what you're doing! This needs to be a pointer to a - * CONTEXT on Windows and should not be passed on other - * platforms. - * - * May skip some stack frames due to compiler optimizations or code - * generation. - * - */ -MFBT_API bool -MozStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames, - uint32_t aMaxFrames, void* aClosure, uintptr_t aThread, - void* aPlatformData); - -typedef struct -{ - /* - * The name of the shared library or executable containing an - * address and the address's offset within that library, or empty - * string and zero if unknown. - */ - char library[256]; - ptrdiff_t loffset; - /* - * The name of the file name and line number of the code - * corresponding to the address, or empty string and zero if - * unknown. - */ - char filename[256]; - unsigned long lineno; - /* - * The name of the function containing an address and the address's - * offset within that function, or empty string and zero if unknown. - */ - char function[256]; - ptrdiff_t foffset; -} MozCodeAddressDetails; - -/** - * For a given pointer to code, fill in the pieces of information used - * when printing a stack trace. - * - * @param aPC The code address. - * @param aDetails A structure to be filled in with the result. - */ -MFBT_API bool -MozDescribeCodeAddress(void* aPC, MozCodeAddressDetails* aDetails); - -/** - * Format the information about a code address in a format suitable for - * stack traces on the current platform. When available, this string - * should contain the function name, source file, and line number. When - * these are not available, library and offset should be reported, if - * possible. - * - * Note that this output is parsed by several scripts including the fix*.py and - * make-tree.pl scripts in tools/rb/. It should only be change with care, and - * in conjunction with those scripts. - * - * @param aBuffer A string to be filled in with the description. - * The string will always be null-terminated. - * @param aBufferSize The size, in bytes, of aBuffer, including - * room for the terminating null. If the information - * to be printed would be larger than aBuffer, it - * will be truncated so that aBuffer[aBufferSize-1] - * is the terminating null. - * @param aFrameNumber The frame number. - * @param aPC The code address. - * @param aFunction The function name. Possibly null or the empty string. - * @param aLibrary The library name. Possibly null or the empty string. - * @param aLOffset The library offset. - * @param aFileName The filename. Possibly null or the empty string. - * @param aLineNo The line number. Possibly zero. - */ -MFBT_API void -MozFormatCodeAddress(char* aBuffer, uint32_t aBufferSize, uint32_t aFrameNumber, - const void* aPC, const char* aFunction, - const char* aLibrary, ptrdiff_t aLOffset, - const char* aFileName, uint32_t aLineNo); - -/** - * Format the information about a code address in the same fashion as - * MozFormatCodeAddress. - * - * @param aBuffer A string to be filled in with the description. - * The string will always be null-terminated. - * @param aBufferSize The size, in bytes, of aBuffer, including - * room for the terminating null. If the information - * to be printed would be larger than aBuffer, it - * will be truncated so that aBuffer[aBufferSize-1] - * is the terminating null. - * @param aFrameNumber The frame number. - * @param aPC The code address. - * @param aDetails The value filled in by MozDescribeCodeAddress(aPC). - */ -MFBT_API void -MozFormatCodeAddressDetails(char* aBuffer, uint32_t aBufferSize, - uint32_t aFrameNumber, void* aPC, - const MozCodeAddressDetails* aDetails); - -namespace mozilla { - -MFBT_API bool -FramePointerStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames, - uint32_t aMaxFrames, void* aClosure, void** aBp, - void* aStackEnd); - -} // namespace mozilla - -/** - * Initialize the critical sections for this platform so that we can - * abort stack walks when needed. - */ -MFBT_API void -StackWalkInitCriticalAddress(void); - -#endif diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/StaticAnalysisFunctions.h b/android/arm64-v8a/include/spidermonkey/mozilla/StaticAnalysisFunctions.h deleted file mode 100644 index a06809dc..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/StaticAnalysisFunctions.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_StaticAnalysisFunctions_h -#define mozilla_StaticAnalysisFunctions_h - -#ifndef __cplusplus -#ifndef bool -#include -#endif -#endif -/* - * Functions that are used as markers in Gecko code for static analysis. Their - * purpose is to have different AST nodes generated during compile time and to - * match them based on different checkers implemented in build/clang-plugin - */ - -#ifdef MOZ_CLANG_PLUGIN - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * MOZ_AssertAssignmentTest - used in MOZ_ASSERT in order to test the possible - * presence of assignment instead of logical comparisons. - * - * Example: - * MOZ_ASSERT(retVal = true); - */ -static MOZ_ALWAYS_INLINE bool MOZ_AssertAssignmentTest(bool exprResult) { - return exprResult; -} - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#define MOZ_CHECK_ASSERT_ASSIGNMENT(expr) MOZ_AssertAssignmentTest(!!(expr)) - -#else - -#define MOZ_CHECK_ASSERT_ASSIGNMENT(expr) (!!(expr)) - -#endif /* MOZ_CLANG_PLUGIN */ -#endif /* StaticAnalysisFunctions_h */ \ No newline at end of file diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/TaggedAnonymousMemory.h b/android/arm64-v8a/include/spidermonkey/mozilla/TaggedAnonymousMemory.h deleted file mode 100644 index d26b06df..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/TaggedAnonymousMemory.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -// Some Linux kernels -- specifically, newer versions of Android and -// some B2G devices -- have a feature for assigning names to ranges of -// anonymous memory (i.e., memory that doesn't have a "name" in the -// form of an underlying mapped file). These names are reported in -// /proc//smaps alongside system-level memory usage information -// such as Proportional Set Size (memory usage adjusted for sharing -// between processes), which allows reporting this information at a -// finer granularity than would otherwise be possible (e.g., -// separating malloc() heap from JS heap). -// -// Existing memory can be tagged with MozTagAnonymousMemory(); it will -// tag the range of complete pages containing the given interval, so -// the results may be inexact if the range isn't page-aligned. -// MozTaggedAnonymousMmap() can be used like mmap() with an extra -// parameter, and will tag the returned memory if the mapping was -// successful (and if it was in fact anonymous). -// -// NOTE: The pointer given as the "tag" argument MUST remain valid as -// long as the mapping exists. The referenced string is read when -// /proc//smaps or /proc//maps is read, not when the tag is -// established, so freeing it or changing its contents will have -// unexpected results. Using a static string is probably best. -// -// Also note that this header can be used by both C and C++ code. - -#ifndef mozilla_TaggedAnonymousMemory_h -#define mozilla_TaggedAnonymousMemory_h - -#ifndef XP_WIN - -#include -#include - -#include "mozilla/Types.h" - -#ifdef ANDROID - -#ifdef __cplusplus -extern "C" { -#endif - -MFBT_API void -MozTagAnonymousMemory(const void* aPtr, size_t aLength, const char* aTag); - -MFBT_API void* -MozTaggedAnonymousMmap(void* aAddr, size_t aLength, int aProt, int aFlags, - int aFd, off_t aOffset, const char* aTag); - -MFBT_API int -MozTaggedMemoryIsSupported(void); - -#ifdef __cplusplus -} // extern "C" -#endif - -#else // ANDROID - -static inline void -MozTagAnonymousMemory(const void* aPtr, size_t aLength, const char* aTag) -{ -} - -static inline void* -MozTaggedAnonymousMmap(void* aAddr, size_t aLength, int aProt, int aFlags, - int aFd, off_t aOffset, const char* aTag) -{ - return mmap(aAddr, aLength, aProt, aFlags, aFd, aOffset); -} - -static inline int -MozTaggedMemoryIsSupported(void) -{ - return 0; -} - -#endif // ANDROID - -#endif // !XP_WIN - -#endif // mozilla_TaggedAnonymousMemory_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/TemplateLib.h b/android/arm64-v8a/include/spidermonkey/mozilla/TemplateLib.h deleted file mode 100644 index 6286452d..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/TemplateLib.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Reusable template meta-functions on types and compile-time values. Meta- - * functions are placed inside the 'tl' namespace to avoid conflict with non- - * meta functions of the same name (e.g., mozilla::tl::FloorLog2 vs. - * mozilla::FloorLog2). - * - * When constexpr support becomes universal, we should probably use that instead - * of some of these templates, for simplicity. - */ - -#ifndef mozilla_TemplateLib_h -#define mozilla_TemplateLib_h - -#include -#include - -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -namespace tl { - -/** Compute min/max. */ -template -struct Min -{ - static const size_t value = I < J ? I : J; -}; -template -struct Max -{ - static const size_t value = I > J ? I : J; -}; - -/** Compute floor(log2(i)). */ -template -struct FloorLog2 -{ - static const size_t value = 1 + FloorLog2::value; -}; -template<> struct FloorLog2<0> { /* Error */ }; -template<> struct FloorLog2<1> { static const size_t value = 0; }; - -/** Compute ceiling(log2(i)). */ -template -struct CeilingLog2 -{ - static const size_t value = FloorLog2<2 * I - 1>::value; -}; - -/** Round up to the nearest power of 2. */ -template -struct RoundUpPow2 -{ - static const size_t value = size_t(1) << CeilingLog2::value; -}; -template<> -struct RoundUpPow2<0> -{ - static const size_t value = 1; -}; - -/** Compute the number of bits in the given unsigned type. */ -template -struct BitSize -{ - static const size_t value = sizeof(T) * CHAR_BIT; -}; - -/** - * Produce an N-bit mask, where N <= BitSize::value. Handle the - * language-undefined edge case when N = BitSize::value. - */ -template -struct NBitMask -{ - // Assert the precondition. On success this evaluates to 0. Otherwise it - // triggers divide-by-zero at compile time: a guaranteed compile error in - // C++11, and usually one in C++98. Add this value to |value| to assure - // its computation. - static const size_t checkPrecondition = - 0 / size_t(N < BitSize::value); - static const size_t value = (size_t(1) << N) - 1 + checkPrecondition; -}; -template<> -struct NBitMask::value> -{ - static const size_t value = size_t(-1); -}; - -/** - * For the unsigned integral type size_t, compute a mask M for N such that - * for all X, !(X & M) implies X * N will not overflow (w.r.t size_t) - */ -template -struct MulOverflowMask -{ - static const size_t value = - ~NBitMask::value - CeilingLog2::value>::value; -}; -template<> struct MulOverflowMask<0> { /* Error */ }; -template<> struct MulOverflowMask<1> { static const size_t value = 0; }; - -/** - * And computes the logical 'and' of its argument booleans. - * - * Examples: - * mozilla::t1::And::value is true. - * mozilla::t1::And::value is false. - * mozilla::t1::And<>::value is true. - */ - -template -struct And; - -template<> -struct And<> : public TrueType { }; - -template -struct And - : public Conditional, FalseType>::Type { }; - -} // namespace tl - -} // namespace mozilla - -#endif /* mozilla_TemplateLib_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/ThreadLocal.h b/android/arm64-v8a/include/spidermonkey/mozilla/ThreadLocal.h deleted file mode 100644 index 880e6773..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/ThreadLocal.h +++ /dev/null @@ -1,222 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Cross-platform lightweight thread local data wrappers. */ - -#ifndef mozilla_ThreadLocal_h -#define mozilla_ThreadLocal_h - -#if defined(XP_WIN) -// This file will get included in any file that wants to add a profiler mark. -// In order to not bring together we could include windef.h and -// winbase.h which are sufficient to get the prototypes for the Tls* functions. -// # include -// # include -// Unfortunately, even including these headers causes us to add a bunch of ugly -// stuff to our namespace e.g #define CreateEvent CreateEventW -extern "C" { -__declspec(dllimport) void* __stdcall TlsGetValue(unsigned long); -__declspec(dllimport) int __stdcall TlsSetValue(unsigned long, void*); -__declspec(dllimport) unsigned long __stdcall TlsAlloc(); -} -#else -# include -# include -#endif - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -// sig_safe_t denotes an atomic type which can be read or stored in a single -// instruction. This means that data of this type is safe to be manipulated -// from a signal handler, or other similar asynchronous execution contexts. -#if defined(XP_WIN) -typedef unsigned long sig_safe_t; -#else -typedef sig_atomic_t sig_safe_t; -#endif - -namespace detail { - -#if defined(HAVE_THREAD_TLS_KEYWORD) -#define MOZ_HAS_THREAD_LOCAL -#endif - -/* - * Thread Local Storage helpers. - * - * Usage: - * - * Do not directly instantiate this class. Instead, use the - * MOZ_THREAD_LOCAL macro to declare or define instances. The macro - * takes a type name as its argument. - * - * Declare like this: - * extern MOZ_THREAD_LOCAL(int) tlsInt; - * Define like this: - * MOZ_THREAD_LOCAL(int) tlsInt; - * or: - * static MOZ_THREAD_LOCAL(int) tlsInt; - * - * Only static-storage-duration (e.g. global variables, or static class members) - * objects of this class should be instantiated. This class relies on - * zero-initialization, which is implicit for static-storage-duration objects. - * It doesn't have a custom default constructor, to avoid static initializers. - * - * API usage: - * - * // Create a TLS item. - * // - * // Note that init() should be invoked before the first use of set() - * // or get(). It is ok to call it multiple times. This must be - * // called in a way that avoids possible races with other threads. - * MOZ_THREAD_LOCAL(int) tlsKey; - * if (!tlsKey.init()) { - * // deal with the error - * } - * - * // Set the TLS value - * tlsKey.set(123); - * - * // Get the TLS value - * int value = tlsKey.get(); - */ -template -class ThreadLocal -{ -#ifndef MOZ_HAS_THREAD_LOCAL -#if defined(XP_WIN) - typedef unsigned long key_t; -#else - typedef pthread_key_t key_t; -#endif - - // Integral types narrower than void* must be extended to avoid - // warnings from valgrind on some platforms. This helper type - // achieves that without penalizing the common case of ThreadLocals - // instantiated using a pointer type. - template - struct Helper - { - typedef uintptr_t Type; - }; - - template - struct Helper - { - typedef S *Type; - }; -#endif - - bool initialized() const { -#ifdef MOZ_HAS_THREAD_LOCAL - return true; -#else - return mInited; -#endif - } - -public: - // __thread does not allow non-trivial constructors, but we can - // instead rely on zero-initialization. -#ifndef MOZ_HAS_THREAD_LOCAL - ThreadLocal() - : mKey(0), mInited(false) - {} -#endif - - MOZ_MUST_USE inline bool init(); - - inline T get() const; - - inline void set(const T aValue); - -private: -#ifdef MOZ_HAS_THREAD_LOCAL - T mValue; -#else - key_t mKey; - bool mInited; -#endif -}; - -template -inline bool -ThreadLocal::init() -{ - static_assert(mozilla::IsPointer::value || mozilla::IsIntegral::value, - "mozilla::ThreadLocal must be used with a pointer or " - "integral type"); - static_assert(sizeof(T) <= sizeof(void*), - "mozilla::ThreadLocal can't be used for types larger than " - "a pointer"); - -#ifdef MOZ_HAS_THREAD_LOCAL - return true; -#else - if (!initialized()) { -#ifdef XP_WIN - mKey = TlsAlloc(); - mInited = mKey != 0xFFFFFFFFUL; // TLS_OUT_OF_INDEXES -#else - mInited = !pthread_key_create(&mKey, nullptr); -#endif - } - return mInited; -#endif -} - -template -inline T -ThreadLocal::get() const -{ -#ifdef MOZ_HAS_THREAD_LOCAL - return mValue; -#else - MOZ_ASSERT(initialized()); - void* h; -#ifdef XP_WIN - h = TlsGetValue(mKey); -#else - h = pthread_getspecific(mKey); -#endif - return static_cast(reinterpret_cast::Type>(h)); -#endif -} - -template -inline void -ThreadLocal::set(const T aValue) -{ -#ifdef MOZ_HAS_THREAD_LOCAL - mValue = aValue; -#else - MOZ_ASSERT(initialized()); - void* h = reinterpret_cast(static_cast::Type>(aValue)); -#ifdef XP_WIN - bool succeeded = TlsSetValue(mKey, h); -#else - bool succeeded = !pthread_setspecific(mKey, h); -#endif - if (!succeeded) { - MOZ_CRASH(); - } -#endif -} - -#ifdef MOZ_HAS_THREAD_LOCAL -#define MOZ_THREAD_LOCAL(TYPE) __thread mozilla::detail::ThreadLocal -#else -#define MOZ_THREAD_LOCAL(TYPE) mozilla::detail::ThreadLocal -#endif - -} // namespace detail -} // namespace mozilla - -#endif /* mozilla_ThreadLocal_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/TimeStamp.h b/android/arm64-v8a/include/spidermonkey/mozilla/TimeStamp.h deleted file mode 100644 index a1a0eb36..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/TimeStamp.h +++ /dev/null @@ -1,609 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_TimeStamp_h -#define mozilla_TimeStamp_h - -#include -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/FloatingPoint.h" -#include "mozilla/TypeTraits.h" -#include "mozilla/Types.h" - -namespace IPC { -template struct ParamTraits; -} // namespace IPC - -#ifdef XP_WIN -// defines TimeStampValue as a complex value keeping both -// GetTickCount and QueryPerformanceCounter values -#include "TimeStamp_windows.h" -#endif - -namespace mozilla { - -#ifndef XP_WIN -typedef uint64_t TimeStampValue; -#endif - -class TimeStamp; - -/** - * Platform-specific implementation details of BaseTimeDuration. - */ -class BaseTimeDurationPlatformUtils -{ -public: - static MFBT_API double ToSeconds(int64_t aTicks); - static MFBT_API double ToSecondsSigDigits(int64_t aTicks); - static MFBT_API int64_t TicksFromMilliseconds(double aMilliseconds); - static MFBT_API int64_t ResolutionInTicks(); -}; - -/** - * Instances of this class represent the length of an interval of time. - * Negative durations are allowed, meaning the end is before the start. - * - * Internally the duration is stored as a int64_t in units of - * PR_TicksPerSecond() when building with NSPR interval timers, or a - * system-dependent unit when building with system clocks. The - * system-dependent unit must be constant, otherwise the semantics of - * this class would be broken. - * - * The ValueCalculator template parameter determines how arithmetic - * operations are performed on the integer count of ticks (mValue). - */ -template -class BaseTimeDuration -{ -public: - // The default duration is 0. - constexpr BaseTimeDuration() : mValue(0) {} - // Allow construction using '0' as the initial value, for readability, - // but no other numbers (so we don't have any implicit unit conversions). - struct _SomethingVeryRandomHere; - MOZ_IMPLICIT BaseTimeDuration(_SomethingVeryRandomHere* aZero) : mValue(0) - { - MOZ_ASSERT(!aZero, "Who's playing funny games here?"); - } - // Default copy-constructor and assignment are OK - - // Converting copy-constructor and assignment operator - template - explicit BaseTimeDuration(const BaseTimeDuration& aOther) - : mValue(aOther.mValue) - { } - - template - BaseTimeDuration& operator=(const BaseTimeDuration& aOther) - { - mValue = aOther.mValue; - return *this; - } - - double ToSeconds() const - { - if (mValue == INT64_MAX) { - return PositiveInfinity(); - } - if (mValue == INT64_MIN) { - return NegativeInfinity(); - } - return BaseTimeDurationPlatformUtils::ToSeconds(mValue); - } - // Return a duration value that includes digits of time we think to - // be significant. This method should be used when displaying a - // time to humans. - double ToSecondsSigDigits() const - { - if (mValue == INT64_MAX) { - return PositiveInfinity(); - } - if (mValue == INT64_MIN) { - return NegativeInfinity(); - } - return BaseTimeDurationPlatformUtils::ToSecondsSigDigits(mValue); - } - double ToMilliseconds() const { return ToSeconds() * 1000.0; } - double ToMicroseconds() const { return ToMilliseconds() * 1000.0; } - - // Using a double here is safe enough; with 53 bits we can represent - // durations up to over 280,000 years exactly. If the units of - // mValue do not allow us to represent durations of that length, - // long durations are clamped to the max/min representable value - // instead of overflowing. - static inline BaseTimeDuration FromSeconds(double aSeconds) - { - return FromMilliseconds(aSeconds * 1000.0); - } - static BaseTimeDuration FromMilliseconds(double aMilliseconds) - { - if (aMilliseconds == PositiveInfinity()) { - return Forever(); - } - if (aMilliseconds == NegativeInfinity()) { - return FromTicks(INT64_MIN); - } - return FromTicks( - BaseTimeDurationPlatformUtils::TicksFromMilliseconds(aMilliseconds)); - } - static inline BaseTimeDuration FromMicroseconds(double aMicroseconds) - { - return FromMilliseconds(aMicroseconds / 1000.0); - } - - static BaseTimeDuration Forever() - { - return FromTicks(INT64_MAX); - } - - BaseTimeDuration operator+(const BaseTimeDuration& aOther) const - { - return FromTicks(ValueCalculator::Add(mValue, aOther.mValue)); - } - BaseTimeDuration operator-(const BaseTimeDuration& aOther) const - { - return FromTicks(ValueCalculator::Subtract(mValue, aOther.mValue)); - } - BaseTimeDuration& operator+=(const BaseTimeDuration& aOther) - { - mValue = ValueCalculator::Add(mValue, aOther.mValue); - return *this; - } - BaseTimeDuration& operator-=(const BaseTimeDuration& aOther) - { - mValue = ValueCalculator::Subtract(mValue, aOther.mValue); - return *this; - } - BaseTimeDuration operator-() const - { - // We don't just use FromTicks(ValueCalculator::Subtract(0, mValue)) - // since that won't give the correct result for -TimeDuration::Forever(). - int64_t ticks; - if (mValue == INT64_MAX) { - ticks = INT64_MIN; - } else if (mValue == INT64_MIN) { - ticks = INT64_MAX; - } else { - ticks = -mValue; - } - - return FromTicks(ticks); - } - -private: - // Block double multiplier (slower, imprecise if long duration) - Bug 853398. - // If required, use MultDouble explicitly and with care. - BaseTimeDuration operator*(const double aMultiplier) const = delete; - - // Block double divisor (for the same reason, and because dividing by - // fractional values would otherwise invoke the int64_t variant, and rounding - // the passed argument can then cause divide-by-zero) - Bug 1147491. - BaseTimeDuration operator/(const double aDivisor) const = delete; - -public: - BaseTimeDuration MultDouble(double aMultiplier) const - { - return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); - } - BaseTimeDuration operator*(const int32_t aMultiplier) const - { - return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); - } - BaseTimeDuration operator*(const uint32_t aMultiplier) const - { - return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); - } - BaseTimeDuration operator*(const int64_t aMultiplier) const - { - return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); - } - BaseTimeDuration operator*(const uint64_t aMultiplier) const - { - if (aMultiplier > INT64_MAX) { - return Forever(); - } - return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); - } - BaseTimeDuration operator/(const int64_t aDivisor) const - { - MOZ_ASSERT(aDivisor != 0, "Division by zero"); - return FromTicks(ValueCalculator::Divide(mValue, aDivisor)); - } - double operator/(const BaseTimeDuration& aOther) const - { -#ifndef MOZ_B2G - // Bug 1066388 - This fails on B2G ICS Emulator - MOZ_ASSERT(aOther.mValue != 0, "Division by zero"); -#endif - return ValueCalculator::DivideDouble(mValue, aOther.mValue); - } - BaseTimeDuration operator%(const BaseTimeDuration& aOther) const - { - MOZ_ASSERT(aOther.mValue != 0, "Division by zero"); - return FromTicks(ValueCalculator::Modulo(mValue, aOther.mValue)); - } - - template - bool operator<(const BaseTimeDuration& aOther) const - { - return mValue < aOther.mValue; - } - template - bool operator<=(const BaseTimeDuration& aOther) const - { - return mValue <= aOther.mValue; - } - template - bool operator>=(const BaseTimeDuration& aOther) const - { - return mValue >= aOther.mValue; - } - template - bool operator>(const BaseTimeDuration& aOther) const - { - return mValue > aOther.mValue; - } - template - bool operator==(const BaseTimeDuration& aOther) const - { - return mValue == aOther.mValue; - } - template - bool operator!=(const BaseTimeDuration& aOther) const - { - return mValue != aOther.mValue; - } - bool IsZero() const - { - return mValue == 0; - } - explicit operator bool() const - { - return mValue != 0; - } - - // Return a best guess at the system's current timing resolution, - // which might be variable. BaseTimeDurations below this order of - // magnitude are meaningless, and those at the same order of - // magnitude or just above are suspect. - static BaseTimeDuration Resolution() { - return FromTicks(BaseTimeDurationPlatformUtils::ResolutionInTicks()); - } - - // We could define additional operators here: - // -- convert to/from other time units - // -- scale duration by a float - // but let's do that on demand. - // Comparing durations for equality will only lead to bugs on - // platforms with high-resolution timers. - -private: - friend class TimeStamp; - friend struct IPC::ParamTraits>; - template - friend class BaseTimeDuration; - - static BaseTimeDuration FromTicks(int64_t aTicks) - { - BaseTimeDuration t; - t.mValue = aTicks; - return t; - } - - static BaseTimeDuration FromTicks(double aTicks) - { - // NOTE: this MUST be a >= test, because int64_t(double(INT64_MAX)) - // overflows and gives INT64_MIN. - if (aTicks >= double(INT64_MAX)) { - return FromTicks(INT64_MAX); - } - - // This MUST be a <= test. - if (aTicks <= double(INT64_MIN)) { - return FromTicks(INT64_MIN); - } - - return FromTicks(int64_t(aTicks)); - } - - // Duration, result is implementation-specific difference of two TimeStamps - int64_t mValue; -}; - -/** - * Perform arithmetic operations on the value of a BaseTimeDuration without - * doing strict checks on the range of values. - */ -class TimeDurationValueCalculator -{ -public: - static int64_t Add(int64_t aA, int64_t aB) { return aA + aB; } - static int64_t Subtract(int64_t aA, int64_t aB) { return aA - aB; } - - template - static int64_t Multiply(int64_t aA, T aB) - { - static_assert(IsIntegral::value, - "Using integer multiplication routine with non-integer type." - " Further specialization required"); - return aA * static_cast(aB); - } - - static int64_t Divide(int64_t aA, int64_t aB) { return aA / aB; } - static double DivideDouble(int64_t aA, int64_t aB) - { - return static_cast(aA) / aB; - } - static int64_t Modulo(int64_t aA, int64_t aB) { return aA % aB; } -}; - -template <> -inline int64_t -TimeDurationValueCalculator::Multiply(int64_t aA, double aB) -{ - return static_cast(aA * aB); -} - -/** - * Specialization of BaseTimeDuration that uses TimeDurationValueCalculator for - * arithmetic on the mValue member. - * - * Use this class for time durations that are *not* expected to hold values of - * Forever (or the negative equivalent) or when such time duration are *not* - * expected to be used in arithmetic operations. - */ -typedef BaseTimeDuration TimeDuration; - -/** - * Instances of this class represent moments in time, or a special - * "null" moment. We do not use the non-monotonic system clock or - * local time, since they can be reset, causing apparent backward - * travel in time, which can confuse algorithms. Instead we measure - * elapsed time according to the system. This time can never go - * backwards (i.e. it never wraps around, at least not in less than - * five million years of system elapsed time). It might not advance - * while the system is sleeping. If TimeStamp::SetNow() is not called - * at all for hours or days, we might not notice the passage of some - * of that time. - * - * We deliberately do not expose a way to convert TimeStamps to some - * particular unit. All you can do is compute a difference between two - * TimeStamps to get a TimeDuration. You can also add a TimeDuration - * to a TimeStamp to get a new TimeStamp. You can't do something - * meaningless like add two TimeStamps. - * - * Internally this is implemented as either a wrapper around - * - high-resolution, monotonic, system clocks if they exist on this - * platform - * - PRIntervalTime otherwise. We detect wraparounds of - * PRIntervalTime and work around them. - * - * This class is similar to C++11's time_point, however it is - * explicitly nullable and provides an IsNull() method. time_point - * is initialized to the clock's epoch and provides a - * time_since_epoch() method that functions similiarly. i.e. - * t.IsNull() is equivalent to t.time_since_epoch() == decltype(t)::duration::zero(); - */ -class TimeStamp -{ -public: - /** - * Initialize to the "null" moment - */ - constexpr TimeStamp() : mValue(0) {} - // Default copy-constructor and assignment are OK - - /** - * The system timestamps are the same as the TimeStamp - * retrieved by mozilla::TimeStamp. Since we need this for - * vsync timestamps, we enable the creation of mozilla::TimeStamps - * on platforms that support vsync aligned refresh drivers / compositors - * Verified true as of Jan 31, 2015: B2G and OS X - * False on Windows 7 - * UNTESTED ON OTHER PLATFORMS - */ -#if defined(MOZ_WIDGET_GONK) || defined(XP_DARWIN) - static TimeStamp FromSystemTime(int64_t aSystemTime) - { - static_assert(sizeof(aSystemTime) == sizeof(TimeStampValue), - "System timestamp should be same units as TimeStampValue"); - return TimeStamp(aSystemTime); - } -#endif - - /** - * Return true if this is the "null" moment - */ - bool IsNull() const { return mValue == 0; } - - /** - * Return true if this is not the "null" moment, may be used in tests, e.g.: - * |if (timestamp) { ... }| - */ - explicit operator bool() const - { - return mValue != 0; - } - - /** - * Return a timestamp reflecting the current elapsed system time. This - * is monotonically increasing (i.e., does not decrease) over the - * lifetime of this process' XPCOM session. - * - * Now() is trying to ensure the best possible precision on each platform, - * at least one millisecond. - * - * NowLoRes() has been introduced to workaround performance problems of - * QueryPerformanceCounter on the Windows platform. NowLoRes() is giving - * lower precision, usually 15.6 ms, but with very good performance benefit. - * Use it for measurements of longer times, like >200ms timeouts. - */ - static TimeStamp Now() { return Now(true); } - static TimeStamp NowLoRes() { return Now(false); } - - /** - * Return a timestamp representing the time when the current process was - * created which will be comparable with other timestamps taken with this - * class. If the actual process creation time is detected to be inconsistent - * the @a aIsInconsistent parameter will be set to true, the returned - * timestamp however will still be valid though inaccurate. - * - * @param aIsInconsistent Set to true if an inconsistency was detected in the - * process creation time - * @returns A timestamp representing the time when the process was created, - * this timestamp is always valid even when errors are reported - */ - static MFBT_API TimeStamp ProcessCreation(bool& aIsInconsistent); - - /** - * Records a process restart. After this call ProcessCreation() will return - * the time when the browser was restarted instead of the actual time when - * the process was created. - */ - static MFBT_API void RecordProcessRestart(); - - /** - * Compute the difference between two timestamps. Both must be non-null. - */ - TimeDuration operator-(const TimeStamp& aOther) const - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value"); - static_assert(-INT64_MAX > INT64_MIN, "int64_t sanity check"); - int64_t ticks = int64_t(mValue - aOther.mValue); - // Check for overflow. - if (mValue > aOther.mValue) { - if (ticks < 0) { - ticks = INT64_MAX; - } - } else { - if (ticks > 0) { - ticks = INT64_MIN; - } - } - return TimeDuration::FromTicks(ticks); - } - - TimeStamp operator+(const TimeDuration& aOther) const - { - TimeStamp result = *this; - result += aOther; - return result; - } - TimeStamp operator-(const TimeDuration& aOther) const - { - TimeStamp result = *this; - result -= aOther; - return result; - } - TimeStamp& operator+=(const TimeDuration& aOther) - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - TimeStampValue value = mValue + aOther.mValue; - // Check for underflow. - // (We don't check for overflow because it's not obvious what the error - // behavior should be in that case.) - if (aOther.mValue < 0 && value > mValue) { - value = 0; - } - mValue = value; - return *this; - } - TimeStamp& operator-=(const TimeDuration& aOther) - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - TimeStampValue value = mValue - aOther.mValue; - // Check for underflow. - // (We don't check for overflow because it's not obvious what the error - // behavior should be in that case.) - if (aOther.mValue > 0 && value > mValue) { - value = 0; - } - mValue = value; - return *this; - } - - bool operator<(const TimeStamp& aOther) const - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value"); - return mValue < aOther.mValue; - } - bool operator<=(const TimeStamp& aOther) const - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value"); - return mValue <= aOther.mValue; - } - bool operator>=(const TimeStamp& aOther) const - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value"); - return mValue >= aOther.mValue; - } - bool operator>(const TimeStamp& aOther) const - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value"); - return mValue > aOther.mValue; - } - bool operator==(const TimeStamp& aOther) const - { - return IsNull() - ? aOther.IsNull() - : !aOther.IsNull() && mValue == aOther.mValue; - } - bool operator!=(const TimeStamp& aOther) const - { - return !(*this == aOther); - } - - // Comparing TimeStamps for equality should be discouraged. Adding - // two TimeStamps, or scaling TimeStamps, is nonsense and must never - // be allowed. - - static MFBT_API void Startup(); - static MFBT_API void Shutdown(); - -private: - friend struct IPC::ParamTraits; - friend void StartupTimelineRecordExternal(int, uint64_t); - - MOZ_IMPLICIT TimeStamp(TimeStampValue aValue) : mValue(aValue) {} - - static MFBT_API TimeStamp Now(bool aHighResolution); - - /** - * Computes the uptime of the current process in microseconds. The result - * is platform-dependent and needs to be checked against existing timestamps - * for consistency. - * - * @returns The number of microseconds since the calling process was started - * or 0 if an error was encountered while computing the uptime - */ - static MFBT_API uint64_t ComputeProcessUptime(); - - /** - * When built with PRIntervalTime, a value of 0 means this instance - * is "null". Otherwise, the low 32 bits represent a PRIntervalTime, - * and the high 32 bits represent a counter of the number of - * rollovers of PRIntervalTime that we've seen. This counter starts - * at 1 to avoid a real time colliding with the "null" value. - * - * PR_INTERVAL_MAX is set at 100,000 ticks per second. So the minimum - * time to wrap around is about 2^64/100000 seconds, i.e. about - * 5,849,424 years. - * - * When using a system clock, a value is system dependent. - */ - TimeStampValue mValue; -}; - -} // namespace mozilla - -#endif /* mozilla_TimeStamp_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/ToString.h b/android/arm64-v8a/include/spidermonkey/mozilla/ToString.h deleted file mode 100644 index f11cad5c..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/ToString.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Utilities for converting an object to a string representation. */ - -#ifndef mozilla_ToString_h -#define mozilla_ToString_h - -#include -#include - -namespace mozilla { - -/** - * A convenience function for converting an object to a string representation. - * Supports any object which can be streamed to an std::ostream. - */ -template -std::string -ToString(const T& aValue) -{ - std::ostringstream stream; - stream << aValue; - return stream.str(); -} - -} // namespace mozilla - -#endif /* mozilla_ToString_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Tuple.h b/android/arm64-v8a/include/spidermonkey/mozilla/Tuple.h deleted file mode 100644 index a7f9bee6..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Tuple.h +++ /dev/null @@ -1,461 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A variadic tuple class. */ - -#ifndef mozilla_Tuple_h -#define mozilla_Tuple_h - -#include "mozilla/Move.h" -#include "mozilla/Pair.h" -#include "mozilla/TemplateLib.h" -#include "mozilla/TypeTraits.h" - -#include -#include - -namespace mozilla { - -namespace detail { - -/* - * A helper class that allows passing around multiple variadic argument lists - * by grouping them. - */ -template -struct Group; - -/* - * CheckConvertibility checks whether each type in a source pack of types - * is convertible to the corresponding type in a target pack of types. - * - * It is intended to be invoked like this: - * CheckConvertibility, Group> - * 'Group' is used to separate types in the two packs (otherwise if we just - * wrote 'CheckConvertibility -struct CheckConvertibilityImpl; - -template -struct CheckConvertibilityImpl - : FalseType {}; - -template -struct CheckConvertibilityImpl, Group, true> - : IntegralConstant::value...>::value> { }; - -template -struct CheckConvertibility; - -template -struct CheckConvertibility, Group> - : CheckConvertibilityImpl, Group, - sizeof...(SourceTypes) == sizeof...(TargetTypes)> { }; - -/* - * TupleImpl is a helper class used to implement mozilla::Tuple. - * It represents one node in a recursive inheritance hierarchy. - * 'Index' is the 0-based index of the tuple element stored in this node; - * 'Elements...' are the types of the elements stored in this node and its - * base classes. - * - * Example: - * Tuple inherits from - * TupleImpl<0, int, float, char>, which stores the 'int' and inherits from - * TupleImpl<1, float, char>, which stores the 'float' and inherits from - * TupleImpl<2, char>, which stores the 'char' and inherits from - * TupleImpl<3>, which stores nothing and terminates the recursion. - * - * The purpose of the 'Index' parameter is to allow efficient index-based - * access to a tuple element: given a tuple, and an index 'I' that we wish to - * access, we can cast the tuple to the base which stores the I'th element - * by performing template argument deduction against 'TupleImpl', - * where 'I' is specified explicitly and 'E...' is deduced (this is what the - * non-member 'Get(t)' function does). - * - * This implementation strategy is borrowed from libstdc++'s std::tuple - * implementation. - */ -template -struct TupleImpl; - -/* - * The base case of the inheritance recursion (and also the implementation - * of an empty tuple). - */ -template -struct TupleImpl { - bool operator==(const TupleImpl& aOther) const - { - return true; - } -}; - -/* - * One node of the recursive inheritance hierarchy. It stores the element at - * index 'Index' of a tuple, of type 'HeadT', and inherits from the nodes - * that store the remaining elements, of types 'TailT...'. - */ -template -struct TupleImpl - : public TupleImpl -{ - typedef TupleImpl Base; - - // Accessors for the head and the tail. - // These are static, because the intended usage is for the caller to, - // given a tuple, obtain the type B of the base class which stores the - // element of interest, and then call B::Head(tuple) to access it. - // (Tail() is mostly for internal use, but is exposed for consistency.) - static HeadT& Head(TupleImpl& aTuple) { return aTuple.mHead; } - static const HeadT& Head(const TupleImpl& aTuple) { return aTuple.mHead; } - static Base& Tail(TupleImpl& aTuple) { return aTuple; } - static const Base& Tail(const TupleImpl& aTuple) { return aTuple; } - - TupleImpl() : Base(), mHead() { } - - // Construct from const references to the elements. - explicit TupleImpl(const HeadT& aHead, const TailT&... aTail) - : Base(aTail...), mHead(aHead) { } - - // Construct from objects that are convertible to the elements. - // This constructor is enabled only when the argument types are actually - // convertible to the element types, otherwise it could become a better - // match for certain invocations than the copy constructor. - template , - Group>::value>::Type> - explicit TupleImpl(OtherHeadT&& aHead, OtherTailT&&... aTail) - : Base(Forward(aTail)...), mHead(Forward(aHead)) { } - - // Copy and move constructors. - // We'd like to use '= default' to implement these, but MSVC 2013's support - // for '= default' is incomplete and this doesn't work. - TupleImpl(const TupleImpl& aOther) - : Base(Tail(aOther)) - , mHead(Head(aOther)) {} - TupleImpl(TupleImpl&& aOther) - : Base(Move(Tail(aOther))) - , mHead(Forward(Head(aOther))) {} - - // Assign from a tuple whose elements are convertible to the elements - // of this tuple. - template ::Type> - TupleImpl& operator=(const TupleImpl& aOther) - { - typedef TupleImpl OtherT; - Head(*this) = OtherT::Head(aOther); - Tail(*this) = OtherT::Tail(aOther); - return *this; - } - template ::Type> - TupleImpl& operator=(TupleImpl&& aOther) - { - typedef TupleImpl OtherT; - Head(*this) = Move(OtherT::Head(aOther)); - Tail(*this) = Move(OtherT::Tail(aOther)); - return *this; - } - - // Copy and move assignment operators. - TupleImpl& operator=(const TupleImpl& aOther) - { - Head(*this) = Head(aOther); - Tail(*this) = Tail(aOther); - return *this; - } - TupleImpl& operator=(TupleImpl&& aOther) - { - Head(*this) = Move(Head(aOther)); - Tail(*this) = Move(Tail(aOther)); - return *this; - } - bool operator==(const TupleImpl& aOther) const - { - return Head(*this) == Head(aOther) && Tail(*this) == Tail(aOther); - } -private: - HeadT mHead; // The element stored at this index in the tuple. -}; - -} // namespace detail - -/** - * Tuple is a class that stores zero or more objects, whose types are specified - * as template parameters. It can be thought of as a generalization of Pair, - * (which can be thought of as a 2-tuple). - * - * Tuple allows index-based access to its elements (with the index having to be - * known at compile time) via the non-member function 'Get(tuple)'. - */ -template -class Tuple : public detail::TupleImpl<0, Elements...> -{ - typedef detail::TupleImpl<0, Elements...> Impl; -public: - // The constructors and assignment operators here are simple wrappers - // around those in TupleImpl. - - Tuple() : Impl() { } - explicit Tuple(const Elements&... aElements) : Impl(aElements...) { } - // Here, we can't just use 'typename... OtherElements' because MSVC will give - // a warning "C4520: multiple default constructors specified" (even if no one - // actually instantiates the constructor with an empty parameter pack - - // that's probably a bug) and we compile with warnings-as-errors. - template , - detail::Group>::value>::Type> - explicit Tuple(OtherHead&& aHead, OtherTail&&... aTail) - : Impl(Forward(aHead), Forward(aTail)...) { } - Tuple(const Tuple& aOther) : Impl(aOther) { } - Tuple(Tuple&& aOther) : Impl(Move(aOther)) { } - - template ::Type> - Tuple& operator=(const Tuple& aOther) - { - static_cast(*this) = aOther; - return *this; - } - template ::Type> - Tuple& operator=(Tuple&& aOther) - { - static_cast(*this) = Move(aOther); - return *this; - } - Tuple& operator=(const Tuple& aOther) - { - static_cast(*this) = aOther; - return *this; - } - Tuple& operator=(Tuple&& aOther) - { - static_cast(*this) = Move(aOther); - return *this; - } - bool operator==(const Tuple& aOther) const - { - return static_cast(*this) == static_cast(aOther); - } -}; - -/** - * Specialization of Tuple for two elements. - * This is created to support construction and assignment from a Pair or std::pair. - */ -template -class Tuple : public detail::TupleImpl<0, A, B> -{ - typedef detail::TupleImpl<0, A, B> Impl; - -public: - // The constructors and assignment operators here are simple wrappers - // around those in TupleImpl. - - Tuple() : Impl() { } - explicit Tuple(const A& aA, const B& aB) : Impl(aA, aB) { } - template , - detail::Group>::value>::Type> - explicit Tuple(AArg&& aA, BArg&& aB) - : Impl(Forward(aA), Forward(aB)) { } - Tuple(const Tuple& aOther) : Impl(aOther) { } - Tuple(Tuple&& aOther) : Impl(Move(aOther)) { } - explicit Tuple(const Pair& aOther) - : Impl(aOther.first(), aOther.second()) { } - explicit Tuple(Pair&& aOther) : Impl(Forward(aOther.first()), - Forward(aOther.second())) { } - explicit Tuple(const std::pair& aOther) - : Impl(aOther.first, aOther.second) { } - explicit Tuple(std::pair&& aOther) : Impl(Forward(aOther.first), - Forward(aOther.second)) { } - - template - Tuple& operator=(const Tuple& aOther) - { - static_cast(*this) = aOther; - return *this; - } - template - Tuple& operator=(Tuple&& aOther) - { - static_cast(*this) = Move(aOther); - return *this; - } - Tuple& operator=(const Tuple& aOther) - { - static_cast(*this) = aOther; - return *this; - } - Tuple& operator=(Tuple&& aOther) - { - static_cast(*this) = Move(aOther); - return *this; - } - template - Tuple& operator=(const Pair& aOther) - { - Impl::Head(*this) = aOther.first(); - Impl::Tail(*this).Head(*this) = aOther.second(); - return *this; - } - template - Tuple& operator=(Pair&& aOther) - { - Impl::Head(*this) = Forward(aOther.first()); - Impl::Tail(*this).Head(*this) = Forward(aOther.second()); - return *this; - } - template - Tuple& operator=(const std::pair& aOther) - { - Impl::Head(*this) = aOther.first; - Impl::Tail(*this).Head(*this) = aOther.second; - return *this; - } - template - Tuple& operator=(std::pair&& aOther) - { - Impl::Head(*this) = Forward(aOther.first); - Impl::Tail(*this).Head(*this) = Forward(aOther.second); - return *this; - } -}; - -/** - * Specialization of Tuple for zero arguments. - * This is necessary because if the primary template were instantiated with - * an empty parameter pack, the 'Tuple(Elements...)' constructors would - * become illegal overloads of the default constructor. - */ -template <> -class Tuple<> {}; - -namespace detail { - -/* - * Helper functions for implementing Get(tuple). - * These functions take a TupleImpl, with Index being - * explicitly specified, and Elements being deduced. By passing a Tuple - * object as argument, template argument deduction will do its magic and - * cast the tuple to the base class which stores the element at Index. - */ - -// Const reference version. -template -auto TupleGetHelper(TupleImpl& aTuple) - -> decltype(TupleImpl::Head(aTuple)) -{ - return TupleImpl::Head(aTuple); -} - -// Non-const reference version. -template -auto TupleGetHelper(const TupleImpl& aTuple) - -> decltype(TupleImpl::Head(aTuple)) -{ - return TupleImpl::Head(aTuple); -} - -} // namespace detail - -/** - * Index-based access to an element of a tuple. - * The syntax is Get(tuple). The index is zero-based. - * - * Example: - * - * Tuple t; - * ... - * float f = Get<1>(t); - */ - -// Non-const reference version. -template -auto Get(Tuple& aTuple) - -> decltype(detail::TupleGetHelper(aTuple)) -{ - return detail::TupleGetHelper(aTuple); -} - -// Const reference version. -template -auto Get(const Tuple& aTuple) - -> decltype(detail::TupleGetHelper(aTuple)) -{ - return detail::TupleGetHelper(aTuple); -} - -// Rvalue reference version. -template -auto Get(Tuple&& aTuple) - -> decltype(Move(mozilla::Get(aTuple))) -{ - // We need a 'mozilla::' qualification here to avoid - // name lookup only finding the current function. - return Move(mozilla::Get(aTuple)); -} - -/** - * A convenience function for constructing a tuple out of a sequence of - * values without specifying the type of the tuple. - * The type of the tuple is deduced from the types of its elements. - * - * Example: - * - * auto tuple = MakeTuple(42, 0.5f, 'c'); // has type Tuple - */ -template -inline Tuple::Type...> -MakeTuple(Elements&&... aElements) -{ - return Tuple::Type...>(Forward(aElements)...); -} - -/** - * A convenience function for constructing a tuple of references to a - * sequence of variables. Since assignments to the elements of the tuple - * "go through" to the referenced variables, this can be used to "unpack" - * a tuple into individual variables. - * - * Example: - * - * int i; - * float f; - * char c; - * Tie(i, f, c) = FunctionThatReturnsATuple(); - */ -template -inline Tuple -Tie(Elements&... aVariables) -{ - return Tuple(aVariables...); -} - -} // namespace mozilla - -#endif /* mozilla_Tuple_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/TypeTraits.h b/android/arm64-v8a/include/spidermonkey/mozilla/TypeTraits.h deleted file mode 100644 index 084f608c..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/TypeTraits.h +++ /dev/null @@ -1,1262 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Template-based metaprogramming and type-testing facilities. */ - -#ifndef mozilla_TypeTraits_h -#define mozilla_TypeTraits_h - -#include "mozilla/Types.h" - -/* - * These traits are approximate copies of the traits and semantics from C++11's - * header. Don't add traits not in that header! When all - * platforms provide that header, we can convert all users and remove this one. - */ - -#include - -namespace mozilla { - -/* Forward declarations. */ - -template struct RemoveCV; -template struct AddRvalueReference; - -/* 20.2.4 Function template declval [declval] */ - -/** - * DeclVal simplifies the definition of expressions which occur as unevaluated - * operands. It converts T to a reference type, making it possible to use in - * decltype expressions even if T does not have a default constructor, e.g.: - * decltype(DeclVal().foo()) - */ -template -typename AddRvalueReference::Type DeclVal(); - -/* 20.9.3 Helper classes [meta.help] */ - -/** - * Helper class used as a base for various type traits, exposed publicly - * because exposes it as well. - */ -template -struct IntegralConstant -{ - static const T value = Value; - typedef T ValueType; - typedef IntegralConstant Type; -}; - -/** Convenient aliases. */ -typedef IntegralConstant TrueType; -typedef IntegralConstant FalseType; - -/* 20.9.4 Unary type traits [meta.unary] */ - -/* 20.9.4.1 Primary type categories [meta.unary.cat] */ - -namespace detail { - -template -struct IsVoidHelper : FalseType {}; - -template<> -struct IsVoidHelper : TrueType {}; - -} // namespace detail - -/** - * IsVoid determines whether a type is void. - * - * mozilla::IsVoid::value is false; - * mozilla::IsVoid::value is true; - * mozilla::IsVoid::value is false; - * mozilla::IsVoid::value is true. - */ -template -struct IsVoid : detail::IsVoidHelper::Type> {}; - -namespace detail { - -template -struct IsIntegralHelper : FalseType {}; - -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; - -} /* namespace detail */ - -/** - * IsIntegral determines whether a type is an integral type. - * - * mozilla::IsIntegral::value is true; - * mozilla::IsIntegral::value is true; - * mozilla::IsIntegral::value is true; - * mozilla::IsIntegral::value is false; - * mozilla::IsIntegral::value is false; - */ -template -struct IsIntegral : detail::IsIntegralHelper::Type> -{}; - -template -struct IsSame; - -namespace detail { - -template -struct IsFloatingPointHelper - : IntegralConstant::value || - IsSame::value || - IsSame::value> -{}; - -} // namespace detail - -/** - * IsFloatingPoint determines whether a type is a floating point type (float, - * double, long double). - * - * mozilla::IsFloatingPoint::value is false; - * mozilla::IsFloatingPoint::value is true; - * mozilla::IsFloatingPoint::value is true; - * mozilla::IsFloatingPoint::value is false. - */ -template -struct IsFloatingPoint - : detail::IsFloatingPointHelper::Type> -{}; - -namespace detail { - -template -struct IsArrayHelper : FalseType {}; - -template -struct IsArrayHelper : TrueType {}; - -template -struct IsArrayHelper : TrueType {}; - -} // namespace detail - -/** - * IsArray determines whether a type is an array type, of known or unknown - * length. - * - * mozilla::IsArray::value is false; - * mozilla::IsArray::value is true; - * mozilla::IsArray::value is true. - */ -template -struct IsArray : detail::IsArrayHelper::Type> -{}; - -namespace detail { - -template -struct IsFunPtr; - -template -struct IsFunPtr - : public FalseType -{}; - -template -struct IsFunPtr - : public TrueType -{}; - -}; // namespace detail - -/** - * IsFunction determines whether a type is a function type. Function pointers - * don't qualify here--only the type of an actual function symbol. We do not - * correctly handle varags function types because of a bug in MSVC. - * - * Given the function: - * void f(int) {} - * - * mozilla::IsFunction is true; - * mozilla::IsFunction is false; - * mozilla::IsFunction is true. - */ -template -struct IsFunction - : public detail::IsFunPtr::Type *> -{}; - -namespace detail { - -template -struct IsPointerHelper : FalseType {}; - -template -struct IsPointerHelper : TrueType {}; - -} // namespace detail - -/** - * IsPointer determines whether a type is a possibly-CV-qualified pointer type - * (but not a pointer-to-member type). - * - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is false; - * mozilla::IsPointer::value is false. - * mozilla::IsPointer::value is false - */ -template -struct IsPointer : detail::IsPointerHelper::Type> -{}; - -/** - * IsLvalueReference determines whether a type is an lvalue reference. - * - * mozilla::IsLvalueReference::value is false; - * mozilla::IsLvalueReference::value is false; - * mozilla::IsLvalueReference::value is false; - * mozilla::IsLvalueReference::value is false; - * mozilla::IsLvalueReference::value is false; - * mozilla::IsLvalueReference::value is true; - * mozilla::IsLvalueReference::value is false. - */ -template -struct IsLvalueReference : FalseType {}; - -template -struct IsLvalueReference : TrueType {}; - -/** - * IsRvalueReference determines whether a type is an rvalue reference. - * - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is true. - */ -template -struct IsRvalueReference : FalseType {}; - -template -struct IsRvalueReference : TrueType {}; - -namespace detail { - -// __is_enum is a supported extension across all of our supported compilers. -template -struct IsEnumHelper - : IntegralConstant -{}; - -} // namespace detail - -/** - * IsEnum determines whether a type is an enum type. - * - * mozilla::IsEnum::value is true; - * mozilla::IsEnum::value is false; - * mozilla::IsEnum::value is false; - */ -template -struct IsEnum - : detail::IsEnumHelper::Type> -{}; - -namespace detail { - -// __is_class is a supported extension across all of our supported compilers: -// http://llvm.org/releases/3.0/docs/ClangReleaseNotes.html -// http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Type-Traits.html#Type-Traits -// http://msdn.microsoft.com/en-us/library/ms177194%28v=vs.100%29.aspx -template -struct IsClassHelper - : IntegralConstant -{}; - -} // namespace detail - -/** - * IsClass determines whether a type is a class type (but not a union). - * - * struct S {}; - * union U {}; - * mozilla::IsClass::value is false; - * mozilla::IsClass::value is true; - * mozilla::IsClass::value is false; - */ -template -struct IsClass - : detail::IsClassHelper::Type> -{}; - -/* 20.9.4.2 Composite type traits [meta.unary.comp] */ - -/** - * IsReference determines whether a type is an lvalue or rvalue reference. - * - * mozilla::IsReference::value is false; - * mozilla::IsReference::value is false; - * mozilla::IsReference::value is true; - * mozilla::IsReference::value is false; - * mozilla::IsReference::value is true; - * mozilla::IsReference::value is false; - * mozilla::IsReference::value is false; - * mozilla::IsReference::value is true; - * mozilla::IsReference::value is true; - * mozilla::IsReference::value is true. - */ -template -struct IsReference - : IntegralConstant::value || IsRvalueReference::value> -{}; - -/** - * IsArithmetic determines whether a type is arithmetic. A type is arithmetic - * iff it is an integral type or a floating point type. - * - * mozilla::IsArithmetic::value is true; - * mozilla::IsArithmetic::value is true; - * mozilla::IsArithmetic::value is false. - */ -template -struct IsArithmetic - : IntegralConstant::value || IsFloatingPoint::value> -{}; - -namespace detail { - -template -struct IsMemberPointerHelper : FalseType {}; - -template -struct IsMemberPointerHelper : TrueType {}; - -} // namespace detail - -/** - * IsMemberPointer determines whether a type is pointer to non-static member - * object or a pointer to non-static member function. - * - * mozilla::IsMemberPointer::value is true - * mozilla::IsMemberPointer::value is false - */ -template -struct IsMemberPointer - : detail::IsMemberPointerHelper::Type> -{}; - -/** - * IsScalar determines whether a type is a scalar type. - * - * mozilla::IsScalar::value is true - * mozilla::IsScalar::value is true - * mozilla::IsScalar::value is false - */ -template -struct IsScalar - : IntegralConstant::value || IsEnum::value || - IsPointer::value || IsMemberPointer::value> -{}; - -/* 20.9.4.3 Type properties [meta.unary.prop] */ - -/** - * IsConst determines whether a type is const or not. - * - * mozilla::IsConst::value is false; - * mozilla::IsConst::value is true; - * mozilla::IsConst::value is false. - */ -template -struct IsConst : FalseType {}; - -template -struct IsConst : TrueType {}; - -/** - * IsVolatile determines whether a type is volatile or not. - * - * mozilla::IsVolatile::value is false; - * mozilla::IsVolatile::value is true; - * mozilla::IsVolatile::value is false. - */ -template -struct IsVolatile : FalseType {}; - -template -struct IsVolatile : TrueType {}; - -/** - * Traits class for identifying POD types. Until C++11 there's no automatic - * way to detect PODs, so for the moment this is done manually. Users may - * define specializations of this class that inherit from mozilla::TrueType and - * mozilla::FalseType (or equivalently mozilla::IntegralConstant, or conveniently from mozilla::IsPod for composite types) as needed to - * ensure correct IsPod behavior. - */ -template -struct IsPod : public FalseType {}; - -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template struct IsPod : TrueType {}; - -namespace detail { - -// __is_empty is a supported extension across all of our supported compilers: -// http://llvm.org/releases/3.0/docs/ClangReleaseNotes.html -// http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Type-Traits.html#Type-Traits -// http://msdn.microsoft.com/en-us/library/ms177194%28v=vs.100%29.aspx -template -struct IsEmptyHelper - : IntegralConstant::value && __is_empty(T)> -{}; - -} // namespace detail - -/** - * IsEmpty determines whether a type is a class (but not a union) that is empty. - * - * A class is empty iff it and all its base classes have no non-static data - * members (except bit-fields of length 0) and no virtual member functions, and - * no base class is empty or a virtual base class. - * - * Intuitively, empty classes don't have any data that has to be stored in - * instances of those classes. (The size of the class must still be non-zero, - * because distinct array elements of any type must have different addresses. - * However, if the Empty Base Optimization is implemented by the compiler [most - * compilers implement it, and in certain cases C++11 requires it], the size of - * a class inheriting from an empty |Base| class need not be inflated by - * |sizeof(Base)|.) And intuitively, non-empty classes have data members and/or - * vtable pointers that must be stored in each instance for proper behavior. - * - * static_assert(!mozilla::IsEmpty::value, "not a class => not empty"); - * union U1 { int x; }; - * static_assert(!mozilla::IsEmpty::value, "not a class => not empty"); - * struct E1 {}; - * struct E2 { int : 0 }; - * struct E3 : E1 {}; - * struct E4 : E2 {}; - * static_assert(mozilla::IsEmpty::value && - * mozilla::IsEmpty::value && - * mozilla::IsEmpty::value && - * mozilla::IsEmpty::value, - * "all empty"); - * union U2 { E1 e1; }; - * static_assert(!mozilla::IsEmpty::value, "not a class => not empty"); - * struct NE1 { int x; }; - * struct NE2 : virtual E1 {}; - * struct NE3 : E2 { virtual ~NE3() {} }; - * struct NE4 { virtual void f() {} }; - * static_assert(!mozilla::IsEmpty::value && - * !mozilla::IsEmpty::value && - * !mozilla::IsEmpty::value && - * !mozilla::IsEmpty::value, - * "all empty"); - */ -template -struct IsEmpty : detail::IsEmptyHelper::Type> -{}; - - -namespace detail { - -template::value, - bool = IsIntegral::value, - typename NoCV = typename RemoveCV::Type> -struct IsSignedHelper; - -// Floating point is signed. -template -struct IsSignedHelper : TrueType {}; - -// Integral is conditionally signed. -template -struct IsSignedHelper - : IntegralConstant -{}; - -// Non-floating point, non-integral is not signed. -template -struct IsSignedHelper : FalseType {}; - -} // namespace detail - -/** - * IsSigned determines whether a type is a signed arithmetic type. |char| is - * considered a signed type if it has the same representation as |signed char|. - * - * mozilla::IsSigned::value is true; - * mozilla::IsSigned::value is false; - * mozilla::IsSigned::value is false; - * mozilla::IsSigned::value is true. - */ -template -struct IsSigned : detail::IsSignedHelper {}; - -namespace detail { - -template::value, - bool = IsIntegral::value, - typename NoCV = typename RemoveCV::Type> -struct IsUnsignedHelper; - -// Floating point is not unsigned. -template -struct IsUnsignedHelper : FalseType {}; - -// Integral is conditionally unsigned. -template -struct IsUnsignedHelper - : IntegralConstant::value || bool(NoCV(1) < NoCV(-1)))> -{}; - -// Non-floating point, non-integral is not unsigned. -template -struct IsUnsignedHelper : FalseType {}; - -} // namespace detail - -/** - * IsUnsigned determines whether a type is an unsigned arithmetic type. - * - * mozilla::IsUnsigned::value is false; - * mozilla::IsUnsigned::value is true; - * mozilla::IsUnsigned::value is true; - * mozilla::IsUnsigned::value is false. - */ -template -struct IsUnsigned : detail::IsUnsignedHelper {}; - -namespace detail { - -struct DoIsDestructibleImpl -{ - template().~T())> - static TrueType test(int); - template - static FalseType test(...); -}; - -template -struct IsDestructibleImpl : public DoIsDestructibleImpl -{ - typedef decltype(test(0)) Type; -}; - -} // namespace detail - -template -struct IsDestructible : public detail::IsDestructibleImpl::Type {}; - -/* 20.9.5 Type property queries [meta.unary.prop.query] */ - -/* 20.9.6 Relationships between types [meta.rel] */ - -/** - * IsSame tests whether two types are the same type. - * - * mozilla::IsSame::value is true; - * mozilla::IsSame::value is true; - * mozilla::IsSame::value is false; - * mozilla::IsSame::value is true; - * mozilla::IsSame::value is false; - * mozilla::IsSame::value is true. - */ -template -struct IsSame : FalseType {}; - -template -struct IsSame : TrueType {}; - -namespace detail { - -#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) - -template -struct BaseOfTester : IntegralConstant {}; - -#else - -// The trickery used to implement IsBaseOf here makes it possible to use it for -// the cases of private and multiple inheritance. This code was inspired by the -// sample code here: -// -// http://stackoverflow.com/questions/2910979/how-is-base-of-works -template -struct BaseOfHelper -{ -public: - operator Base*() const; - operator Derived*(); -}; - -template -struct BaseOfTester -{ -private: - template - static char test(Derived*, T); - static int test(Base*, int); - -public: - static const bool value = - sizeof(test(BaseOfHelper(), int())) == sizeof(char); -}; - -template -struct BaseOfTester -{ -private: - template - static char test(Derived*, T); - static int test(Base*, int); - -public: - static const bool value = - sizeof(test(BaseOfHelper(), int())) == sizeof(char); -}; - -template -struct BaseOfTester : FalseType {}; - -template -struct BaseOfTester : TrueType {}; - -template -struct BaseOfTester : TrueType {}; - -#endif - -} /* namespace detail */ - -/* - * IsBaseOf allows to know whether a given class is derived from another. - * - * Consider the following class definitions: - * - * class A {}; - * class B : public A {}; - * class C {}; - * - * mozilla::IsBaseOf::value is true; - * mozilla::IsBaseOf::value is false; - */ -template -struct IsBaseOf - : IntegralConstant::value> -{}; - -namespace detail { - -template -struct ConvertibleTester -{ -private: - template - static char test_helper(To1); - - template - static decltype(test_helper(DeclVal())) test(int); - - template - static int test(...); - -public: - static const bool value = - sizeof(test(0)) == sizeof(char); -}; - -} // namespace detail - -/** - * IsConvertible determines whether a value of type From will implicitly convert - * to a value of type To. For example: - * - * struct A {}; - * struct B : public A {}; - * struct C {}; - * - * mozilla::IsConvertible::value is true; - * mozilla::IsConvertible::value is true; - * mozilla::IsConvertible::value is true; - * mozilla::IsConvertible::value is true; - * mozilla::IsConvertible::value is false; - * mozilla::IsConvertible::value is false; - * mozilla::IsConvertible::value is false; - * mozilla::IsConvertible::value is false. - * - * For obscure reasons, you can't use IsConvertible when the types being tested - * are related through private inheritance, and you'll get a compile error if - * you try. Just don't do it! - * - * Note - we need special handling for void, which ConvertibleTester doesn't - * handle. The void handling here doesn't handle const/volatile void correctly, - * which could be easily fixed if the need arises. - */ -template -struct IsConvertible - : IntegralConstant::value> -{}; - -template -struct IsConvertible - : IntegralConstant::value> -{}; - -template -struct IsConvertible - : IntegralConstant::value> -{}; - -template<> -struct IsConvertible - : TrueType -{}; - -/* 20.9.7 Transformations between types [meta.trans] */ - -/* 20.9.7.1 Const-volatile modifications [meta.trans.cv] */ - -/** - * RemoveConst removes top-level const qualifications on a type. - * - * mozilla::RemoveConst::Type is int; - * mozilla::RemoveConst::Type is int; - * mozilla::RemoveConst::Type is const int*; - * mozilla::RemoveConst::Type is int*. - */ -template -struct RemoveConst -{ - typedef T Type; -}; - -template -struct RemoveConst -{ - typedef T Type; -}; - -/** - * RemoveVolatile removes top-level volatile qualifications on a type. - * - * mozilla::RemoveVolatile::Type is int; - * mozilla::RemoveVolatile::Type is int; - * mozilla::RemoveVolatile::Type is volatile int*; - * mozilla::RemoveVolatile::Type is int*. - */ -template -struct RemoveVolatile -{ - typedef T Type; -}; - -template -struct RemoveVolatile -{ - typedef T Type; -}; - -/** - * RemoveCV removes top-level const and volatile qualifications on a type. - * - * mozilla::RemoveCV::Type is int; - * mozilla::RemoveCV::Type is int; - * mozilla::RemoveCV::Type is int; - * mozilla::RemoveCV::Type is int*. - */ -template -struct RemoveCV -{ - typedef typename RemoveConst::Type>::Type Type; -}; - -/* 20.9.7.2 Reference modifications [meta.trans.ref] */ - -/** - * Converts reference types to the underlying types. - * - * mozilla::RemoveReference::Type is T; - * mozilla::RemoveReference::Type is T; - * mozilla::RemoveReference::Type is T; - */ - -template -struct RemoveReference -{ - typedef T Type; -}; - -template -struct RemoveReference -{ - typedef T Type; -}; - -template -struct RemoveReference -{ - typedef T Type; -}; - -template -struct Conditional; - -namespace detail { - -enum Voidness { TIsVoid, TIsNotVoid }; - -template::value ? TIsVoid : TIsNotVoid> -struct AddLvalueReferenceHelper; - -template -struct AddLvalueReferenceHelper -{ - typedef void Type; -}; - -template -struct AddLvalueReferenceHelper -{ - typedef T& Type; -}; - -} // namespace detail - -/** - * AddLvalueReference adds an lvalue & reference to T if one isn't already - * present. (Note: adding an lvalue reference to an rvalue && reference in - * essence replaces the && with a &&, per C+11 reference collapsing rules. For - * example, int&& would become int&.) - * - * The final computed type will only *not* be an lvalue reference if T is void. - * - * mozilla::AddLvalueReference::Type is int&; - * mozilla::AddLvalueRference::Type is volatile int&; - * mozilla::AddLvalueReference::Type is void*&; - * mozilla::AddLvalueReference::Type is void; - * mozilla::AddLvalueReference::Type is struct S&. - */ -template -struct AddLvalueReference - : detail::AddLvalueReferenceHelper -{}; - -namespace detail { - -template::value ? TIsVoid : TIsNotVoid> -struct AddRvalueReferenceHelper; - -template -struct AddRvalueReferenceHelper -{ - typedef void Type; -}; - -template -struct AddRvalueReferenceHelper -{ - typedef T&& Type; -}; - -} // namespace detail - -/** - * AddRvalueReference adds an rvalue && reference to T if one isn't already - * present. (Note: adding an rvalue reference to an lvalue & reference in - * essence keeps the &, per C+11 reference collapsing rules. For example, - * int& would remain int&.) - * - * The final computed type will only *not* be a reference if T is void. - * - * mozilla::AddRvalueReference::Type is int&&; - * mozilla::AddRvalueRference::Type is volatile int&; - * mozilla::AddRvalueRference::Type is const int&&; - * mozilla::AddRvalueReference::Type is void*&&; - * mozilla::AddRvalueReference::Type is void; - * mozilla::AddRvalueReference::Type is struct S&. - */ -template -struct AddRvalueReference - : detail::AddRvalueReferenceHelper -{}; - -/* 20.9.7.3 Sign modifications [meta.trans.sign] */ - -template -struct EnableIf; - -namespace detail { - -template -struct WithC : Conditional -{}; - -template -struct WithV : Conditional -{}; - - -template -struct WithCV : WithC::Type> -{}; - -template -struct CorrespondingSigned; - -template<> -struct CorrespondingSigned { typedef signed char Type; }; -template<> -struct CorrespondingSigned { typedef signed char Type; }; -template<> -struct CorrespondingSigned { typedef short Type; }; -template<> -struct CorrespondingSigned { typedef int Type; }; -template<> -struct CorrespondingSigned { typedef long Type; }; -template<> -struct CorrespondingSigned { typedef long long Type; }; - -template::Type, - bool IsSignedIntegerType = IsSigned::value && - !IsSame::value> -struct MakeSigned; - -template -struct MakeSigned -{ - typedef T Type; -}; - -template -struct MakeSigned - : WithCV::value, IsVolatile::value, - typename CorrespondingSigned::Type> -{}; - -} // namespace detail - -/** - * MakeSigned produces the corresponding signed integer type for a given - * integral type T, with the const/volatile qualifiers of T. T must be a - * possibly-const/volatile-qualified integral type that isn't bool. - * - * If T is already a signed integer type (not including char!), then T is - * produced. - * - * Otherwise, if T is an unsigned integer type, the signed variety of T, with - * T's const/volatile qualifiers, is produced. - * - * Otherwise, the integral type of the same size as T, with the lowest rank, - * with T's const/volatile qualifiers, is produced. (This basically only acts - * to produce signed char when T = char.) - * - * mozilla::MakeSigned::Type is signed long; - * mozilla::MakeSigned::Type is volatile int; - * mozilla::MakeSigned::Type is const signed short; - * mozilla::MakeSigned::Type is const signed char; - * mozilla::MakeSigned is an error; - * mozilla::MakeSigned is an error. - */ -template -struct MakeSigned - : EnableIf::value && - !IsSame::Type>::value, - typename detail::MakeSigned - >::Type -{}; - -namespace detail { - -template -struct CorrespondingUnsigned; - -template<> -struct CorrespondingUnsigned { typedef unsigned char Type; }; -template<> -struct CorrespondingUnsigned { typedef unsigned char Type; }; -template<> -struct CorrespondingUnsigned { typedef unsigned short Type; }; -template<> -struct CorrespondingUnsigned { typedef unsigned int Type; }; -template<> -struct CorrespondingUnsigned { typedef unsigned long Type; }; -template<> -struct CorrespondingUnsigned { typedef unsigned long long Type; }; - - -template::Type, - bool IsUnsignedIntegerType = IsUnsigned::value && - !IsSame::value> -struct MakeUnsigned; - -template -struct MakeUnsigned -{ - typedef T Type; -}; - -template -struct MakeUnsigned - : WithCV::value, IsVolatile::value, - typename CorrespondingUnsigned::Type> -{}; - -} // namespace detail - -/** - * MakeUnsigned produces the corresponding unsigned integer type for a given - * integral type T, with the const/volatile qualifiers of T. T must be a - * possibly-const/volatile-qualified integral type that isn't bool. - * - * If T is already an unsigned integer type (not including char!), then T is - * produced. - * - * Otherwise, if T is an signed integer type, the unsigned variety of T, with - * T's const/volatile qualifiers, is produced. - * - * Otherwise, the unsigned integral type of the same size as T, with the lowest - * rank, with T's const/volatile qualifiers, is produced. (This basically only - * acts to produce unsigned char when T = char.) - * - * mozilla::MakeUnsigned::Type is unsigned long; - * mozilla::MakeUnsigned::Type is volatile unsigned int; - * mozilla::MakeUnsigned::Type is const unsigned short; - * mozilla::MakeUnsigned::Type is const unsigned char; - * mozilla::MakeUnsigned is an error; - * mozilla::MakeUnsigned is an error. - */ -template -struct MakeUnsigned - : EnableIf::value && - !IsSame::Type>::value, - typename detail::MakeUnsigned - >::Type -{}; - -/* 20.9.7.4 Array modifications [meta.trans.arr] */ - -/** - * RemoveExtent produces either the type of the elements of the array T, or T - * itself. - * - * mozilla::RemoveExtent::Type is int; - * mozilla::RemoveExtent::Type is const int; - * mozilla::RemoveExtent::Type is volatile int; - * mozilla::RemoveExtent::Type is long[17]. - */ -template -struct RemoveExtent -{ - typedef T Type; -}; - -template -struct RemoveExtent -{ - typedef T Type; -}; - -template -struct RemoveExtent -{ - typedef T Type; -}; - -/* 20.9.7.5 Pointer modifications [meta.trans.ptr] */ - -namespace detail { - -template -struct RemovePointerHelper -{ - typedef T Type; -}; - -template -struct RemovePointerHelper -{ - typedef Pointee Type; -}; - -} // namespace detail - -/** - * Produces the pointed-to type if a pointer is provided, else returns the input - * type. Note that this does not dereference pointer-to-member pointers. - * - * struct S { bool m; void f(); }; - * mozilla::RemovePointer::Type is int; - * mozilla::RemovePointer::Type is int; - * mozilla::RemovePointer::Type is int; - * mozilla::RemovePointer::Type is int; - * mozilla::RemovePointer::Type is const long; - * mozilla::RemovePointer::Type is void; - * mozilla::RemovePointer::Type is void (S::*)(); - * mozilla::RemovePointer::Type is void(); - * mozilla::RemovePointer::Type is bool S::*. - */ -template -struct RemovePointer - : detail::RemovePointerHelper::Type> -{}; - -/** - * Converts T& to T*. Otherwise returns T* given T. Note that C++17 wants - * std::add_pointer to work differently for function types. We don't implement - * that behavior here. - * - * mozilla::AddPointer is int*; - * mozilla::AddPointer is int**; - * mozilla::AddPointer is int*; - * mozilla::AddPointer is int** const. - */ -template -struct AddPointer -{ - typedef typename RemoveReference::Type* Type; -}; - -/* 20.9.7.6 Other transformations [meta.trans.other] */ - -/** - * EnableIf is a struct containing a typedef of T if and only if B is true. - * - * mozilla::EnableIf::Type is int; - * mozilla::EnableIf::Type is a compile-time error. - * - * Use this template to implement SFINAE-style (Substitution Failure Is not An - * Error) requirements. For example, you might use it to impose a restriction - * on a template parameter: - * - * template - * class PodVector // vector optimized to store POD (memcpy-able) types - * { - * EnableIf::value, T>::Type* vector; - * size_t length; - * ... - * }; - */ -template -struct EnableIf -{}; - -template -struct EnableIf -{ - typedef T Type; -}; - -/** - * Conditional selects a class between two, depending on a given boolean value. - * - * mozilla::Conditional::Type is A; - * mozilla::Conditional::Type is B; - */ -template -struct Conditional -{ - typedef A Type; -}; - -template -struct Conditional -{ - typedef B Type; -}; - -namespace detail { - -template::value, - bool IsFunction = IsFunction::value> -struct DecaySelector; - -template -struct DecaySelector -{ - typedef typename RemoveCV::Type Type; -}; - -template -struct DecaySelector -{ - typedef typename RemoveExtent::Type* Type; -}; - -template -struct DecaySelector -{ - typedef typename AddPointer::Type Type; -}; - -}; // namespace detail - -/** - * Strips const/volatile off a type and decays it from an lvalue to an - * rvalue. So function types are converted to function pointers, arrays to - * pointers, and references are removed. - * - * mozilla::Decay::Type is int - * mozilla::Decay::Type is int - * mozilla::Decay::Type is int - * mozilla::Decay::Type is int - * mozilla::Decay::Type is int* - * mozilla::Decay::Type is int(*)(int) - */ -template -class Decay - : public detail::DecaySelector::Type> -{ -}; - -} /* namespace mozilla */ - -#endif /* mozilla_TypeTraits_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/TypedEnumBits.h b/android/arm64-v8a/include/spidermonkey/mozilla/TypedEnumBits.h deleted file mode 100644 index 5ee6315c..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/TypedEnumBits.h +++ /dev/null @@ -1,156 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS allows using a typed enum as bit flags. - */ - -#ifndef mozilla_TypedEnumBits_h -#define mozilla_TypedEnumBits_h - -#include "mozilla/Attributes.h" -#include "mozilla/IntegerTypeTraits.h" - -namespace mozilla { - -/* - * The problem that CastableTypedEnumResult aims to solve is that - * typed enums are not convertible to bool, and there is no way to make them - * be, yet user code wants to be able to write - * - * if (myFlags & Flags::SOME_PARTICULAR_FLAG) (1) - * - * There are different approaches to solving this. Most of them require - * adapting user code. For example, we could implement operator! and have - * the user write - * - * if (!!(myFlags & Flags::SOME_PARTICULAR_FLAG)) (2) - * - * Or we could supply a IsNonZero() or Any() function returning whether - * an enum value is nonzero, and have the user write - * - * if (Any(Flags & Flags::SOME_PARTICULAR_FLAG)) (3) - * - * But instead, we choose to preserve the original user syntax (1) as it - * is inherently more readable, and to ease porting existing code to typed - * enums. We achieve this by having operator& and other binary bitwise - * operators have as return type a class, CastableTypedEnumResult, - * that wraps a typed enum but adds bool convertibility. - */ -template -class CastableTypedEnumResult -{ -private: - const E mValue; - -public: - explicit constexpr CastableTypedEnumResult(E aValue) - : mValue(aValue) - {} - - constexpr operator E() const { return mValue; } - - template - explicit constexpr - operator DestinationType() const { return DestinationType(mValue); } - - constexpr bool operator !() const { return !bool(mValue); } -}; - -#define MOZ_CASTABLETYPEDENUMRESULT_BINOP(Op, OtherType, ReturnType) \ -template \ -constexpr ReturnType \ -operator Op(const OtherType& aE, const CastableTypedEnumResult& aR) \ -{ \ - return ReturnType(aE Op OtherType(aR)); \ -} \ -template \ -constexpr ReturnType \ -operator Op(const CastableTypedEnumResult& aR, const OtherType& aE) \ -{ \ - return ReturnType(OtherType(aR) Op aE); \ -} \ -template \ -constexpr ReturnType \ -operator Op(const CastableTypedEnumResult& aR1, \ - const CastableTypedEnumResult& aR2) \ -{ \ - return ReturnType(OtherType(aR1) Op OtherType(aR2)); \ -} - -MOZ_CASTABLETYPEDENUMRESULT_BINOP(|, E, CastableTypedEnumResult) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(&, E, CastableTypedEnumResult) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(^, E, CastableTypedEnumResult) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(==, E, bool) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(!=, E, bool) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(||, bool, bool) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(&&, bool, bool) - -template -constexpr CastableTypedEnumResult -operator ~(const CastableTypedEnumResult& aR) -{ - return CastableTypedEnumResult(~(E(aR))); -} - -#define MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(Op) \ -template \ -E& \ -operator Op(E& aR1, \ - const CastableTypedEnumResult& aR2) \ -{ \ - return aR1 Op E(aR2); \ -} - -MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(&=) -MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(|=) -MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(^=) - -#undef MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP - -#undef MOZ_CASTABLETYPEDENUMRESULT_BINOP - -namespace detail { -template -struct UnsignedIntegerTypeForEnum - : UnsignedStdintTypeForSize -{}; -} // namespace detail - -} // namespace mozilla - -#define MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, Op) \ - inline constexpr mozilla::CastableTypedEnumResult \ - operator Op(Name a, Name b) \ - { \ - typedef mozilla::CastableTypedEnumResult Result; \ - typedef mozilla::detail::UnsignedIntegerTypeForEnum::Type U; \ - return Result(Name(U(a) Op U(b))); \ - } \ - \ - inline Name& \ - operator Op##=(Name& a, Name b) \ - { \ - return a = a Op b; \ - } - -/** - * MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS generates standard bitwise operators - * for the given enum type. Use this to enable using an enum type as bit-field. - */ -#define MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Name) \ - MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, |) \ - MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, &) \ - MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, ^) \ - inline constexpr mozilla::CastableTypedEnumResult \ - operator~(Name a) \ - { \ - typedef mozilla::CastableTypedEnumResult Result; \ - typedef mozilla::detail::UnsignedIntegerTypeForEnum::Type U; \ - return Result(Name(~(U(a)))); \ - } - -#endif // mozilla_TypedEnumBits_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Types.h b/android/arm64-v8a/include/spidermonkey/mozilla/Types.h deleted file mode 100644 index e7e18abb..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Types.h +++ /dev/null @@ -1,134 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* mfbt foundational types and macros. */ - -#ifndef mozilla_Types_h -#define mozilla_Types_h - -/* - * This header must be valid C and C++, includable by code embedding either - * SpiderMonkey or Gecko. - */ - -/* Expose all types and size_t. */ -#include -#include - -/* Implement compiler and linker macros needed for APIs. */ - -/* - * MOZ_EXPORT is used to declare and define a symbol or type which is externally - * visible to users of the current library. It encapsulates various decorations - * needed to properly export the method's symbol. - * - * api.h: - * extern MOZ_EXPORT int MeaningOfLife(void); - * extern MOZ_EXPORT int LuggageCombination; - * - * api.c: - * int MeaningOfLife(void) { return 42; } - * int LuggageCombination = 12345; - * - * If you are merely sharing a method across files, just use plain |extern|. - * These macros are designed for use by library interfaces -- not for normal - * methods or data used cross-file. - */ -#if defined(WIN32) -# define MOZ_EXPORT __declspec(dllexport) -#else /* Unix */ -# ifdef HAVE_VISIBILITY_ATTRIBUTE -# define MOZ_EXPORT __attribute__((visibility("default"))) -# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) -# define MOZ_EXPORT __global -# else -# define MOZ_EXPORT /* nothing */ -# endif -#endif - - -/* - * Whereas implementers use MOZ_EXPORT to declare and define library symbols, - * users use MOZ_IMPORT_API and MOZ_IMPORT_DATA to access them. Most often the - * implementer of the library will expose an API macro which expands to either - * the export or import version of the macro, depending upon the compilation - * mode. - */ -#ifdef _WIN32 -# if defined(__MWERKS__) -# define MOZ_IMPORT_API /* nothing */ -# else -# define MOZ_IMPORT_API __declspec(dllimport) -# endif -#else -# define MOZ_IMPORT_API MOZ_EXPORT -#endif - -#if defined(_WIN32) && !defined(__MWERKS__) -# define MOZ_IMPORT_DATA __declspec(dllimport) -#else -# define MOZ_IMPORT_DATA MOZ_EXPORT -#endif - -/* - * Consistent with the above comment, the MFBT_API and MFBT_DATA macros expose - * export mfbt declarations when building mfbt, and they expose import mfbt - * declarations when using mfbt. - */ -#if defined(IMPL_MFBT) -# define MFBT_API MOZ_EXPORT -# define MFBT_DATA MOZ_EXPORT -#else - /* - * On linux mozglue is linked in the program and we link libxul.so with - * -z,defs. Normally that causes the linker to reject undefined references in - * libxul.so, but as a loophole it allows undefined references to weak - * symbols. We add the weak attribute to the import version of the MFBT API - * macros to exploit this. - */ -# if defined(MOZ_GLUE_IN_PROGRAM) -# define MFBT_API __attribute__((weak)) MOZ_IMPORT_API -# define MFBT_DATA __attribute__((weak)) MOZ_IMPORT_DATA -# else -# define MFBT_API MOZ_IMPORT_API -# define MFBT_DATA MOZ_IMPORT_DATA -# endif -#endif - -/* - * C symbols in C++ code must be declared immediately within |extern "C"| - * blocks. However, in C code, they need not be declared specially. This - * difference is abstracted behind the MOZ_BEGIN_EXTERN_C and MOZ_END_EXTERN_C - * macros, so that the user need not know whether he is being used in C or C++ - * code. - * - * MOZ_BEGIN_EXTERN_C - * - * extern MOZ_EXPORT int MostRandomNumber(void); - * ...other declarations... - * - * MOZ_END_EXTERN_C - * - * This said, it is preferable to just use |extern "C"| in C++ header files for - * its greater clarity. - */ -#ifdef __cplusplus -# define MOZ_BEGIN_EXTERN_C extern "C" { -# define MOZ_END_EXTERN_C } -#else -# define MOZ_BEGIN_EXTERN_C -# define MOZ_END_EXTERN_C -#endif - -/* - * GCC's typeof is available when decltype is not. - */ -#if defined(__GNUC__) && defined(__cplusplus) && \ - !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L -# define decltype __typeof__ -#endif - -#endif /* mozilla_Types_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/UniquePtr.h b/android/arm64-v8a/include/spidermonkey/mozilla/UniquePtr.h deleted file mode 100644 index 7e1035bc..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/UniquePtr.h +++ /dev/null @@ -1,697 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Smart pointer managing sole ownership of a resource. */ - -#ifndef mozilla_UniquePtr_h -#define mozilla_UniquePtr_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Compiler.h" -#include "mozilla/Move.h" -#include "mozilla/Pair.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -template class DefaultDelete; -template> class UniquePtr; - -} // namespace mozilla - -namespace mozilla { - -namespace detail { - -struct HasPointerTypeHelper -{ - template static double Test(...); - template static char Test(typename U::pointer* = 0); -}; - -template -class HasPointerType : public IntegralConstant(0)) == 1> -{ -}; - -template ::value> -struct PointerTypeImpl -{ - typedef typename D::pointer Type; -}; - -template -struct PointerTypeImpl -{ - typedef T* Type; -}; - -template -struct PointerType -{ - typedef typename PointerTypeImpl::Type>::Type Type; -}; - -} // namespace detail - -/** - * UniquePtr is a smart pointer that wholly owns a resource. Ownership may be - * transferred out of a UniquePtr through explicit action, but otherwise the - * resource is destroyed when the UniquePtr is destroyed. - * - * UniquePtr is similar to C++98's std::auto_ptr, but it improves upon auto_ptr - * in one crucial way: it's impossible to copy a UniquePtr. Copying an auto_ptr - * obviously *can't* copy ownership of its singly-owned resource. So what - * happens if you try to copy one? Bizarrely, ownership is implicitly - * *transferred*, preserving single ownership but breaking code that assumes a - * copy of an object is identical to the original. (This is why auto_ptr is - * prohibited in STL containers.) - * - * UniquePtr solves this problem by being *movable* rather than copyable. - * Instead of passing a |UniquePtr u| directly to the constructor or assignment - * operator, you pass |Move(u)|. In doing so you indicate that you're *moving* - * ownership out of |u|, into the target of the construction/assignment. After - * the transfer completes, |u| contains |nullptr| and may be safely destroyed. - * This preserves single ownership but also allows UniquePtr to be moved by - * algorithms that have been made move-safe. (Note: if |u| is instead a - * temporary expression, don't use |Move()|: just pass the expression, because - * it's already move-ready. For more information see Move.h.) - * - * UniquePtr is also better than std::auto_ptr in that the deletion operation is - * customizable. An optional second template parameter specifies a class that - * (through its operator()(T*)) implements the desired deletion policy. If no - * policy is specified, mozilla::DefaultDelete is used -- which will either - * |delete| or |delete[]| the resource, depending whether the resource is an - * array. Custom deletion policies ideally should be empty classes (no member - * fields, no member fields in base classes, no virtual methods/inheritance), - * because then UniquePtr can be just as efficient as a raw pointer. - * - * Use of UniquePtr proceeds like so: - * - * UniquePtr g1; // initializes to nullptr - * g1.reset(new int); // switch resources using reset() - * g1 = nullptr; // clears g1, deletes the int - * - * UniquePtr g2(new int); // owns that int - * int* p = g2.release(); // g2 leaks its int -- still requires deletion - * delete p; // now freed - * - * struct S { int x; S(int x) : x(x) {} }; - * UniquePtr g3, g4(new S(5)); - * g3 = Move(g4); // g3 owns the S, g4 cleared - * S* p = g3.get(); // g3 still owns |p| - * assert(g3->x == 5); // operator-> works (if .get() != nullptr) - * assert((*g3).x == 5); // also operator* (again, if not cleared) - * Swap(g3, g4); // g4 now owns the S, g3 cleared - * g3.swap(g4); // g3 now owns the S, g4 cleared - * UniquePtr g5(Move(g3)); // g5 owns the S, g3 cleared - * g5.reset(); // deletes the S, g5 cleared - * - * struct FreePolicy { void operator()(void* p) { free(p); } }; - * UniquePtr g6(static_cast(malloc(sizeof(int)))); - * int* ptr = g6.get(); - * g6 = nullptr; // calls free(ptr) - * - * Now, carefully note a few things you *can't* do: - * - * UniquePtr b1; - * b1 = new int; // BAD: can only assign another UniquePtr - * int* ptr = b1; // BAD: no auto-conversion to pointer, use get() - * - * UniquePtr b2(b1); // BAD: can't copy a UniquePtr - * UniquePtr b3 = b1; // BAD: can't copy-assign a UniquePtr - * - * (Note that changing a UniquePtr to store a direct |new| expression is - * permitted, but usually you should use MakeUnique, defined at the end of this - * header.) - * - * A few miscellaneous notes: - * - * UniquePtr, when not instantiated for an array type, can be move-constructed - * and move-assigned, not only from itself but from "derived" UniquePtr - * instantiations where U converts to T and E converts to D. If you want to use - * this, you're going to have to specify a deletion policy for both UniquePtr - * instantations, and T pretty much has to have a virtual destructor. In other - * words, this doesn't work: - * - * struct Base { virtual ~Base() {} }; - * struct Derived : Base {}; - * - * UniquePtr b1; - * // BAD: DefaultDelete and DefaultDelete don't interconvert - * UniquePtr d1(Move(b)); - * - * UniquePtr b2; - * UniquePtr> d2(Move(b2)); // okay - * - * UniquePtr is specialized for array types. Specializing with an array type - * creates a smart-pointer version of that array -- not a pointer to such an - * array. - * - * UniquePtr arr(new int[5]); - * arr[0] = 4; - * - * What else is different? Deletion of course uses |delete[]|. An operator[] - * is provided. Functionality that doesn't make sense for arrays is removed. - * The constructors and mutating methods only accept array pointers (not T*, U* - * that converts to T*, or UniquePtr or UniquePtr) or |nullptr|. - * - * It's perfectly okay for a function to return a UniquePtr. This transfers - * the UniquePtr's sole ownership of the data, to the fresh UniquePtr created - * in the calling function, that will then solely own that data. Such functions - * can return a local variable UniquePtr, |nullptr|, |UniquePtr(ptr)| where - * |ptr| is a |T*|, or a UniquePtr |Move()|'d from elsewhere. - * - * UniquePtr will commonly be a member of a class, with lifetime equivalent to - * that of that class. If you want to expose the related resource, you could - * expose a raw pointer via |get()|, but ownership of a raw pointer is - * inherently unclear. So it's better to expose a |const UniquePtr&| instead. - * This prohibits mutation but still allows use of |get()| when needed (but - * operator-> is preferred). Of course, you can only use this smart pointer as - * long as the enclosing class instance remains live -- no different than if you - * exposed the |get()| raw pointer. - * - * To pass a UniquePtr-managed resource as a pointer, use a |const UniquePtr&| - * argument. To specify an inout parameter (where the method may or may not - * take ownership of the resource, or reset it), or to specify an out parameter - * (where simply returning a |UniquePtr| isn't possible), use a |UniquePtr&| - * argument. To unconditionally transfer ownership of a UniquePtr - * into a method, use a |UniquePtr| argument. To conditionally transfer - * ownership of a resource into a method, should the method want it, use a - * |UniquePtr&&| argument. - */ -template -class UniquePtr -{ -public: - typedef T ElementType; - typedef D DeleterType; - typedef typename detail::PointerType::Type Pointer; - -private: - Pair mTuple; - - Pointer& ptr() { return mTuple.first(); } - const Pointer& ptr() const { return mTuple.first(); } - - DeleterType& del() { return mTuple.second(); } - const DeleterType& del() const { return mTuple.second(); } - -public: - /** - * Construct a UniquePtr containing |nullptr|. - */ - constexpr UniquePtr() - : mTuple(static_cast(nullptr), DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - /** - * Construct a UniquePtr containing |aPtr|. - */ - explicit UniquePtr(Pointer aPtr) - : mTuple(aPtr, DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - UniquePtr(Pointer aPtr, - typename Conditional::value, - D, - const D&>::Type aD1) - : mTuple(aPtr, aD1) - {} - - // If you encounter an error with MSVC10 about RemoveReference below, along - // the lines that "more than one partial specialization matches the template - // argument list": don't use UniquePtr! Ideally - // you should make deletion use the same function every time, using a - // deleter policy: - // - // // BAD, won't compile with MSVC10, deleter doesn't need to be a - // // variable at all - // typedef void (&FreeSignature)(void*); - // UniquePtr ptr((int*) malloc(sizeof(int)), free); - // - // // GOOD, compiles with MSVC10, deletion behavior statically known and - // // optimizable - // struct DeleteByFreeing - // { - // void operator()(void* aPtr) { free(aPtr); } - // }; - // - // If deletion really, truly, must be a variable: you might be able to work - // around this with a deleter class that contains the function reference. - // But this workaround is untried and untested, because variable deletion - // behavior really isn't something you should use. - UniquePtr(Pointer aPtr, - typename RemoveReference::Type&& aD2) - : mTuple(aPtr, Move(aD2)) - { - static_assert(!IsReference::value, - "rvalue deleter can't be stored by reference"); - } - - UniquePtr(UniquePtr&& aOther) - : mTuple(aOther.release(), Forward(aOther.get_deleter())) - {} - - MOZ_IMPLICIT - UniquePtr(decltype(nullptr)) - : mTuple(nullptr, DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - template - MOZ_IMPLICIT - UniquePtr(UniquePtr&& aOther, - typename EnableIf::Pointer, - Pointer>::value && - !IsArray::value && - (IsReference::value - ? IsSame::value - : IsConvertible::value), - int>::Type aDummy = 0) - : mTuple(aOther.release(), Forward(aOther.get_deleter())) - { - } - - ~UniquePtr() { reset(nullptr); } - - UniquePtr& operator=(UniquePtr&& aOther) - { - reset(aOther.release()); - get_deleter() = Forward(aOther.get_deleter()); - return *this; - } - - template - UniquePtr& operator=(UniquePtr&& aOther) - { - static_assert(IsConvertible::Pointer, - Pointer>::value, - "incompatible UniquePtr pointees"); - static_assert(!IsArray::value, - "can't assign from UniquePtr holding an array"); - - reset(aOther.release()); - get_deleter() = Forward(aOther.get_deleter()); - return *this; - } - - UniquePtr& operator=(decltype(nullptr)) - { - reset(nullptr); - return *this; - } - - T& operator*() const { return *get(); } - Pointer operator->() const - { - MOZ_ASSERT(get(), "dereferencing a UniquePtr containing nullptr"); - return get(); - } - - explicit operator bool() const { return get() != nullptr; } - - Pointer get() const { return ptr(); } - - DeleterType& get_deleter() { return del(); } - const DeleterType& get_deleter() const { return del(); } - - MOZ_MUST_USE Pointer release() - { - Pointer p = ptr(); - ptr() = nullptr; - return p; - } - - void reset(Pointer aPtr = Pointer()) - { - Pointer old = ptr(); - ptr() = aPtr; - if (old != nullptr) { - get_deleter()(old); - } - } - - void swap(UniquePtr& aOther) - { - mTuple.swap(aOther.mTuple); - } - - UniquePtr(const UniquePtr& aOther) = delete; // construct using Move()! - void operator=(const UniquePtr& aOther) = delete; // assign using Move()! -}; - -// In case you didn't read the comment by the main definition (you should!): the -// UniquePtr specialization exists to manage array pointers. It deletes -// such pointers using delete[], it will reject construction and modification -// attempts using U* or U[]. Otherwise it works like the normal UniquePtr. -template -class UniquePtr -{ -public: - typedef T* Pointer; - typedef T ElementType; - typedef D DeleterType; - -private: - Pair mTuple; - -public: - /** - * Construct a UniquePtr containing nullptr. - */ - constexpr UniquePtr() - : mTuple(static_cast(nullptr), DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - /** - * Construct a UniquePtr containing |aPtr|. - */ - explicit UniquePtr(Pointer aPtr) - : mTuple(aPtr, DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - // delete[] knows how to handle *only* an array of a single class type. For - // delete[] to work correctly, it must know the size of each element, the - // fields and base classes of each element requiring destruction, and so on. - // So forbid all overloads which would end up invoking delete[] on a pointer - // of the wrong type. - template - UniquePtr(U&& aU, - typename EnableIf::value && - IsConvertible::value, - int>::Type aDummy = 0) - = delete; - - UniquePtr(Pointer aPtr, - typename Conditional::value, - D, - const D&>::Type aD1) - : mTuple(aPtr, aD1) - {} - - // If you encounter an error with MSVC10 about RemoveReference below, along - // the lines that "more than one partial specialization matches the template - // argument list": don't use UniquePtr! See the - // comment by this constructor in the non-T[] specialization above. - UniquePtr(Pointer aPtr, - typename RemoveReference::Type&& aD2) - : mTuple(aPtr, Move(aD2)) - { - static_assert(!IsReference::value, - "rvalue deleter can't be stored by reference"); - } - - // Forbidden for the same reasons as stated above. - template - UniquePtr(U&& aU, V&& aV, - typename EnableIf::value && - IsConvertible::value, - int>::Type aDummy = 0) - = delete; - - UniquePtr(UniquePtr&& aOther) - : mTuple(aOther.release(), Forward(aOther.get_deleter())) - {} - - MOZ_IMPLICIT - UniquePtr(decltype(nullptr)) - : mTuple(nullptr, DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - ~UniquePtr() { reset(nullptr); } - - UniquePtr& operator=(UniquePtr&& aOther) - { - reset(aOther.release()); - get_deleter() = Forward(aOther.get_deleter()); - return *this; - } - - UniquePtr& operator=(decltype(nullptr)) - { - reset(); - return *this; - } - - explicit operator bool() const { return get() != nullptr; } - - T& operator[](decltype(sizeof(int)) aIndex) const { return get()[aIndex]; } - Pointer get() const { return mTuple.first(); } - - DeleterType& get_deleter() { return mTuple.second(); } - const DeleterType& get_deleter() const { return mTuple.second(); } - - MOZ_MUST_USE Pointer release() - { - Pointer p = mTuple.first(); - mTuple.first() = nullptr; - return p; - } - - void reset(Pointer aPtr = Pointer()) - { - Pointer old = mTuple.first(); - mTuple.first() = aPtr; - if (old != nullptr) { - mTuple.second()(old); - } - } - - void reset(decltype(nullptr)) - { - Pointer old = mTuple.first(); - mTuple.first() = nullptr; - if (old != nullptr) { - mTuple.second()(old); - } - } - - template - void reset(U) = delete; - - void swap(UniquePtr& aOther) { mTuple.swap(aOther.mTuple); } - - UniquePtr(const UniquePtr& aOther) = delete; // construct using Move()! - void operator=(const UniquePtr& aOther) = delete; // assign using Move()! -}; - -/** - * A default deletion policy using plain old operator delete. - * - * Note that this type can be specialized, but authors should beware of the risk - * that the specialization may at some point cease to match (either because it - * gets moved to a different compilation unit or the signature changes). If the - * non-specialized (|delete|-based) version compiles for that type but does the - * wrong thing, bad things could happen. - * - * This is a non-issue for types which are always incomplete (i.e. opaque handle - * types), since |delete|-ing such a type will always trigger a compilation - * error. - */ -template -class DefaultDelete -{ -public: - constexpr DefaultDelete() {} - - template - MOZ_IMPLICIT DefaultDelete(const DefaultDelete& aOther, - typename EnableIf::value, - int>::Type aDummy = 0) - {} - - void operator()(T* aPtr) const - { - static_assert(sizeof(T) > 0, "T must be complete"); - delete aPtr; - } -}; - -/** A default deletion policy using operator delete[]. */ -template -class DefaultDelete -{ -public: - constexpr DefaultDelete() {} - - void operator()(T* aPtr) const - { - static_assert(sizeof(T) > 0, "T must be complete"); - delete[] aPtr; - } - - template - void operator()(U* aPtr) const = delete; -}; - -template -void -Swap(UniquePtr& aX, UniquePtr& aY) -{ - aX.swap(aY); -} - -template -bool -operator==(const UniquePtr& aX, const UniquePtr& aY) -{ - return aX.get() == aY.get(); -} - -template -bool -operator!=(const UniquePtr& aX, const UniquePtr& aY) -{ - return aX.get() != aY.get(); -} - -template -bool -operator==(const UniquePtr& aX, decltype(nullptr)) -{ - return !aX; -} - -template -bool -operator==(decltype(nullptr), const UniquePtr& aX) -{ - return !aX; -} - -template -bool -operator!=(const UniquePtr& aX, decltype(nullptr)) -{ - return bool(aX); -} - -template -bool -operator!=(decltype(nullptr), const UniquePtr& aX) -{ - return bool(aX); -} - -// No operator<, operator>, operator<=, operator>= for now because simplicity. - -namespace detail { - -template -struct UniqueSelector -{ - typedef UniquePtr SingleObject; -}; - -template -struct UniqueSelector -{ - typedef UniquePtr UnknownBound; -}; - -template -struct UniqueSelector -{ - typedef UniquePtr KnownBound; -}; - -} // namespace detail - -/** - * MakeUnique is a helper function for allocating new'd objects and arrays, - * returning a UniquePtr containing the resulting pointer. The semantics of - * MakeUnique(...) are as follows. - * - * If Type is an array T[n]: - * Disallowed, deleted, no overload for you! - * If Type is an array T[]: - * MakeUnique(size_t) is the only valid overload. The pointer returned - * is as if by |new T[n]()|, which value-initializes each element. (If T - * isn't a class type, this will zero each element. If T is a class type, - * then roughly speaking, each element will be constructed using its default - * constructor. See C++11 [dcl.init]p7 for the full gory details.) - * If Type is non-array T: - * The arguments passed to MakeUnique(...) are forwarded into a - * |new T(...)| call, initializing the T as would happen if executing - * |T(...)|. - * - * There are various benefits to using MakeUnique instead of |new| expressions. - * - * First, MakeUnique eliminates use of |new| from code entirely. If objects are - * only created through UniquePtr, then (assuming all explicit release() calls - * are safe, including transitively, and no type-safety casting funniness) - * correctly maintained ownership of the UniquePtr guarantees no leaks are - * possible. (This pays off best if a class is only ever created through a - * factory method on the class, using a private constructor.) - * - * Second, initializing a UniquePtr using a |new| expression requires repeating - * the name of the new'd type, whereas MakeUnique in concert with the |auto| - * keyword names it only once: - * - * UniquePtr ptr1(new char()); // repetitive - * auto ptr2 = MakeUnique(); // shorter - * - * Of course this assumes the reader understands the operation MakeUnique - * performs. In the long run this is probably a reasonable assumption. In the - * short run you'll have to use your judgment about what readers can be expected - * to know, or to quickly look up. - * - * Third, a call to MakeUnique can be assigned directly to a UniquePtr. In - * contrast you can't assign a pointer into a UniquePtr without using the - * cumbersome reset(). - * - * UniquePtr p; - * p = new char; // ERROR - * p.reset(new char); // works, but fugly - * p = MakeUnique(); // preferred - * - * (And third, although not relevant to Mozilla: MakeUnique is exception-safe. - * An exception thrown after |new T| succeeds will leak that memory, unless the - * pointer is assigned to an object that will manage its ownership. UniquePtr - * ably serves this function.) - */ - -template -typename detail::UniqueSelector::SingleObject -MakeUnique(Args&&... aArgs) -{ - return UniquePtr(new T(Forward(aArgs)...)); -} - -template -typename detail::UniqueSelector::UnknownBound -MakeUnique(decltype(sizeof(int)) aN) -{ - typedef typename RemoveExtent::Type ArrayType; - return UniquePtr(new ArrayType[aN]()); -} - -template -typename detail::UniqueSelector::KnownBound -MakeUnique(Args&&... aArgs) = delete; - -} // namespace mozilla - -#endif /* mozilla_UniquePtr_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/UniquePtrExtensions.h b/android/arm64-v8a/include/spidermonkey/mozilla/UniquePtrExtensions.h deleted file mode 100644 index d94f33ee..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/UniquePtrExtensions.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Useful extensions to UniquePtr. */ - -#ifndef mozilla_UniquePtrExtensions_h -#define mozilla_UniquePtrExtensions_h - -#include "mozilla/fallible.h" -#include "mozilla/UniquePtr.h" - -namespace mozilla { - -/** - * MakeUniqueFallible works exactly like MakeUnique, except that the memory - * allocation performed is done fallibly, i.e. it can return nullptr. - */ -template -typename detail::UniqueSelector::SingleObject -MakeUniqueFallible(Args&&... aArgs) -{ - return UniquePtr(new (fallible) T(Forward(aArgs)...)); -} - -template -typename detail::UniqueSelector::UnknownBound -MakeUniqueFallible(decltype(sizeof(int)) aN) -{ - typedef typename RemoveExtent::Type ArrayType; - return UniquePtr(new (fallible) ArrayType[aN]()); -} - -template -typename detail::UniqueSelector::KnownBound -MakeUniqueFallible(Args&&... aArgs) = delete; - -namespace detail { - -template -struct FreePolicy -{ - void operator()(const void* ptr) { - free(const_cast(ptr)); - } -}; - -} // namespace detail - -template -using UniqueFreePtr = UniquePtr>; - -} // namespace mozilla - -#endif // mozilla_UniquePtrExtensions_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Unused.h b/android/arm64-v8a/include/spidermonkey/mozilla/Unused.h deleted file mode 100644 index e693e32a..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Unused.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_unused_h -#define mozilla_unused_h - -#include "mozilla/Types.h" - -#ifdef __cplusplus - -namespace mozilla { - -// -// Suppress GCC warnings about unused return values with -// Unused << SomeFuncDeclaredWarnUnusedReturnValue(); -// -struct unused_t -{ - template - inline void - operator<<(const T& /*unused*/) const {} -}; - -extern MFBT_DATA const unused_t Unused; - -} // namespace mozilla - -#endif // __cplusplus - -// An alternative to mozilla::Unused for use in (a) C code and (b) code where -// linking with unused.o is difficult. -#define MOZ_UNUSED(expr) \ - do { if (expr) { (void)0; } } while (0) - -#endif // mozilla_unused_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Variant.h b/android/arm64-v8a/include/spidermonkey/mozilla/Variant.h deleted file mode 100644 index 8a33286e..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Variant.h +++ /dev/null @@ -1,625 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A template class for tagged unions. */ - -#include -#include - -#include "mozilla/Alignment.h" -#include "mozilla/Assertions.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -#ifndef mozilla_Variant_h -#define mozilla_Variant_h - -namespace mozilla { - -template -class Variant; - -namespace detail { - -// MaxSizeOf computes the maximum sizeof(T) for each T in Ts. - -template -struct MaxSizeOf -{ - static const size_t size = sizeof(T) > MaxSizeOf::size - ? sizeof(T) - : MaxSizeOf::size; -}; - -template -struct MaxSizeOf -{ - static const size_t size = sizeof(T); -}; - -// The `IsVariant` helper is used in conjunction with static_assert and -// `mozilla::EnableIf` to catch passing non-variant types to `Variant::is()` -// and friends at compile time, rather than at runtime. It ensures that the -// given type `Needle` is one of the types in the set of types `Haystack`. - -template -struct IsVariant; - -template -struct IsVariant -{ - static const bool value = false; -}; - -template -struct IsVariant -{ - static const bool value = true; -}; - -template -struct IsVariant : public IsVariant { }; - -/// SelectVariantTypeHelper is used in the implementation of SelectVariantType. -template -struct SelectVariantTypeHelper; - -template -struct SelectVariantTypeHelper -{ }; - -template -struct SelectVariantTypeHelper -{ - typedef T Type; -}; - -template -struct SelectVariantTypeHelper -{ - typedef const T Type; -}; - -template -struct SelectVariantTypeHelper -{ - typedef const T& Type; -}; - -template -struct SelectVariantTypeHelper -{ - typedef T&& Type; -}; - -template -struct SelectVariantTypeHelper - : public SelectVariantTypeHelper -{ }; - -/** - * SelectVariantType takes a type T and a list of variant types Variants and - * yields a type Type, selected from Variants, that can store a value of type T - * or a reference to type T. If no such type was found, Type is not defined. - */ -template -struct SelectVariantType - : public SelectVariantTypeHelper::Type>::Type, - Variants...> -{ }; - -// Compute a fast, compact type that can be used to hold integral values that -// distinctly map to every type in Ts. -template -struct VariantTag -{ -private: - static const size_t TypeCount = sizeof...(Ts); - -public: - using Type = - typename Conditional::Type - >::Type; -}; - -// TagHelper gets the given sentinel tag value for the given type T. This has to -// be split out from VariantImplementation because you can't nest a partial -// template specialization within a template class. - -template -struct TagHelper; - -// In the case where T != U, we continue recursion. -template -struct TagHelper -{ - static Tag tag() { return Next::template tag(); } -}; - -// In the case where T == U, return the tag number. -template -struct TagHelper -{ - static Tag tag() { return Tag(N); } -}; - -// The VariantImplementation template provides the guts of mozilla::Variant. We -// create a VariantImplementation for each T in Ts... which handles -// construction, destruction, etc for when the Variant's type is T. If the -// Variant's type isn't T, it punts the request on to the next -// VariantImplementation. - -template -struct VariantImplementation; - -// The singly typed Variant / recursion base case. -template -struct VariantImplementation -{ - template - static Tag tag() { - static_assert(mozilla::IsSame::value, - "mozilla::Variant: tag: bad type!"); - return Tag(N); - } - - template - static void copyConstruct(void* aLhs, const Variant& aRhs) { - new (aLhs) T(aRhs.template as()); - } - - template - static void moveConstruct(void* aLhs, Variant&& aRhs) { - new (aLhs) T(aRhs.template extract()); - } - - template - static void destroy(Variant& aV) { - aV.template as().~T(); - } - - template - static bool - equal(const Variant& aLhs, const Variant& aRhs) { - return aLhs.template as() == aRhs.template as(); - } - - template - static auto - match(Matcher&& aMatcher, ConcreteVariant& aV) - -> decltype(aMatcher.match(aV.template as())) - { - return aMatcher.match(aV.template as()); - } -}; - -// VariantImplementation for some variant type T. -template -struct VariantImplementation -{ - // The next recursive VariantImplementation. - using Next = VariantImplementation; - - template - static Tag tag() { - return TagHelper::value>::tag(); - } - - template - static void copyConstruct(void* aLhs, const Variant& aRhs) { - if (aRhs.template is()) { - new (aLhs) T(aRhs.template as()); - } else { - Next::copyConstruct(aLhs, aRhs); - } - } - - template - static void moveConstruct(void* aLhs, Variant&& aRhs) { - if (aRhs.template is()) { - new (aLhs) T(aRhs.template extract()); - } else { - Next::moveConstruct(aLhs, aRhs); - } - } - - template - static void destroy(Variant& aV) { - if (aV.template is()) { - aV.template as().~T(); - } else { - Next::destroy(aV); - } - } - - template - static bool equal(const Variant& aLhs, const Variant& aRhs) { - if (aLhs.template is()) { - MOZ_ASSERT(aRhs.template is()); - return aLhs.template as() == aRhs.template as(); - } else { - return Next::equal(aLhs, aRhs); - } - } - - template - static auto - match(Matcher&& aMatcher, ConcreteVariant& aV) - -> decltype(aMatcher.match(aV.template as())) - { - if (aV.template is()) { - return aMatcher.match(aV.template as()); - } else { - // If you're seeing compilation errors here like "no matching - // function for call to 'match'" then that means that the - // Matcher doesn't exhaust all variant types. There must exist a - // Matcher::match(T&) for every variant type T. - // - // If you're seeing compilation errors here like "cannot - // initialize return object of type <...> with an rvalue of type - // <...>" then that means that the Matcher::match(T&) overloads - // are returning different types. They must all return the same - // Matcher::ReturnType type. - return Next::match(aMatcher, aV); - } - } -}; - -/** - * AsVariantTemporary stores a value of type T to allow construction of a - * Variant value via type inference. Because T is copied and there's no - * guarantee that the copy can be elided, AsVariantTemporary is best used with - * primitive or very small types. - */ -template -struct AsVariantTemporary -{ - explicit AsVariantTemporary(const T& aValue) - : mValue(aValue) - {} - - template - explicit AsVariantTemporary(U&& aValue) - : mValue(Forward(aValue)) - {} - - AsVariantTemporary(const AsVariantTemporary& aOther) - : mValue(aOther.mValue) - {} - - AsVariantTemporary(AsVariantTemporary&& aOther) - : mValue(Move(aOther.mValue)) - {} - - AsVariantTemporary() = delete; - void operator=(const AsVariantTemporary&) = delete; - void operator=(AsVariantTemporary&&) = delete; - - typename RemoveConst::Type>::Type mValue; -}; - -} // namespace detail - -/** - * # mozilla::Variant - * - * A variant / tagged union / heterogenous disjoint union / sum-type template - * class. Similar in concept to (but not derived from) `boost::variant`. - * - * Sometimes, you may wish to use a C union with non-POD types. However, this is - * forbidden in C++ because it is not clear which type in the union should have - * its constructor and destructor run on creation and deletion - * respectively. This is the problem that `mozilla::Variant` solves. - * - * ## Usage - * - * A `mozilla::Variant` instance is constructed (via move or copy) from one of - * its variant types (ignoring const and references). It does *not* support - * construction from subclasses of variant types or types that coerce to one of - * the variant types. - * - * Variant v1('a'); - * Variant, B, C> v2(MakeUnique()); - * - * Because specifying the full type of a Variant value is often verbose, - * AsVariant() can be used to construct a Variant value using type inference in - * contexts such as expressions or when returning values from functions. Because - * AsVariant() must copy or move the value into a temporary and this cannot - * necessarily be elided by the compiler, it's mostly appropriate only for use - * with primitive or very small types. - * - * - * Variant Foo() { return AsVariant('x'); } - * // ... - * Variant v1 = Foo(); // v1 holds char('x'). - * - * All access to the contained value goes through type-safe accessors. - * - * void - * Foo(Variant v) - * { - * if (v.is()) { - * A& ref = v.as(); - * ... - * } else { - * ... - * } - * } - * - * Attempting to use the contained value as type `T1` when the `Variant` - * instance contains a value of type `T2` causes an assertion failure. - * - * A a; - * Variant v(a); - * v.as(); // <--- Assertion failure! - * - * Trying to use a `Variant` instance as some type `U` that is not a - * member of the set of `Ts...` is a compiler error. - * - * A a; - * Variant v(a); - * v.as(); // <--- Compiler error! - * - * Additionally, you can turn a `Variant` that `is` into a `T` by moving it - * out of the containing `Variant` instance with the `extract` method: - * - * Variant, B, C> v(MakeUnique()); - * auto ptr = v.extract>(); - * - * Finally, you can exhaustively match on the contained variant and branch into - * different code paths depending which type is contained. This is preferred to - * manually checking every variant type T with is() because it provides - * compile-time checking that you handled every type, rather than runtime - * assertion failures. - * - * // Bad! - * char* foo(Variant& v) { - * if (v.is()) { - * return ...; - * } else if (v.is()) { - * return ...; - * } else { - * return doSomething(v.as()); // Forgot about case D! - * } - * } - * - * // Good! - * struct FooMatcher - * { - * // The return type of all matchers must be identical. - * char* match(A& a) { ... } - * char* match(B& b) { ... } - * char* match(C& c) { ... } - * char* match(D& d) { ... } // Compile-time error to forget D! - * } - * char* foo(Variant& v) { - * return v.match(FooMatcher()); - * } - * - * ## Examples - * - * A tree is either an empty leaf, or a node with a value and two children: - * - * struct Leaf { }; - * - * template - * struct Node - * { - * T value; - * Tree* left; - * Tree* right; - * }; - * - * template - * using Tree = Variant>; - * - * A copy-on-write string is either a non-owning reference to some existing - * string, or an owning reference to our copy: - * - * class CopyOnWriteString - * { - * Variant> string; - * - * ... - * }; - */ -template -class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS Variant -{ - using Tag = typename detail::VariantTag::Type; - using Impl = detail::VariantImplementation; - using RawData = AlignedStorage::size>; - - // Raw storage for the contained variant value. - RawData raw; - - // Each type is given a unique tag value that lets us keep track of the - // contained variant value's type. - Tag tag; - - void* ptr() { - return reinterpret_cast(&raw); - } - -public: - /** Perfect forwarding construction for some variant type T. */ - template::Type> - explicit Variant(RefT&& aT) - : tag(Impl::template tag()) - { - new (ptr()) T(Forward(aT)); - } - - /** - * Constructs this Variant from an AsVariantTemporary such that T can be - * stored in one of the types allowable in this Variant. This is used in the - * implementation of AsVariant(). - */ - template::Type> - MOZ_IMPLICIT Variant(detail::AsVariantTemporary&& aValue) - : tag(Impl::template tag()) - { - new (ptr()) T(Move(aValue.mValue)); - } - - /** Copy construction. */ - Variant(const Variant& aRhs) - : tag(aRhs.tag) - { - Impl::copyConstruct(ptr(), aRhs); - } - - /** Move construction. */ - Variant(Variant&& aRhs) - : tag(aRhs.tag) - { - Impl::moveConstruct(ptr(), Move(aRhs)); - } - - /** Copy assignment. */ - Variant& operator=(const Variant& aRhs) { - MOZ_ASSERT(&aRhs != this, "self-assign disallowed"); - this->~Variant(); - new (this) Variant(aRhs); - return *this; - } - - /** Move assignment. */ - Variant& operator=(Variant&& aRhs) { - MOZ_ASSERT(&aRhs != this, "self-assign disallowed"); - this->~Variant(); - new (this) Variant(Move(aRhs)); - return *this; - } - - /** Move assignment from AsVariant(). */ - template - Variant& operator=(detail::AsVariantTemporary&& aValue) - { - this->~Variant(); - new (this) Variant(Move(aValue)); - return *this; - } - - ~Variant() - { - Impl::destroy(*this); - } - - /** Check which variant type is currently contained. */ - template - bool is() const { - static_assert(detail::IsVariant::value, - "provided a type not found in this Variant's type list"); - return Impl::template tag() == tag; - } - - /** - * Operator == overload that defers to the variant type's operator== - * implementation if the rhs is tagged as the same type as this one. - */ - bool operator==(const Variant& aRhs) const { - return tag == aRhs.tag && Impl::equal(*this, aRhs); - } - - /** - * Operator != overload that defers to the negation of the variant type's - * operator== implementation if the rhs is tagged as the same type as this - * one. - */ - bool operator!=(const Variant& aRhs) const { - return !(*this == aRhs); - } - - // Accessors for working with the contained variant value. - - /** Mutable reference. */ - template - T& as() { - static_assert(detail::IsVariant::value, - "provided a type not found in this Variant's type list"); - MOZ_ASSERT(is()); - return *reinterpret_cast(&raw); - } - - /** Immutable const reference. */ - template - const T& as() const { - static_assert(detail::IsVariant::value, - "provided a type not found in this Variant's type list"); - MOZ_ASSERT(is()); - return *reinterpret_cast(&raw); - } - - /** - * Extract the contained variant value from this container into a temporary - * value. On completion, the value in the variant will be in a - * safely-destructible state, as determined by the behavior of T's move - * constructor when provided the variant's internal value. - */ - template - T extract() { - static_assert(detail::IsVariant::value, - "provided a type not found in this Variant's type list"); - MOZ_ASSERT(is()); - return T(Move(as())); - } - - // Exhaustive matching of all variant types on the contained value. - - /** Match on an immutable const reference. */ - template - auto - match(Matcher&& aMatcher) const - -> decltype(Impl::match(aMatcher, *this)) - { - return Impl::match(aMatcher, *this); - } - - /** Match on a mutable non-const reference. */ - template - auto - match(Matcher&& aMatcher) - -> decltype(Impl::match(aMatcher, *this)) - { - return Impl::match(aMatcher, *this); - } -}; - -/* - * AsVariant() is used to construct a Variant value containing the - * provided T value using type inference. It can be used to construct Variant - * values in expressions or return them from functions without specifying the - * entire Variant type. - * - * Because AsVariant() must copy or move the value into a temporary and this - * cannot necessarily be elided by the compiler, it's mostly appropriate only - * for use with primitive or very small types. - * - * AsVariant() returns a AsVariantTemporary value which is implicitly - * convertible to any Variant that can hold a value of type T. - */ -template -detail::AsVariantTemporary -AsVariant(T&& aValue) -{ - return detail::AsVariantTemporary(Forward(aValue)); -} - -} // namespace mozilla - -#endif /* mozilla_Variant_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/Vector.h b/android/arm64-v8a/include/spidermonkey/mozilla/Vector.h deleted file mode 100644 index fc43afcf..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/Vector.h +++ /dev/null @@ -1,1491 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A type/length-parametrized vector class. */ - -#ifndef mozilla_Vector_h -#define mozilla_Vector_h - -#include "mozilla/Alignment.h" -#include "mozilla/AllocPolicy.h" -#include "mozilla/ArrayUtils.h" // for PointerRangeSize -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/MathAlgorithms.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" -#include "mozilla/OperatorNewExtensions.h" -#include "mozilla/ReentrancyGuard.h" -#include "mozilla/TemplateLib.h" -#include "mozilla/TypeTraits.h" - -#include // for placement new - -/* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */ -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4345) -#endif - -namespace mozilla { - -template -class Vector; - -namespace detail { - -/* - * Check that the given capacity wastes the minimal amount of space if - * allocated on the heap. This means that aCapacity*sizeof(T) is as close to a - * power-of-two as possible. growStorageBy() is responsible for ensuring this. - */ -template -static bool CapacityHasExcessSpace(size_t aCapacity) -{ - size_t size = aCapacity * sizeof(T); - return RoundUpPow2(size) - size >= sizeof(T); -} - -/* - * This template class provides a default implementation for vector operations - * when the element type is not known to be a POD, as judged by IsPod. - */ -template -struct VectorImpl -{ - /* - * Constructs an object in the uninitialized memory at *aDst with aArgs. - */ - template - MOZ_NONNULL(1) - static inline void new_(T* aDst, Args&&... aArgs) - { - new(KnownNotNull, aDst) T(Forward(aArgs)...); - } - - /* Destroys constructed objects in the range [aBegin, aEnd). */ - static inline void destroy(T* aBegin, T* aEnd) - { - MOZ_ASSERT(aBegin <= aEnd); - for (T* p = aBegin; p < aEnd; ++p) { - p->~T(); - } - } - - /* Constructs objects in the uninitialized range [aBegin, aEnd). */ - static inline void initialize(T* aBegin, T* aEnd) - { - MOZ_ASSERT(aBegin <= aEnd); - for (T* p = aBegin; p < aEnd; ++p) { - new_(p); - } - } - - /* - * Copy-constructs objects in the uninitialized range - * [aDst, aDst+(aSrcEnd-aSrcStart)) from the range [aSrcStart, aSrcEnd). - */ - template - static inline void copyConstruct(T* aDst, - const U* aSrcStart, const U* aSrcEnd) - { - MOZ_ASSERT(aSrcStart <= aSrcEnd); - for (const U* p = aSrcStart; p < aSrcEnd; ++p, ++aDst) { - new_(aDst, *p); - } - } - - /* - * Move-constructs objects in the uninitialized range - * [aDst, aDst+(aSrcEnd-aSrcStart)) from the range [aSrcStart, aSrcEnd). - */ - template - static inline void moveConstruct(T* aDst, U* aSrcStart, U* aSrcEnd) - { - MOZ_ASSERT(aSrcStart <= aSrcEnd); - for (U* p = aSrcStart; p < aSrcEnd; ++p, ++aDst) { - new_(aDst, Move(*p)); - } - } - - /* - * Copy-constructs objects in the uninitialized range [aDst, aDst+aN) from - * the same object aU. - */ - template - static inline void copyConstructN(T* aDst, size_t aN, const U& aU) - { - for (T* end = aDst + aN; aDst < end; ++aDst) { - new_(aDst, aU); - } - } - - /* - * Grows the given buffer to have capacity aNewCap, preserving the objects - * constructed in the range [begin, end) and updating aV. Assumes that (1) - * aNewCap has not overflowed, and (2) multiplying aNewCap by sizeof(T) will - * not overflow. - */ - static inline MOZ_MUST_USE bool - growTo(Vector& aV, size_t aNewCap) - { - MOZ_ASSERT(!aV.usingInlineStorage()); - MOZ_ASSERT(!CapacityHasExcessSpace(aNewCap)); - T* newbuf = aV.template pod_malloc(aNewCap); - if (MOZ_UNLIKELY(!newbuf)) { - return false; - } - T* dst = newbuf; - T* src = aV.beginNoCheck(); - for (; src < aV.endNoCheck(); ++dst, ++src) { - new_(dst, Move(*src)); - } - VectorImpl::destroy(aV.beginNoCheck(), aV.endNoCheck()); - aV.free_(aV.mBegin); - aV.mBegin = newbuf; - /* aV.mLength is unchanged. */ - aV.mCapacity = aNewCap; - return true; - } -}; - -/* - * This partial template specialization provides a default implementation for - * vector operations when the element type is known to be a POD, as judged by - * IsPod. - */ -template -struct VectorImpl -{ - template - MOZ_NONNULL(1) - static inline void new_(T* aDst, Args&&... aArgs) - { - // Explicitly construct a local object instead of using a temporary since - // T(args...) will be treated like a C-style cast in the unary case and - // allow unsafe conversions. Both forms should be equivalent to an - // optimizing compiler. - T temp(Forward(aArgs)...); - *aDst = temp; - } - - static inline void destroy(T*, T*) {} - - static inline void initialize(T* aBegin, T* aEnd) - { - /* - * You would think that memset would be a big win (or even break even) - * when we know T is a POD. But currently it's not. This is probably - * because |append| tends to be given small ranges and memset requires - * a function call that doesn't get inlined. - * - * memset(aBegin, 0, sizeof(T) * (aEnd - aBegin)); - */ - MOZ_ASSERT(aBegin <= aEnd); - for (T* p = aBegin; p < aEnd; ++p) { - new_(p); - } - } - - template - static inline void copyConstruct(T* aDst, - const U* aSrcStart, const U* aSrcEnd) - { - /* - * See above memset comment. Also, notice that copyConstruct is - * currently templated (T != U), so memcpy won't work without - * requiring T == U. - * - * memcpy(aDst, aSrcStart, sizeof(T) * (aSrcEnd - aSrcStart)); - */ - MOZ_ASSERT(aSrcStart <= aSrcEnd); - for (const U* p = aSrcStart; p < aSrcEnd; ++p, ++aDst) { - new_(aDst, *p); - } - } - - template - static inline void moveConstruct(T* aDst, - const U* aSrcStart, const U* aSrcEnd) - { - copyConstruct(aDst, aSrcStart, aSrcEnd); - } - - static inline void copyConstructN(T* aDst, size_t aN, const T& aT) - { - for (T* end = aDst + aN; aDst < end; ++aDst) { - new_(aDst, aT); - } - } - - static inline MOZ_MUST_USE bool - growTo(Vector& aV, size_t aNewCap) - { - MOZ_ASSERT(!aV.usingInlineStorage()); - MOZ_ASSERT(!CapacityHasExcessSpace(aNewCap)); - T* newbuf = aV.template pod_realloc(aV.mBegin, aV.mCapacity, aNewCap); - if (MOZ_UNLIKELY(!newbuf)) { - return false; - } - aV.mBegin = newbuf; - /* aV.mLength is unchanged. */ - aV.mCapacity = aNewCap; - return true; - } - - static inline void - podResizeToFit(Vector& aV) - { - if (aV.usingInlineStorage() || aV.mLength == aV.mCapacity) { - return; - } - T* newbuf = aV.template pod_realloc(aV.mBegin, aV.mCapacity, aV.mLength); - if (MOZ_UNLIKELY(!newbuf)) { - return; - } - aV.mBegin = newbuf; - aV.mCapacity = aV.mLength; - } -}; - -// A struct for TestVector.cpp to access private internal fields. -// DO NOT DEFINE IN YOUR OWN CODE. -struct VectorTesting; - -} // namespace detail - -/* - * STL-like container providing a short-lived, dynamic buffer. Vector calls the - * constructors/destructors of all elements stored in its internal buffer, so - * non-PODs may be safely used. Additionally, Vector will store the first N - * elements in-place before resorting to dynamic allocation. - * - * T requirements: - * - default and copy constructible, assignable, destructible - * - operations do not throw - * MinInlineCapacity requirements: - * - any value, however, MinInlineCapacity is clamped to min/max values - * AllocPolicy: - * - see "Allocation policies" in AllocPolicy.h (defaults to - * mozilla::MallocAllocPolicy) - * - * Vector is not reentrant: T member functions called during Vector member - * functions must not call back into the same object! - */ -template -class Vector final : private AllocPolicy -{ - /* utilities */ - - static const bool kElemIsPod = IsPod::value; - typedef detail::VectorImpl Impl; - friend struct detail::VectorImpl; - - friend struct detail::VectorTesting; - - MOZ_MUST_USE bool growStorageBy(size_t aIncr); - MOZ_MUST_USE bool convertToHeapStorage(size_t aNewCap); - MOZ_MUST_USE bool maybeCheckSimulatedOOM(size_t aRequestedSize); - - /* magic constants */ - - static const int kMaxInlineBytes = 1024; - - /* compute constants */ - - /* - * Consider element size to be 1 for buffer sizing if there are 0 inline - * elements. This allows us to compile when the definition of the element - * type is not visible here. - * - * Explicit specialization is only allowed at namespace scope, so in order - * to keep everything here, we use a dummy template parameter with partial - * specialization. - */ - template - struct ElemSize - { - static const size_t value = sizeof(T); - }; - template - struct ElemSize<0, Dummy> - { - static const size_t value = 1; - }; - - static const size_t kInlineCapacity = - tl::Min::value>::value; - - /* Calculate inline buffer size; avoid 0-sized array. */ - static const size_t kInlineBytes = - tl::Max<1, kInlineCapacity * ElemSize::value>::value; - - /* member data */ - - /* - * Pointer to the buffer, be it inline or heap-allocated. Only [mBegin, - * mBegin + mLength) hold valid constructed T objects. The range [mBegin + - * mLength, mBegin + mCapacity) holds uninitialized memory. The range - * [mBegin + mLength, mBegin + mReserved) also holds uninitialized memory - * previously allocated by a call to reserve(). - */ - T* mBegin; - - /* Number of elements in the vector. */ - size_t mLength; - - /* Max number of elements storable in the vector without resizing. */ - size_t mCapacity; - -#ifdef DEBUG - /* Max elements of reserved or used space in this vector. */ - size_t mReserved; -#endif - - /* Memory used for inline storage. */ - AlignedStorage mStorage; - -#ifdef DEBUG - friend class ReentrancyGuard; - bool mEntered; -#endif - - /* private accessors */ - - bool usingInlineStorage() const - { - return mBegin == const_cast(this)->inlineStorage(); - } - - T* inlineStorage() - { - return static_cast(mStorage.addr()); - } - - T* beginNoCheck() const - { - return mBegin; - } - - T* endNoCheck() - { - return mBegin + mLength; - } - - const T* endNoCheck() const - { - return mBegin + mLength; - } - -#ifdef DEBUG - /** - * The amount of explicitly allocated space in this vector that is immediately - * available to be filled by appending additional elements. This value is - * always greater than or equal to |length()| -- the vector's actual elements - * are implicitly reserved. This value is always less than or equal to - * |capacity()|. It may be explicitly increased using the |reserve()| method. - */ - size_t reserved() const - { - MOZ_ASSERT(mLength <= mReserved); - MOZ_ASSERT(mReserved <= mCapacity); - return mReserved; - } -#endif - - /* Append operations guaranteed to succeed due to pre-reserved space. */ - template void internalAppend(U&& aU); - template - void internalAppendAll(const Vector& aU); - void internalAppendN(const T& aT, size_t aN); - template void internalAppend(const U* aBegin, size_t aLength); - -public: - static const size_t sMaxInlineStorage = MinInlineCapacity; - - typedef T ElementType; - - explicit Vector(AllocPolicy = AllocPolicy()); - Vector(Vector&&); /* Move constructor. */ - Vector& operator=(Vector&&); /* Move assignment. */ - ~Vector(); - - /* accessors */ - - const AllocPolicy& allocPolicy() const { return *this; } - - AllocPolicy& allocPolicy() { return *this; } - - enum { InlineLength = MinInlineCapacity }; - - size_t length() const { return mLength; } - - bool empty() const { return mLength == 0; } - - size_t capacity() const { return mCapacity; } - - T* begin() - { - MOZ_ASSERT(!mEntered); - return mBegin; - } - - const T* begin() const - { - MOZ_ASSERT(!mEntered); - return mBegin; - } - - T* end() - { - MOZ_ASSERT(!mEntered); - return mBegin + mLength; - } - - const T* end() const - { - MOZ_ASSERT(!mEntered); - return mBegin + mLength; - } - - T& operator[](size_t aIndex) - { - MOZ_ASSERT(!mEntered); - MOZ_ASSERT(aIndex < mLength); - return begin()[aIndex]; - } - - const T& operator[](size_t aIndex) const - { - MOZ_ASSERT(!mEntered); - MOZ_ASSERT(aIndex < mLength); - return begin()[aIndex]; - } - - T& back() - { - MOZ_ASSERT(!mEntered); - MOZ_ASSERT(!empty()); - return *(end() - 1); - } - - const T& back() const - { - MOZ_ASSERT(!mEntered); - MOZ_ASSERT(!empty()); - return *(end() - 1); - } - - class Range - { - friend class Vector; - T* mCur; - T* mEnd; - Range(T* aCur, T* aEnd) - : mCur(aCur) - , mEnd(aEnd) - { - MOZ_ASSERT(aCur <= aEnd); - } - - public: - bool empty() const { return mCur == mEnd; } - size_t remain() const { return PointerRangeSize(mCur, mEnd); } - T& front() const { MOZ_ASSERT(!empty()); return *mCur; } - void popFront() { MOZ_ASSERT(!empty()); ++mCur; } - T popCopyFront() { MOZ_ASSERT(!empty()); return *mCur++; } - }; - - class ConstRange - { - friend class Vector; - const T* mCur; - const T* mEnd; - ConstRange(const T* aCur, const T* aEnd) - : mCur(aCur) - , mEnd(aEnd) - { - MOZ_ASSERT(aCur <= aEnd); - } - - public: - bool empty() const { return mCur == mEnd; } - size_t remain() const { return PointerRangeSize(mCur, mEnd); } - const T& front() const { MOZ_ASSERT(!empty()); return *mCur; } - void popFront() { MOZ_ASSERT(!empty()); ++mCur; } - T popCopyFront() { MOZ_ASSERT(!empty()); return *mCur++; } - }; - - Range all() { return Range(begin(), end()); } - ConstRange all() const { return ConstRange(begin(), end()); } - - /* mutators */ - - /** - * Reverse the order of the elements in the vector in place. - */ - void reverse(); - - /** - * Given that the vector is empty, grow the internal capacity to |aRequest|, - * keeping the length 0. - */ - MOZ_MUST_USE bool initCapacity(size_t aRequest); - - /** - * Given that the vector is empty, grow the internal capacity and length to - * |aRequest| leaving the elements' memory completely uninitialized (with all - * the associated hazards and caveats). This avoids the usual allocation-size - * rounding that happens in resize and overhead of initialization for elements - * that are about to be overwritten. - */ - MOZ_MUST_USE bool initLengthUninitialized(size_t aRequest); - - /** - * If reserve(aRequest) succeeds and |aRequest >= length()|, then appending - * |aRequest - length()| elements, in any sequence of append/appendAll calls, - * is guaranteed to succeed. - * - * A request to reserve an amount less than the current length does not affect - * reserved space. - */ - MOZ_MUST_USE bool reserve(size_t aRequest); - - /** - * Destroy elements in the range [end() - aIncr, end()). Does not deallocate - * or unreserve storage for those elements. - */ - void shrinkBy(size_t aIncr); - - /** - * Destroy elements in the range [aNewLength, end()). Does not deallocate - * or unreserve storage for those elements. - */ - void shrinkTo(size_t aNewLength); - - /** Grow the vector by aIncr elements. */ - MOZ_MUST_USE bool growBy(size_t aIncr); - - /** Call shrinkBy or growBy based on whether newSize > length(). */ - MOZ_MUST_USE bool resize(size_t aNewLength); - - /** - * Increase the length of the vector, but don't initialize the new elements - * -- leave them as uninitialized memory. - */ - MOZ_MUST_USE bool growByUninitialized(size_t aIncr); - void infallibleGrowByUninitialized(size_t aIncr); - MOZ_MUST_USE bool resizeUninitialized(size_t aNewLength); - - /** Shorthand for shrinkBy(length()). */ - void clear(); - - /** Clears and releases any heap-allocated storage. */ - void clearAndFree(); - - /** - * Calls the AllocPolicy's pod_realloc to release excess capacity. Since - * realloc is only safe on PODs, this method fails to compile if IsPod - * is false. - */ - void podResizeToFit(); - - /** - * If true, appending |aNeeded| elements won't reallocate elements storage. - * This *doesn't* mean that infallibleAppend may be used! You still must - * reserve the extra space, even if this method indicates that appends won't - * need to reallocate elements storage. - */ - bool canAppendWithoutRealloc(size_t aNeeded) const; - - /** Potentially fallible append operations. */ - - /** - * This can take either a T& or a T&&. Given a T&&, it moves |aU| into the - * vector, instead of copying it. If it fails, |aU| is left unmoved. ("We are - * not amused.") - */ - template MOZ_MUST_USE bool append(U&& aU); - - /** - * Construct a T in-place as a new entry at the end of this vector. - */ - template - MOZ_MUST_USE bool emplaceBack(Args&&... aArgs) - { - if (!growByUninitialized(1)) - return false; - Impl::new_(&back(), Forward(aArgs)...); - return true; - } - - template - MOZ_MUST_USE bool appendAll(const Vector& aU); - MOZ_MUST_USE bool appendN(const T& aT, size_t aN); - template MOZ_MUST_USE bool append(const U* aBegin, const U* aEnd); - template MOZ_MUST_USE bool append(const U* aBegin, size_t aLength); - - /* - * Guaranteed-infallible append operations for use upon vectors whose - * memory has been pre-reserved. Don't use this if you haven't reserved the - * memory! - */ - template void infallibleAppend(U&& aU) - { - internalAppend(Forward(aU)); - } - void infallibleAppendN(const T& aT, size_t aN) - { - internalAppendN(aT, aN); - } - template void infallibleAppend(const U* aBegin, const U* aEnd) - { - internalAppend(aBegin, PointerRangeSize(aBegin, aEnd)); - } - template void infallibleAppend(const U* aBegin, size_t aLength) - { - internalAppend(aBegin, aLength); - } - template - void infallibleEmplaceBack(Args&&... aArgs) - { - infallibleGrowByUninitialized(1); - Impl::new_(&back(), Forward(aArgs)...); - } - - void popBack(); - - T popCopy(); - - /** - * If elements are stored in-place, return nullptr and leave this vector - * unmodified. - * - * Otherwise return this vector's elements buffer, and clear this vector as if - * by clearAndFree(). The caller now owns the buffer and is responsible for - * deallocating it consistent with this vector's AllocPolicy. - * - * N.B. Although a T*, only the range [0, length()) is constructed. - */ - MOZ_MUST_USE T* extractRawBuffer(); - - /** - * If elements are stored in-place, allocate a new buffer, move this vector's - * elements into it, and return that buffer. - * - * Otherwise return this vector's elements buffer. The caller now owns the - * buffer and is responsible for deallocating it consistent with this vector's - * AllocPolicy. - * - * This vector is cleared, as if by clearAndFree(), when this method - * succeeds. This method fails and returns nullptr only if new elements buffer - * allocation fails. - * - * N.B. Only the range [0, length()) of the returned buffer is constructed. - * If any of these elements are uninitialized (as growByUninitialized - * enables), behavior is undefined. - */ - MOZ_MUST_USE T* extractOrCopyRawBuffer(); - - /** - * Transfer ownership of an array of objects into the vector. The caller - * must have allocated the array in accordance with this vector's - * AllocPolicy. - * - * N.B. This call assumes that there are no uninitialized elements in the - * passed array. - */ - void replaceRawBuffer(T* aP, size_t aLength); - - /** - * Places |aVal| at position |aP|, shifting existing elements from |aP| onward - * one position higher. On success, |aP| should not be reused because it'll - * be a dangling pointer if reallocation of the vector storage occurred; the - * return value should be used instead. On failure, nullptr is returned. - * - * Example usage: - * - * if (!(p = vec.insert(p, val))) { - * - * } - * - * - * This is inherently a linear-time operation. Be careful! - */ - template - MOZ_MUST_USE T* insert(T* aP, U&& aVal); - - /** - * Removes the element |aT|, which must fall in the bounds [begin, end), - * shifting existing elements from |aT + 1| onward one position lower. - */ - void erase(T* aT); - - /** - * Removes the elements [|aBegin|, |aEnd|), which must fall in the bounds - * [begin, end), shifting existing elements from |aEnd + 1| onward to aBegin's - * old position. - */ - void erase(T* aBegin, T* aEnd); - - /** - * Measure the size of the vector's heap-allocated storage. - */ - size_t sizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const; - - /** - * Like sizeOfExcludingThis, but also measures the size of the vector - * object (which must be heap-allocated) itself. - */ - size_t sizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const; - - void swap(Vector& aOther); - -private: - Vector(const Vector&) = delete; - void operator=(const Vector&) = delete; -}; - -/* This does the re-entrancy check plus several other sanity checks. */ -#define MOZ_REENTRANCY_GUARD_ET_AL \ - ReentrancyGuard g(*this); \ - MOZ_ASSERT_IF(usingInlineStorage(), mCapacity == kInlineCapacity); \ - MOZ_ASSERT(reserved() <= mCapacity); \ - MOZ_ASSERT(mLength <= reserved()); \ - MOZ_ASSERT(mLength <= mCapacity) - -/* Vector Implementation */ - -template -MOZ_ALWAYS_INLINE -Vector::Vector(AP aAP) - : AP(aAP) - , mLength(0) - , mCapacity(kInlineCapacity) -#ifdef DEBUG - , mReserved(0) - , mEntered(false) -#endif -{ - mBegin = static_cast(mStorage.addr()); -} - -/* Move constructor. */ -template -MOZ_ALWAYS_INLINE -Vector::Vector(Vector&& aRhs) - : AllocPolicy(Move(aRhs)) -#ifdef DEBUG - , mEntered(false) -#endif -{ - mLength = aRhs.mLength; - mCapacity = aRhs.mCapacity; -#ifdef DEBUG - mReserved = aRhs.mReserved; -#endif - - if (aRhs.usingInlineStorage()) { - /* We can't move the buffer over in this case, so copy elements. */ - mBegin = static_cast(mStorage.addr()); - Impl::moveConstruct(mBegin, aRhs.beginNoCheck(), aRhs.endNoCheck()); - /* - * Leave aRhs's mLength, mBegin, mCapacity, and mReserved as they are. - * The elements in its in-line storage still need to be destroyed. - */ - } else { - /* - * Take src's buffer, and turn src into an empty vector using - * in-line storage. - */ - mBegin = aRhs.mBegin; - aRhs.mBegin = static_cast(aRhs.mStorage.addr()); - aRhs.mCapacity = kInlineCapacity; - aRhs.mLength = 0; -#ifdef DEBUG - aRhs.mReserved = 0; -#endif - } -} - -/* Move assignment. */ -template -MOZ_ALWAYS_INLINE Vector& -Vector::operator=(Vector&& aRhs) -{ - MOZ_ASSERT(this != &aRhs, "self-move assignment is prohibited"); - this->~Vector(); - new(KnownNotNull, this) Vector(Move(aRhs)); - return *this; -} - -template -MOZ_ALWAYS_INLINE -Vector::~Vector() -{ - MOZ_REENTRANCY_GUARD_ET_AL; - Impl::destroy(beginNoCheck(), endNoCheck()); - if (!usingInlineStorage()) { - this->free_(beginNoCheck()); - } -} - -template -MOZ_ALWAYS_INLINE void -Vector::reverse() { - MOZ_REENTRANCY_GUARD_ET_AL; - T* elems = mBegin; - size_t len = mLength; - size_t mid = len / 2; - for (size_t i = 0; i < mid; i++) { - Swap(elems[i], elems[len - i - 1]); - } -} - -/* - * This function will create a new heap buffer with capacity aNewCap, - * move all elements in the inline buffer to this new buffer, - * and fail on OOM. - */ -template -inline bool -Vector::convertToHeapStorage(size_t aNewCap) -{ - MOZ_ASSERT(usingInlineStorage()); - - /* Allocate buffer. */ - MOZ_ASSERT(!detail::CapacityHasExcessSpace(aNewCap)); - T* newBuf = this->template pod_malloc(aNewCap); - if (MOZ_UNLIKELY(!newBuf)) { - return false; - } - - /* Copy inline elements into heap buffer. */ - Impl::moveConstruct(newBuf, beginNoCheck(), endNoCheck()); - Impl::destroy(beginNoCheck(), endNoCheck()); - - /* Switch in heap buffer. */ - mBegin = newBuf; - /* mLength is unchanged. */ - mCapacity = aNewCap; - return true; -} - -template -MOZ_NEVER_INLINE bool -Vector::growStorageBy(size_t aIncr) -{ - MOZ_ASSERT(mLength + aIncr > mCapacity); - - /* - * When choosing a new capacity, its size should is as close to 2**N bytes - * as possible. 2**N-sized requests are best because they are unlikely to - * be rounded up by the allocator. Asking for a 2**N number of elements - * isn't as good, because if sizeof(T) is not a power-of-two that would - * result in a non-2**N request size. - */ - - size_t newCap; - - if (aIncr == 1) { - if (usingInlineStorage()) { - /* This case occurs in ~70--80% of the calls to this function. */ - size_t newSize = - tl::RoundUpPow2<(kInlineCapacity + 1) * sizeof(T)>::value; - newCap = newSize / sizeof(T); - goto convert; - } - - if (mLength == 0) { - /* This case occurs in ~0--10% of the calls to this function. */ - newCap = 1; - goto grow; - } - - /* This case occurs in ~15--20% of the calls to this function. */ - - /* - * Will mLength * 4 *sizeof(T) overflow? This condition limits a vector - * to 1GB of memory on a 32-bit system, which is a reasonable limit. It - * also ensures that - * - * static_cast(end()) - static_cast(begin()) - * - * doesn't overflow ptrdiff_t (see bug 510319). - */ - if (MOZ_UNLIKELY(mLength & tl::MulOverflowMask<4 * sizeof(T)>::value)) { - this->reportAllocOverflow(); - return false; - } - - /* - * If we reach here, the existing capacity will have a size that is already - * as close to 2^N as sizeof(T) will allow. Just double the capacity, and - * then there might be space for one more element. - */ - newCap = mLength * 2; - if (detail::CapacityHasExcessSpace(newCap)) { - newCap += 1; - } - } else { - /* This case occurs in ~2% of the calls to this function. */ - size_t newMinCap = mLength + aIncr; - - /* Did mLength + aIncr overflow? Will newCap * sizeof(T) overflow? */ - if (MOZ_UNLIKELY(newMinCap < mLength || - newMinCap & tl::MulOverflowMask<2 * sizeof(T)>::value)) - { - this->reportAllocOverflow(); - return false; - } - - size_t newMinSize = newMinCap * sizeof(T); - size_t newSize = RoundUpPow2(newMinSize); - newCap = newSize / sizeof(T); - } - - if (usingInlineStorage()) { -convert: - return convertToHeapStorage(newCap); - } - -grow: - return Impl::growTo(*this, newCap); -} - -template -inline bool -Vector::initCapacity(size_t aRequest) -{ - MOZ_ASSERT(empty()); - MOZ_ASSERT(usingInlineStorage()); - if (aRequest == 0) { - return true; - } - T* newbuf = this->template pod_malloc(aRequest); - if (MOZ_UNLIKELY(!newbuf)) { - return false; - } - mBegin = newbuf; - mCapacity = aRequest; -#ifdef DEBUG - mReserved = aRequest; -#endif - return true; -} - -template -inline bool -Vector::initLengthUninitialized(size_t aRequest) -{ - if (!initCapacity(aRequest)) { - return false; - } - infallibleGrowByUninitialized(aRequest); - return true; -} - -template -inline bool -Vector::maybeCheckSimulatedOOM(size_t aRequestedSize) -{ - if (aRequestedSize <= N) { - return true; - } - -#ifdef DEBUG - if (aRequestedSize <= mReserved) { - return true; - } -#endif - - return allocPolicy().checkSimulatedOOM(); -} - -template -inline bool -Vector::reserve(size_t aRequest) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - if (aRequest > mCapacity) { - if (MOZ_UNLIKELY(!growStorageBy(aRequest - mLength))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(aRequest)) { - return false; - } -#ifdef DEBUG - if (aRequest > mReserved) { - mReserved = aRequest; - } - MOZ_ASSERT(mLength <= mReserved); - MOZ_ASSERT(mReserved <= mCapacity); -#endif - return true; -} - -template -inline void -Vector::shrinkBy(size_t aIncr) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - MOZ_ASSERT(aIncr <= mLength); - Impl::destroy(endNoCheck() - aIncr, endNoCheck()); - mLength -= aIncr; -} - -template -MOZ_ALWAYS_INLINE void -Vector::shrinkTo(size_t aNewLength) -{ - MOZ_ASSERT(aNewLength <= mLength); - shrinkBy(mLength - aNewLength); -} - -template -MOZ_ALWAYS_INLINE bool -Vector::growBy(size_t aIncr) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - if (aIncr > mCapacity - mLength) { - if (MOZ_UNLIKELY(!growStorageBy(aIncr))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(mLength + aIncr)) { - return false; - } - MOZ_ASSERT(mLength + aIncr <= mCapacity); - T* newend = endNoCheck() + aIncr; - Impl::initialize(endNoCheck(), newend); - mLength += aIncr; -#ifdef DEBUG - if (mLength > mReserved) { - mReserved = mLength; - } -#endif - return true; -} - -template -MOZ_ALWAYS_INLINE bool -Vector::growByUninitialized(size_t aIncr) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - if (aIncr > mCapacity - mLength) { - if (MOZ_UNLIKELY(!growStorageBy(aIncr))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(mLength + aIncr)) { - return false; - } -#ifdef DEBUG - if (mLength + aIncr > mReserved) { - mReserved = mLength + aIncr; - } -#endif - infallibleGrowByUninitialized(aIncr); - return true; -} - -template -MOZ_ALWAYS_INLINE void -Vector::infallibleGrowByUninitialized(size_t aIncr) -{ - MOZ_ASSERT(mLength + aIncr <= reserved()); - mLength += aIncr; -} - -template -inline bool -Vector::resize(size_t aNewLength) -{ - size_t curLength = mLength; - if (aNewLength > curLength) { - return growBy(aNewLength - curLength); - } - shrinkBy(curLength - aNewLength); - return true; -} - -template -MOZ_ALWAYS_INLINE bool -Vector::resizeUninitialized(size_t aNewLength) -{ - size_t curLength = mLength; - if (aNewLength > curLength) { - return growByUninitialized(aNewLength - curLength); - } - shrinkBy(curLength - aNewLength); - return true; -} - -template -inline void -Vector::clear() -{ - MOZ_REENTRANCY_GUARD_ET_AL; - Impl::destroy(beginNoCheck(), endNoCheck()); - mLength = 0; -} - -template -inline void -Vector::clearAndFree() -{ - clear(); - - if (usingInlineStorage()) { - return; - } - this->free_(beginNoCheck()); - mBegin = static_cast(mStorage.addr()); - mCapacity = kInlineCapacity; -#ifdef DEBUG - mReserved = 0; -#endif -} - -template -inline void -Vector::podResizeToFit() -{ - // This function is only defined if IsPod is true and will fail to compile - // otherwise. - Impl::podResizeToFit(*this); -} - -template -inline bool -Vector::canAppendWithoutRealloc(size_t aNeeded) const -{ - return mLength + aNeeded <= mCapacity; -} - -template -template -MOZ_ALWAYS_INLINE void -Vector::internalAppendAll(const Vector& aOther) -{ - internalAppend(aOther.begin(), aOther.length()); -} - -template -template -MOZ_ALWAYS_INLINE void -Vector::internalAppend(U&& aU) -{ - MOZ_ASSERT(mLength + 1 <= mReserved); - MOZ_ASSERT(mReserved <= mCapacity); - Impl::new_(endNoCheck(), Forward(aU)); - ++mLength; -} - -template -MOZ_ALWAYS_INLINE bool -Vector::appendN(const T& aT, size_t aNeeded) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - if (mLength + aNeeded > mCapacity) { - if (MOZ_UNLIKELY(!growStorageBy(aNeeded))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(mLength + aNeeded)) { - return false; - } -#ifdef DEBUG - if (mLength + aNeeded > mReserved) { - mReserved = mLength + aNeeded; - } -#endif - internalAppendN(aT, aNeeded); - return true; -} - -template -MOZ_ALWAYS_INLINE void -Vector::internalAppendN(const T& aT, size_t aNeeded) -{ - MOZ_ASSERT(mLength + aNeeded <= mReserved); - MOZ_ASSERT(mReserved <= mCapacity); - Impl::copyConstructN(endNoCheck(), aNeeded, aT); - mLength += aNeeded; -} - -template -template -inline T* -Vector::insert(T* aP, U&& aVal) -{ - MOZ_ASSERT(begin() <= aP); - MOZ_ASSERT(aP <= end()); - size_t pos = aP - begin(); - MOZ_ASSERT(pos <= mLength); - size_t oldLength = mLength; - if (pos == oldLength) { - if (!append(Forward(aVal))) { - return nullptr; - } - } else { - T oldBack = Move(back()); - if (!append(Move(oldBack))) { /* Dup the last element. */ - return nullptr; - } - for (size_t i = oldLength; i > pos; --i) { - (*this)[i] = Move((*this)[i - 1]); - } - (*this)[pos] = Forward(aVal); - } - return begin() + pos; -} - -template -inline void -Vector::erase(T* aIt) -{ - MOZ_ASSERT(begin() <= aIt); - MOZ_ASSERT(aIt < end()); - while (aIt + 1 < end()) { - *aIt = Move(*(aIt + 1)); - ++aIt; - } - popBack(); -} - -template -inline void -Vector::erase(T* aBegin, T* aEnd) -{ - MOZ_ASSERT(begin() <= aBegin); - MOZ_ASSERT(aBegin <= aEnd); - MOZ_ASSERT(aEnd <= end()); - while (aEnd < end()) { - *aBegin++ = Move(*aEnd++); - } - shrinkBy(aEnd - aBegin); -} - -template -template -MOZ_ALWAYS_INLINE bool -Vector::append(const U* aInsBegin, const U* aInsEnd) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - size_t aNeeded = PointerRangeSize(aInsBegin, aInsEnd); - if (mLength + aNeeded > mCapacity) { - if (MOZ_UNLIKELY(!growStorageBy(aNeeded))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(mLength + aNeeded)) { - return false; - } -#ifdef DEBUG - if (mLength + aNeeded > mReserved) { - mReserved = mLength + aNeeded; - } -#endif - internalAppend(aInsBegin, aNeeded); - return true; -} - -template -template -MOZ_ALWAYS_INLINE void -Vector::internalAppend(const U* aInsBegin, size_t aInsLength) -{ - MOZ_ASSERT(mLength + aInsLength <= mReserved); - MOZ_ASSERT(mReserved <= mCapacity); - Impl::copyConstruct(endNoCheck(), aInsBegin, aInsBegin + aInsLength); - mLength += aInsLength; -} - -template -template -MOZ_ALWAYS_INLINE bool -Vector::append(U&& aU) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - if (mLength == mCapacity) { - if (MOZ_UNLIKELY(!growStorageBy(1))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(mLength + 1)) { - return false; - } -#ifdef DEBUG - if (mLength + 1 > mReserved) { - mReserved = mLength + 1; - } -#endif - internalAppend(Forward(aU)); - return true; -} - -template -template -MOZ_ALWAYS_INLINE bool -Vector::appendAll(const Vector& aOther) -{ - return append(aOther.begin(), aOther.length()); -} - -template -template -MOZ_ALWAYS_INLINE bool -Vector::append(const U* aInsBegin, size_t aInsLength) -{ - return append(aInsBegin, aInsBegin + aInsLength); -} - -template -MOZ_ALWAYS_INLINE void -Vector::popBack() -{ - MOZ_REENTRANCY_GUARD_ET_AL; - MOZ_ASSERT(!empty()); - --mLength; - endNoCheck()->~T(); -} - -template -MOZ_ALWAYS_INLINE T -Vector::popCopy() -{ - T ret = back(); - popBack(); - return ret; -} - -template -inline T* -Vector::extractRawBuffer() -{ - MOZ_REENTRANCY_GUARD_ET_AL; - - if (usingInlineStorage()) { - return nullptr; - } - - T* ret = mBegin; - mBegin = static_cast(mStorage.addr()); - mLength = 0; - mCapacity = kInlineCapacity; -#ifdef DEBUG - mReserved = 0; -#endif - return ret; -} - -template -inline T* -Vector::extractOrCopyRawBuffer() -{ - if (T* ret = extractRawBuffer()) { - return ret; - } - - MOZ_REENTRANCY_GUARD_ET_AL; - - T* copy = this->template pod_malloc(mLength); - if (!copy) { - return nullptr; - } - - Impl::moveConstruct(copy, beginNoCheck(), endNoCheck()); - Impl::destroy(beginNoCheck(), endNoCheck()); - mBegin = static_cast(mStorage.addr()); - mLength = 0; - mCapacity = kInlineCapacity; -#ifdef DEBUG - mReserved = 0; -#endif - return copy; -} - -template -inline void -Vector::replaceRawBuffer(T* aP, size_t aLength) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - - /* Destroy what we have. */ - Impl::destroy(beginNoCheck(), endNoCheck()); - if (!usingInlineStorage()) { - this->free_(beginNoCheck()); - } - - /* Take in the new buffer. */ - if (aLength <= kInlineCapacity) { - /* - * We convert to inline storage if possible, even though aP might - * otherwise be acceptable. Maybe this behaviour should be - * specifiable with an argument to this function. - */ - mBegin = static_cast(mStorage.addr()); - mLength = aLength; - mCapacity = kInlineCapacity; - Impl::moveConstruct(mBegin, aP, aP + aLength); - Impl::destroy(aP, aP + aLength); - this->free_(aP); - } else { - mBegin = aP; - mLength = aLength; - mCapacity = aLength; - } -#ifdef DEBUG - mReserved = aLength; -#endif -} - -template -inline size_t -Vector::sizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const -{ - return usingInlineStorage() ? 0 : aMallocSizeOf(beginNoCheck()); -} - -template -inline size_t -Vector::sizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const -{ - return aMallocSizeOf(this) + sizeOfExcludingThis(aMallocSizeOf); -} - -template -inline void -Vector::swap(Vector& aOther) -{ - static_assert(N == 0, - "still need to implement this for N != 0"); - - // This only works when inline storage is always empty. - if (!usingInlineStorage() && aOther.usingInlineStorage()) { - aOther.mBegin = mBegin; - mBegin = inlineStorage(); - } else if (usingInlineStorage() && !aOther.usingInlineStorage()) { - mBegin = aOther.mBegin; - aOther.mBegin = aOther.inlineStorage(); - } else if (!usingInlineStorage() && !aOther.usingInlineStorage()) { - Swap(mBegin, aOther.mBegin); - } else { - // This case is a no-op, since we'd set both to use their inline storage. - } - - Swap(mLength, aOther.mLength); - Swap(mCapacity, aOther.mCapacity); -#ifdef DEBUG - Swap(mReserved, aOther.mReserved); -#endif -} - -} // namespace mozilla - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#endif /* mozilla_Vector_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/WeakPtr.h b/android/arm64-v8a/include/spidermonkey/mozilla/WeakPtr.h deleted file mode 100644 index ef0c19f4..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/WeakPtr.h +++ /dev/null @@ -1,283 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Weak pointer functionality, implemented as a mixin for use with any class. */ - -/** - * SupportsWeakPtr lets you have a pointer to an object 'Foo' without affecting - * its lifetime. It works by creating a single shared reference counted object - * (WeakReference) that each WeakPtr will access 'Foo' through. This lets 'Foo' - * clear the pointer in the WeakReference without having to know about all of - * the WeakPtrs to it and allows the WeakReference to live beyond the lifetime - * of 'Foo'. - * - * PLEASE NOTE: This weak pointer implementation is not thread-safe. - * - * Note that when deriving from SupportsWeakPtr you should add - * MOZ_DECLARE_WEAKREFERENCE_TYPENAME(ClassName) to the public section of your - * class, where ClassName is the name of your class. - * - * The overhead of WeakPtr is that accesses to 'Foo' becomes an additional - * dereference, and an additional heap allocated pointer sized object shared - * between all of the WeakPtrs. - * - * Example of usage: - * - * // To have a class C support weak pointers, inherit from - * // SupportsWeakPtr. - * class C : public SupportsWeakPtr - * { - * public: - * MOZ_DECLARE_WEAKREFERENCE_TYPENAME(C) - * int mNum; - * void act(); - * }; - * - * C* ptr = new C(); - * - * // Get weak pointers to ptr. The first time a weak pointer - * // is obtained, a reference counted WeakReference object is created that - * // can live beyond the lifetime of 'ptr'. The WeakReference - * // object will be notified of 'ptr's destruction. - * WeakPtr weak = ptr; - * WeakPtr other = ptr; - * - * // Test a weak pointer for validity before using it. - * if (weak) { - * weak->mNum = 17; - * weak->act(); - * } - * - * // Destroying the underlying object clears weak pointers to it. - * delete ptr; - * - * MOZ_ASSERT(!weak, "Deleting |ptr| clears weak pointers to it."); - * MOZ_ASSERT(!other, "Deleting |ptr| clears all weak pointers to it."); - * - * WeakPtr is typesafe and may be used with any class. It is not required that - * the class be reference-counted or allocated in any particular way. - * - * The API was loosely inspired by Chromium's weak_ptr.h: - * http://src.chromium.org/svn/trunk/src/base/memory/weak_ptr.h - */ - -#ifndef mozilla_WeakPtr_h -#define mozilla_WeakPtr_h - -#include "mozilla/ArrayUtils.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/RefCounted.h" -#include "mozilla/RefPtr.h" -#include "mozilla/TypeTraits.h" - -#include - -// Weak referencing is not implemeted as thread safe. When a WeakPtr -// is created or dereferenced on thread A but the real object is just -// being Released() on thread B, there is a possibility of a race -// when the proxy object (detail::WeakReference) is notified about -// the real object destruction just between when thread A is storing -// the object pointer locally and is about to add a reference to it. -// -// Hence, a non-null weak proxy object is considered to have a single -// "owning thread". It means that each query for a weak reference, -// its dereference, and destruction of the real object must all happen -// on a single thread. The following macros implement assertions for -// checking these conditions. -// -// We disable this on MinGW. MinGW has two threading models: win32 -// API based, which disables std::thread; and POSIX based which -// enables it but requires an emulation library (winpthreads). -// Rather than attempting to switch to pthread emulation at this point, -// we are disabling the std::thread based assertion checking. -// -// In the future, to enable it we could -// a. have libgcc/stdc++ support win32 threads natively -// b. switch to POSIX-based threading in MinGW with pthread emulation -// c. refactor it to not use std::thread - -#if !defined(__MINGW32__) && (defined(DEBUG) || (defined(NIGHTLY_BUILD) && !defined(MOZ_PROFILING))) - -#include -#define MOZ_WEAKPTR_DECLARE_THREAD_SAFETY_CHECK \ - std::thread::id _owningThread; \ - bool _empty; // If it was initialized as a placeholder with mPtr = nullptr. -#define MOZ_WEAKPTR_INIT_THREAD_SAFETY_CHECK() \ - do { \ - _owningThread = std::this_thread::get_id(); \ - _empty = !p; \ - } while (false) -#define MOZ_WEAKPTR_ASSERT_THREAD_SAFETY() \ - MOZ_DIAGNOSTIC_ASSERT(_empty || _owningThread == std::this_thread::get_id(), \ - "WeakPtr used on multiple threads") -#define MOZ_WEAKPTR_ASSERT_THREAD_SAFETY_DELEGATED(that) \ - (that)->AssertThreadSafety(); - -#define MOZ_WEAKPTR_THREAD_SAFETY_CHECKING 1 - -#else - -#define MOZ_WEAKPTR_DECLARE_THREAD_SAFETY_CHECK -#define MOZ_WEAKPTR_INIT_THREAD_SAFETY_CHECK() do { } while (false) -#define MOZ_WEAKPTR_ASSERT_THREAD_SAFETY() do { } while (false) -#define MOZ_WEAKPTR_ASSERT_THREAD_SAFETY_DELEGATED(that) do { } while (false) - -#endif - -namespace mozilla { - -template class WeakPtr; -template class SupportsWeakPtr; - -#ifdef MOZ_REFCOUNTED_LEAK_CHECKING -#define MOZ_DECLARE_WEAKREFERENCE_TYPENAME(T) \ - static const char* weakReferenceTypeName() { return "WeakReference<" #T ">"; } -#else -#define MOZ_DECLARE_WEAKREFERENCE_TYPENAME(T) -#endif - -namespace detail { - -// This can live beyond the lifetime of the class derived from -// SupportsWeakPtr. -template -class WeakReference : public ::mozilla::RefCounted > -{ -public: - explicit WeakReference(T* p) : mPtr(p) - { - MOZ_WEAKPTR_INIT_THREAD_SAFETY_CHECK(); - } - - T* get() const { - MOZ_WEAKPTR_ASSERT_THREAD_SAFETY(); - return mPtr; - } - -#ifdef MOZ_REFCOUNTED_LEAK_CHECKING - const char* typeName() const - { - // The first time this is called mPtr is null, so don't - // invoke any methods on mPtr. - return T::weakReferenceTypeName(); - } - size_t typeSize() const { return sizeof(*this); } -#endif - -#ifdef MOZ_WEAKPTR_THREAD_SAFETY_CHECKING - void AssertThreadSafety() { MOZ_WEAKPTR_ASSERT_THREAD_SAFETY(); } -#endif - -private: - friend class mozilla::SupportsWeakPtr; - - void detach() { - MOZ_WEAKPTR_ASSERT_THREAD_SAFETY(); - mPtr = nullptr; - } - - T* MOZ_NON_OWNING_REF mPtr; - MOZ_WEAKPTR_DECLARE_THREAD_SAFETY_CHECK -}; - -} // namespace detail - -template -class SupportsWeakPtr -{ -protected: - ~SupportsWeakPtr() - { - static_assert(IsBaseOf, T>::value, - "T must derive from SupportsWeakPtr"); - if (mSelfReferencingWeakPtr) { - mSelfReferencingWeakPtr.mRef->detach(); - } - } - -private: - const WeakPtr& SelfReferencingWeakPtr() - { - if (!mSelfReferencingWeakPtr) { - mSelfReferencingWeakPtr.mRef = new detail::WeakReference(static_cast(this)); - } else { - MOZ_WEAKPTR_ASSERT_THREAD_SAFETY_DELEGATED(mSelfReferencingWeakPtr.mRef); - } - return mSelfReferencingWeakPtr; - } - - const WeakPtr& SelfReferencingWeakPtr() const - { - const WeakPtr& p = const_cast(this)->SelfReferencingWeakPtr(); - return reinterpret_cast&>(p); - } - - friend class WeakPtr; - friend class WeakPtr; - - WeakPtr mSelfReferencingWeakPtr; -}; - -template -class WeakPtr -{ - typedef detail::WeakReference WeakReference; - -public: - WeakPtr& operator=(const WeakPtr& aOther) - { - mRef = aOther.mRef; - MOZ_WEAKPTR_ASSERT_THREAD_SAFETY_DELEGATED(mRef); - return *this; - } - - WeakPtr(const WeakPtr& aOther) - { - // The thread safety check is performed inside of the operator= method. - *this = aOther; - } - - WeakPtr& operator=(T* aOther) - { - if (aOther) { - *this = aOther->SelfReferencingWeakPtr(); - } else if (!mRef || mRef->get()) { - // Ensure that mRef is dereferenceable in the uninitialized state. - mRef = new WeakReference(nullptr); - } - // The thread safety check happens inside SelfReferencingWeakPtr - // or is initialized in the WeakReference constructor. - return *this; - } - - MOZ_IMPLICIT WeakPtr(T* aOther) - { - *this = aOther; - MOZ_WEAKPTR_ASSERT_THREAD_SAFETY_DELEGATED(mRef); - } - - // Ensure that mRef is dereferenceable in the uninitialized state. - WeakPtr() : mRef(new WeakReference(nullptr)) {} - - operator T*() const { return mRef->get(); } - T& operator*() const { return *mRef->get(); } - - T* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN { return mRef->get(); } - - T* get() const { return mRef->get(); } - -private: - friend class SupportsWeakPtr; - - explicit WeakPtr(const RefPtr& aOther) : mRef(aOther) {} - - RefPtr mRef; -}; - -} // namespace mozilla - -#endif /* mozilla_WeakPtr_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/XorShift128PlusRNG.h b/android/arm64-v8a/include/spidermonkey/mozilla/XorShift128PlusRNG.h deleted file mode 100644 index 2f182f0f..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/XorShift128PlusRNG.h +++ /dev/null @@ -1,121 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* The xorshift128+ pseudo-random number generator. */ - -#ifndef mozilla_XorShift128Plus_h -#define mozilla_XorShift128Plus_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/FloatingPoint.h" - -#include - -namespace mozilla { -namespace non_crypto { - -/* - * A stream of pseudo-random numbers generated using the xorshift+ technique - * described here: - * - * Vigna, Sebastiano (2014). "Further scramblings of Marsaglia's xorshift - * generators". arXiv:1404.0390 (http://arxiv.org/abs/1404.0390) - * - * That paper says: - * - * In particular, we propose a tightly coded xorshift128+ generator that - * does not fail systematically any test from the BigCrush suite of TestU01 - * (even reversed) and generates 64 pseudorandom bits in 1.10 ns on an - * Intel(R) Core(TM) i7-4770 CPU @3.40GHz (Haswell). It is the fastest - * generator we are aware of with such empirical statistical properties. - * - * The stream of numbers produced by this method repeats every 2**128 - 1 calls - * (i.e. never, for all practical purposes). Zero appears 2**64 - 1 times in - * this period; all other numbers appear 2**64 times. Additionally, each *bit* - * in the produced numbers repeats every 2**128 - 1 calls. - * - * This generator is not suitable as a cryptographically secure random number - * generator. - */ -class XorShift128PlusRNG { - uint64_t mState[2]; - - public: - /* - * Construct a xorshift128+ pseudo-random number stream using |aInitial0| and - * |aInitial1| as the initial state. These MUST NOT both be zero. - * - * If the initial states contain many zeros, for a few iterations you'll see - * many zeroes in the generated numbers. It's suggested to seed a SplitMix64 - * generator and use its first two - * outputs to seed xorshift128+. - */ - XorShift128PlusRNG(uint64_t aInitial0, uint64_t aInitial1) { - setState(aInitial0, aInitial1); - } - - /** - * Return a pseudo-random 64-bit number. - */ - uint64_t next() { - /* - * The offsetOfState*() methods below are provided so that exceedingly-rare - * callers that want to observe or poke at RNG state in C++ type-system- - * ignoring means can do so. Don't change the next() or nextDouble() - * algorithms without altering code that uses offsetOfState*()! - */ - uint64_t s1 = mState[0]; - const uint64_t s0 = mState[1]; - mState[0] = s0; - s1 ^= s1 << 23; - mState[1] = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26); - return mState[1] + s0; - } - - /* - * Return a pseudo-random floating-point value in the range [0, 1). More - * precisely, choose an integer in the range [0, 2**53) and divide it by - * 2**53. Given the 2**128 - 1 period noted above, the produced doubles are - * all but uniformly distributed in this range. - */ - double nextDouble() { - /* - * Because the IEEE 64-bit floating point format stores the leading '1' bit - * of the mantissa implicitly, it effectively represents a mantissa in the - * range [0, 2**53) in only 52 bits. FloatingPoint::kExponentShift - * is the width of the bitfield in the in-memory format, so we must add one - * to get the mantissa's range. - */ - static constexpr int kMantissaBits = - mozilla::FloatingPoint::kExponentShift + 1; - uint64_t mantissa = next() & ((UINT64_C(1) << kMantissaBits) - 1); - return double(mantissa) / (UINT64_C(1) << kMantissaBits); - } - - /* - * Set the stream's current state to |aState0| and |aState1|. These must not - * both be zero; ideally, they should have an almost even mix of zero and one - * bits. - */ - void setState(uint64_t aState0, uint64_t aState1) { - MOZ_ASSERT(aState0 || aState1); - mState[0] = aState0; - mState[1] = aState1; - } - - static size_t offsetOfState0() { - return offsetof(XorShift128PlusRNG, mState[0]); - } - static size_t offsetOfState1() { - return offsetof(XorShift128PlusRNG, mState[1]); - } -}; - -} // namespace non_crypto -} // namespace mozilla - -#endif // mozilla_XorShift128Plus_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/double-conversion.h b/android/arm64-v8a/include/spidermonkey/mozilla/double-conversion.h deleted file mode 100644 index 957575cf..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/double-conversion.h +++ /dev/null @@ -1,538 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ -#define DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ - -#include "mozilla/Types.h" -#include "utils.h" - -namespace double_conversion { - -class DoubleToStringConverter { - public: - // When calling ToFixed with a double > 10^kMaxFixedDigitsBeforePoint - // or a requested_digits parameter > kMaxFixedDigitsAfterPoint then the - // function returns false. - static const int kMaxFixedDigitsBeforePoint = 60; - static const int kMaxFixedDigitsAfterPoint = 60; - - // When calling ToExponential with a requested_digits - // parameter > kMaxExponentialDigits then the function returns false. - static const int kMaxExponentialDigits = 120; - - // When calling ToPrecision with a requested_digits - // parameter < kMinPrecisionDigits or requested_digits > kMaxPrecisionDigits - // then the function returns false. - static const int kMinPrecisionDigits = 1; - static const int kMaxPrecisionDigits = 120; - - enum Flags { - NO_FLAGS = 0, - EMIT_POSITIVE_EXPONENT_SIGN = 1, - EMIT_TRAILING_DECIMAL_POINT = 2, - EMIT_TRAILING_ZERO_AFTER_POINT = 4, - UNIQUE_ZERO = 8 - }; - - // Flags should be a bit-or combination of the possible Flags-enum. - // - NO_FLAGS: no special flags. - // - EMIT_POSITIVE_EXPONENT_SIGN: when the number is converted into exponent - // form, emits a '+' for positive exponents. Example: 1.2e+2. - // - EMIT_TRAILING_DECIMAL_POINT: when the input number is an integer and is - // converted into decimal format then a trailing decimal point is appended. - // Example: 2345.0 is converted to "2345.". - // - EMIT_TRAILING_ZERO_AFTER_POINT: in addition to a trailing decimal point - // emits a trailing '0'-character. This flag requires the - // EXMIT_TRAILING_DECIMAL_POINT flag. - // Example: 2345.0 is converted to "2345.0". - // - UNIQUE_ZERO: "-0.0" is converted to "0.0". - // - // Infinity symbol and nan_symbol provide the string representation for these - // special values. If the string is NULL and the special value is encountered - // then the conversion functions return false. - // - // The exponent_character is used in exponential representations. It is - // usually 'e' or 'E'. - // - // When converting to the shortest representation the converter will - // represent input numbers in decimal format if they are in the interval - // [10^decimal_in_shortest_low; 10^decimal_in_shortest_high[ - // (lower boundary included, greater boundary excluded). - // Example: with decimal_in_shortest_low = -6 and - // decimal_in_shortest_high = 21: - // ToShortest(0.000001) -> "0.000001" - // ToShortest(0.0000001) -> "1e-7" - // ToShortest(111111111111111111111.0) -> "111111111111111110000" - // ToShortest(100000000000000000000.0) -> "100000000000000000000" - // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21" - // - // When converting to precision mode the converter may add - // max_leading_padding_zeroes before returning the number in exponential - // format. - // Example with max_leading_padding_zeroes_in_precision_mode = 6. - // ToPrecision(0.0000012345, 2) -> "0.0000012" - // ToPrecision(0.00000012345, 2) -> "1.2e-7" - // Similarily the converter may add up to - // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid - // returning an exponential representation. A zero added by the - // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit. - // Examples for max_trailing_padding_zeroes_in_precision_mode = 1: - // ToPrecision(230.0, 2) -> "230" - // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT. - // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT. - DoubleToStringConverter(int flags, - const char* infinity_symbol, - const char* nan_symbol, - char exponent_character, - int decimal_in_shortest_low, - int decimal_in_shortest_high, - int max_leading_padding_zeroes_in_precision_mode, - int max_trailing_padding_zeroes_in_precision_mode) - : flags_(flags), - infinity_symbol_(infinity_symbol), - nan_symbol_(nan_symbol), - exponent_character_(exponent_character), - decimal_in_shortest_low_(decimal_in_shortest_low), - decimal_in_shortest_high_(decimal_in_shortest_high), - max_leading_padding_zeroes_in_precision_mode_( - max_leading_padding_zeroes_in_precision_mode), - max_trailing_padding_zeroes_in_precision_mode_( - max_trailing_padding_zeroes_in_precision_mode) { - // When 'trailing zero after the point' is set, then 'trailing point' - // must be set too. - ASSERT(((flags & EMIT_TRAILING_DECIMAL_POINT) != 0) || - !((flags & EMIT_TRAILING_ZERO_AFTER_POINT) != 0)); - } - - // Returns a converter following the EcmaScript specification. - static MFBT_API const DoubleToStringConverter& EcmaScriptConverter(); - - // Computes the shortest string of digits that correctly represent the input - // number. Depending on decimal_in_shortest_low and decimal_in_shortest_high - // (see constructor) it then either returns a decimal representation, or an - // exponential representation. - // Example with decimal_in_shortest_low = -6, - // decimal_in_shortest_high = 21, - // EMIT_POSITIVE_EXPONENT_SIGN activated, and - // EMIT_TRAILING_DECIMAL_POINT deactived: - // ToShortest(0.000001) -> "0.000001" - // ToShortest(0.0000001) -> "1e-7" - // ToShortest(111111111111111111111.0) -> "111111111111111110000" - // ToShortest(100000000000000000000.0) -> "100000000000000000000" - // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21" - // - // Note: the conversion may round the output if the returned string - // is accurate enough to uniquely identify the input-number. - // For example the most precise representation of the double 9e59 equals - // "899999999999999918767229449717619953810131273674690656206848", but - // the converter will return the shorter (but still correct) "9e59". - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except when the input value is special and no infinity_symbol or - // nan_symbol has been given to the constructor. - bool ToShortest(double value, StringBuilder* result_builder) const { - return ToShortestIeeeNumber(value, result_builder, SHORTEST); - } - - // Same as ToShortest, but for single-precision floats. - bool ToShortestSingle(float value, StringBuilder* result_builder) const { - return ToShortestIeeeNumber(value, result_builder, SHORTEST_SINGLE); - } - - - // Computes a decimal representation with a fixed number of digits after the - // decimal point. The last emitted digit is rounded. - // - // Examples: - // ToFixed(3.12, 1) -> "3.1" - // ToFixed(3.1415, 3) -> "3.142" - // ToFixed(1234.56789, 4) -> "1234.5679" - // ToFixed(1.23, 5) -> "1.23000" - // ToFixed(0.1, 4) -> "0.1000" - // ToFixed(1e30, 2) -> "1000000000000000019884624838656.00" - // ToFixed(0.1, 30) -> "0.100000000000000005551115123126" - // ToFixed(0.1, 17) -> "0.10000000000000001" - // - // If requested_digits equals 0, then the tail of the result depends on - // the EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT. - // Examples, for requested_digits == 0, - // let EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT be - // - false and false: then 123.45 -> 123 - // 0.678 -> 1 - // - true and false: then 123.45 -> 123. - // 0.678 -> 1. - // - true and true: then 123.45 -> 123.0 - // 0.678 -> 1.0 - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except for the following cases: - // - the input value is special and no infinity_symbol or nan_symbol has - // been provided to the constructor, - // - 'value' > 10^kMaxFixedDigitsBeforePoint, or - // - 'requested_digits' > kMaxFixedDigitsAfterPoint. - // The last two conditions imply that the result will never contain more than - // 1 + kMaxFixedDigitsBeforePoint + 1 + kMaxFixedDigitsAfterPoint characters - // (one additional character for the sign, and one for the decimal point). - MFBT_API bool ToFixed(double value, - int requested_digits, - StringBuilder* result_builder) const; - - // Computes a representation in exponential format with requested_digits - // after the decimal point. The last emitted digit is rounded. - // If requested_digits equals -1, then the shortest exponential representation - // is computed. - // - // Examples with EMIT_POSITIVE_EXPONENT_SIGN deactivated, and - // exponent_character set to 'e'. - // ToExponential(3.12, 1) -> "3.1e0" - // ToExponential(5.0, 3) -> "5.000e0" - // ToExponential(0.001, 2) -> "1.00e-3" - // ToExponential(3.1415, -1) -> "3.1415e0" - // ToExponential(3.1415, 4) -> "3.1415e0" - // ToExponential(3.1415, 3) -> "3.142e0" - // ToExponential(123456789000000, 3) -> "1.235e14" - // ToExponential(1000000000000000019884624838656.0, -1) -> "1e30" - // ToExponential(1000000000000000019884624838656.0, 32) -> - // "1.00000000000000001988462483865600e30" - // ToExponential(1234, 0) -> "1e3" - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except for the following cases: - // - the input value is special and no infinity_symbol or nan_symbol has - // been provided to the constructor, - // - 'requested_digits' > kMaxExponentialDigits. - // The last condition implies that the result will never contain more than - // kMaxExponentialDigits + 8 characters (the sign, the digit before the - // decimal point, the decimal point, the exponent character, the - // exponent's sign, and at most 3 exponent digits). - MFBT_API bool ToExponential(double value, - int requested_digits, - StringBuilder* result_builder) const; - - // Computes 'precision' leading digits of the given 'value' and returns them - // either in exponential or decimal format, depending on - // max_{leading|trailing}_padding_zeroes_in_precision_mode (given to the - // constructor). - // The last computed digit is rounded. - // - // Example with max_leading_padding_zeroes_in_precision_mode = 6. - // ToPrecision(0.0000012345, 2) -> "0.0000012" - // ToPrecision(0.00000012345, 2) -> "1.2e-7" - // Similarily the converter may add up to - // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid - // returning an exponential representation. A zero added by the - // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit. - // Examples for max_trailing_padding_zeroes_in_precision_mode = 1: - // ToPrecision(230.0, 2) -> "230" - // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT. - // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT. - // Examples for max_trailing_padding_zeroes_in_precision_mode = 3, and no - // EMIT_TRAILING_ZERO_AFTER_POINT: - // ToPrecision(123450.0, 6) -> "123450" - // ToPrecision(123450.0, 5) -> "123450" - // ToPrecision(123450.0, 4) -> "123500" - // ToPrecision(123450.0, 3) -> "123000" - // ToPrecision(123450.0, 2) -> "1.2e5" - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except for the following cases: - // - the input value is special and no infinity_symbol or nan_symbol has - // been provided to the constructor, - // - precision < kMinPericisionDigits - // - precision > kMaxPrecisionDigits - // The last condition implies that the result will never contain more than - // kMaxPrecisionDigits + 7 characters (the sign, the decimal point, the - // exponent character, the exponent's sign, and at most 3 exponent digits). - MFBT_API bool ToPrecision(double value, - int precision, - bool* used_exponential_notation, - StringBuilder* result_builder) const; - - enum DtoaMode { - // Produce the shortest correct representation. - // For example the output of 0.299999999999999988897 is (the less accurate - // but correct) 0.3. - SHORTEST, - // Same as SHORTEST, but for single-precision floats. - SHORTEST_SINGLE, - // Produce a fixed number of digits after the decimal point. - // For instance fixed(0.1, 4) becomes 0.1000 - // If the input number is big, the output will be big. - FIXED, - // Fixed number of digits (independent of the decimal point). - PRECISION - }; - - // The maximal number of digits that are needed to emit a double in base 10. - // A higher precision can be achieved by using more digits, but the shortest - // accurate representation of any double will never use more digits than - // kBase10MaximalLength. - // Note that DoubleToAscii null-terminates its input. So the given buffer - // should be at least kBase10MaximalLength + 1 characters long. - static const MFBT_DATA int kBase10MaximalLength = 17; - - // Converts the given double 'v' to ascii. 'v' must not be NaN, +Infinity, or - // -Infinity. In SHORTEST_SINGLE-mode this restriction also applies to 'v' - // after it has been casted to a single-precision float. That is, in this - // mode static_cast(v) must not be NaN, +Infinity or -Infinity. - // - // The result should be interpreted as buffer * 10^(point-length). - // - // The output depends on the given mode: - // - SHORTEST: produce the least amount of digits for which the internal - // identity requirement is still satisfied. If the digits are printed - // (together with the correct exponent) then reading this number will give - // 'v' again. The buffer will choose the representation that is closest to - // 'v'. If there are two at the same distance, than the one farther away - // from 0 is chosen (halfway cases - ending with 5 - are rounded up). - // In this mode the 'requested_digits' parameter is ignored. - // - SHORTEST_SINGLE: same as SHORTEST but with single-precision. - // - FIXED: produces digits necessary to print a given number with - // 'requested_digits' digits after the decimal point. The produced digits - // might be too short in which case the caller has to fill the remainder - // with '0's. - // Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2. - // Halfway cases are rounded towards +/-Infinity (away from 0). The call - // toFixed(0.15, 2) thus returns buffer="2", point=0. - // The returned buffer may contain digits that would be truncated from the - // shortest representation of the input. - // - PRECISION: produces 'requested_digits' where the first digit is not '0'. - // Even though the length of produced digits usually equals - // 'requested_digits', the function is allowed to return fewer digits, in - // which case the caller has to fill the missing digits with '0's. - // Halfway cases are again rounded away from 0. - // DoubleToAscii expects the given buffer to be big enough to hold all - // digits and a terminating null-character. In SHORTEST-mode it expects a - // buffer of at least kBase10MaximalLength + 1. In all other modes the - // requested_digits parameter and the padding-zeroes limit the size of the - // output. Don't forget the decimal point, the exponent character and the - // terminating null-character when computing the maximal output size. - // The given length is only used in debug mode to ensure the buffer is big - // enough. - static MFBT_API void DoubleToAscii(double v, - DtoaMode mode, - int requested_digits, - char* buffer, - int buffer_length, - bool* sign, - int* length, - int* point); - - private: - // Implementation for ToShortest and ToShortestSingle. - MFBT_API bool ToShortestIeeeNumber(double value, - StringBuilder* result_builder, - DtoaMode mode) const; - - // If the value is a special value (NaN or Infinity) constructs the - // corresponding string using the configured infinity/nan-symbol. - // If either of them is NULL or the value is not special then the - // function returns false. - MFBT_API bool HandleSpecialValues(double value, StringBuilder* result_builder) const; - // Constructs an exponential representation (i.e. 1.234e56). - // The given exponent assumes a decimal point after the first decimal digit. - MFBT_API void CreateExponentialRepresentation(const char* decimal_digits, - int length, - int exponent, - StringBuilder* result_builder) const; - // Creates a decimal representation (i.e 1234.5678). - MFBT_API void CreateDecimalRepresentation(const char* decimal_digits, - int length, - int decimal_point, - int digits_after_point, - StringBuilder* result_builder) const; - - const int flags_; - const char* const infinity_symbol_; - const char* const nan_symbol_; - const char exponent_character_; - const int decimal_in_shortest_low_; - const int decimal_in_shortest_high_; - const int max_leading_padding_zeroes_in_precision_mode_; - const int max_trailing_padding_zeroes_in_precision_mode_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter); -}; - - -class StringToDoubleConverter { - public: - // Enumeration for allowing octals and ignoring junk when converting - // strings to numbers. - enum Flags { - NO_FLAGS = 0, - ALLOW_HEX = 1, - ALLOW_OCTALS = 2, - ALLOW_TRAILING_JUNK = 4, - ALLOW_LEADING_SPACES = 8, - ALLOW_TRAILING_SPACES = 16, - ALLOW_SPACES_AFTER_SIGN = 32 - }; - - // Flags should be a bit-or combination of the possible Flags-enum. - // - NO_FLAGS: no special flags. - // - ALLOW_HEX: recognizes the prefix "0x". Hex numbers may only be integers. - // Ex: StringToDouble("0x1234") -> 4660.0 - // In StringToDouble("0x1234.56") the characters ".56" are trailing - // junk. The result of the call is hence dependent on - // the ALLOW_TRAILING_JUNK flag and/or the junk value. - // With this flag "0x" is a junk-string. Even with ALLOW_TRAILING_JUNK, - // the string will not be parsed as "0" followed by junk. - // - // - ALLOW_OCTALS: recognizes the prefix "0" for octals: - // If a sequence of octal digits starts with '0', then the number is - // read as octal integer. Octal numbers may only be integers. - // Ex: StringToDouble("01234") -> 668.0 - // StringToDouble("012349") -> 12349.0 // Not a sequence of octal - // // digits. - // In StringToDouble("01234.56") the characters ".56" are trailing - // junk. The result of the call is hence dependent on - // the ALLOW_TRAILING_JUNK flag and/or the junk value. - // In StringToDouble("01234e56") the characters "e56" are trailing - // junk, too. - // - ALLOW_TRAILING_JUNK: ignore trailing characters that are not part of - // a double literal. - // - ALLOW_LEADING_SPACES: skip over leading spaces. - // - ALLOW_TRAILING_SPACES: ignore trailing spaces. - // - ALLOW_SPACES_AFTER_SIGN: ignore spaces after the sign. - // Ex: StringToDouble("- 123.2") -> -123.2. - // StringToDouble("+ 123.2") -> 123.2 - // - // empty_string_value is returned when an empty string is given as input. - // If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a string - // containing only spaces is converted to the 'empty_string_value', too. - // - // junk_string_value is returned when - // a) ALLOW_TRAILING_JUNK is not set, and a junk character (a character not - // part of a double-literal) is found. - // b) ALLOW_TRAILING_JUNK is set, but the string does not start with a - // double literal. - // - // infinity_symbol and nan_symbol are strings that are used to detect - // inputs that represent infinity and NaN. They can be null, in which case - // they are ignored. - // The conversion routine first reads any possible signs. Then it compares the - // following character of the input-string with the first character of - // the infinity, and nan-symbol. If either matches, the function assumes, that - // a match has been found, and expects the following input characters to match - // the remaining characters of the special-value symbol. - // This means that the following restrictions apply to special-value symbols: - // - they must not start with signs ('+', or '-'), - // - they must not have the same first character. - // - they must not start with digits. - // - // Examples: - // flags = ALLOW_HEX | ALLOW_TRAILING_JUNK, - // empty_string_value = 0.0, - // junk_string_value = NaN, - // infinity_symbol = "infinity", - // nan_symbol = "nan": - // StringToDouble("0x1234") -> 4660.0. - // StringToDouble("0x1234K") -> 4660.0. - // StringToDouble("") -> 0.0 // empty_string_value. - // StringToDouble(" ") -> NaN // junk_string_value. - // StringToDouble(" 1") -> NaN // junk_string_value. - // StringToDouble("0x") -> NaN // junk_string_value. - // StringToDouble("-123.45") -> -123.45. - // StringToDouble("--123.45") -> NaN // junk_string_value. - // StringToDouble("123e45") -> 123e45. - // StringToDouble("123E45") -> 123e45. - // StringToDouble("123e+45") -> 123e45. - // StringToDouble("123E-45") -> 123e-45. - // StringToDouble("123e") -> 123.0 // trailing junk ignored. - // StringToDouble("123e-") -> 123.0 // trailing junk ignored. - // StringToDouble("+NaN") -> NaN // NaN string literal. - // StringToDouble("-infinity") -> -inf. // infinity literal. - // StringToDouble("Infinity") -> NaN // junk_string_value. - // - // flags = ALLOW_OCTAL | ALLOW_LEADING_SPACES, - // empty_string_value = 0.0, - // junk_string_value = NaN, - // infinity_symbol = NULL, - // nan_symbol = NULL: - // StringToDouble("0x1234") -> NaN // junk_string_value. - // StringToDouble("01234") -> 668.0. - // StringToDouble("") -> 0.0 // empty_string_value. - // StringToDouble(" ") -> 0.0 // empty_string_value. - // StringToDouble(" 1") -> 1.0 - // StringToDouble("0x") -> NaN // junk_string_value. - // StringToDouble("0123e45") -> NaN // junk_string_value. - // StringToDouble("01239E45") -> 1239e45. - // StringToDouble("-infinity") -> NaN // junk_string_value. - // StringToDouble("NaN") -> NaN // junk_string_value. - StringToDoubleConverter(int flags, - double empty_string_value, - double junk_string_value, - const char* infinity_symbol, - const char* nan_symbol) - : flags_(flags), - empty_string_value_(empty_string_value), - junk_string_value_(junk_string_value), - infinity_symbol_(infinity_symbol), - nan_symbol_(nan_symbol) { - } - - // Performs the conversion. - // The output parameter 'processed_characters_count' is set to the number - // of characters that have been processed to read the number. - // Spaces than are processed with ALLOW_{LEADING|TRAILING}_SPACES are included - // in the 'processed_characters_count'. Trailing junk is never included. - double StringToDouble(const char* buffer, - int length, - int* processed_characters_count) const { - return StringToIeee(buffer, length, processed_characters_count, true); - } - - // Same as StringToDouble but reads a float. - // Note that this is not equivalent to static_cast(StringToDouble(...)) - // due to potential double-rounding. - float StringToFloat(const char* buffer, - int length, - int* processed_characters_count) const { - return static_cast(StringToIeee(buffer, length, - processed_characters_count, false)); - } - - private: - const int flags_; - const double empty_string_value_; - const double junk_string_value_; - const char* const infinity_symbol_; - const char* const nan_symbol_; - - double StringToIeee(const char* buffer, - int length, - int* processed_characters_count, - bool read_as_double) const; - - DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter); -}; - -} // namespace double_conversion - -#endif // DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/fallible.h b/android/arm64-v8a/include/spidermonkey/mozilla/fallible.h deleted file mode 100644 index c028360b..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/fallible.h +++ /dev/null @@ -1,68 +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/. */ - -#ifndef mozilla_fallible_h -#define mozilla_fallible_h - -#if defined(__cplusplus) - -/* Explicit fallible allocation - * - * Memory allocation (normally) defaults to abort in case of failed - * allocation. That is, it never returns NULL, and crashes instead. - * - * Code can explicitely request for fallible memory allocation thanks - * to the declarations below. - * - * The typical use of the mozilla::fallible const is with placement new, - * like the following: - * - * foo = new (mozilla::fallible) Foo(); - * - * The following forms, or derivatives, are also possible but deprecated: - * - * foo = new ((mozilla::fallible_t())) Foo(); - * - * const mozilla::fallible_t fallible = mozilla::fallible_t(); - * bar = new (f) Bar(); - * - * It is also possible to declare method overloads with fallible allocation - * alternatives, like so: - * - * class Foo { - * public: - * void Method(void *); - * void Method(void *, const mozilla::fallible_t&); - * }; - * - * Foo foo; - * foo.Method(nullptr, mozilla::fallible); - * - * If that last method call is in a method that itself takes a const - * fallible_t& argument, it is recommended to propagate that argument - * instead of using mozilla::fallible: - * - * void Func(Foo &foo, const mozilla::fallible_t& aFallible) { - * foo.Method(nullptr, aFallible); - * } - * - */ -namespace mozilla { - -struct fallible_t { }; - -/* This symbol is kept unexported, such that in corner cases where the - * compiler can't remove its use (essentially, cross compilation-unit - * calls), the smallest machine code is used. - * Depending how the linker packs symbols, it will consume between 1 and - * 8 bytes of read-only data in each executable or shared library, but - * only in those where it's actually not optimized out by the compiler. - */ -extern const fallible_t fallible; - -} // namespace mozilla - -#endif - -#endif // mozilla_fallible_h diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/mozalloc.h b/android/arm64-v8a/include/spidermonkey/mozilla/mozalloc.h deleted file mode 100644 index f7ddb7e6..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/mozalloc.h +++ /dev/null @@ -1,361 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: sw=4 ts=4 et : - */ -/* 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 mozilla_mozalloc_h -#define mozilla_mozalloc_h - -/* - * https://bugzilla.mozilla.org/show_bug.cgi?id=427099 - */ - -#if defined(__cplusplus) -# include -// Since libstdc++ 6, including the C headers (e.g. stdlib.h) instead of the -// corresponding C++ header (e.g. cstdlib) can cause confusion in C++ code -// using things defined there. Specifically, with stdlib.h, the use of abs() -// in gfx/graphite2/src/inc/UtfCodec.h somehow ends up picking the wrong abs() -# include -# include -#else -# include -# include -#endif - -#if defined(__cplusplus) -#include "mozilla/fallible.h" -#include "mozilla/mozalloc_abort.h" -#include "mozilla/TemplateLib.h" -#endif -#include "mozilla/Attributes.h" -#include "mozilla/Types.h" - -#define MOZALLOC_HAVE_XMALLOC - -#if defined(MOZ_ALWAYS_INLINE_EVEN_DEBUG) -# define MOZALLOC_INLINE MOZ_ALWAYS_INLINE_EVEN_DEBUG -#elif defined(HAVE_FORCEINLINE) -# define MOZALLOC_INLINE __forceinline -#else -# define MOZALLOC_INLINE inline -#endif - -/* Workaround build problem with Sun Studio 12 */ -#if defined(__SUNPRO_C) || defined(__SUNPRO_CC) -# undef MOZ_MUST_USE -# define MOZ_MUST_USE -# undef MOZ_ALLOCATOR -# define MOZ_ALLOCATOR -#endif - -#if defined(__cplusplus) -extern "C" { -#endif /* ifdef __cplusplus */ - -/* - * We need to use malloc_impl and free_impl in this file when they are - * defined, because of how mozglue.dll is linked on Windows, where using - * malloc/free would end up using the symbols from the MSVCRT instead of - * ours. - */ -#ifndef free_impl -#define free_impl free -#define free_impl_ -#endif -#ifndef malloc_impl -#define malloc_impl malloc -#define malloc_impl_ -#endif - -/* - * Each declaration below is analogous to a "standard" allocation - * function, except that the out-of-memory handling is made explicit. - * The |moz_x| versions will never return a NULL pointer; if memory - * is exhausted, they abort. The |moz_| versions may return NULL - * pointers if memory is exhausted: their return value must be checked. - * - * All these allocation functions are *guaranteed* to return a pointer - * to memory allocated in such a way that that memory can be freed by - * passing that pointer to |free()|. - */ - -MFBT_API void* moz_xmalloc(size_t size) - MOZ_ALLOCATOR; - -MFBT_API void* moz_xcalloc(size_t nmemb, size_t size) - MOZ_ALLOCATOR; - -MFBT_API void* moz_xrealloc(void* ptr, size_t size) - MOZ_ALLOCATOR; - -MFBT_API char* moz_xstrdup(const char* str) - MOZ_ALLOCATOR; - -MFBT_API size_t moz_malloc_usable_size(void *ptr); - -MFBT_API size_t moz_malloc_size_of(const void *ptr); - -#if defined(HAVE_STRNDUP) -MFBT_API char* moz_xstrndup(const char* str, size_t strsize) - MOZ_ALLOCATOR; -#endif /* if defined(HAVE_STRNDUP) */ - - -#if defined(HAVE_POSIX_MEMALIGN) -MFBT_API MOZ_MUST_USE -int moz_xposix_memalign(void **ptr, size_t alignment, size_t size); - -MFBT_API MOZ_MUST_USE -int moz_posix_memalign(void **ptr, size_t alignment, size_t size); -#endif /* if defined(HAVE_POSIX_MEMALIGN) */ - - -#if defined(HAVE_MEMALIGN) -MFBT_API void* moz_xmemalign(size_t boundary, size_t size) - MOZ_ALLOCATOR; -#endif /* if defined(HAVE_MEMALIGN) */ - - -#if defined(HAVE_VALLOC) -MFBT_API void* moz_xvalloc(size_t size) - MOZ_ALLOCATOR; -#endif /* if defined(HAVE_VALLOC) */ - - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* ifdef __cplusplus */ - - -#ifdef __cplusplus - -/* - * We implement the default operators new/delete as part of - * libmozalloc, replacing their definitions in libstdc++. The - * operator new* definitions in libmozalloc will never return a NULL - * pointer. - * - * Each operator new immediately below returns a pointer to memory - * that can be delete'd by any of - * - * (1) the matching infallible operator delete immediately below - * (2) the matching "fallible" operator delete further below - * (3) the matching system |operator delete(void*, std::nothrow)| - * (4) the matching system |operator delete(void*) throw(std::bad_alloc)| - * - * NB: these are declared |throw(std::bad_alloc)|, though they will never - * throw that exception. This declaration is consistent with the rule - * that |::operator new() throw(std::bad_alloc)| will never return NULL. - */ - -/* NB: This is defined just to silence vacuous warnings about symbol - * visibility on OS X/gcc. These symbols are force-inline and not - * exported. */ -#if defined(XP_MACOSX) -# define MOZALLOC_EXPORT_NEW MFBT_API -#else -# define MOZALLOC_EXPORT_NEW -#endif - -#if defined(ANDROID) -/* - * It's important to always specify 'throw()' in GCC because it's used to tell - * GCC that 'new' may return null. That makes GCC null-check the result before - * potentially initializing the memory to zero. - * Also, the Android minimalistic headers don't include std::bad_alloc. - */ -#define MOZALLOC_THROW_IF_HAS_EXCEPTIONS throw() -#define MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS -#elif defined(_MSC_VER) -/* - * Suppress build warning spam (bug 578546). - */ -#define MOZALLOC_THROW_IF_HAS_EXCEPTIONS -#define MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS -#else -#define MOZALLOC_THROW_IF_HAS_EXCEPTIONS throw() -#define MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS throw(std::bad_alloc) -#endif - -#define MOZALLOC_THROW_BAD_ALLOC MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS - -MOZALLOC_EXPORT_NEW -#if defined(__GNUC__) && !defined(__clang__) && defined(__SANITIZE_ADDRESS__) -/* gcc's asan somehow doesn't like always_inline on this function. */ -__attribute__((gnu_inline)) inline -#else -MOZALLOC_INLINE -#endif -void* operator new(size_t size) MOZALLOC_THROW_BAD_ALLOC -{ - return moz_xmalloc(size); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void* operator new(size_t size, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return malloc_impl(size); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void* operator new[](size_t size) MOZALLOC_THROW_BAD_ALLOC -{ - return moz_xmalloc(size); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void* operator new[](size_t size, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return malloc_impl(size); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void operator delete(void* ptr) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return free_impl(ptr); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void operator delete(void* ptr, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return free_impl(ptr); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void operator delete[](void* ptr) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return free_impl(ptr); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void operator delete[](void* ptr, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return free_impl(ptr); -} - - -/* - * We also add a new allocator variant: "fallible operator new." - * Unlike libmozalloc's implementations of the standard nofail - * allocators, this allocator is allowed to return NULL. It can be used - * as follows - * - * Foo* f = new (mozilla::fallible) Foo(...); - * - * operator delete(fallible) is defined for completeness only. - * - * Each operator new below returns a pointer to memory that can be - * delete'd by any of - * - * (1) the matching "fallible" operator delete below - * (2) the matching infallible operator delete above - * (3) the matching system |operator delete(void*, std::nothrow)| - * (4) the matching system |operator delete(void*) throw(std::bad_alloc)| - */ - -MOZALLOC_INLINE -void* operator new(size_t size, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return malloc_impl(size); -} - -MOZALLOC_INLINE -void* operator new[](size_t size, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return malloc_impl(size); -} - -MOZALLOC_INLINE -void operator delete(void* ptr, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - free_impl(ptr); -} - -MOZALLOC_INLINE -void operator delete[](void* ptr, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - free_impl(ptr); -} - - -/* - * This policy is identical to MallocAllocPolicy, except it uses - * moz_xmalloc/moz_xcalloc/moz_xrealloc instead of - * malloc/calloc/realloc. - */ -class InfallibleAllocPolicy -{ -public: - template - T* maybe_pod_malloc(size_t aNumElems) - { - return pod_malloc(aNumElems); - } - - template - T* maybe_pod_calloc(size_t aNumElems) - { - return pod_calloc(aNumElems); - } - - template - T* maybe_pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) - { - return pod_realloc(aPtr, aOldSize, aNewSize); - } - - template - T* pod_malloc(size_t aNumElems) - { - if (aNumElems & mozilla::tl::MulOverflowMask::value) { - reportAllocOverflow(); - } - return static_cast(moz_xmalloc(aNumElems * sizeof(T))); - } - - template - T* pod_calloc(size_t aNumElems) - { - return static_cast(moz_xcalloc(aNumElems, sizeof(T))); - } - - template - T* pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) - { - if (aNewSize & mozilla::tl::MulOverflowMask::value) { - reportAllocOverflow(); - } - return static_cast(moz_xrealloc(aPtr, aNewSize * sizeof(T))); - } - - void free_(void* aPtr) - { - free_impl(aPtr); - } - - void reportAllocOverflow() const - { - mozalloc_abort("alloc overflow"); - } - - bool checkSimulatedOOM() const - { - return true; - } -}; - -#endif /* ifdef __cplusplus */ - -#ifdef malloc_impl_ -#undef malloc_impl_ -#undef malloc_impl -#endif -#ifdef free_impl_ -#undef free_impl_ -#undef free_impl -#endif - -#endif /* ifndef mozilla_mozalloc_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/mozalloc_abort.h b/android/arm64-v8a/include/spidermonkey/mozilla/mozalloc_abort.h deleted file mode 100644 index 065cebcb..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/mozalloc_abort.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: sw=4 ts=4 et : - */ -/* 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 mozilla_mozalloc_abort_h -#define mozilla_mozalloc_abort_h - -#include "mozilla/Attributes.h" -#include "mozilla/Types.h" - -/** - * Terminate this process in such a way that breakpad is triggered, if - * at all possible. - * - * Note: MOZ_NORETURN seems to break crash stacks on ARM, so we don't - * use that annotation there. - */ -MFBT_API -#if !defined(__arm__) - MOZ_NORETURN -#endif - void mozalloc_abort(const char* const msg); - - -#endif /* ifndef mozilla_mozalloc_abort_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/mozalloc_oom.h b/android/arm64-v8a/include/spidermonkey/mozilla/mozalloc_oom.h deleted file mode 100644 index 35bb9acc..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/mozalloc_oom.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: sw=4 ts=4 et : - */ -/* 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 mozilla_mozalloc_oom_h -#define mozilla_mozalloc_oom_h - -#include "mozalloc.h" - -/** - * Called when memory is critically low. Returns iff it was able to - * remedy the critical memory situation; if not, it will abort(). - */ -MFBT_API void mozalloc_handle_oom(size_t requestedSize); - -/** - * Called by embedders (specifically Mozilla breakpad) which wants to be - * notified of an intentional abort, to annotate any crash report with - * the size of the allocation on which we aborted. - */ -typedef void (*mozalloc_oom_abort_handler)(size_t size); -MFBT_API void mozalloc_set_oom_abort_handler(mozalloc_oom_abort_handler handler); - -/* TODO: functions to query system memory usage and register - * critical-memory handlers. */ - - -#endif /* ifndef mozilla_mozalloc_oom_h */ diff --git a/android/arm64-v8a/include/spidermonkey/mozilla/utils.h b/android/arm64-v8a/include/spidermonkey/mozilla/utils.h deleted file mode 100644 index 15dd4bfb..00000000 --- a/android/arm64-v8a/include/spidermonkey/mozilla/utils.h +++ /dev/null @@ -1,298 +0,0 @@ -// Copyright 2010 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DOUBLE_CONVERSION_UTILS_H_ -#define DOUBLE_CONVERSION_UTILS_H_ - -#include -#include - -#include "mozilla/Assertions.h" -#ifndef ASSERT -#define ASSERT(condition) MOZ_ASSERT(condition) -#endif -#ifndef UNIMPLEMENTED -#define UNIMPLEMENTED() MOZ_CRASH() -#endif -#ifndef UNREACHABLE -#define UNREACHABLE() MOZ_CRASH() -#endif - -// Double operations detection based on target architecture. -// Linux uses a 80bit wide floating point stack on x86. This induces double -// rounding, which in turn leads to wrong results. -// An easy way to test if the floating-point operations are correct is to -// evaluate: 89255.0/1e22. If the floating-point stack is 64 bits wide then -// the result is equal to 89255e-22. -// The best way to test this, is to create a division-function and to compare -// the output of the division with the expected result. (Inlining must be -// disabled.) -// On Linux,x86 89255e-22 != Div_double(89255.0/1e22) -#if defined(_M_X64) || defined(__x86_64__) || \ - defined(__ARMEL__) || defined(__avr32__) || \ - defined(__hppa__) || defined(__ia64__) || \ - defined(__mips__) || \ - defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \ - defined(__sparc__) || defined(__sparc) || defined(__s390__) || \ - defined(__SH4__) || defined(__alpha__) || \ - defined(_MIPS_ARCH_MIPS32R2) || \ - defined(__AARCH64EL__) || defined(__aarch64__) -#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 -#elif defined(_M_IX86) || defined(__i386__) || defined(__i386) -#if defined(_WIN32) -// Windows uses a 64bit wide floating point stack. -#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 -#else -#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS -#endif // _WIN32 -#else -#error Target architecture was not detected as supported by Double-Conversion. -#endif - - -#include - -// The following macro works on both 32 and 64-bit platforms. -// Usage: instead of writing 0x1234567890123456 -// write UINT64_2PART_C(0x12345678,90123456); -#define UINT64_2PART_C(a, b) (((static_cast(a) << 32) + 0x##b##u)) - - -// The expression ARRAY_SIZE(a) is a compile-time constant of type -// size_t which represents the number of elements of the given -// array. You should only use ARRAY_SIZE on statically allocated -// arrays. -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) \ - ((sizeof(a) / sizeof(*(a))) / \ - static_cast(!(sizeof(a) % sizeof(*(a))))) -#endif - -// A macro to disallow the evil copy constructor and operator= functions -// This should be used in the private: declarations for a class -#ifndef DISALLOW_COPY_AND_ASSIGN -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) -#endif - -// A macro to disallow all the implicit constructors, namely the -// default constructor, copy constructor and operator= functions. -// -// This should be used in the private: declarations for a class -// that wants to prevent anyone from instantiating it. This is -// especially useful for classes containing only static methods. -#ifndef DISALLOW_IMPLICIT_CONSTRUCTORS -#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ - TypeName(); \ - DISALLOW_COPY_AND_ASSIGN(TypeName) -#endif - -namespace double_conversion { - -static const int kCharSize = sizeof(char); - -// Returns the maximum of the two parameters. -template -static T Max(T a, T b) { - return a < b ? b : a; -} - - -// Returns the minimum of the two parameters. -template -static T Min(T a, T b) { - return a < b ? a : b; -} - - -inline int StrLength(const char* string) { - size_t length = strlen(string); - ASSERT(length == static_cast(static_cast(length))); - return static_cast(length); -} - -// This is a simplified version of V8's Vector class. -template -class Vector { - public: - Vector() : start_(NULL), length_(0) {} - Vector(T* data, int len) : start_(data), length_(len) { - ASSERT(len == 0 || (len > 0 && data != NULL)); - } - - // Returns a vector using the same backing storage as this one, - // spanning from and including 'from', to but not including 'to'. - Vector SubVector(int from, int to) { - ASSERT(to <= length_); - ASSERT(from < to); - ASSERT(0 <= from); - return Vector(start() + from, to - from); - } - - // Returns the length of the vector. - int length() const { return length_; } - - // Returns whether or not the vector is empty. - bool is_empty() const { return length_ == 0; } - - // Returns the pointer to the start of the data in the vector. - T* start() const { return start_; } - - // Access individual vector elements - checks bounds in debug mode. - T& operator[](int index) const { - ASSERT(0 <= index && index < length_); - return start_[index]; - } - - T& first() { return start_[0]; } - - T& last() { return start_[length_ - 1]; } - - private: - T* start_; - int length_; -}; - - -// Helper class for building result strings in a character buffer. The -// purpose of the class is to use safe operations that checks the -// buffer bounds on all operations in debug mode. -class StringBuilder { - public: - StringBuilder(char* buffer, int buffer_size) - : buffer_(buffer, buffer_size), position_(0) { } - - ~StringBuilder() { if (!is_finalized()) Finalize(); } - - int size() const { return buffer_.length(); } - - // Get the current position in the builder. - int position() const { - ASSERT(!is_finalized()); - return position_; - } - - // Reset the position. - void Reset() { position_ = 0; } - - // Add a single character to the builder. It is not allowed to add - // 0-characters; use the Finalize() method to terminate the string - // instead. - void AddCharacter(char c) { - ASSERT(c != '\0'); - ASSERT(!is_finalized() && position_ < buffer_.length()); - buffer_[position_++] = c; - } - - // Add an entire string to the builder. Uses strlen() internally to - // compute the length of the input string. - void AddString(const char* s) { - AddSubstring(s, StrLength(s)); - } - - // Add the first 'n' characters of the given string 's' to the - // builder. The input string must have enough characters. - void AddSubstring(const char* s, int n) { - ASSERT(!is_finalized() && position_ + n < buffer_.length()); - ASSERT(static_cast(n) <= strlen(s)); - memmove(&buffer_[position_], s, n * kCharSize); - position_ += n; - } - - - // Add character padding to the builder. If count is non-positive, - // nothing is added to the builder. - void AddPadding(char c, int count) { - for (int i = 0; i < count; i++) { - AddCharacter(c); - } - } - - // Finalize the string by 0-terminating it and returning the buffer. - char* Finalize() { - ASSERT(!is_finalized() && position_ < buffer_.length()); - buffer_[position_] = '\0'; - // Make sure nobody managed to add a 0-character to the - // buffer while building the string. - ASSERT(strlen(buffer_.start()) == static_cast(position_)); - position_ = -1; - ASSERT(is_finalized()); - return buffer_.start(); - } - - private: - Vector buffer_; - int position_; - - bool is_finalized() const { return position_ < 0; } - - DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder); -}; - -// The type-based aliasing rule allows the compiler to assume that pointers of -// different types (for some definition of different) never alias each other. -// Thus the following code does not work: -// -// float f = foo(); -// int fbits = *(int*)(&f); -// -// The compiler 'knows' that the int pointer can't refer to f since the types -// don't match, so the compiler may cache f in a register, leaving random data -// in fbits. Using C++ style casts makes no difference, however a pointer to -// char data is assumed to alias any other pointer. This is the 'memcpy -// exception'. -// -// Bit_cast uses the memcpy exception to move the bits from a variable of one -// type of a variable of another type. Of course the end result is likely to -// be implementation dependent. Most compilers (gcc-4.2 and MSVC 2005) -// will completely optimize BitCast away. -// -// There is an additional use for BitCast. -// Recent gccs will warn when they see casts that may result in breakage due to -// the type-based aliasing rule. If you have checked that there is no breakage -// you can use BitCast to cast one pointer type to another. This confuses gcc -// enough that it can no longer see that you have cast one pointer type to -// another thus avoiding the warning. -template -inline Dest BitCast(const Source& source) { - static_assert(sizeof(Dest) == sizeof(Source), - "BitCast's source and destination types must be the same size"); - - Dest dest; - memmove(&dest, &source, sizeof(dest)); - return dest; -} - -template -inline Dest BitCast(Source* source) { - return BitCast(reinterpret_cast(source)); -} - -} // namespace double_conversion - -#endif // DOUBLE_CONVERSION_UTILS_H_ diff --git a/android/arm64-v8a/libjs_static.a b/android/arm64-v8a/libjs_static.a deleted file mode 100644 index 5f2dbbb7..00000000 Binary files a/android/arm64-v8a/libjs_static.a and /dev/null differ diff --git a/android/arm64-v8a/libmozglue.a b/android/arm64-v8a/libmozglue.a deleted file mode 100644 index cdbcecd5..00000000 Binary files a/android/arm64-v8a/libmozglue.a and /dev/null differ diff --git a/android/armeabi-v7a/include/spidermonkey/fdlibm.h b/android/armeabi-v7a/include/spidermonkey/fdlibm.h deleted file mode 100644 index 0ad21591..00000000 --- a/android/armeabi-v7a/include/spidermonkey/fdlibm.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* - * from: @(#)fdlibm.h 5.1 93/09/24 - * $FreeBSD$ - */ - -#ifndef mozilla_imported_fdlibm_h -#define mozilla_imported_fdlibm_h - -namespace fdlibm { - -double acos(double); -double asin(double); -double atan(double); -double atan2(double, double); - -double cosh(double); -double sinh(double); -double tanh(double); - -double exp(double); -double log(double); -double log10(double); - -double pow(double, double); -double sqrt(double); -double fabs(double); - -double floor(double); -double trunc(double); -double ceil(double); - -double acosh(double); -double asinh(double); -double atanh(double); -double cbrt(double); -double expm1(double); -double hypot(double, double); -double log1p(double); -double log2(double); -double rint(double); -double copysign(double, double); -double nearbyint(double); -double scalbn(double, int); - -float ceilf(float); -float floorf(float); - -float nearbyintf(float); -float rintf(float); -float truncf(float); - -} /* namespace fdlibm */ - -#endif /* mozilla_imported_fdlibm_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/jemalloc_types.h b/android/armeabi-v7a/include/spidermonkey/jemalloc_types.h deleted file mode 100644 index ae8dc441..00000000 --- a/android/armeabi-v7a/include/spidermonkey/jemalloc_types.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- Mode: C; tab-width: 8; c-basic-offset: 8 -*- */ -/* vim:set softtabstop=8 shiftwidth=8: */ -/*- - * Copyright (C) 2006-2008 Jason Evans . - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _JEMALLOC_TYPES_H_ -#define _JEMALLOC_TYPES_H_ - -/* grab size_t */ -#ifdef _MSC_VER -#include -#else -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef unsigned char jemalloc_bool; - -/* - * jemalloc_stats() is not a stable interface. When using jemalloc_stats_t, be - * sure that the compiled results of jemalloc.c are in sync with this header - * file. - */ -typedef struct { - /* - * Run-time configuration settings. - */ - jemalloc_bool opt_abort; /* abort(3) on error? */ - jemalloc_bool opt_junk; /* Fill allocated memory with 0xe4? */ - jemalloc_bool opt_poison; /* Fill free memory with 0xe5? */ - jemalloc_bool opt_utrace; /* Trace all allocation events? */ - jemalloc_bool opt_sysv; /* SysV semantics? */ - jemalloc_bool opt_xmalloc; /* abort(3) on OOM? */ - jemalloc_bool opt_zero; /* Fill allocated memory with 0x0? */ - size_t narenas; /* Number of arenas. */ - size_t balance_threshold; /* Arena contention rebalance threshold. */ - size_t quantum; /* Allocation quantum. */ - size_t small_max; /* Max quantum-spaced allocation size. */ - size_t large_max; /* Max sub-chunksize allocation size. */ - size_t chunksize; /* Size of each virtual memory mapping. */ - size_t dirty_max; /* Max dirty pages per arena. */ - - /* - * Current memory usage statistics. - */ - size_t mapped; /* Bytes mapped (not necessarily committed). */ - size_t allocated; /* Bytes allocated (committed, in use by application). */ - size_t waste; /* Bytes committed, not in use by the - application, and not intentionally left - unused (i.e., not dirty). */ - size_t page_cache; /* Committed, unused pages kept around as a - cache. (jemalloc calls these "dirty".) */ - size_t bookkeeping; /* Committed bytes used internally by the - allocator. */ - size_t bin_unused; /* Bytes committed to a bin but currently unused. */ -} jemalloc_stats_t; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* _JEMALLOC_TYPES_H_ */ diff --git a/android/armeabi-v7a/include/spidermonkey/js-config.h b/android/armeabi-v7a/include/spidermonkey/js-config.h deleted file mode 100644 index f21bdf41..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js-config.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=78: - * - * 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 js_config_h -#define js_config_h - -/* Definitions set at build time that affect SpiderMonkey's public API. - This header file is generated by the SpiderMonkey configure script, - and installed along with jsapi.h. */ - -/* Define to 1 if SpiderMonkey is in debug mode. */ -/* #undef JS_DEBUG */ - -/* - * NB: We have a special case for rust-bindgen, which wants to be able to - * generate both debug and release bindings on a single objdir. - */ -#ifdef JS_DEBUG -#if !defined(DEBUG) && !defined(RUST_BINDGEN) -# error "SpiderMonkey was configured with --enable-debug, so DEBUG must be defined when including this header" -# endif -#else -# if defined(DEBUG) && !defined(RUST_BINDGEN) -# error "SpiderMonkey was configured with --disable-debug, so DEBUG must be not defined when including this header" -# endif -#endif - -/* Define to 1 if SpiderMonkey should not use struct types in debug builds. */ -/* #undef JS_NO_JSVAL_JSID_STRUCT_TYPES */ - -/* Define to 1 if SpiderMonkey should support multi-threaded clients. */ -/* #undef JS_THREADSAFE */ - -/* Define to 1 if SpiderMonkey should include ctypes support. */ -/* #undef JS_HAS_CTYPES */ - -/* Define to 1 if SpiderMonkey should support the ability to perform - entirely too much GC. */ -/* #undef JS_GC_ZEAL */ - -/* Define to 1 if SpiderMonkey should use small chunks. */ -/* #undef JS_GC_SMALL_CHUNK_SIZE */ - -/* Define to 1 to perform extra assertions and heap poisoning. */ -/* #undef JS_CRASH_DIAGNOSTICS */ - -/* Define to 1 if SpiderMonkey is in NUNBOX32 mode. */ -#define JS_NUNBOX32 1 - -/* Define to 1 if SpiderMonkey is in PUNBOX64 mode. */ -/* #undef JS_PUNBOX64 */ - -/* MOZILLA JSAPI version number components */ -#define MOZJS_MAJOR_VERSION 52 -#define MOZJS_MINOR_VERSION 0 - -#endif /* js_config_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js.msg b/android/armeabi-v7a/include/spidermonkey/js.msg deleted file mode 100644 index 246e363c..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js.msg +++ /dev/null @@ -1,581 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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/. */ - -/* - * This is the JavaScript error message file. - * - * The format for each JS error message is: - * - * MSG_DEF(, , , - * ) - * - * where ; - * is a legal C identifer that will be used in the - * JS engine source. - * - * is an integer literal specifying the total number of - * replaceable arguments in the following format string. - * - * is an exception index from the enum in jsexn.c; - * JSEXN_NONE for none. The given exception index will be raised by the - * engine when the corresponding error occurs. - * - * is a string literal, optionally containing sequences - * {X} where X is an integer representing the argument number that will - * be replaced with a string value when the error is reported. - * - * e.g. - * - * MSG_DEF(JSMSG_NOT_A_SUBSPECIES, 2, JSEXN_NONE, - * "{0} is not a member of the {1} family") - * - * can be used: - * - * JS_ReportErrorNumberASCII(JSMSG_NOT_A_SUBSPECIES, "Rhino", "Monkey"); - * - * to report: - * - * "Rhino is not a member of the Monkey family" - */ - -MSG_DEF(JSMSG_NOT_AN_ERROR, 0, JSEXN_ERR, "") -MSG_DEF(JSMSG_NOT_DEFINED, 1, JSEXN_REFERENCEERR, "{0} is not defined") -MSG_DEF(JSMSG_MORE_ARGS_NEEDED, 3, JSEXN_TYPEERR, "{0} requires more than {1} argument{2}") -MSG_DEF(JSMSG_INCOMPATIBLE_PROTO, 3, JSEXN_TYPEERR, "{0}.prototype.{1} called on incompatible {2}") -MSG_DEF(JSMSG_NO_CONSTRUCTOR, 1, JSEXN_TYPEERR, "{0} has no constructor") -MSG_DEF(JSMSG_BAD_SORT_ARG, 0, JSEXN_TYPEERR, "invalid Array.prototype.sort argument") -MSG_DEF(JSMSG_CANT_WATCH, 1, JSEXN_TYPEERR, "can't watch non-native objects of class {0}") -MSG_DEF(JSMSG_READ_ONLY, 1, JSEXN_TYPEERR, "{0} is read-only") -MSG_DEF(JSMSG_CANT_DELETE, 1, JSEXN_TYPEERR, "property {0} is non-configurable and can't be deleted") -MSG_DEF(JSMSG_CANT_TRUNCATE_ARRAY, 0, JSEXN_TYPEERR, "can't delete non-configurable array element") -MSG_DEF(JSMSG_NOT_FUNCTION, 1, JSEXN_TYPEERR, "{0} is not a function") -MSG_DEF(JSMSG_NOT_CONSTRUCTOR, 1, JSEXN_TYPEERR, "{0} is not a constructor") -MSG_DEF(JSMSG_CANT_CONVERT_TO, 2, JSEXN_TYPEERR, "can't convert {0} to {1}") -MSG_DEF(JSMSG_TOPRIMITIVE_NOT_CALLABLE, 2, JSEXN_TYPEERR, "can't convert {0} to {1}: its [Symbol.toPrimitive] property is not a function") -MSG_DEF(JSMSG_TOPRIMITIVE_RETURNED_OBJECT, 2, JSEXN_TYPEERR, "can't convert {0} to {1}: its [Symbol.toPrimitive] method returned an object") -MSG_DEF(JSMSG_NO_PROPERTIES, 1, JSEXN_TYPEERR, "{0} has no properties") -MSG_DEF(JSMSG_BAD_REGEXP_FLAG, 1, JSEXN_SYNTAXERR, "invalid regular expression flag {0}") -MSG_DEF(JSMSG_ARG_INDEX_OUT_OF_RANGE, 1, JSEXN_RANGEERR, "argument {0} accesses an index that is out of range") -MSG_DEF(JSMSG_SPREAD_TOO_LARGE, 0, JSEXN_RANGEERR, "array too large due to spread operand(s)") -MSG_DEF(JSMSG_BAD_WEAKMAP_KEY, 0, JSEXN_TYPEERR, "cannot use the given object as a weak map key") -MSG_DEF(JSMSG_BAD_GETTER_OR_SETTER, 1, JSEXN_TYPEERR, "invalid {0} usage") -MSG_DEF(JSMSG_BAD_ARRAY_LENGTH, 0, JSEXN_RANGEERR, "invalid array length") -MSG_DEF(JSMSG_REDECLARED_VAR, 2, JSEXN_SYNTAXERR, "redeclaration of {0} {1}") -MSG_DEF(JSMSG_UNDECLARED_VAR, 1, JSEXN_REFERENCEERR, "assignment to undeclared variable {0}") -MSG_DEF(JSMSG_GETTER_ONLY, 0, JSEXN_TYPEERR, "setting a property that has only a getter") -MSG_DEF(JSMSG_OVERWRITING_ACCESSOR, 1, JSEXN_TYPEERR, "can't overwrite accessor property {0}") -MSG_DEF(JSMSG_UNDEFINED_PROP, 1, JSEXN_REFERENCEERR, "reference to undefined property {0}") -MSG_DEF(JSMSG_INVALID_MAP_ITERABLE, 1, JSEXN_TYPEERR, "iterable for {0} should have array-like objects") -MSG_DEF(JSMSG_NESTING_GENERATOR, 0, JSEXN_TYPEERR, "already executing generator") -MSG_DEF(JSMSG_INCOMPATIBLE_METHOD, 3, JSEXN_TYPEERR, "{0} {1} called on incompatible {2}") -MSG_DEF(JSMSG_OBJECT_WATCH_DEPRECATED, 0, JSEXN_WARN, "Object.prototype.watch and unwatch are very slow, non-standard, and deprecated; use a getter/setter instead") -MSG_DEF(JSMSG_ARRAYBUFFER_SLICE_DEPRECATED, 0, JSEXN_WARN, "ArrayBuffer.slice is deprecated; use ArrayBuffer.prototype.slice instead") -MSG_DEF(JSMSG_BAD_SURROGATE_CHAR, 1, JSEXN_TYPEERR, "bad surrogate character {0}") -MSG_DEF(JSMSG_UTF8_CHAR_TOO_LARGE, 1, JSEXN_TYPEERR, "UTF-8 character {0} too large") -MSG_DEF(JSMSG_MALFORMED_UTF8_CHAR, 1, JSEXN_TYPEERR, "malformed UTF-8 character sequence at offset {0}") -MSG_DEF(JSMSG_BUILTIN_CTOR_NO_NEW, 1, JSEXN_TYPEERR, "calling a builtin {0} constructor without new is forbidden") -MSG_DEF(JSMSG_BAD_GENERATOR_YIELD, 1, JSEXN_TYPEERR, "yield from closing generator {0}") -MSG_DEF(JSMSG_EMPTY_ARRAY_REDUCE, 0, JSEXN_TYPEERR, "reduce of empty array with no initial value") -MSG_DEF(JSMSG_UNEXPECTED_TYPE, 2, JSEXN_TYPEERR, "{0} is {1}") -MSG_DEF(JSMSG_MISSING_FUN_ARG, 2, JSEXN_TYPEERR, "missing argument {0} when calling function {1}") -MSG_DEF(JSMSG_NOT_NONNULL_OBJECT, 1, JSEXN_TYPEERR, "{0} is not a non-null object") -MSG_DEF(JSMSG_SET_NON_OBJECT_RECEIVER, 1, JSEXN_TYPEERR, "can't assign to properties of {0}: not an object") -MSG_DEF(JSMSG_INVALID_DESCRIPTOR, 0, JSEXN_TYPEERR, "property descriptors must not specify a value or be writable when a getter or setter has been specified") -MSG_DEF(JSMSG_OBJECT_NOT_EXTENSIBLE, 1, JSEXN_TYPEERR, "{0}: Object is not extensible") -MSG_DEF(JSMSG_CANT_DEFINE_PROP_OBJECT_NOT_EXTENSIBLE, 2, JSEXN_TYPEERR, "can't define property {1}: {0} is not extensible") -MSG_DEF(JSMSG_CANT_REDEFINE_PROP, 1, JSEXN_TYPEERR, "can't redefine non-configurable property {0}") -MSG_DEF(JSMSG_CANT_REDEFINE_ARRAY_LENGTH, 0, JSEXN_TYPEERR, "can't redefine array length") -MSG_DEF(JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH, 0, JSEXN_TYPEERR, "can't define array index property past the end of an array with non-writable length") -MSG_DEF(JSMSG_BAD_GET_SET_FIELD, 1, JSEXN_TYPEERR, "property descriptor's {0} field is neither undefined nor a function") -MSG_DEF(JSMSG_THROW_TYPE_ERROR, 0, JSEXN_TYPEERR, "'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them") -MSG_DEF(JSMSG_NOT_EXPECTED_TYPE, 3, JSEXN_TYPEERR, "{0}: expected {1}, got {2}") -MSG_DEF(JSMSG_NOT_ITERABLE, 1, JSEXN_TYPEERR, "{0} is not iterable") -MSG_DEF(JSMSG_NOT_ITERATOR, 1, JSEXN_TYPEERR, "{0} is not iterator") -MSG_DEF(JSMSG_ALREADY_HAS_PRAGMA, 2, JSEXN_WARN, "{0} is being assigned a {1}, but already has one") -MSG_DEF(JSMSG_GET_ITER_RETURNED_PRIMITIVE, 0, JSEXN_TYPEERR, "[Symbol.iterator]() returned a non-object value") -MSG_DEF(JSMSG_NEXT_RETURNED_PRIMITIVE, 0, JSEXN_TYPEERR, "iterator.next() returned a non-object value") -MSG_DEF(JSMSG_CANT_SET_PROTO, 0, JSEXN_TYPEERR, "can't set prototype of this object") -MSG_DEF(JSMSG_CANT_SET_PROTO_OF, 1, JSEXN_TYPEERR, "can't set prototype of {0}") -MSG_DEF(JSMSG_CANT_SET_PROTO_CYCLE, 0, JSEXN_TYPEERR, "can't set prototype: it would cause a prototype chain cycle") -MSG_DEF(JSMSG_INVALID_ARG_TYPE, 3, JSEXN_TYPEERR, "Invalid type: {0} can't be a{1} {2}") -MSG_DEF(JSMSG_TERMINATED, 1, JSEXN_ERR, "Script terminated by timeout at:\n{0}") -MSG_DEF(JSMSG_PROTO_NOT_OBJORNULL, 1, JSEXN_TYPEERR, "{0}.prototype is not an object or null") -MSG_DEF(JSMSG_CANT_CALL_CLASS_CONSTRUCTOR, 0, JSEXN_TYPEERR, "class constructors must be invoked with |new|") -MSG_DEF(JSMSG_UNINITIALIZED_THIS, 1, JSEXN_REFERENCEERR, "|this| used uninitialized in {0} class constructor") -MSG_DEF(JSMSG_UNINITIALIZED_THIS_ARROW, 0, JSEXN_REFERENCEERR, "|this| used uninitialized in arrow function in class constructor") -MSG_DEF(JSMSG_BAD_DERIVED_RETURN, 1, JSEXN_TYPEERR, "derived class constructor returned invalid value {0}") - -// JSON -MSG_DEF(JSMSG_JSON_BAD_PARSE, 3, JSEXN_SYNTAXERR, "JSON.parse: {0} at line {1} column {2} of the JSON data") -MSG_DEF(JSMSG_JSON_CYCLIC_VALUE, 0, JSEXN_TYPEERR, "cyclic object value") - -// Runtime errors -MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS, 1, JSEXN_TYPEERR, "invalid 'instanceof' operand {0}") -MSG_DEF(JSMSG_BAD_LEFTSIDE_OF_ASS, 0, JSEXN_REFERENCEERR, "invalid assignment left-hand side") -MSG_DEF(JSMSG_BAD_PROTOTYPE, 1, JSEXN_TYPEERR, "'prototype' property of {0} is not an object") -MSG_DEF(JSMSG_IN_NOT_OBJECT, 1, JSEXN_TYPEERR, "invalid 'in' operand {0}") -MSG_DEF(JSMSG_TOO_MANY_CON_SPREADARGS, 0, JSEXN_RANGEERR, "too many constructor arguments") -MSG_DEF(JSMSG_TOO_MANY_FUN_SPREADARGS, 0, JSEXN_RANGEERR, "too many function arguments") -MSG_DEF(JSMSG_UNINITIALIZED_LEXICAL, 1, JSEXN_REFERENCEERR, "can't access lexical declaration `{0}' before initialization") -MSG_DEF(JSMSG_BAD_CONST_ASSIGN, 1, JSEXN_TYPEERR, "invalid assignment to const `{0}'") -MSG_DEF(JSMSG_CANT_DECLARE_GLOBAL_BINDING, 2, JSEXN_TYPEERR, "cannot declare global binding `{0}': {1}") - -// Date -MSG_DEF(JSMSG_INVALID_DATE, 0, JSEXN_RANGEERR, "invalid date") -MSG_DEF(JSMSG_BAD_TOISOSTRING_PROP, 0, JSEXN_TYPEERR, "toISOString property is not callable") - -// String -MSG_DEF(JSMSG_BAD_URI, 0, JSEXN_URIERR, "malformed URI sequence") -MSG_DEF(JSMSG_INVALID_NORMALIZE_FORM, 0, JSEXN_RANGEERR, "form must be one of 'NFC', 'NFD', 'NFKC', or 'NFKD'") -MSG_DEF(JSMSG_NEGATIVE_REPETITION_COUNT, 0, JSEXN_RANGEERR, "repeat count must be non-negative") -MSG_DEF(JSMSG_NOT_A_CODEPOINT, 1, JSEXN_RANGEERR, "{0} is not a valid code point") -MSG_DEF(JSMSG_RESULTING_STRING_TOO_LARGE, 0, JSEXN_RANGEERR, "repeat count must be less than infinity and not overflow maximum string size") - -// Number -MSG_DEF(JSMSG_BAD_RADIX, 0, JSEXN_RANGEERR, "radix must be an integer at least 2 and no greater than 36") -MSG_DEF(JSMSG_PRECISION_RANGE, 1, JSEXN_RANGEERR, "precision {0} out of range") - -// Function -MSG_DEF(JSMSG_BAD_APPLY_ARGS, 1, JSEXN_TYPEERR, "second argument to Function.prototype.{0} must be an array") -MSG_DEF(JSMSG_BAD_FORMAL, 0, JSEXN_SYNTAXERR, "malformed formal parameter") -MSG_DEF(JSMSG_CALLER_IS_STRICT, 0, JSEXN_TYPEERR, "access to strict mode caller function is censored") -MSG_DEF(JSMSG_DEPRECATED_USAGE, 1, JSEXN_REFERENCEERR, "deprecated {0} usage") -MSG_DEF(JSMSG_NOT_SCRIPTED_FUNCTION, 1, JSEXN_TYPEERR, "{0} is not a scripted function") -MSG_DEF(JSMSG_NO_REST_NAME, 0, JSEXN_SYNTAXERR, "no parameter name after ...") -MSG_DEF(JSMSG_PARAMETER_AFTER_REST, 0, JSEXN_SYNTAXERR, "parameter after rest parameter") -MSG_DEF(JSMSG_TOO_MANY_ARGUMENTS, 0, JSEXN_RANGEERR, "too many arguments provided for a function call") - -// CSP -MSG_DEF(JSMSG_CSP_BLOCKED_EVAL, 0, JSEXN_ERR, "call to eval() blocked by CSP") -MSG_DEF(JSMSG_CSP_BLOCKED_FUNCTION, 0, JSEXN_ERR, "call to Function() blocked by CSP") - -// Wrappers -MSG_DEF(JSMSG_ACCESSOR_DEF_DENIED, 1, JSEXN_ERR, "Permission denied to define accessor property {0}") -MSG_DEF(JSMSG_DEAD_OBJECT, 0, JSEXN_TYPEERR, "can't access dead object") -MSG_DEF(JSMSG_UNWRAP_DENIED, 0, JSEXN_ERR, "permission denied to unwrap object") - -// JSAPI-only (Not thrown as JS exceptions) -MSG_DEF(JSMSG_BAD_CLONE_FUNOBJ_SCOPE, 0, JSEXN_TYPEERR, "bad cloned function scope chain") -MSG_DEF(JSMSG_CANT_CLONE_OBJECT, 0, JSEXN_TYPEERR, "can't clone object") -MSG_DEF(JSMSG_CANT_OPEN, 2, JSEXN_ERR, "can't open {0}: {1}") -MSG_DEF(JSMSG_USER_DEFINED_ERROR, 0, JSEXN_ERR, "JS_ReportError was called") - -// Internal errors -MSG_DEF(JSMSG_ALLOC_OVERFLOW, 0, JSEXN_INTERNALERR, "allocation size overflow") -MSG_DEF(JSMSG_BAD_BYTECODE, 1, JSEXN_INTERNALERR, "unimplemented JavaScript bytecode {0}") -MSG_DEF(JSMSG_BUFFER_TOO_SMALL, 0, JSEXN_INTERNALERR, "buffer too small") -MSG_DEF(JSMSG_BUILD_ID_NOT_AVAILABLE, 0, JSEXN_INTERNALERR, "build ID is not available") -MSG_DEF(JSMSG_BYTECODE_TOO_BIG, 2, JSEXN_INTERNALERR, "bytecode {0} too large (limit {1})") -MSG_DEF(JSMSG_ERR_DURING_THROW, 0, JSEXN_INTERNALERR, "an internal error occurred while throwing an exception") -MSG_DEF(JSMSG_NEED_DIET, 1, JSEXN_INTERNALERR, "{0} too large") -MSG_DEF(JSMSG_OUT_OF_MEMORY, 0, JSEXN_INTERNALERR, "out of memory") -MSG_DEF(JSMSG_OVER_RECURSED, 0, JSEXN_INTERNALERR, "too much recursion") -MSG_DEF(JSMSG_TOO_BIG_TO_ENCODE, 0, JSEXN_INTERNALERR, "data are to big to encode") -MSG_DEF(JSMSG_TOO_DEEP, 1, JSEXN_INTERNALERR, "{0} nested too deeply") -MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION, 1, JSEXN_INTERNALERR, "uncaught exception: {0}") -MSG_DEF(JSMSG_UNKNOWN_FORMAT, 1, JSEXN_INTERNALERR, "unknown bytecode format {0}") - -// Frontend -MSG_DEF(JSMSG_ACCESSOR_WRONG_ARGS, 3, JSEXN_SYNTAXERR, "{0} functions must have {1} argument{2}") -MSG_DEF(JSMSG_ARRAY_COMP_LEFTSIDE, 0, JSEXN_SYNTAXERR, "invalid array comprehension left-hand side") -MSG_DEF(JSMSG_ARRAY_INIT_TOO_BIG, 0, JSEXN_INTERNALERR, "array initializer too large") -MSG_DEF(JSMSG_AS_AFTER_IMPORT_STAR, 0, JSEXN_SYNTAXERR, "missing keyword 'as' after import *") -MSG_DEF(JSMSG_AS_AFTER_RESERVED_WORD, 1, JSEXN_SYNTAXERR, "missing keyword 'as' after reserved word '{0}'") -MSG_DEF(JSMSG_ASYNC_GENERATOR, 0, JSEXN_SYNTAXERR, "generator function or method can't be async") -MSG_DEF(JSMSG_AWAIT_IN_DEFAULT, 0, JSEXN_SYNTAXERR, "await can't be used in default expression") -MSG_DEF(JSMSG_BAD_ANON_GENERATOR_RETURN, 0, JSEXN_TYPEERR, "anonymous generator function returns a value") -MSG_DEF(JSMSG_BAD_ARROW_ARGS, 0, JSEXN_SYNTAXERR, "invalid arrow-function arguments (parentheses around the arrow-function may help)") -MSG_DEF(JSMSG_BAD_BINDING, 1, JSEXN_SYNTAXERR, "redefining {0} is deprecated") -MSG_DEF(JSMSG_BAD_CONST_DECL, 0, JSEXN_SYNTAXERR, "missing = in const declaration") -MSG_DEF(JSMSG_BAD_CONTINUE, 0, JSEXN_SYNTAXERR, "continue must be inside loop") -MSG_DEF(JSMSG_BAD_DESTRUCT_ASS, 0, JSEXN_REFERENCEERR, "invalid destructuring assignment operator") -MSG_DEF(JSMSG_BAD_DESTRUCT_TARGET, 0, JSEXN_SYNTAXERR, "invalid destructuring target") -MSG_DEF(JSMSG_BAD_DESTRUCT_PARENS, 0, JSEXN_SYNTAXERR, "destructuring patterns in assignments can't be parenthesized") -MSG_DEF(JSMSG_BAD_DESTRUCT_DECL, 0, JSEXN_SYNTAXERR, "missing = in destructuring declaration") -MSG_DEF(JSMSG_BAD_DUP_ARGS, 0, JSEXN_SYNTAXERR, "duplicate argument names not allowed in this context") -MSG_DEF(JSMSG_BAD_FOR_EACH_LOOP, 0, JSEXN_SYNTAXERR, "invalid for each loop") -MSG_DEF(JSMSG_BAD_FOR_LEFTSIDE, 0, JSEXN_SYNTAXERR, "invalid for-in/of left-hand side") -MSG_DEF(JSMSG_LEXICAL_DECL_DEFINES_LET,0, JSEXN_SYNTAXERR, "a lexical declaration can't define a 'let' binding") -MSG_DEF(JSMSG_LET_STARTING_FOROF_LHS, 0, JSEXN_SYNTAXERR, "an expression X in 'for (X of Y)' must not start with 'let'") -MSG_DEF(JSMSG_BAD_GENERATOR_RETURN, 1, JSEXN_TYPEERR, "generator function {0} returns a value") -MSG_DEF(JSMSG_BAD_GENEXP_BODY, 1, JSEXN_SYNTAXERR, "illegal use of {0} in generator expression") -MSG_DEF(JSMSG_BAD_INCOP_OPERAND, 0, JSEXN_REFERENCEERR, "invalid increment/decrement operand") -MSG_DEF(JSMSG_BAD_METHOD_DEF, 0, JSEXN_SYNTAXERR, "bad method definition") -MSG_DEF(JSMSG_BAD_OCTAL, 1, JSEXN_SYNTAXERR, "{0} is not a legal ECMA-262 octal constant") -MSG_DEF(JSMSG_BAD_OPERAND, 1, JSEXN_SYNTAXERR, "invalid {0} operand") -MSG_DEF(JSMSG_BAD_POW_LEFTSIDE, 0, JSEXN_SYNTAXERR, "unparenthesized unary expression can't appear on the left-hand side of '**'") -MSG_DEF(JSMSG_BAD_PROP_ID, 0, JSEXN_SYNTAXERR, "invalid property id") -MSG_DEF(JSMSG_BAD_RETURN_OR_YIELD, 1, JSEXN_SYNTAXERR, "{0} not in function") -MSG_DEF(JSMSG_BAD_STRICT_ASSIGN, 1, JSEXN_SYNTAXERR, "'{0}' can't be defined or assigned to in strict mode code") -MSG_DEF(JSMSG_BAD_SWITCH, 0, JSEXN_SYNTAXERR, "invalid switch statement") -MSG_DEF(JSMSG_BAD_SUPER, 0, JSEXN_SYNTAXERR, "invalid use of keyword 'super'") -MSG_DEF(JSMSG_BAD_SUPERPROP, 1, JSEXN_SYNTAXERR, "use of super {0} accesses only valid within methods or eval code within methods") -MSG_DEF(JSMSG_BAD_SUPERCALL, 0, JSEXN_SYNTAXERR, "super() is only valid in derived class constructors") -MSG_DEF(JSMSG_BRACKET_AFTER_ARRAY_COMPREHENSION, 0, JSEXN_SYNTAXERR, "missing ] after array comprehension") -MSG_DEF(JSMSG_BRACKET_AFTER_LIST, 0, JSEXN_SYNTAXERR, "missing ] after element list") -MSG_DEF(JSMSG_BRACKET_IN_INDEX, 0, JSEXN_SYNTAXERR, "missing ] in index expression") -MSG_DEF(JSMSG_CATCH_AFTER_GENERAL, 0, JSEXN_SYNTAXERR, "catch after unconditional catch") -MSG_DEF(JSMSG_CATCH_IDENTIFIER, 0, JSEXN_SYNTAXERR, "missing identifier in catch") -MSG_DEF(JSMSG_CATCH_OR_FINALLY, 0, JSEXN_SYNTAXERR, "missing catch or finally after try") -MSG_DEF(JSMSG_CATCH_WITHOUT_TRY, 0, JSEXN_SYNTAXERR, "catch without try") -MSG_DEF(JSMSG_COLON_AFTER_CASE, 0, JSEXN_SYNTAXERR, "missing : after case label") -MSG_DEF(JSMSG_COLON_AFTER_ID, 0, JSEXN_SYNTAXERR, "missing : after property id") -MSG_DEF(JSMSG_COLON_IN_COND, 0, JSEXN_SYNTAXERR, "missing : in conditional expression") -MSG_DEF(JSMSG_COMP_PROP_UNTERM_EXPR, 0, JSEXN_SYNTAXERR, "missing ] in computed property name") -MSG_DEF(JSMSG_CONTRARY_NONDIRECTIVE, 1, JSEXN_SYNTAXERR, "'{0}' statement won't be enforced as a directive because it isn't in directive prologue position") -MSG_DEF(JSMSG_CURLY_AFTER_BODY, 0, JSEXN_SYNTAXERR, "missing } after function body") -MSG_DEF(JSMSG_CURLY_AFTER_CATCH, 0, JSEXN_SYNTAXERR, "missing } after catch block") -MSG_DEF(JSMSG_CURLY_AFTER_FINALLY, 0, JSEXN_SYNTAXERR, "missing } after finally block") -MSG_DEF(JSMSG_CURLY_AFTER_LIST, 0, JSEXN_SYNTAXERR, "missing } after property list") -MSG_DEF(JSMSG_CURLY_AFTER_TRY, 0, JSEXN_SYNTAXERR, "missing } after try block") -MSG_DEF(JSMSG_CURLY_BEFORE_BODY, 0, JSEXN_SYNTAXERR, "missing { before function body") -MSG_DEF(JSMSG_CURLY_BEFORE_CATCH, 0, JSEXN_SYNTAXERR, "missing { before catch block") -MSG_DEF(JSMSG_CURLY_BEFORE_CLASS, 0, JSEXN_SYNTAXERR, "missing { before class body") -MSG_DEF(JSMSG_CURLY_BEFORE_FINALLY, 0, JSEXN_SYNTAXERR, "missing { before finally block") -MSG_DEF(JSMSG_CURLY_BEFORE_SWITCH, 0, JSEXN_SYNTAXERR, "missing { before switch body") -MSG_DEF(JSMSG_CURLY_BEFORE_TRY, 0, JSEXN_SYNTAXERR, "missing { before try block") -MSG_DEF(JSMSG_CURLY_IN_COMPOUND, 0, JSEXN_SYNTAXERR, "missing } in compound statement") -MSG_DEF(JSMSG_DECLARATION_AFTER_EXPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'export' keyword") -MSG_DEF(JSMSG_DECLARATION_AFTER_IMPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'import' keyword") -MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 0, JSEXN_SYNTAXERR, "applying the 'delete' operator to an unqualified name is deprecated") -MSG_DEF(JSMSG_DEPRECATED_EXPR_CLOSURE, 0, JSEXN_WARN, "expression closures are deprecated") -MSG_DEF(JSMSG_DEPRECATED_FOR_EACH, 0, JSEXN_WARN, "JavaScript 1.6's for-each-in loops are deprecated; consider using ES6 for-of instead") -MSG_DEF(JSMSG_DEPRECATED_OCTAL, 0, JSEXN_SYNTAXERR, "\"0\"-prefixed octal literals and octal escape sequences are deprecated; for octal literals use the \"0o\" prefix instead") -MSG_DEF(JSMSG_DEPRECATED_PRAGMA, 1, JSEXN_WARN, "Using //@ to indicate {0} pragmas is deprecated. Use //# instead") -MSG_DEF(JSMSG_DEPRECATED_BLOCK_SCOPE_FUN_REDECL, 1, JSEXN_WARN, "redeclaration of block-scoped function `{0}' is deprecated") -MSG_DEF(JSMSG_DUPLICATE_EXPORT_NAME, 1, JSEXN_SYNTAXERR, "duplicate export name '{0}'") -MSG_DEF(JSMSG_DUPLICATE_FORMAL, 1, JSEXN_SYNTAXERR, "duplicate formal argument {0}") -MSG_DEF(JSMSG_DUPLICATE_LABEL, 0, JSEXN_SYNTAXERR, "duplicate label") -MSG_DEF(JSMSG_DUPLICATE_PROPERTY, 1, JSEXN_SYNTAXERR, "property name {0} appears more than once in object literal") -MSG_DEF(JSMSG_DUPLICATE_PROTO_PROPERTY, 0, JSEXN_SYNTAXERR, "property name __proto__ appears more than once in object literal") -MSG_DEF(JSMSG_EMPTY_CONSEQUENT, 0, JSEXN_SYNTAXERR, "mistyped ; after conditional?") -MSG_DEF(JSMSG_EQUAL_AS_ASSIGN, 0, JSEXN_SYNTAXERR, "test for equality (==) mistyped as assignment (=)?") -MSG_DEF(JSMSG_EXPORT_DECL_AT_TOP_LEVEL,0, JSEXN_SYNTAXERR, "export declarations may only appear at top level of a module") -MSG_DEF(JSMSG_FINALLY_WITHOUT_TRY, 0, JSEXN_SYNTAXERR, "finally without try") -MSG_DEF(JSMSG_FORBIDDEN_AS_STATEMENT, 1, JSEXN_SYNTAXERR, "{0} can't appear in single-statement context") -MSG_DEF(JSMSG_FROM_AFTER_IMPORT_CLAUSE, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after import clause") -MSG_DEF(JSMSG_FROM_AFTER_EXPORT_STAR, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after export *") -MSG_DEF(JSMSG_GARBAGE_AFTER_INPUT, 2, JSEXN_SYNTAXERR, "unexpected garbage after {0}, starting with {1}") -MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER, 0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal") -MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 0, JSEXN_SYNTAXERR, "illegal character") -MSG_DEF(JSMSG_IMPORT_DECL_AT_TOP_LEVEL, 0, JSEXN_SYNTAXERR, "import declarations may only appear at top level of a module") -MSG_DEF(JSMSG_INVALID_FOR_IN_DECL_WITH_INIT,0,JSEXN_SYNTAXERR,"for-in loop head declarations may not have initializers") -MSG_DEF(JSMSG_LABEL_NOT_FOUND, 0, JSEXN_SYNTAXERR, "label not found") -MSG_DEF(JSMSG_LET_COMP_BINDING, 0, JSEXN_SYNTAXERR, "'let' is not a valid name for a comprehension variable") -MSG_DEF(JSMSG_LEXICAL_DECL_NOT_IN_BLOCK, 1, JSEXN_SYNTAXERR, "{0} declaration not directly within block") -MSG_DEF(JSMSG_LEXICAL_DECL_LABEL, 1, JSEXN_SYNTAXERR, "{0} declarations cannot be labelled") -MSG_DEF(JSMSG_GENERATOR_LABEL, 0, JSEXN_SYNTAXERR, "generator functions cannot be labelled") -MSG_DEF(JSMSG_FUNCTION_LABEL, 0, JSEXN_SYNTAXERR, "functions cannot be labelled") -MSG_DEF(JSMSG_SLOPPY_FUNCTION_LABEL, 0, JSEXN_SYNTAXERR, "functions can only be labelled inside blocks") -MSG_DEF(JSMSG_LINE_BREAK_AFTER_THROW, 0, JSEXN_SYNTAXERR, "no line break is allowed between 'throw' and its expression") -MSG_DEF(JSMSG_LINE_BREAK_BEFORE_ARROW, 0, JSEXN_SYNTAXERR, "no line break is allowed before '=>'") -MSG_DEF(JSMSG_MALFORMED_ESCAPE, 1, JSEXN_SYNTAXERR, "malformed {0} character escape sequence") -MSG_DEF(JSMSG_MISSING_BINARY_DIGITS, 0, JSEXN_SYNTAXERR, "missing binary digits after '0b'") -MSG_DEF(JSMSG_MISSING_EXPONENT, 0, JSEXN_SYNTAXERR, "missing exponent") -MSG_DEF(JSMSG_MISSING_EXPR_AFTER_THROW,0, JSEXN_SYNTAXERR, "throw statement is missing an expression") -MSG_DEF(JSMSG_MISSING_FORMAL, 0, JSEXN_SYNTAXERR, "missing formal parameter") -MSG_DEF(JSMSG_MISSING_HEXDIGITS, 0, JSEXN_SYNTAXERR, "missing hexadecimal digits after '0x'") -MSG_DEF(JSMSG_MISSING_OCTAL_DIGITS, 0, JSEXN_SYNTAXERR, "missing octal digits after '0o'") -MSG_DEF(JSMSG_MODULE_SPEC_AFTER_FROM, 0, JSEXN_SYNTAXERR, "missing module specifier after 'from' keyword") -MSG_DEF(JSMSG_NAME_AFTER_DOT, 0, JSEXN_SYNTAXERR, "missing name after . operator") -MSG_DEF(JSMSG_NAMED_IMPORTS_OR_NAMESPACE_IMPORT, 0, JSEXN_SYNTAXERR, "expected named imports or namespace import after comma") -MSG_DEF(JSMSG_NO_BINDING_NAME, 0, JSEXN_SYNTAXERR, "missing binding name") -MSG_DEF(JSMSG_NO_EXPORT_NAME, 0, JSEXN_SYNTAXERR, "missing export name") -MSG_DEF(JSMSG_NO_IMPORT_NAME, 0, JSEXN_SYNTAXERR, "missing import name") -MSG_DEF(JSMSG_NO_VARIABLE_NAME, 0, JSEXN_SYNTAXERR, "missing variable name") -MSG_DEF(JSMSG_OF_AFTER_FOR_NAME, 0, JSEXN_SYNTAXERR, "missing 'of' after for") -MSG_DEF(JSMSG_PAREN_AFTER_ARGS, 0, JSEXN_SYNTAXERR, "missing ) after argument list") -MSG_DEF(JSMSG_PAREN_AFTER_CATCH, 0, JSEXN_SYNTAXERR, "missing ) after catch") -MSG_DEF(JSMSG_PAREN_AFTER_COND, 0, JSEXN_SYNTAXERR, "missing ) after condition") -MSG_DEF(JSMSG_PAREN_AFTER_FOR, 0, JSEXN_SYNTAXERR, "missing ( after for") -MSG_DEF(JSMSG_PAREN_AFTER_FORMAL, 0, JSEXN_SYNTAXERR, "missing ) after formal parameters") -MSG_DEF(JSMSG_PAREN_AFTER_FOR_CTRL, 0, JSEXN_SYNTAXERR, "missing ) after for-loop control") -MSG_DEF(JSMSG_PAREN_AFTER_FOR_OF_ITERABLE, 0, JSEXN_SYNTAXERR, "missing ) after for-of iterable") -MSG_DEF(JSMSG_PAREN_AFTER_SWITCH, 0, JSEXN_SYNTAXERR, "missing ) after switch expression") -MSG_DEF(JSMSG_PAREN_AFTER_WITH, 0, JSEXN_SYNTAXERR, "missing ) after with-statement object") -MSG_DEF(JSMSG_PAREN_BEFORE_CATCH, 0, JSEXN_SYNTAXERR, "missing ( before catch") -MSG_DEF(JSMSG_PAREN_BEFORE_COND, 0, JSEXN_SYNTAXERR, "missing ( before condition") -MSG_DEF(JSMSG_PAREN_BEFORE_FORMAL, 0, JSEXN_SYNTAXERR, "missing ( before formal parameters") -MSG_DEF(JSMSG_PAREN_BEFORE_SWITCH, 0, JSEXN_SYNTAXERR, "missing ( before switch expression") -MSG_DEF(JSMSG_PAREN_BEFORE_WITH, 0, JSEXN_SYNTAXERR, "missing ( before with-statement object") -MSG_DEF(JSMSG_PAREN_IN_PAREN, 0, JSEXN_SYNTAXERR, "missing ) in parenthetical") -MSG_DEF(JSMSG_RC_AFTER_EXPORT_SPEC_LIST, 0, JSEXN_SYNTAXERR, "missing '}' after export specifier list") -MSG_DEF(JSMSG_RC_AFTER_IMPORT_SPEC_LIST, 0, JSEXN_SYNTAXERR, "missing '}' after module specifier list") -MSG_DEF(JSMSG_REDECLARED_CATCH_IDENTIFIER, 1, JSEXN_SYNTAXERR, "redeclaration of identifier '{0}' in catch") -MSG_DEF(JSMSG_RESERVED_ID, 1, JSEXN_SYNTAXERR, "{0} is a reserved identifier") -MSG_DEF(JSMSG_REST_WITH_COMMA, 0, JSEXN_SYNTAXERR, "rest element may not have a trailing comma") -MSG_DEF(JSMSG_REST_WITH_DEFAULT, 0, JSEXN_SYNTAXERR, "rest parameter may not have a default") -MSG_DEF(JSMSG_SELFHOSTED_TOP_LEVEL_LEXICAL, 1, JSEXN_SYNTAXERR, "self-hosted code cannot contain top-level {0} declarations") -MSG_DEF(JSMSG_SELFHOSTED_METHOD_CALL, 0, JSEXN_SYNTAXERR, "self-hosted code may not contain direct method calls. Use callFunction() or callContentFunction()") -MSG_DEF(JSMSG_SELFHOSTED_UNBOUND_NAME, 0, JSEXN_TYPEERR, "self-hosted code may not contain unbound name lookups") -MSG_DEF(JSMSG_SEMI_AFTER_FOR_COND, 0, JSEXN_SYNTAXERR, "missing ; after for-loop condition") -MSG_DEF(JSMSG_SEMI_AFTER_FOR_INIT, 0, JSEXN_SYNTAXERR, "missing ; after for-loop initializer") -MSG_DEF(JSMSG_SEMI_BEFORE_STMNT, 0, JSEXN_SYNTAXERR, "missing ; before statement") -MSG_DEF(JSMSG_SOURCE_TOO_LONG, 0, JSEXN_RANGEERR, "source is too long") -MSG_DEF(JSMSG_STMT_AFTER_RETURN, 0, JSEXN_WARN, "unreachable code after return statement") -MSG_DEF(JSMSG_STRICT_CODE_WITH, 0, JSEXN_SYNTAXERR, "strict mode code may not contain 'with' statements") -MSG_DEF(JSMSG_STRICT_NON_SIMPLE_PARAMS, 1, JSEXN_SYNTAXERR, "\"use strict\" not allowed in function with {0} parameter") -MSG_DEF(JSMSG_TEMPLSTR_UNTERM_EXPR, 0, JSEXN_SYNTAXERR, "missing } in template string") -MSG_DEF(JSMSG_SIMD_NOT_A_VECTOR, 2, JSEXN_TYPEERR, "expecting a SIMD {0} object as argument {1}") -MSG_DEF(JSMSG_TOO_MANY_CASES, 0, JSEXN_INTERNALERR, "too many switch cases") -MSG_DEF(JSMSG_TOO_MANY_CATCH_VARS, 0, JSEXN_SYNTAXERR, "too many catch variables") -MSG_DEF(JSMSG_TOO_MANY_CON_ARGS, 0, JSEXN_SYNTAXERR, "too many constructor arguments") -MSG_DEF(JSMSG_TOO_MANY_DEFAULTS, 0, JSEXN_SYNTAXERR, "more than one switch default") -MSG_DEF(JSMSG_TOO_MANY_FUN_ARGS, 0, JSEXN_SYNTAXERR, "too many function arguments") -MSG_DEF(JSMSG_TOO_MANY_LOCALS, 0, JSEXN_SYNTAXERR, "too many local variables") -MSG_DEF(JSMSG_TOO_MANY_YIELDS, 0, JSEXN_SYNTAXERR, "too many yield expressions") -MSG_DEF(JSMSG_TOUGH_BREAK, 0, JSEXN_SYNTAXERR, "unlabeled break must be inside loop or switch") -MSG_DEF(JSMSG_UNEXPECTED_TOKEN, 2, JSEXN_SYNTAXERR, "expected {0}, got {1}") -MSG_DEF(JSMSG_UNNAMED_CLASS_STMT, 0, JSEXN_SYNTAXERR, "class statement requires a name") -MSG_DEF(JSMSG_UNNAMED_FUNCTION_STMT, 0, JSEXN_SYNTAXERR, "function statement requires a name") -MSG_DEF(JSMSG_UNTERMINATED_COMMENT, 0, JSEXN_SYNTAXERR, "unterminated comment") -MSG_DEF(JSMSG_UNTERMINATED_REGEXP, 0, JSEXN_SYNTAXERR, "unterminated regular expression literal") -MSG_DEF(JSMSG_UNTERMINATED_STRING, 0, JSEXN_SYNTAXERR, "unterminated string literal") -MSG_DEF(JSMSG_USELESS_EXPR, 0, JSEXN_TYPEERR, "useless expression") -MSG_DEF(JSMSG_USE_ASM_DIRECTIVE_FAIL, 0, JSEXN_SYNTAXERR, "\"use asm\" is only meaningful in the Directive Prologue of a function body") -MSG_DEF(JSMSG_VAR_HIDES_ARG, 1, JSEXN_TYPEERR, "variable {0} redeclares argument") -MSG_DEF(JSMSG_WHILE_AFTER_DO, 0, JSEXN_SYNTAXERR, "missing while after do-loop body") -MSG_DEF(JSMSG_YIELD_IN_ARROW, 0, JSEXN_SYNTAXERR, "arrow function may not contain yield") -MSG_DEF(JSMSG_YIELD_IN_DEFAULT, 0, JSEXN_SYNTAXERR, "yield in default expression") -MSG_DEF(JSMSG_YIELD_IN_METHOD, 0, JSEXN_SYNTAXERR, "non-generator method definitions may not contain yield") -MSG_DEF(JSMSG_BAD_COLUMN_NUMBER, 0, JSEXN_RANGEERR, "column number out of range") -MSG_DEF(JSMSG_COMPUTED_NAME_IN_PATTERN,0, JSEXN_SYNTAXERR, "computed property names aren't supported in this destructuring declaration") -MSG_DEF(JSMSG_DEFAULT_IN_PATTERN, 0, JSEXN_SYNTAXERR, "destructuring defaults aren't supported in this destructuring declaration") -MSG_DEF(JSMSG_BAD_NEWTARGET, 0, JSEXN_SYNTAXERR, "new.target only allowed within functions") -MSG_DEF(JSMSG_ESCAPED_KEYWORD, 0, JSEXN_SYNTAXERR, "keywords must be written literally, without embedded escapes") - -// asm.js -MSG_DEF(JSMSG_USE_ASM_TYPE_FAIL, 1, JSEXN_TYPEERR, "asm.js type error: {0}") -MSG_DEF(JSMSG_USE_ASM_LINK_FAIL, 1, JSEXN_TYPEERR, "asm.js link error: {0}") -MSG_DEF(JSMSG_USE_ASM_TYPE_OK, 1, JSEXN_WARN, "Successfully compiled asm.js code ({0})") - -// wasm -MSG_DEF(JSMSG_WASM_COMPILE_ERROR, 1, JSEXN_WASMCOMPILEERROR, "{0}") -MSG_DEF(JSMSG_WASM_IND_CALL_TO_NULL, 0, JSEXN_WASMRUNTIMEERROR, "indirect call to null") -MSG_DEF(JSMSG_WASM_IND_CALL_BAD_SIG, 0, JSEXN_WASMRUNTIMEERROR, "indirect call signature mismatch") -MSG_DEF(JSMSG_WASM_UNREACHABLE, 0, JSEXN_WASMRUNTIMEERROR, "unreachable executed") -MSG_DEF(JSMSG_WASM_INTEGER_OVERFLOW, 0, JSEXN_WASMRUNTIMEERROR, "integer overflow") -MSG_DEF(JSMSG_WASM_INVALID_CONVERSION, 0, JSEXN_WASMRUNTIMEERROR, "invalid conversion to integer") -MSG_DEF(JSMSG_WASM_INT_DIVIDE_BY_ZERO, 0, JSEXN_WASMRUNTIMEERROR, "integer divide by zero") -MSG_DEF(JSMSG_WASM_OUT_OF_BOUNDS, 0, JSEXN_WASMRUNTIMEERROR, "index out of bounds") -MSG_DEF(JSMSG_WASM_UNALIGNED_ACCESS, 0, JSEXN_WASMRUNTIMEERROR, "unaligned memory access") -MSG_DEF(JSMSG_WASM_BAD_UINT32, 2, JSEXN_RANGEERR, "bad {0} {1}") -MSG_DEF(JSMSG_WASM_BAD_GROW, 1, JSEXN_RANGEERR, "failed to grow {0}") -MSG_DEF(JSMSG_WASM_BAD_FIT, 2, JSEXN_RANGEERR, "{0} segment does not fit in {1}") -MSG_DEF(JSMSG_WASM_BAD_BUF_ARG, 0, JSEXN_TYPEERR, "first argument must be an ArrayBuffer or typed array object") -MSG_DEF(JSMSG_WASM_BAD_MOD_ARG, 0, JSEXN_TYPEERR, "first argument must be a WebAssembly.Module") -MSG_DEF(JSMSG_WASM_BAD_BUF_MOD_ARG, 0, JSEXN_TYPEERR, "first argument must be a WebAssembly.Module, ArrayBuffer or typed array object") -MSG_DEF(JSMSG_WASM_BAD_DESC_ARG, 1, JSEXN_TYPEERR, "first argument must be a {0} descriptor") -MSG_DEF(JSMSG_WASM_BAD_IMP_SIZE, 1, JSEXN_TYPEERR, "imported {0} with incompatible size") -MSG_DEF(JSMSG_WASM_BAD_IMP_MAX, 1, JSEXN_TYPEERR, "imported {0} with incompatible maximum size") -MSG_DEF(JSMSG_WASM_BAD_ELEMENT, 0, JSEXN_TYPEERR, "\"element\" property of table descriptor must be \"anyfunc\"") -MSG_DEF(JSMSG_WASM_BAD_IMPORT_ARG, 0, JSEXN_TYPEERR, "second argument must be an object") -MSG_DEF(JSMSG_WASM_BAD_IMPORT_FIELD, 2, JSEXN_TYPEERR, "import object field '{0}' is not {1}") -MSG_DEF(JSMSG_WASM_BAD_IMPORT_SIG, 0, JSEXN_TYPEERR, "imported function signature mismatch") -MSG_DEF(JSMSG_WASM_BAD_TABLE_VALUE, 0, JSEXN_TYPEERR, "can only assign WebAssembly exported functions to Table") -MSG_DEF(JSMSG_WASM_BAD_I64, 0, JSEXN_TYPEERR, "cannot pass i64 to or from JS") -MSG_DEF(JSMSG_WASM_NO_TRANSFER, 0, JSEXN_TYPEERR, "cannot transfer WebAssembly/asm.js ArrayBuffer") -MSG_DEF(JSMSG_WASM_TEXT_FAIL, 1, JSEXN_SYNTAXERR, "wasm text error: {0}") - -// Proxy -MSG_DEF(JSMSG_BAD_TRAP_RETURN_VALUE, 2, JSEXN_TYPEERR,"trap {1} for {0} returned a primitive value") -MSG_DEF(JSMSG_BAD_GETPROTOTYPEOF_TRAP_RETURN,0,JSEXN_TYPEERR,"proxy getPrototypeOf handler returned a non-object, non-null value") -MSG_DEF(JSMSG_INCONSISTENT_GETPROTOTYPEOF_TRAP,0,JSEXN_TYPEERR,"proxy getPrototypeOf handler didn't return the target object's prototype") -MSG_DEF(JSMSG_PROXY_SETPROTOTYPEOF_RETURNED_FALSE, 0, JSEXN_TYPEERR, "proxy setPrototypeOf handler returned false") -MSG_DEF(JSMSG_PROXY_ISEXTENSIBLE_RETURNED_FALSE,0,JSEXN_TYPEERR,"proxy isExtensible handler must return the same extensibility as target") -MSG_DEF(JSMSG_INCONSISTENT_SETPROTOTYPEOF_TRAP,0,JSEXN_TYPEERR,"proxy setPrototypeOf handler returned true, even though the target's prototype is immutable because the target is non-extensible") -MSG_DEF(JSMSG_CANT_CHANGE_EXTENSIBILITY, 0, JSEXN_TYPEERR, "can't change object's extensibility") -MSG_DEF(JSMSG_CANT_DEFINE_INVALID, 0, JSEXN_TYPEERR, "proxy can't define an incompatible property descriptor") -MSG_DEF(JSMSG_CANT_DEFINE_NEW, 0, JSEXN_TYPEERR, "proxy can't define a new property on a non-extensible object") -MSG_DEF(JSMSG_CANT_DEFINE_NE_AS_NC, 0, JSEXN_TYPEERR, "proxy can't define a non-existent property as non-configurable") -MSG_DEF(JSMSG_PROXY_DEFINE_RETURNED_FALSE, 1, JSEXN_TYPEERR, "proxy defineProperty handler returned false for property '{0}'") -MSG_DEF(JSMSG_PROXY_DELETE_RETURNED_FALSE, 1, JSEXN_TYPEERR, "can't delete property '{0}': proxy deleteProperty handler returned false") -MSG_DEF(JSMSG_PROXY_PREVENTEXTENSIONS_RETURNED_FALSE, 0, JSEXN_TYPEERR, "proxy preventExtensions handler returned false") -MSG_DEF(JSMSG_PROXY_SET_RETURNED_FALSE, 1, JSEXN_TYPEERR, "proxy set handler returned false for property '{0}'") -MSG_DEF(JSMSG_CANT_REPORT_AS_NON_EXTENSIBLE, 0, JSEXN_TYPEERR, "proxy can't report an extensible object as non-extensible") -MSG_DEF(JSMSG_CANT_REPORT_C_AS_NC, 0, JSEXN_TYPEERR, "proxy can't report existing configurable property as non-configurable") -MSG_DEF(JSMSG_CANT_REPORT_E_AS_NE, 0, JSEXN_TYPEERR, "proxy can't report an existing own property as non-existent on a non-extensible object") -MSG_DEF(JSMSG_CANT_REPORT_INVALID, 0, JSEXN_TYPEERR, "proxy can't report an incompatible property descriptor") -MSG_DEF(JSMSG_CANT_REPORT_NC_AS_NE, 0, JSEXN_TYPEERR, "proxy can't report a non-configurable own property as non-existent") -MSG_DEF(JSMSG_CANT_REPORT_NEW, 0, JSEXN_TYPEERR, "proxy can't report a new property on a non-extensible object") -MSG_DEF(JSMSG_CANT_REPORT_NE_AS_NC, 0, JSEXN_TYPEERR, "proxy can't report a non-existent property as non-configurable") -MSG_DEF(JSMSG_CANT_SET_NW_NC, 0, JSEXN_TYPEERR, "proxy can't successfully set a non-writable, non-configurable property") -MSG_DEF(JSMSG_CANT_SET_WO_SETTER, 0, JSEXN_TYPEERR, "proxy can't succesfully set an accessor property without a setter") -MSG_DEF(JSMSG_CANT_SKIP_NC, 0, JSEXN_TYPEERR, "proxy can't skip a non-configurable property") -MSG_DEF(JSMSG_ONWKEYS_STR_SYM, 0, JSEXN_TYPEERR, "proxy [[OwnPropertyKeys]] must return an array with only string and symbol elements") -MSG_DEF(JSMSG_MUST_REPORT_SAME_VALUE, 0, JSEXN_TYPEERR, "proxy must report the same value for a non-writable, non-configurable property") -MSG_DEF(JSMSG_MUST_REPORT_UNDEFINED, 0, JSEXN_TYPEERR, "proxy must report undefined for a non-configurable accessor property without a getter") -MSG_DEF(JSMSG_OBJECT_ACCESS_DENIED, 0, JSEXN_ERR, "Permission denied to access object") -MSG_DEF(JSMSG_PROPERTY_ACCESS_DENIED, 1, JSEXN_ERR, "Permission denied to access property {0}") -MSG_DEF(JSMSG_PROXY_CONSTRUCT_OBJECT, 0, JSEXN_TYPEERR, "proxy [[Construct]] must return an object") -MSG_DEF(JSMSG_PROXY_EXTENSIBILITY, 0, JSEXN_TYPEERR, "proxy must report same extensiblitity as target") -MSG_DEF(JSMSG_PROXY_GETOWN_OBJORUNDEF, 0, JSEXN_TYPEERR, "proxy [[GetOwnProperty]] must return an object or undefined") -MSG_DEF(JSMSG_PROXY_REVOKED, 0, JSEXN_TYPEERR, "illegal operation attempted on a revoked proxy") -MSG_DEF(JSMSG_PROXY_ARG_REVOKED, 1, JSEXN_TYPEERR, "argument {0} cannot be a revoked proxy") -MSG_DEF(JSMSG_BAD_TRAP, 1, JSEXN_TYPEERR, "proxy handler's {0} trap wasn't undefined, null, or callable") - -// Structured cloning -MSG_DEF(JSMSG_SC_BAD_CLONE_VERSION, 0, JSEXN_ERR, "unsupported structured clone version") -MSG_DEF(JSMSG_SC_BAD_SERIALIZED_DATA, 1, JSEXN_INTERNALERR, "bad serialized structured data ({0})") -MSG_DEF(JSMSG_SC_DUP_TRANSFERABLE, 0, JSEXN_TYPEERR, "duplicate transferable for structured clone") -MSG_DEF(JSMSG_SC_NOT_TRANSFERABLE, 0, JSEXN_TYPEERR, "invalid transferable array for structured clone") -MSG_DEF(JSMSG_SC_UNSUPPORTED_TYPE, 0, JSEXN_TYPEERR, "unsupported type for structured data") -MSG_DEF(JSMSG_SC_NOT_CLONABLE, 1, JSEXN_TYPEERR, "{0} cannot be cloned in this context") -MSG_DEF(JSMSG_SC_SAB_TRANSFER, 0, JSEXN_WARN, "SharedArrayBuffer must not be in the transfer list") -MSG_DEF(JSMSG_SC_SAB_DISABLED, 0, JSEXN_TYPEERR, "SharedArrayBuffer not cloned - shared memory disabled in receiver") - -// Debugger -MSG_DEF(JSMSG_ASSIGN_FUNCTION_OR_NULL, 1, JSEXN_TYPEERR, "value assigned to {0} must be a function or null") -MSG_DEF(JSMSG_DEBUG_BAD_AWAIT, 0, JSEXN_TYPEERR, "await expression received invalid value") -MSG_DEF(JSMSG_DEBUG_BAD_LINE, 0, JSEXN_TYPEERR, "invalid line number") -MSG_DEF(JSMSG_DEBUG_BAD_OFFSET, 0, JSEXN_TYPEERR, "invalid script offset") -MSG_DEF(JSMSG_DEBUG_BAD_REFERENT, 2, JSEXN_TYPEERR, "{0} does not refer to {1}") -MSG_DEF(JSMSG_DEBUG_BAD_RESUMPTION, 0, JSEXN_TYPEERR, "debugger resumption value must be undefined, {throw: val}, {return: val}, or null") -MSG_DEF(JSMSG_DEBUG_BAD_YIELD, 0, JSEXN_TYPEERR, "generator yielded invalid value") -MSG_DEF(JSMSG_DEBUG_CANT_DEBUG_GLOBAL, 0, JSEXN_TYPEERR, "passing non-debuggable global to addDebuggee") -MSG_DEF(JSMSG_DEBUG_CCW_REQUIRED, 1, JSEXN_TYPEERR, "{0}: argument must be an object from a different compartment") -MSG_DEF(JSMSG_DEBUG_COMPARTMENT_MISMATCH, 2, JSEXN_TYPEERR, "{0}: descriptor .{1} property is an object in a different compartment than the target object") -MSG_DEF(JSMSG_DEBUG_LOOP, 0, JSEXN_TYPEERR, "cannot debug an object in same compartment as debugger or a compartment that is already debugging the debugger") -MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGEE, 2, JSEXN_ERR, "{0} is not a debuggee {1}") -MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGING, 0, JSEXN_ERR, "can't set breakpoint: script global is not a debuggee") -MSG_DEF(JSMSG_DEBUG_NOT_IDLE, 0, JSEXN_ERR, "can't start debugging: a debuggee script is on the stack") -MSG_DEF(JSMSG_DEBUG_NOT_LIVE, 1, JSEXN_ERR, "{0} is not live") -MSG_DEF(JSMSG_DEBUG_NO_ENV_OBJECT, 0, JSEXN_TYPEERR, "declarative Environments don't have binding objects") -MSG_DEF(JSMSG_DEBUG_PROTO, 2, JSEXN_TYPEERR, "{0}.prototype is not a valid {1} instance") -MSG_DEF(JSMSG_DEBUG_WRONG_OWNER, 1, JSEXN_TYPEERR, "{0} belongs to a different Debugger") -MSG_DEF(JSMSG_DEBUG_OPTIMIZED_OUT, 1, JSEXN_ERR, "variable `{0}' has been optimized out") -MSG_DEF(JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED, 0, JSEXN_TYPEERR, "resumption values are disallowed in this hook") -MSG_DEF(JSMSG_DEBUG_VARIABLE_NOT_FOUND,0, JSEXN_TYPEERR, "variable not found in environment") -MSG_DEF(JSMSG_DEBUG_WRAPPER_IN_WAY, 3, JSEXN_TYPEERR, "{0} is {1}{2}a global object, but a direct reference is required") -MSG_DEF(JSMSG_DEBUGGEE_WOULD_RUN, 2, JSEXN_DEBUGGEEWOULDRUN, "debuggee `{0}:{1}' would run") -MSG_DEF(JSMSG_NOT_CALLABLE_OR_UNDEFINED, 0, JSEXN_TYPEERR, "value is not a function or undefined") -MSG_DEF(JSMSG_NOT_TRACKING_ALLOCATIONS, 1, JSEXN_ERR, "Cannot call {0} without setting trackingAllocationSites to true") -MSG_DEF(JSMSG_OBJECT_METADATA_CALLBACK_ALREADY_SET, 0, JSEXN_ERR, "Cannot track object allocation, because other tools are already doing so") -MSG_DEF(JSMSG_QUERY_INNERMOST_WITHOUT_LINE_URL, 0, JSEXN_TYPEERR, "findScripts query object with 'innermost' property must have 'line' and either 'displayURL', 'url', or 'source'") -MSG_DEF(JSMSG_QUERY_LINE_WITHOUT_URL, 0, JSEXN_TYPEERR, "findScripts query object has 'line' property, but no 'displayURL', 'url', or 'source' property") -MSG_DEF(JSMSG_DEBUG_CANT_SET_OPT_ENV, 1, JSEXN_REFERENCEERR, "can't set `{0}' in an optimized-out environment") -MSG_DEF(JSMSG_DEBUG_INVISIBLE_COMPARTMENT, 0, JSEXN_TYPEERR, "object in compartment marked as invisible to Debugger") -MSG_DEF(JSMSG_DEBUG_CENSUS_BREAKDOWN, 1, JSEXN_TYPEERR, "unrecognized 'by' value in takeCensus breakdown: {0}") -MSG_DEF(JSMSG_DEBUG_PROMISE_NOT_RESOLVED, 0, JSEXN_TYPEERR, "Promise hasn't been resolved") -MSG_DEF(JSMSG_DEBUG_PROMISE_NOT_FULFILLED, 0, JSEXN_TYPEERR, "Promise hasn't been fulfilled") -MSG_DEF(JSMSG_DEBUG_PROMISE_NOT_REJECTED, 0, JSEXN_TYPEERR, "Promise hasn't been rejected") - -// Tracelogger -MSG_DEF(JSMSG_TRACELOGGER_ENABLE_FAIL, 1, JSEXN_ERR, "enabling tracelogger failed: {0}") - -// Intl -MSG_DEF(JSMSG_DATE_NOT_FINITE, 0, JSEXN_RANGEERR, "date value is not finite in DateTimeFormat.format()") -MSG_DEF(JSMSG_INTERNAL_INTL_ERROR, 0, JSEXN_ERR, "internal error while computing Intl data") -MSG_DEF(JSMSG_INTL_OBJECT_NOT_INITED, 3, JSEXN_TYPEERR, "Intl.{0}.prototype.{1} called on value that's not an object initialized as a {2}") -MSG_DEF(JSMSG_INTL_OBJECT_REINITED, 0, JSEXN_TYPEERR, "can't initialize object twice as an object of an Intl constructor") -MSG_DEF(JSMSG_INVALID_CURRENCY_CODE, 1, JSEXN_RANGEERR, "invalid currency code in NumberFormat(): {0}") -MSG_DEF(JSMSG_INVALID_DIGITS_VALUE, 1, JSEXN_RANGEERR, "invalid digits value: {0}") -MSG_DEF(JSMSG_INVALID_LANGUAGE_TAG, 1, JSEXN_RANGEERR, "invalid language tag: {0}") -MSG_DEF(JSMSG_INVALID_LOCALES_ELEMENT, 0, JSEXN_TYPEERR, "invalid element in locales argument") -MSG_DEF(JSMSG_INVALID_LOCALE_MATCHER, 1, JSEXN_RANGEERR, "invalid locale matcher in supportedLocalesOf(): {0}") -MSG_DEF(JSMSG_INVALID_OPTION_VALUE, 2, JSEXN_RANGEERR, "invalid value {1} for option {0}") -MSG_DEF(JSMSG_INVALID_TIME_ZONE, 1, JSEXN_RANGEERR, "invalid time zone in DateTimeFormat(): {0}") -MSG_DEF(JSMSG_UNDEFINED_CURRENCY, 0, JSEXN_TYPEERR, "undefined currency in NumberFormat() with currency style") - -// RegExp -MSG_DEF(JSMSG_BACK_REF_OUT_OF_RANGE, 0, JSEXN_SYNTAXERR, "back reference out of range in regular expression") -MSG_DEF(JSMSG_BAD_CLASS_RANGE, 0, JSEXN_SYNTAXERR, "invalid range in character class") -MSG_DEF(JSMSG_ESCAPE_AT_END_OF_REGEXP, 0, JSEXN_SYNTAXERR, "\\ at end of pattern") -MSG_DEF(JSMSG_EXEC_NOT_OBJORNULL, 0, JSEXN_TYPEERR, "RegExp exec method should return object or null") -MSG_DEF(JSMSG_INVALID_DECIMAL_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid decimal escape in regular expression") -MSG_DEF(JSMSG_INVALID_GROUP, 0, JSEXN_SYNTAXERR, "invalid regexp group") -MSG_DEF(JSMSG_INVALID_IDENTITY_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid identity escape in regular expression") -MSG_DEF(JSMSG_INVALID_UNICODE_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid unicode escape in regular expression") -MSG_DEF(JSMSG_MISSING_PAREN, 0, JSEXN_SYNTAXERR, "unterminated parenthetical") -MSG_DEF(JSMSG_NEWREGEXP_FLAGGED, 0, JSEXN_TYPEERR, "can't supply flags when constructing one RegExp from another") -MSG_DEF(JSMSG_NOTHING_TO_REPEAT, 0, JSEXN_SYNTAXERR, "nothing to repeat") -MSG_DEF(JSMSG_NUMBERS_OUT_OF_ORDER, 0, JSEXN_SYNTAXERR, "numbers out of order in {} quantifier.") -MSG_DEF(JSMSG_RANGE_WITH_CLASS_ESCAPE, 0, JSEXN_SYNTAXERR, "character class escape cannot be used in class range in regular expression") -MSG_DEF(JSMSG_RAW_BRACE_IN_REGEP, 0, JSEXN_SYNTAXERR, "raw brace is not allowed in regular expression with unicode flag") -MSG_DEF(JSMSG_RAW_BRACKET_IN_REGEP, 0, JSEXN_SYNTAXERR, "raw bracket is not allowed in regular expression with unicode flag") -MSG_DEF(JSMSG_TOO_MANY_PARENS, 0, JSEXN_INTERNALERR, "too many parentheses in regular expression") -MSG_DEF(JSMSG_UNICODE_OVERFLOW, 0, JSEXN_SYNTAXERR, "unicode codepoint should not be greater than 0x10FFFF in regular expression") -MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN, 0, JSEXN_SYNTAXERR, "unmatched ) in regular expression") -MSG_DEF(JSMSG_UNTERM_CLASS, 0, JSEXN_SYNTAXERR, "unterminated character class") - -// Self-hosting -MSG_DEF(JSMSG_DEFAULT_LOCALE_ERROR, 0, JSEXN_ERR, "internal error getting the default locale") -MSG_DEF(JSMSG_NO_SUCH_SELF_HOSTED_PROP,1, JSEXN_ERR, "No such property on self-hosted object: {0}") - -// Typed object / SIMD -MSG_DEF(JSMSG_INVALID_PROTOTYPE, 0, JSEXN_TYPEERR, "prototype field is not an object") -MSG_DEF(JSMSG_TYPEDOBJECT_BAD_ARGS, 0, JSEXN_TYPEERR, "invalid arguments") -MSG_DEF(JSMSG_TYPEDOBJECT_BINARYARRAY_BAD_INDEX, 0, JSEXN_RANGEERR, "invalid or out-of-range index") -MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED, 0, JSEXN_TYPEERR, "handle unattached") -MSG_DEF(JSMSG_TYPEDOBJECT_STRUCTTYPE_BAD_ARGS, 0, JSEXN_RANGEERR, "invalid field descriptor") -MSG_DEF(JSMSG_TYPEDOBJECT_TOO_BIG, 0, JSEXN_ERR, "Type is too large to allocate") -MSG_DEF(JSMSG_SIMD_FAILED_CONVERSION, 0, JSEXN_RANGEERR, "SIMD conversion loses precision") -MSG_DEF(JSMSG_SIMD_TO_NUMBER, 0, JSEXN_TYPEERR, "can't convert SIMD value to number") - -// Array -MSG_DEF(JSMSG_TOO_LONG_ARRAY, 0, JSEXN_TYPEERR, "Too long array") - -// Typed array -MSG_DEF(JSMSG_BAD_INDEX, 0, JSEXN_RANGEERR, "invalid or out-of-range index") -MSG_DEF(JSMSG_NON_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected ArrayBuffer, but species constructor returned non-ArrayBuffer") -MSG_DEF(JSMSG_SAME_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected different ArrayBuffer, but species constructor returned same ArrayBuffer") -MSG_DEF(JSMSG_SHORT_ARRAY_BUFFER_RETURNED, 2, JSEXN_TYPEERR, "expected ArrayBuffer with at least {0} bytes, but species constructor returns ArrayBuffer with {1} bytes") -MSG_DEF(JSMSG_TYPED_ARRAY_BAD_ARGS, 0, JSEXN_TYPEERR, "invalid arguments") -MSG_DEF(JSMSG_TYPED_ARRAY_NEGATIVE_ARG,1, JSEXN_RANGEERR, "argument {0} must be >= 0") -MSG_DEF(JSMSG_TYPED_ARRAY_DETACHED, 0, JSEXN_TYPEERR, "attempting to access detached ArrayBuffer") -MSG_DEF(JSMSG_TYPED_ARRAY_CONSTRUCT_BOUNDS, 0, JSEXN_RANGEERR, "attempting to construct out-of-bounds TypedArray on ArrayBuffer") -MSG_DEF(JSMSG_TYPED_ARRAY_CALL_OR_CONSTRUCT, 1, JSEXN_TYPEERR, "cannot directly {0} builtin %TypedArray%") -MSG_DEF(JSMSG_NON_TYPED_ARRAY_RETURNED, 0, JSEXN_TYPEERR, "constructor didn't return TypedArray object") -MSG_DEF(JSMSG_SHORT_TYPED_ARRAY_RETURNED, 2, JSEXN_TYPEERR, "expected TypedArray of at least length {0}, but constructor returned TypedArray of length {1}") - -// Shared array buffer -MSG_DEF(JSMSG_SHARED_ARRAY_BAD_LENGTH, 0, JSEXN_RANGEERR, "length argument out of range") -MSG_DEF(JSMSG_NON_SHARED_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected SharedArrayBuffer, but species constructor returned non-SharedArrayBuffer") -MSG_DEF(JSMSG_SAME_SHARED_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected different SharedArrayBuffer, but species constructor returned same SharedArrayBuffer") -MSG_DEF(JSMSG_SHORT_SHARED_ARRAY_BUFFER_RETURNED, 2, JSEXN_TYPEERR, "expected SharedArrayBuffer with at least {0} bytes, but species constructor returns SharedArrayBuffer with {1} bytes") - -// Reflect -MSG_DEF(JSMSG_BAD_PARSE_NODE, 0, JSEXN_INTERNALERR, "bad parse node") - -// Symbol -MSG_DEF(JSMSG_SYMBOL_TO_STRING, 0, JSEXN_TYPEERR, "can't convert symbol to string") -MSG_DEF(JSMSG_SYMBOL_TO_NUMBER, 0, JSEXN_TYPEERR, "can't convert symbol to number") - -// Atomics and futexes -MSG_DEF(JSMSG_ATOMICS_BAD_ARRAY, 0, JSEXN_TYPEERR, "invalid array type for the operation") -MSG_DEF(JSMSG_ATOMICS_TOO_LONG, 0, JSEXN_RANGEERR, "timeout value too large") -MSG_DEF(JSMSG_ATOMICS_WAIT_NOT_ALLOWED, 0, JSEXN_ERR, "waiting is not allowed on this thread") - -// XPConnect wrappers and DOM bindings -MSG_DEF(JSMSG_CANT_SET_INTERPOSED, 1, JSEXN_TYPEERR, "unable to set interposed data property '{0}'") -MSG_DEF(JSMSG_CANT_DEFINE_WINDOW_ELEMENT, 0, JSEXN_TYPEERR, "can't define elements on a Window object") -MSG_DEF(JSMSG_CANT_DELETE_WINDOW_ELEMENT, 0, JSEXN_TYPEERR, "can't delete elements from a Window object") -MSG_DEF(JSMSG_CANT_DELETE_WINDOW_NAMED_PROPERTY, 1, JSEXN_TYPEERR, "can't delete property {0} from window's named properties object") -MSG_DEF(JSMSG_CANT_PREVENT_EXTENSIONS, 0, JSEXN_TYPEERR, "can't prevent extensions on this proxy object") -MSG_DEF(JSMSG_NO_NAMED_SETTER, 2, JSEXN_TYPEERR, "{0} doesn't have a named property setter for '{1}'") -MSG_DEF(JSMSG_NO_INDEXED_SETTER, 2, JSEXN_TYPEERR, "{0} doesn't have an indexed property setter for '{1}'") - -// Super -MSG_DEF(JSMSG_CANT_DELETE_SUPER, 0, JSEXN_REFERENCEERR, "invalid delete involving 'super'") -MSG_DEF(JSMSG_REINIT_THIS, 0, JSEXN_REFERENCEERR, "super() called twice in derived class constructor") - -// Modules -MSG_DEF(JSMSG_BAD_DEFAULT_EXPORT, 0, JSEXN_SYNTAXERR, "default export cannot be provided by export *") -MSG_DEF(JSMSG_MISSING_INDIRECT_EXPORT, 1, JSEXN_SYNTAXERR, "indirect export '{0}' not found") -MSG_DEF(JSMSG_AMBIGUOUS_INDIRECT_EXPORT, 1, JSEXN_SYNTAXERR, "ambiguous indirect export '{0}'") -MSG_DEF(JSMSG_MISSING_IMPORT, 1, JSEXN_SYNTAXERR, "import '{0}' not found") -MSG_DEF(JSMSG_AMBIGUOUS_IMPORT, 1, JSEXN_SYNTAXERR, "ambiguous import '{0}'") -MSG_DEF(JSMSG_MISSING_NAMESPACE_EXPORT, 0, JSEXN_SYNTAXERR, "export not found for namespace") -MSG_DEF(JSMSG_MISSING_EXPORT, 1, JSEXN_SYNTAXERR, "local binding for export '{0}' not found") -MSG_DEF(JSMSG_MODULE_INSTANTIATE_FAILED, 0, JSEXN_INTERNALERR, "attempt to re-instantiate module after failure") -MSG_DEF(JSMSG_BAD_MODULE_STATE, 0, JSEXN_INTERNALERR, "module record in unexpected state") - -// Promise -MSG_DEF(JSMSG_CANNOT_RESOLVE_PROMISE_WITH_ITSELF, 0, JSEXN_TYPEERR, "A promise cannot be resolved with itself.") -MSG_DEF(JSMSG_PROMISE_CAPABILITY_HAS_SOMETHING_ALREADY, 0, JSEXN_TYPEERR, "GetCapabilitiesExecutor function already invoked with non-undefined values.") -MSG_DEF(JSMSG_PROMISE_RESOLVE_FUNCTION_NOT_CALLABLE, 0, JSEXN_TYPEERR, "A Promise subclass passed a non-callable value as the resolve function.") -MSG_DEF(JSMSG_PROMISE_REJECT_FUNCTION_NOT_CALLABLE, 0, JSEXN_TYPEERR, "A Promise subclass passed a non-callable value as the reject function.") -MSG_DEF(JSMSG_PROMISE_ERROR_IN_WRAPPED_REJECTION_REASON,0, JSEXN_INTERNALERR, "Promise rejection value is a non-unwrappable cross-compartment wrapper.") diff --git a/android/armeabi-v7a/include/spidermonkey/js/CallArgs.h b/android/armeabi-v7a/include/spidermonkey/js/CallArgs.h deleted file mode 100644 index 1e0d909a..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/CallArgs.h +++ /dev/null @@ -1,369 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* - * Helper classes encapsulating access to the callee, |this| value, arguments, - * and argument count for a call/construct operation. - * - * JS::CallArgs encapsulates access to a JSNative's un-abstracted - * |unsigned argc, Value* vp| arguments. The principal way to create a - * JS::CallArgs is using JS::CallArgsFromVp: - * - * // If provided no arguments or a non-numeric first argument, return zero. - * // Otherwise return |this| exactly as given, without boxing. - * static bool - * Func(JSContext* cx, unsigned argc, JS::Value* vp) - * { - * JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - * - * // Guard against no arguments or a non-numeric arg0. - * if (args.length() == 0 || !args[0].isNumber()) { - * args.rval().setInt32(0); - * return true; - * } - * - * // Access to the callee must occur before accessing/setting - * // the return value. - * JSObject& callee = args.callee(); - * args.rval().setObject(callee); - * - * // callee() and calleev() will now assert. - * - * // It's always fine to access thisv(). - * HandleValue thisv = args.thisv(); - * args.rval().set(thisv); - * - * // As the return value was last set to |this|, returns |this|. - * return true; - * } - * - * CallArgs is exposed publicly and used internally. Not all parts of its - * public interface are meant to be used by embedders! See inline comments to - * for details. - * - * It's possible (albeit deprecated) to manually index into |vp| to access the - * callee, |this|, and arguments of a function, and to set its return value. - * It's also possible to use the supported API of JS_CALLEE, JS_THIS, JS_ARGV, - * JS_RVAL, and JS_SET_RVAL to the same ends. - * - * But neither API has the error-handling or moving-GC correctness of CallArgs. - * New code should use CallArgs instead whenever possible. - * - * The eventual plan is to change JSNative to take |const CallArgs&| directly, - * for automatic assertion of correct use and to make calling functions more - * efficient. Embedders should start internally switching away from using - * |argc| and |vp| directly, except to create a |CallArgs|. Then, when an - * eventual release making that change occurs, porting efforts will require - * changing methods' signatures but won't require invasive changes to the - * methods' implementations, potentially under time pressure. - */ - -#ifndef js_CallArgs_h -#define js_CallArgs_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/TypeTraits.h" - -#include "jstypes.h" - -#include "js/RootingAPI.h" -#include "js/Value.h" - -/* Typedef for native functions called by the JS VM. */ -typedef bool -(* JSNative)(JSContext* cx, unsigned argc, JS::Value* vp); - -namespace JS { - -extern JS_PUBLIC_DATA(const HandleValue) UndefinedHandleValue; - -namespace detail { - -/* - * Compute |this| for the |vp| inside a JSNative, either boxing primitives or - * replacing with the global object as necessary. - */ -extern JS_PUBLIC_API(Value) -ComputeThis(JSContext* cx, JS::Value* vp); - -#ifdef JS_DEBUG -extern JS_PUBLIC_API(void) -CheckIsValidConstructible(const Value& v); -#endif - -class MOZ_STACK_CLASS IncludeUsedRval -{ - protected: -#ifdef JS_DEBUG - mutable bool usedRval_; - void setUsedRval() const { usedRval_ = true; } - void clearUsedRval() const { usedRval_ = false; } - void assertUnusedRval() const { MOZ_ASSERT(!usedRval_); } -#else - void setUsedRval() const {} - void clearUsedRval() const {} - void assertUnusedRval() const {} -#endif -}; - -class MOZ_STACK_CLASS NoUsedRval -{ - protected: - void setUsedRval() const {} - void clearUsedRval() const {} - void assertUnusedRval() const {} -}; - -template -class MOZ_STACK_CLASS CallArgsBase : public WantUsedRval -{ - static_assert(mozilla::IsSame::value || - mozilla::IsSame::value, - "WantUsedRval can only be IncludeUsedRval or NoUsedRval"); - - protected: - Value* argv_; - unsigned argc_; - bool constructing_; - - public: - // CALLEE ACCESS - - /* - * Returns the function being called, as a value. Must not be called after - * rval() has been used! - */ - HandleValue calleev() const { - this->assertUnusedRval(); - return HandleValue::fromMarkedLocation(&argv_[-2]); - } - - /* - * Returns the function being called, as an object. Must not be called - * after rval() has been used! - */ - JSObject& callee() const { - return calleev().toObject(); - } - - // CALLING/CONSTRUCTING-DIFFERENTIATIONS - - bool isConstructing() const { - if (!argv_[-1].isMagic()) - return false; - -#ifdef JS_DEBUG - if (!this->usedRval_) - CheckIsValidConstructible(calleev()); -#endif - - return true; - } - - MutableHandleValue newTarget() const { - MOZ_ASSERT(constructing_); - return MutableHandleValue::fromMarkedLocation(&this->argv_[argc_]); - } - - /* - * Returns the |this| value passed to the function. This method must not - * be called when the function is being called as a constructor via |new|. - * The value may or may not be an object: it is the individual function's - * responsibility to box the value if needed. - */ - HandleValue thisv() const { - // Some internal code uses thisv() in constructing cases, so don't do - // this yet. - // MOZ_ASSERT(!argv_[-1].isMagic(JS_IS_CONSTRUCTING)); - return HandleValue::fromMarkedLocation(&argv_[-1]); - } - - Value computeThis(JSContext* cx) const { - if (thisv().isObject()) - return thisv(); - - return ComputeThis(cx, base()); - } - - // ARGUMENTS - - /* Returns the number of arguments. */ - unsigned length() const { return argc_; } - - /* Returns the i-th zero-indexed argument. */ - MutableHandleValue operator[](unsigned i) const { - MOZ_ASSERT(i < argc_); - return MutableHandleValue::fromMarkedLocation(&this->argv_[i]); - } - - /* - * Returns the i-th zero-indexed argument, or |undefined| if there's no - * such argument. - */ - HandleValue get(unsigned i) const { - return i < length() - ? HandleValue::fromMarkedLocation(&this->argv_[i]) - : UndefinedHandleValue; - } - - /* - * Returns true if the i-th zero-indexed argument is present and is not - * |undefined|. - */ - bool hasDefined(unsigned i) const { - return i < argc_ && !this->argv_[i].isUndefined(); - } - - // RETURN VALUE - - /* - * Returns the currently-set return value. The initial contents of this - * value are unspecified. Once this method has been called, callee() and - * calleev() can no longer be used. (If you're compiling against a debug - * build of SpiderMonkey, these methods will assert to aid debugging.) - * - * If the method you're implementing succeeds by returning true, you *must* - * set this. (SpiderMonkey doesn't currently assert this, but it will do - * so eventually.) You don't need to use or change this if your method - * fails. - */ - MutableHandleValue rval() const { - this->setUsedRval(); - return MutableHandleValue::fromMarkedLocation(&argv_[-2]); - } - - public: - // These methods are publicly exposed, but they are *not* to be used when - // implementing a JSNative method and encapsulating access to |vp| within - // it. You probably don't want to use these! - - void setCallee(const Value& aCalleev) const { - this->clearUsedRval(); - argv_[-2] = aCalleev; - } - - void setThis(const Value& aThisv) const { - argv_[-1] = aThisv; - } - - MutableHandleValue mutableThisv() const { - return MutableHandleValue::fromMarkedLocation(&argv_[-1]); - } - - public: - // These methods are publicly exposed, but we're unsure of the interfaces - // (because they're hackish and drop assertions). Avoid using these if you - // can. - - Value* array() const { return argv_; } - Value* end() const { return argv_ + argc_ + constructing_; } - - public: - // These methods are only intended for internal use. Embedders shouldn't - // use them! - - Value* base() const { return argv_ - 2; } - - Value* spAfterCall() const { - this->setUsedRval(); - return argv_ - 1; - } -}; - -} // namespace detail - -class MOZ_STACK_CLASS CallArgs : public detail::CallArgsBase -{ - private: - friend CallArgs CallArgsFromVp(unsigned argc, Value* vp); - friend CallArgs CallArgsFromSp(unsigned stackSlots, Value* sp, bool constructing); - - static CallArgs create(unsigned argc, Value* argv, bool constructing) { - CallArgs args; - args.clearUsedRval(); - args.argv_ = argv; - args.argc_ = argc; - args.constructing_ = constructing; -#ifdef DEBUG - for (unsigned i = 0; i < argc; ++i) - MOZ_ASSERT_IF(argv[i].isMarkable(), !GCThingIsMarkedGray(GCCellPtr(argv[i]))); -#endif - return args; - } - - public: - /* - * Returns true if there are at least |required| arguments passed in. If - * false, it reports an error message on the context. - */ - bool requireAtLeast(JSContext* cx, const char* fnname, unsigned required) const; - -}; - -MOZ_ALWAYS_INLINE CallArgs -CallArgsFromVp(unsigned argc, Value* vp) -{ - return CallArgs::create(argc, vp + 2, vp[1].isMagic(JS_IS_CONSTRUCTING)); -} - -// This method is only intended for internal use in SpiderMonkey. We may -// eventually move it to an internal header. Embedders should use -// JS::CallArgsFromVp! -MOZ_ALWAYS_INLINE CallArgs -CallArgsFromSp(unsigned stackSlots, Value* sp, bool constructing = false) -{ - return CallArgs::create(stackSlots - constructing, sp - stackSlots, constructing); -} - -} // namespace JS - -/* - * Macros to hide interpreter stack layout details from a JSNative using its - * JS::Value* vp parameter. DO NOT USE THESE! Instead use JS::CallArgs and - * friends, above. These macros will be removed when we change JSNative to - * take a const JS::CallArgs&. - */ - -/* - * Return |this| if |this| is an object. Otherwise, return the global object - * if |this| is null or undefined, and finally return a boxed version of any - * other primitive. - * - * Note: if this method returns null, an error has occurred and must be - * propagated or caught. - */ -MOZ_ALWAYS_INLINE JS::Value -JS_THIS(JSContext* cx, JS::Value* vp) -{ - return vp[1].isPrimitive() ? JS::detail::ComputeThis(cx, vp) : vp[1]; -} - -/* - * A note on JS_THIS_OBJECT: no equivalent method is part of the CallArgs - * interface, and we're unlikely to add one (functions shouldn't be implicitly - * exposing the global object to arbitrary callers). Continue using |vp| - * directly for this case, but be aware this API will eventually be replaced - * with a function that operates directly upon |args.thisv()|. - */ -#define JS_THIS_OBJECT(cx,vp) (JS_THIS(cx,vp).toObjectOrNull()) - -/* - * |this| is passed to functions in ES5 without change. Functions themselves - * do any post-processing they desire to box |this|, compute the global object, - * &c. This macro retrieves a function's unboxed |this| value. - * - * This macro must not be used in conjunction with JS_THIS or JS_THIS_OBJECT, - * or vice versa. Either use the provided this value with this macro, or - * compute the boxed |this| value using those. JS_THIS_VALUE must not be used - * if the function is being called as a constructor. - * - * But: DO NOT USE THIS! Instead use JS::CallArgs::thisv(), above. - * - */ -#define JS_THIS_VALUE(cx,vp) ((vp)[1]) - -#endif /* js_CallArgs_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/CallNonGenericMethod.h b/android/armeabi-v7a/include/spidermonkey/js/CallNonGenericMethod.h deleted file mode 100644 index 9a1cf010..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/CallNonGenericMethod.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_CallNonGenericMethod_h -#define js_CallNonGenericMethod_h - -#include "jstypes.h" - -#include "js/CallArgs.h" - -namespace JS { - -// Returns true if |v| is considered an acceptable this-value. -typedef bool (*IsAcceptableThis)(HandleValue v); - -// Implements the guts of a method; guaranteed to be provided an acceptable -// this-value, as determined by a corresponding IsAcceptableThis method. -typedef bool (*NativeImpl)(JSContext* cx, const CallArgs& args); - -namespace detail { - -// DON'T CALL THIS DIRECTLY. It's for use only by CallNonGenericMethod! -extern JS_PUBLIC_API(bool) -CallMethodIfWrapped(JSContext* cx, IsAcceptableThis test, NativeImpl impl, const CallArgs& args); - -} // namespace detail - -// Methods usually act upon |this| objects only from a single global object and -// compartment. Sometimes, however, a method must act upon |this| values from -// multiple global objects or compartments. In such cases the |this| value a -// method might see will be wrapped, such that various access to the object -- -// to its class, its private data, its reserved slots, and so on -- will not -// work properly without entering that object's compartment. This method -// implements a solution to this problem. -// -// To implement a method that accepts |this| values from multiple compartments, -// define two functions. The first function matches the IsAcceptableThis type -// and indicates whether the provided value is an acceptable |this| for the -// method; it must be a pure function only of its argument. -// -// static const JSClass AnswerClass = { ... }; -// -// static bool -// IsAnswerObject(const Value& v) -// { -// if (!v.isObject()) -// return false; -// return JS_GetClass(&v.toObject()) == &AnswerClass; -// } -// -// The second function implements the NativeImpl signature and defines the -// behavior of the method when it is provided an acceptable |this| value. -// Aside from some typing niceties -- see the CallArgs interface for details -- -// its interface is the same as that of JSNative. -// -// static bool -// answer_getAnswer_impl(JSContext* cx, JS::CallArgs args) -// { -// args.rval().setInt32(42); -// return true; -// } -// -// The implementation function is guaranteed to be called *only* with a |this| -// value which is considered acceptable. -// -// Now to implement the actual method, write a JSNative that calls the method -// declared below, passing the appropriate template and runtime arguments. -// -// static bool -// answer_getAnswer(JSContext* cx, unsigned argc, JS::Value* vp) -// { -// JS::CallArgs args = JS::CallArgsFromVp(argc, vp); -// return JS::CallNonGenericMethod(cx, args); -// } -// -// Note that, because they are used as template arguments, the predicate -// and implementation functions must have external linkage. (This is -// unfortunate, but GCC wasn't inlining things as one would hope when we -// passed them as function arguments.) -// -// JS::CallNonGenericMethod will test whether |args.thisv()| is acceptable. If -// it is, it will call the provided implementation function, which will return -// a value and indicate success. If it is not, it will attempt to unwrap -// |this| and call the implementation function on the unwrapped |this|. If -// that succeeds, all well and good. If it doesn't succeed, a TypeError will -// be thrown. -// -// Note: JS::CallNonGenericMethod will only work correctly if it's called in -// tail position in a JSNative. Do not call it from any other place. -// -template -MOZ_ALWAYS_INLINE bool -CallNonGenericMethod(JSContext* cx, const CallArgs& args) -{ - HandleValue thisv = args.thisv(); - if (Test(thisv)) - return Impl(cx, args); - - return detail::CallMethodIfWrapped(cx, Test, Impl, args); -} - -MOZ_ALWAYS_INLINE bool -CallNonGenericMethod(JSContext* cx, IsAcceptableThis Test, NativeImpl Impl, const CallArgs& args) -{ - HandleValue thisv = args.thisv(); - if (Test(thisv)) - return Impl(cx, args); - - return detail::CallMethodIfWrapped(cx, Test, Impl, args); -} - -} // namespace JS - -#endif /* js_CallNonGenericMethod_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/CharacterEncoding.h b/android/armeabi-v7a/include/spidermonkey/js/CharacterEncoding.h deleted file mode 100644 index fe39a415..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/CharacterEncoding.h +++ /dev/null @@ -1,338 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_CharacterEncoding_h -#define js_CharacterEncoding_h - -#include "mozilla/Range.h" - -#include "js/TypeDecls.h" -#include "js/Utility.h" - -namespace js { -class ExclusiveContext; -} // namespace js - -class JSFlatString; - -namespace JS { - -/* - * By default, all C/C++ 1-byte-per-character strings passed into the JSAPI - * are treated as ISO/IEC 8859-1, also known as Latin-1. That is, each - * byte is treated as a 2-byte character, and there is no way to pass in a - * string containing characters beyond U+00FF. - */ -class Latin1Chars : public mozilla::Range -{ - typedef mozilla::Range Base; - - public: - using CharT = Latin1Char; - - Latin1Chars() : Base() {} - Latin1Chars(char* aBytes, size_t aLength) : Base(reinterpret_cast(aBytes), aLength) {} - Latin1Chars(const Latin1Char* aBytes, size_t aLength) - : Base(const_cast(aBytes), aLength) - {} - Latin1Chars(const char* aBytes, size_t aLength) - : Base(reinterpret_cast(const_cast(aBytes)), aLength) - {} -}; - -/* - * A Latin1Chars, but with \0 termination for C compatibility. - */ -class Latin1CharsZ : public mozilla::RangedPtr -{ - typedef mozilla::RangedPtr Base; - - public: - using CharT = Latin1Char; - - Latin1CharsZ() : Base(nullptr, 0) {} - - Latin1CharsZ(char* aBytes, size_t aLength) - : Base(reinterpret_cast(aBytes), aLength) - { - MOZ_ASSERT(aBytes[aLength] == '\0'); - } - - Latin1CharsZ(Latin1Char* aBytes, size_t aLength) - : Base(aBytes, aLength) - { - MOZ_ASSERT(aBytes[aLength] == '\0'); - } - - using Base::operator=; - - char* c_str() { return reinterpret_cast(get()); } -}; - -class UTF8Chars : public mozilla::Range -{ - typedef mozilla::Range Base; - - public: - using CharT = unsigned char; - - UTF8Chars() : Base() {} - UTF8Chars(char* aBytes, size_t aLength) - : Base(reinterpret_cast(aBytes), aLength) - {} - UTF8Chars(const char* aBytes, size_t aLength) - : Base(reinterpret_cast(const_cast(aBytes)), aLength) - {} -}; - -/* - * SpiderMonkey also deals directly with UTF-8 encoded text in some places. - */ -class UTF8CharsZ : public mozilla::RangedPtr -{ - typedef mozilla::RangedPtr Base; - - public: - using CharT = unsigned char; - - UTF8CharsZ() : Base(nullptr, 0) {} - - UTF8CharsZ(char* aBytes, size_t aLength) - : Base(reinterpret_cast(aBytes), aLength) - { - MOZ_ASSERT(aBytes[aLength] == '\0'); - } - - UTF8CharsZ(unsigned char* aBytes, size_t aLength) - : Base(aBytes, aLength) - { - MOZ_ASSERT(aBytes[aLength] == '\0'); - } - - using Base::operator=; - - char* c_str() { return reinterpret_cast(get()); } -}; - -/* - * A wrapper for a "const char*" that is encoded using UTF-8. - * This class does not manage ownership of the data; that is left - * to others. This differs from UTF8CharsZ in that the chars are - * const and it allows assignment. - */ -class ConstUTF8CharsZ -{ - const char* data_; - - public: - using CharT = unsigned char; - - ConstUTF8CharsZ() : data_(nullptr) - {} - - ConstUTF8CharsZ(const char* aBytes, size_t aLength) - : data_(aBytes) - { - MOZ_ASSERT(aBytes[aLength] == '\0'); -#ifdef DEBUG - validate(aLength); -#endif - } - - const void* get() const { return data_; } - - const char* c_str() const { return data_; } - - explicit operator bool() const { return data_ != nullptr; } - - private: -#ifdef DEBUG - void validate(size_t aLength); -#endif -}; - -/* - * SpiderMonkey uses a 2-byte character representation: it is a - * 2-byte-at-a-time view of a UTF-16 byte stream. This is similar to UCS-2, - * but unlike UCS-2, we do not strip UTF-16 extension bytes. This allows a - * sufficiently dedicated JavaScript program to be fully unicode-aware by - * manually interpreting UTF-16 extension characters embedded in the JS - * string. - */ -class TwoByteChars : public mozilla::Range -{ - typedef mozilla::Range Base; - - public: - using CharT = char16_t; - - TwoByteChars() : Base() {} - TwoByteChars(char16_t* aChars, size_t aLength) : Base(aChars, aLength) {} - TwoByteChars(const char16_t* aChars, size_t aLength) : Base(const_cast(aChars), aLength) {} -}; - -/* - * A TwoByteChars, but \0 terminated for compatibility with JSFlatString. - */ -class TwoByteCharsZ : public mozilla::RangedPtr -{ - typedef mozilla::RangedPtr Base; - - public: - using CharT = char16_t; - - TwoByteCharsZ() : Base(nullptr, 0) {} - - TwoByteCharsZ(char16_t* chars, size_t length) - : Base(chars, length) - { - MOZ_ASSERT(chars[length] == '\0'); - } - - using Base::operator=; -}; - -typedef mozilla::RangedPtr ConstCharPtr; - -/* - * Like TwoByteChars, but the chars are const. - */ -class ConstTwoByteChars : public mozilla::Range -{ - typedef mozilla::Range Base; - - public: - using CharT = char16_t; - - ConstTwoByteChars() : Base() {} - ConstTwoByteChars(const char16_t* aChars, size_t aLength) : Base(aChars, aLength) {} -}; - -/* - * Convert a 2-byte character sequence to "ISO-Latin-1". This works by - * truncating each 2-byte pair in the sequence to a 1-byte pair. If the source - * contains any UTF-16 extension characters, then this may give invalid Latin1 - * output. The returned string is zero terminated. The returned string or the - * returned string's |start()| must be freed with JS_free or js_free, - * respectively. If allocation fails, an OOM error will be set and the method - * will return a nullptr chars (which can be tested for with the ! operator). - * This method cannot trigger GC. - */ -extern Latin1CharsZ -LossyTwoByteCharsToNewLatin1CharsZ(js::ExclusiveContext* cx, - const mozilla::Range tbchars); - -inline Latin1CharsZ -LossyTwoByteCharsToNewLatin1CharsZ(js::ExclusiveContext* cx, const char16_t* begin, size_t length) -{ - const mozilla::Range tbchars(begin, length); - return JS::LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars); -} - -template -extern UTF8CharsZ -CharsToNewUTF8CharsZ(js::ExclusiveContext* maybeCx, const mozilla::Range chars); - -uint32_t -Utf8ToOneUcs4Char(const uint8_t* utf8Buffer, int utf8Length); - -/* - * Inflate bytes in UTF-8 encoding to char16_t. - * - On error, returns an empty TwoByteCharsZ. - * - On success, returns a malloc'd TwoByteCharsZ, and updates |outlen| to hold - * its length; the length value excludes the trailing null. - */ -extern TwoByteCharsZ -UTF8CharsToNewTwoByteCharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen); - -/* - * Like UTF8CharsToNewTwoByteCharsZ, but for ConstUTF8CharsZ. - */ -extern TwoByteCharsZ -UTF8CharsToNewTwoByteCharsZ(JSContext* cx, const ConstUTF8CharsZ& utf8, size_t* outlen); - -/* - * The same as UTF8CharsToNewTwoByteCharsZ(), except that any malformed UTF-8 characters - * will be replaced by \uFFFD. No exception will be thrown for malformed UTF-8 - * input. - */ -extern TwoByteCharsZ -LossyUTF8CharsToNewTwoByteCharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen); - -extern TwoByteCharsZ -LossyUTF8CharsToNewTwoByteCharsZ(JSContext* cx, const ConstUTF8CharsZ& utf8, size_t* outlen); - -/* - * Returns the length of the char buffer required to encode |s| as UTF8. - * Does not include the null-terminator. - */ -JS_PUBLIC_API(size_t) -GetDeflatedUTF8StringLength(JSFlatString* s); - -/* - * Encode |src| as UTF8. The caller must either ensure |dst| has enough space - * to encode the entire string or pass the length of the buffer as |dstlenp|, - * in which case the function will encode characters from the string until - * the buffer is exhausted. Does not write the null terminator. - * - * If |dstlenp| is provided, it will be updated to hold the number of bytes - * written to the buffer. If |numcharsp| is provided, it will be updated to hold - * the number of Unicode characters written to the buffer (which can be less - * than the length of the string, if the buffer is exhausted before the string - * is fully encoded). - */ -JS_PUBLIC_API(void) -DeflateStringToUTF8Buffer(JSFlatString* src, mozilla::RangedPtr dst, - size_t* dstlenp = nullptr, size_t* numcharsp = nullptr); - -/* - * The smallest character encoding capable of fully representing a particular - * string. - */ -enum class SmallestEncoding { - ASCII, - Latin1, - UTF16 -}; - -/* - * Returns the smallest encoding possible for the given string: if all - * codepoints are <128 then ASCII, otherwise if all codepoints are <256 - * Latin-1, else UTF16. - */ -JS_PUBLIC_API(SmallestEncoding) -FindSmallestEncoding(UTF8Chars utf8); - -/* - * Return a null-terminated Latin-1 string copied from the input string, - * storing its length (excluding null terminator) in |*outlen|. Fail and - * report an error if the string contains non-Latin-1 codepoints. Returns - * Latin1CharsZ() on failure. - */ -extern Latin1CharsZ -UTF8CharsToNewLatin1CharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen); - -/* - * Return a null-terminated Latin-1 string copied from the input string, - * storing its length (excluding null terminator) in |*outlen|. Non-Latin-1 - * codepoints are replaced by '?'. Returns Latin1CharsZ() on failure. - */ -extern Latin1CharsZ -LossyUTF8CharsToNewLatin1CharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen); - -/* - * Returns true if all characters in the given null-terminated string are - * ASCII, i.e. < 0x80, false otherwise. - */ -extern bool -StringIsASCII(const char* s); - -} // namespace JS - -inline void JS_free(JS::Latin1CharsZ& ptr) { js_free((void*)ptr.get()); } -inline void JS_free(JS::UTF8CharsZ& ptr) { js_free((void*)ptr.get()); } - -#endif /* js_CharacterEncoding_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/Class.h b/android/armeabi-v7a/include/spidermonkey/js/Class.h deleted file mode 100644 index 3b502387..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/Class.h +++ /dev/null @@ -1,995 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* JSClass definition and its component types, plus related interfaces. */ - -#ifndef js_Class_h -#define js_Class_h - -#include "jstypes.h" - -#include "js/CallArgs.h" -#include "js/Id.h" -#include "js/TypeDecls.h" - -/* - * A JSClass acts as a vtable for JS objects that allows JSAPI clients to - * control various aspects of the behavior of an object like property lookup. - * js::Class is an engine-private extension that allows more control over - * object behavior and, e.g., allows custom slow layout. - */ - -struct JSAtomState; -struct JSFreeOp; -struct JSFunctionSpec; - -namespace js { - -struct Class; -class FreeOp; -class Shape; - -// This is equal to JSFunction::class_. Use it in places where you don't want -// to #include jsfun.h. -extern JS_FRIEND_DATA(const js::Class* const) FunctionClassPtr; - -} // namespace js - -namespace JS { - -class AutoIdVector; - -/** - * The answer to a successful query as to whether an object is an Array per - * ES6's internal |IsArray| operation (as exposed by |Array.isArray|). - */ -enum class IsArrayAnswer -{ - Array, - NotArray, - RevokedProxy -}; - -/** - * ES6 7.2.2. - * - * Returns false on failure, otherwise returns true and sets |*isArray| - * indicating whether the object passes ECMAScript's IsArray test. This is the - * same test performed by |Array.isArray|. - * - * This is NOT the same as asking whether |obj| is an Array or a wrapper around - * one. If |obj| is a proxy created by |Proxy.revocable()| and has been - * revoked, or if |obj| is a proxy whose target (at any number of hops) is a - * revoked proxy, this method throws a TypeError and returns false. - */ -extern JS_PUBLIC_API(bool) -IsArray(JSContext* cx, HandleObject obj, bool* isArray); - -/** - * Identical to IsArray above, but the nature of the object (if successfully - * determined) is communicated via |*answer|. In particular this method - * returns true and sets |*answer = IsArrayAnswer::RevokedProxy| when called on - * a revoked proxy. - * - * Most users will want the overload above, not this one. - */ -extern JS_PUBLIC_API(bool) -IsArray(JSContext* cx, HandleObject obj, IsArrayAnswer* answer); - -/** - * Per ES6, the [[DefineOwnProperty]] internal method has three different - * possible outcomes: - * - * - It can throw an exception (which we indicate by returning false). - * - * - It can return true, indicating unvarnished success. - * - * - It can return false, indicating "strict failure". The property could - * not be defined. It's an error, but no exception was thrown. - * - * It's not just [[DefineOwnProperty]]: all the mutating internal methods have - * the same three outcomes. (The other affected internal methods are [[Set]], - * [[Delete]], [[SetPrototypeOf]], and [[PreventExtensions]].) - * - * If you think this design is awful, you're not alone. But as it's the - * standard, we must represent these boolean "success" values somehow. - * ObjectOpSuccess is the class for this. It's like a bool, but when it's false - * it also stores an error code. - * - * Typical usage: - * - * ObjectOpResult result; - * if (!DefineProperty(cx, obj, id, ..., result)) - * return false; - * if (!result) - * return result.reportError(cx, obj, id); - * - * Users don't have to call `result.report()`; another possible ending is: - * - * argv.rval().setBoolean(bool(result)); - * return true; - */ -class ObjectOpResult -{ - private: - /** - * code_ is either one of the special codes OkCode or Uninitialized, or - * an error code. For now the error codes are private to the JS engine; - * they're defined in js/src/js.msg. - * - * code_ is uintptr_t (rather than uint32_t) for the convenience of the - * JITs, which would otherwise have to deal with either padding or stack - * alignment on 64-bit platforms. - */ - uintptr_t code_; - - public: - enum SpecialCodes : uintptr_t { - OkCode = 0, - Uninitialized = uintptr_t(-1) - }; - - ObjectOpResult() : code_(Uninitialized) {} - - /* Return true if succeed() was called. */ - bool ok() const { - MOZ_ASSERT(code_ != Uninitialized); - return code_ == OkCode; - } - - explicit operator bool() const { return ok(); } - - /* Set this ObjectOpResult to true and return true. */ - bool succeed() { - code_ = OkCode; - return true; - } - - /* - * Set this ObjectOpResult to false with an error code. - * - * Always returns true, as a convenience. Typical usage will be: - * - * if (funny condition) - * return result.fail(JSMSG_CANT_DO_THE_THINGS); - * - * The true return value indicates that no exception is pending, and it - * would be OK to ignore the failure and continue. - */ - bool fail(uint32_t msg) { - MOZ_ASSERT(msg != OkCode); - code_ = msg; - return true; - } - - JS_PUBLIC_API(bool) failCantRedefineProp(); - JS_PUBLIC_API(bool) failReadOnly(); - JS_PUBLIC_API(bool) failGetterOnly(); - JS_PUBLIC_API(bool) failCantDelete(); - - JS_PUBLIC_API(bool) failCantSetInterposed(); - JS_PUBLIC_API(bool) failCantDefineWindowElement(); - JS_PUBLIC_API(bool) failCantDeleteWindowElement(); - JS_PUBLIC_API(bool) failCantDeleteWindowNamedProperty(); - JS_PUBLIC_API(bool) failCantPreventExtensions(); - JS_PUBLIC_API(bool) failCantSetProto(); - JS_PUBLIC_API(bool) failNoNamedSetter(); - JS_PUBLIC_API(bool) failNoIndexedSetter(); - - uint32_t failureCode() const { - MOZ_ASSERT(!ok()); - return uint32_t(code_); - } - - /* - * Report an error or warning if necessary; return true to proceed and - * false if an error was reported. Call this when failure should cause - * a warning if extraWarnings are enabled. - * - * The precise rules are like this: - * - * - If ok(), then we succeeded. Do nothing and return true. - * - Otherwise, if |strict| is true, or if cx has both extraWarnings and - * werrorOption enabled, throw a TypeError and return false. - * - Otherwise, if cx has extraWarnings enabled, emit a warning and - * return true. - * - Otherwise, do nothing and return true. - */ - bool checkStrictErrorOrWarning(JSContext* cx, HandleObject obj, HandleId id, bool strict) { - if (ok()) - return true; - return reportStrictErrorOrWarning(cx, obj, id, strict); - } - - /* - * The same as checkStrictErrorOrWarning(cx, id, strict), except the - * operation is not associated with a particular property id. This is - * used for [[PreventExtensions]] and [[SetPrototypeOf]]. failureCode() - * must not be an error that has "{0}" in the error message. - */ - bool checkStrictErrorOrWarning(JSContext* cx, HandleObject obj, bool strict) { - return ok() || reportStrictErrorOrWarning(cx, obj, strict); - } - - /* Throw a TypeError. Call this only if !ok(). */ - bool reportError(JSContext* cx, HandleObject obj, HandleId id) { - return reportStrictErrorOrWarning(cx, obj, id, true); - } - - /* - * The same as reportError(cx, obj, id), except the operation is not - * associated with a particular property id. - */ - bool reportError(JSContext* cx, HandleObject obj) { - return reportStrictErrorOrWarning(cx, obj, true); - } - - /* Helper function for checkStrictErrorOrWarning's slow path. */ - JS_PUBLIC_API(bool) reportStrictErrorOrWarning(JSContext* cx, HandleObject obj, HandleId id, bool strict); - JS_PUBLIC_API(bool) reportStrictErrorOrWarning(JSContext* cx, HandleObject obj, bool strict); - - /* - * Convenience method. Return true if ok() or if strict is false; otherwise - * throw a TypeError and return false. - */ - bool checkStrict(JSContext* cx, HandleObject obj, HandleId id) { - return checkStrictErrorOrWarning(cx, obj, id, true); - } - - /* - * Convenience method. The same as checkStrict(cx, id), except the - * operation is not associated with a particular property id. - */ - bool checkStrict(JSContext* cx, HandleObject obj) { - return checkStrictErrorOrWarning(cx, obj, true); - } -}; - -} // namespace JS - -// JSClass operation signatures. - -/** - * Get a property named by id in obj. Note the jsid id type -- id may - * be a string (Unicode property identifier) or an int (element index). The - * *vp out parameter, on success, is the new property value after the action. - */ -typedef bool -(* JSGetterOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp); - -/** Add a property named by id to obj. */ -typedef bool -(* JSAddPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v); - -/** - * Set a property named by id in obj, treating the assignment as strict - * mode code if strict is true. Note the jsid id type -- id may be a string - * (Unicode property identifier) or an int (element index). The *vp out - * parameter, on success, is the new property value after the - * set. - */ -typedef bool -(* JSSetterOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp, JS::ObjectOpResult& result); - -/** - * Delete a property named by id in obj. - * - * If an error occurred, return false as per normal JSAPI error practice. - * - * If no error occurred, but the deletion attempt wasn't allowed (perhaps - * because the property was non-configurable), call result.fail() and - * return true. This will cause |delete obj[id]| to evaluate to false in - * non-strict mode code, and to throw a TypeError in strict mode code. - * - * If no error occurred and the deletion wasn't disallowed (this is *not* the - * same as saying that a deletion actually occurred -- deleting a non-existent - * property, or an inherited property, is allowed -- it's just pointless), - * call result.succeed() and return true. - */ -typedef bool -(* JSDeletePropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::ObjectOpResult& result); - -/** - * The type of ObjectOps::enumerate. This callback overrides a portion of - * SpiderMonkey's default [[Enumerate]] internal method. When an ordinary object - * is enumerated, that object and each object on its prototype chain is tested - * for an enumerate op, and those ops are called in order. The properties each - * op adds to the 'properties' vector are added to the set of values the for-in - * loop will iterate over. All of this is nonstandard. - * - * An object is "enumerated" when it's the target of a for-in loop or - * JS_Enumerate(). The callback's job is to populate 'properties' with the - * object's property keys. If `enumerableOnly` is true, the callback should only - * add enumerable properties. - */ -typedef bool -(* JSNewEnumerateOp)(JSContext* cx, JS::HandleObject obj, JS::AutoIdVector& properties, - bool enumerableOnly); - -/** - * The old-style JSClass.enumerate op should define all lazy properties not - * yet reflected in obj. - */ -typedef bool -(* JSEnumerateOp)(JSContext* cx, JS::HandleObject obj); - -/** - * The type of ObjectOps::funToString. This callback allows an object to - * provide a custom string to use when Function.prototype.toString is invoked on - * that object. A null return value means OOM. - */ -typedef JSString* -(* JSFunToStringOp)(JSContext* cx, JS::HandleObject obj, unsigned indent); - -/** - * Resolve a lazy property named by id in obj by defining it directly in obj. - * Lazy properties are those reflected from some peer native property space - * (e.g., the DOM attributes for a given node reflected as obj) on demand. - * - * JS looks for a property in an object, and if not found, tries to resolve - * the given id. *resolvedp should be set to true iff the property was defined - * on |obj|. - */ -typedef bool -(* JSResolveOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - bool* resolvedp); - -/** - * A class with a resolve hook can optionally have a mayResolve hook. This hook - * must have no side effects and must return true for a given id if the resolve - * hook may resolve this id. This is useful when we're doing a "pure" lookup: if - * mayResolve returns false, we know we don't have to call the effectful resolve - * hook. - * - * maybeObj, if non-null, is the object on which we're doing the lookup. This - * can be nullptr: during JIT compilation we sometimes know the Class but not - * the object. - */ -typedef bool -(* JSMayResolveOp)(const JSAtomState& names, jsid id, JSObject* maybeObj); - -/** - * Finalize obj, which the garbage collector has determined to be unreachable - * from other live objects or from GC roots. Obviously, finalizers must never - * store a reference to obj. - */ -typedef void -(* JSFinalizeOp)(JSFreeOp* fop, JSObject* obj); - -/** Finalizes external strings created by JS_NewExternalString. */ -struct JSStringFinalizer { - void (*finalize)(JS::Zone* zone, const JSStringFinalizer* fin, char16_t* chars); -}; - -/** - * Check whether v is an instance of obj. Return false on error or exception, - * true on success with true in *bp if v is an instance of obj, false in - * *bp otherwise. - */ -typedef bool -(* JSHasInstanceOp)(JSContext* cx, JS::HandleObject obj, JS::MutableHandleValue vp, - bool* bp); - -/** - * Function type for trace operation of the class called to enumerate all - * traceable things reachable from obj's private data structure. For each such - * thing, a trace implementation must call JS::TraceEdge on the thing's - * location. - * - * JSTraceOp implementation can assume that no other threads mutates object - * state. It must not change state of the object or corresponding native - * structures. The only exception for this rule is the case when the embedding - * needs a tight integration with GC. In that case the embedding can check if - * the traversal is a part of the marking phase through calling - * JS_IsGCMarkingTracer and apply a special code like emptying caches or - * marking its native structures. - */ -typedef void -(* JSTraceOp)(JSTracer* trc, JSObject* obj); - -typedef JSObject* -(* JSWeakmapKeyDelegateOp)(JSObject* obj); - -typedef void -(* JSObjectMovedOp)(JSObject* obj, const JSObject* old); - -/* js::Class operation signatures. */ - -namespace js { - -typedef bool -(* LookupPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleObject objp, JS::MutableHandle propp); -typedef bool -(* DefinePropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::Handle desc, - JS::ObjectOpResult& result); -typedef bool -(* HasPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp); -typedef bool -(* GetPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleValue receiver, JS::HandleId id, - JS::MutableHandleValue vp); -typedef bool -(* SetPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v, - JS::HandleValue receiver, JS::ObjectOpResult& result); -typedef bool -(* GetOwnPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandle desc); -typedef bool -(* DeletePropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::ObjectOpResult& result); - -typedef bool -(* WatchOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable); - -typedef bool -(* UnwatchOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id); - -class JS_FRIEND_API(ElementAdder) -{ - public: - enum GetBehavior { - // Check if the element exists before performing the Get and preserve - // holes. - CheckHasElemPreserveHoles, - - // Perform a Get operation, like obj[index] in JS. - GetElement - }; - - private: - // Only one of these is used. - JS::RootedObject resObj_; - JS::Value* vp_; - - uint32_t index_; -#ifdef DEBUG - uint32_t length_; -#endif - GetBehavior getBehavior_; - - public: - ElementAdder(JSContext* cx, JSObject* obj, uint32_t length, GetBehavior behavior) - : resObj_(cx, obj), vp_(nullptr), index_(0), -#ifdef DEBUG - length_(length), -#endif - getBehavior_(behavior) - {} - ElementAdder(JSContext* cx, JS::Value* vp, uint32_t length, GetBehavior behavior) - : resObj_(cx), vp_(vp), index_(0), -#ifdef DEBUG - length_(length), -#endif - getBehavior_(behavior) - {} - - GetBehavior getBehavior() const { return getBehavior_; } - - bool append(JSContext* cx, JS::HandleValue v); - void appendHole(); -}; - -typedef bool -(* GetElementsOp)(JSContext* cx, JS::HandleObject obj, uint32_t begin, uint32_t end, - ElementAdder* adder); - -typedef void -(* FinalizeOp)(FreeOp* fop, JSObject* obj); - -// The special treatment of |finalize| and |trace| is necessary because if we -// assign either of those hooks to a local variable and then call it -- as is -// done with the other hooks -- the GC hazard analysis gets confused. -#define JS_CLASS_MEMBERS(ClassOpsType, FreeOpType) \ - const char* name; \ - uint32_t flags; \ - const ClassOpsType* cOps; \ - \ - JSAddPropertyOp getAddProperty() const { return cOps ? cOps->addProperty : nullptr; } \ - JSDeletePropertyOp getDelProperty() const { return cOps ? cOps->delProperty : nullptr; } \ - JSGetterOp getGetProperty() const { return cOps ? cOps->getProperty : nullptr; } \ - JSSetterOp getSetProperty() const { return cOps ? cOps->setProperty : nullptr; } \ - JSEnumerateOp getEnumerate() const { return cOps ? cOps->enumerate : nullptr; } \ - JSResolveOp getResolve() const { return cOps ? cOps->resolve : nullptr; } \ - JSMayResolveOp getMayResolve() const { return cOps ? cOps->mayResolve : nullptr; } \ - JSNative getCall() const { return cOps ? cOps->call : nullptr; } \ - JSHasInstanceOp getHasInstance() const { return cOps ? cOps->hasInstance : nullptr; } \ - JSNative getConstruct() const { return cOps ? cOps->construct : nullptr; } \ - \ - bool hasFinalize() const { return cOps && cOps->finalize; } \ - bool hasTrace() const { return cOps && cOps->trace; } \ - \ - bool isTrace(JSTraceOp trace) const { return cOps && cOps->trace == trace; } \ - \ - void doFinalize(FreeOpType* fop, JSObject* obj) const { \ - MOZ_ASSERT(cOps && cOps->finalize); \ - cOps->finalize(fop, obj); \ - } \ - void doTrace(JSTracer* trc, JSObject* obj) const { \ - MOZ_ASSERT(cOps && cOps->trace); \ - cOps->trace(trc, obj); \ - } - -struct ClassOps -{ - /* Function pointer members (may be null). */ - JSAddPropertyOp addProperty; - JSDeletePropertyOp delProperty; - JSGetterOp getProperty; - JSSetterOp setProperty; - JSEnumerateOp enumerate; - JSResolveOp resolve; - JSMayResolveOp mayResolve; - FinalizeOp finalize; - JSNative call; - JSHasInstanceOp hasInstance; - JSNative construct; - JSTraceOp trace; -}; - -/** Callback for the creation of constructor and prototype objects. */ -typedef JSObject* (*ClassObjectCreationOp)(JSContext* cx, JSProtoKey key); - -/** Callback for custom post-processing after class initialization via ClassSpec. */ -typedef bool (*FinishClassInitOp)(JSContext* cx, JS::HandleObject ctor, - JS::HandleObject proto); - -const size_t JSCLASS_CACHED_PROTO_WIDTH = 6; - -struct ClassSpec -{ - // All properties except flags should be accessed through accessor. - ClassObjectCreationOp createConstructor_; - ClassObjectCreationOp createPrototype_; - const JSFunctionSpec* constructorFunctions_; - const JSPropertySpec* constructorProperties_; - const JSFunctionSpec* prototypeFunctions_; - const JSPropertySpec* prototypeProperties_; - FinishClassInitOp finishInit_; - uintptr_t flags; - - static const size_t ProtoKeyWidth = JSCLASS_CACHED_PROTO_WIDTH; - - static const uintptr_t ProtoKeyMask = (1 << ProtoKeyWidth) - 1; - static const uintptr_t DontDefineConstructor = 1 << ProtoKeyWidth; - static const uintptr_t IsDelegated = 1 << (ProtoKeyWidth + 1); - - bool defined() const { return !!createConstructor_; } - - bool delegated() const { - return (flags & IsDelegated); - } - - // The ProtoKey this class inherits from. - JSProtoKey inheritanceProtoKey() const { - MOZ_ASSERT(defined()); - static_assert(JSProto_Null == 0, "zeroed key must be null"); - - // Default: Inherit from Object. - if (!(flags & ProtoKeyMask)) - return JSProto_Object; - - return JSProtoKey(flags & ProtoKeyMask); - } - - bool shouldDefineConstructor() const { - MOZ_ASSERT(defined()); - return !(flags & DontDefineConstructor); - } - - const ClassSpec* delegatedClassSpec() const { - MOZ_ASSERT(delegated()); - return reinterpret_cast(createConstructor_); - } - - ClassObjectCreationOp createConstructorHook() const { - if (delegated()) - return delegatedClassSpec()->createConstructorHook(); - return createConstructor_; - } - ClassObjectCreationOp createPrototypeHook() const { - if (delegated()) - return delegatedClassSpec()->createPrototypeHook(); - return createPrototype_; - } - const JSFunctionSpec* constructorFunctions() const { - if (delegated()) - return delegatedClassSpec()->constructorFunctions(); - return constructorFunctions_; - } - const JSPropertySpec* constructorProperties() const { - if (delegated()) - return delegatedClassSpec()->constructorProperties(); - return constructorProperties_; - } - const JSFunctionSpec* prototypeFunctions() const { - if (delegated()) - return delegatedClassSpec()->prototypeFunctions(); - return prototypeFunctions_; - } - const JSPropertySpec* prototypeProperties() const { - if (delegated()) - return delegatedClassSpec()->prototypeProperties(); - return prototypeProperties_; - } - FinishClassInitOp finishInitHook() const { - if (delegated()) - return delegatedClassSpec()->finishInitHook(); - return finishInit_; - } -}; - -struct ClassExtension -{ - /** - * If an object is used as a key in a weakmap, it may be desirable for the - * garbage collector to keep that object around longer than it otherwise - * would. A common case is when the key is a wrapper around an object in - * another compartment, and we want to avoid collecting the wrapper (and - * removing the weakmap entry) as long as the wrapped object is alive. In - * that case, the wrapped object is returned by the wrapper's - * weakmapKeyDelegateOp hook. As long as the wrapper is used as a weakmap - * key, it will not be collected (and remain in the weakmap) until the - * wrapped object is collected. - */ - JSWeakmapKeyDelegateOp weakmapKeyDelegateOp; - - /** - * Optional hook called when an object is moved by a compacting GC. - * - * There may exist weak pointers to an object that are not traced through - * when the normal trace APIs are used, for example objects in the wrapper - * cache. This hook allows these pointers to be updated. - * - * Note that this hook can be called before JS_NewObject() returns if a GC - * is triggered during construction of the object. This can happen for - * global objects for example. - */ - JSObjectMovedOp objectMovedOp; -}; - -inline ClassObjectCreationOp DELEGATED_CLASSSPEC(const ClassSpec* spec) { - return reinterpret_cast(const_cast(spec)); -} - -#define JS_NULL_CLASS_SPEC nullptr -#define JS_NULL_CLASS_EXT nullptr - -struct ObjectOps -{ - LookupPropertyOp lookupProperty; - DefinePropertyOp defineProperty; - HasPropertyOp hasProperty; - GetPropertyOp getProperty; - SetPropertyOp setProperty; - GetOwnPropertyOp getOwnPropertyDescriptor; - DeletePropertyOp deleteProperty; - WatchOp watch; - UnwatchOp unwatch; - GetElementsOp getElements; - JSNewEnumerateOp enumerate; - JSFunToStringOp funToString; -}; - -#define JS_NULL_OBJECT_OPS nullptr - -} // namespace js - -// Classes, objects, and properties. - -typedef void (*JSClassInternal)(); - -struct JSClassOps -{ - /* Function pointer members (may be null). */ - JSAddPropertyOp addProperty; - JSDeletePropertyOp delProperty; - JSGetterOp getProperty; - JSSetterOp setProperty; - JSEnumerateOp enumerate; - JSResolveOp resolve; - JSMayResolveOp mayResolve; - JSFinalizeOp finalize; - JSNative call; - JSHasInstanceOp hasInstance; - JSNative construct; - JSTraceOp trace; -}; - -#define JS_NULL_CLASS_OPS nullptr - -struct JSClass { - JS_CLASS_MEMBERS(JSClassOps, JSFreeOp); - - void* reserved[3]; -}; - -#define JSCLASS_HAS_PRIVATE (1<<0) // objects have private slot -#define JSCLASS_DELAY_METADATA_BUILDER (1<<1) // class's initialization code - // will call - // SetNewObjectMetadata itself -#define JSCLASS_IS_WRAPPED_NATIVE (1<<2) // class is an XPCWrappedNative. - // WeakMaps use this to override - // the wrapper disposal - // mechanism. -#define JSCLASS_PRIVATE_IS_NSISUPPORTS (1<<3) // private is (nsISupports*) -#define JSCLASS_IS_DOMJSCLASS (1<<4) // objects are DOM -#define JSCLASS_HAS_XRAYED_CONSTRUCTOR (1<<5) // if wrapped by an xray - // wrapper, the builtin - // class's constructor won't - // be unwrapped and invoked. - // Instead, the constructor is - // resolved in the caller's - // compartment and invoked - // with a wrapped newTarget. - // The constructor has to - // detect and handle this - // situation. - // See PromiseConstructor for - // details. -#define JSCLASS_EMULATES_UNDEFINED (1<<6) // objects of this class act - // like the value undefined, - // in some contexts -#define JSCLASS_USERBIT1 (1<<7) // Reserved for embeddings. - -// To reserve slots fetched and stored via JS_Get/SetReservedSlot, bitwise-or -// JSCLASS_HAS_RESERVED_SLOTS(n) into the initializer for JSClass.flags, where -// n is a constant in [1, 255]. Reserved slots are indexed from 0 to n-1. -#define JSCLASS_RESERVED_SLOTS_SHIFT 8 // room for 8 flags below */ -#define JSCLASS_RESERVED_SLOTS_WIDTH 8 // and 16 above this field */ -#define JSCLASS_RESERVED_SLOTS_MASK JS_BITMASK(JSCLASS_RESERVED_SLOTS_WIDTH) -#define JSCLASS_HAS_RESERVED_SLOTS(n) (((n) & JSCLASS_RESERVED_SLOTS_MASK) \ - << JSCLASS_RESERVED_SLOTS_SHIFT) -#define JSCLASS_RESERVED_SLOTS(clasp) (((clasp)->flags \ - >> JSCLASS_RESERVED_SLOTS_SHIFT) \ - & JSCLASS_RESERVED_SLOTS_MASK) - -#define JSCLASS_HIGH_FLAGS_SHIFT (JSCLASS_RESERVED_SLOTS_SHIFT + \ - JSCLASS_RESERVED_SLOTS_WIDTH) - -#define JSCLASS_IS_ANONYMOUS (1<<(JSCLASS_HIGH_FLAGS_SHIFT+0)) -#define JSCLASS_IS_GLOBAL (1<<(JSCLASS_HIGH_FLAGS_SHIFT+1)) -#define JSCLASS_INTERNAL_FLAG2 (1<<(JSCLASS_HIGH_FLAGS_SHIFT+2)) -#define JSCLASS_INTERNAL_FLAG3 (1<<(JSCLASS_HIGH_FLAGS_SHIFT+3)) - -#define JSCLASS_IS_PROXY (1<<(JSCLASS_HIGH_FLAGS_SHIFT+4)) - -#define JSCLASS_SKIP_NURSERY_FINALIZE (1<<(JSCLASS_HIGH_FLAGS_SHIFT+5)) - -// Reserved for embeddings. -#define JSCLASS_USERBIT2 (1<<(JSCLASS_HIGH_FLAGS_SHIFT+6)) -#define JSCLASS_USERBIT3 (1<<(JSCLASS_HIGH_FLAGS_SHIFT+7)) - -#define JSCLASS_BACKGROUND_FINALIZE (1<<(JSCLASS_HIGH_FLAGS_SHIFT+8)) -#define JSCLASS_FOREGROUND_FINALIZE (1<<(JSCLASS_HIGH_FLAGS_SHIFT+9)) - -// Bits 26 through 31 are reserved for the CACHED_PROTO_KEY mechanism, see -// below. - -// ECMA-262 requires that most constructors used internally create objects -// with "the original Foo.prototype value" as their [[Prototype]] (__proto__) -// member initial value. The "original ... value" verbiage is there because -// in ECMA-262, global properties naming class objects are read/write and -// deleteable, for the most part. -// -// Implementing this efficiently requires that global objects have classes -// with the following flags. Failure to use JSCLASS_GLOBAL_FLAGS was -// previously allowed, but is now an ES5 violation and thus unsupported. -// -// JSCLASS_GLOBAL_APPLICATION_SLOTS is the number of slots reserved at -// the beginning of every global object's slots for use by the -// application. -#define JSCLASS_GLOBAL_APPLICATION_SLOTS 5 -#define JSCLASS_GLOBAL_SLOT_COUNT \ - (JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 39) -#define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \ - (JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n))) -#define JSCLASS_GLOBAL_FLAGS \ - JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(0) -#define JSCLASS_HAS_GLOBAL_FLAG_AND_SLOTS(clasp) \ - (((clasp)->flags & JSCLASS_IS_GLOBAL) \ - && JSCLASS_RESERVED_SLOTS(clasp) >= JSCLASS_GLOBAL_SLOT_COUNT) - -// Fast access to the original value of each standard class's prototype. -#define JSCLASS_CACHED_PROTO_SHIFT (JSCLASS_HIGH_FLAGS_SHIFT + 10) -#define JSCLASS_CACHED_PROTO_MASK JS_BITMASK(js::JSCLASS_CACHED_PROTO_WIDTH) -#define JSCLASS_HAS_CACHED_PROTO(key) (uint32_t(key) << JSCLASS_CACHED_PROTO_SHIFT) -#define JSCLASS_CACHED_PROTO_KEY(clasp) ((JSProtoKey) \ - (((clasp)->flags \ - >> JSCLASS_CACHED_PROTO_SHIFT) \ - & JSCLASS_CACHED_PROTO_MASK)) - -// Initializer for unused members of statically initialized JSClass structs. -#define JSCLASS_NO_INTERNAL_MEMBERS {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} -#define JSCLASS_NO_OPTIONAL_MEMBERS 0,0,0,0,0,JSCLASS_NO_INTERNAL_MEMBERS - -namespace js { - -struct Class -{ - JS_CLASS_MEMBERS(js::ClassOps, FreeOp); - const ClassSpec* spec; - const ClassExtension* ext; - const ObjectOps* oOps; - - /* - * Objects of this class aren't native objects. They don't have Shapes that - * describe their properties and layout. Classes using this flag must - * provide their own property behavior, either by being proxy classes (do - * this) or by overriding all the ObjectOps except getElements, watch and - * unwatch (don't do this). - */ - static const uint32_t NON_NATIVE = JSCLASS_INTERNAL_FLAG2; - - bool isNative() const { - return !(flags & NON_NATIVE); - } - - bool hasPrivate() const { - return !!(flags & JSCLASS_HAS_PRIVATE); - } - - bool emulatesUndefined() const { - return flags & JSCLASS_EMULATES_UNDEFINED; - } - - bool isJSFunction() const { - return this == js::FunctionClassPtr; - } - - bool nonProxyCallable() const { - MOZ_ASSERT(!isProxy()); - return isJSFunction() || getCall(); - } - - bool isProxy() const { - return flags & JSCLASS_IS_PROXY; - } - - bool isDOMClass() const { - return flags & JSCLASS_IS_DOMJSCLASS; - } - - bool shouldDelayMetadataBuilder() const { - return flags & JSCLASS_DELAY_METADATA_BUILDER; - } - - bool isWrappedNative() const { - return flags & JSCLASS_IS_WRAPPED_NATIVE; - } - - static size_t offsetOfFlags() { return offsetof(Class, flags); } - - bool specDefined() const { return spec ? spec->defined() : false; } - JSProtoKey specInheritanceProtoKey() - const { return spec ? spec->inheritanceProtoKey() : JSProto_Null; } - bool specShouldDefineConstructor() - const { return spec ? spec->shouldDefineConstructor() : true; } - ClassObjectCreationOp specCreateConstructorHook() - const { return spec ? spec->createConstructorHook() : nullptr; } - ClassObjectCreationOp specCreatePrototypeHook() - const { return spec ? spec->createPrototypeHook() : nullptr; } - const JSFunctionSpec* specConstructorFunctions() - const { return spec ? spec->constructorFunctions() : nullptr; } - const JSPropertySpec* specConstructorProperties() - const { return spec ? spec->constructorProperties() : nullptr; } - const JSFunctionSpec* specPrototypeFunctions() - const { return spec ? spec->prototypeFunctions() : nullptr; } - const JSPropertySpec* specPrototypeProperties() - const { return spec ? spec->prototypeProperties() : nullptr; } - FinishClassInitOp specFinishInitHook() - const { return spec ? spec->finishInitHook() : nullptr; } - - JSWeakmapKeyDelegateOp extWeakmapKeyDelegateOp() - const { return ext ? ext->weakmapKeyDelegateOp : nullptr; } - JSObjectMovedOp extObjectMovedOp() - const { return ext ? ext->objectMovedOp : nullptr; } - - LookupPropertyOp getOpsLookupProperty() const { return oOps ? oOps->lookupProperty : nullptr; } - DefinePropertyOp getOpsDefineProperty() const { return oOps ? oOps->defineProperty : nullptr; } - HasPropertyOp getOpsHasProperty() const { return oOps ? oOps->hasProperty : nullptr; } - GetPropertyOp getOpsGetProperty() const { return oOps ? oOps->getProperty : nullptr; } - SetPropertyOp getOpsSetProperty() const { return oOps ? oOps->setProperty : nullptr; } - GetOwnPropertyOp getOpsGetOwnPropertyDescriptor() - const { return oOps ? oOps->getOwnPropertyDescriptor - : nullptr; } - DeletePropertyOp getOpsDeleteProperty() const { return oOps ? oOps->deleteProperty : nullptr; } - WatchOp getOpsWatch() const { return oOps ? oOps->watch : nullptr; } - UnwatchOp getOpsUnwatch() const { return oOps ? oOps->unwatch : nullptr; } - GetElementsOp getOpsGetElements() const { return oOps ? oOps->getElements : nullptr; } - JSNewEnumerateOp getOpsEnumerate() const { return oOps ? oOps->enumerate : nullptr; } - JSFunToStringOp getOpsFunToString() const { return oOps ? oOps->funToString : nullptr; } -}; - -static_assert(offsetof(JSClassOps, addProperty) == offsetof(ClassOps, addProperty), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, delProperty) == offsetof(ClassOps, delProperty), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, getProperty) == offsetof(ClassOps, getProperty), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, setProperty) == offsetof(ClassOps, setProperty), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, enumerate) == offsetof(ClassOps, enumerate), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, resolve) == offsetof(ClassOps, resolve), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, mayResolve) == offsetof(ClassOps, mayResolve), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, finalize) == offsetof(ClassOps, finalize), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, call) == offsetof(ClassOps, call), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, construct) == offsetof(ClassOps, construct), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, hasInstance) == offsetof(ClassOps, hasInstance), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, trace) == offsetof(ClassOps, trace), - "ClassOps and JSClassOps must be consistent"); -static_assert(sizeof(JSClassOps) == sizeof(ClassOps), - "ClassOps and JSClassOps must be consistent"); - -static_assert(offsetof(JSClass, name) == offsetof(Class, name), - "Class and JSClass must be consistent"); -static_assert(offsetof(JSClass, flags) == offsetof(Class, flags), - "Class and JSClass must be consistent"); -static_assert(offsetof(JSClass, cOps) == offsetof(Class, cOps), - "Class and JSClass must be consistent"); -static_assert(sizeof(JSClass) == sizeof(Class), - "Class and JSClass must be consistent"); - -static MOZ_ALWAYS_INLINE const JSClass* -Jsvalify(const Class* c) -{ - return (const JSClass*)c; -} - -static MOZ_ALWAYS_INLINE const Class* -Valueify(const JSClass* c) -{ - return (const Class*)c; -} - -/** - * Enumeration describing possible values of the [[Class]] internal property - * value of objects. - */ -enum class ESClass { - Object, - Array, - Number, - String, - Boolean, - RegExp, - ArrayBuffer, - SharedArrayBuffer, - Date, - Set, - Map, - Promise, - MapIterator, - SetIterator, - Arguments, - Error, - - /** None of the above. */ - Other -}; - -/* Fills |vp| with the unboxed value for boxed types, or undefined otherwise. */ -bool -Unbox(JSContext* cx, JS::HandleObject obj, JS::MutableHandleValue vp); - -#ifdef DEBUG -JS_FRIEND_API(bool) -HasObjectMovedOp(JSObject* obj); -#endif - -} /* namespace js */ - -#endif /* js_Class_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/Conversions.h b/android/armeabi-v7a/include/spidermonkey/js/Conversions.h deleted file mode 100644 index 1cee31c5..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/Conversions.h +++ /dev/null @@ -1,581 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* ECMAScript conversion operations. */ - -#ifndef js_Conversions_h -#define js_Conversions_h - -#include "mozilla/Casting.h" -#include "mozilla/FloatingPoint.h" -#include "mozilla/TypeTraits.h" - -#include - -#include "jspubtd.h" - -#include "js/RootingAPI.h" -#include "js/Value.h" - -struct JSContext; - -namespace js { - -/* DO NOT CALL THIS. Use JS::ToBoolean. */ -extern JS_PUBLIC_API(bool) -ToBooleanSlow(JS::HandleValue v); - -/* DO NOT CALL THIS. Use JS::ToNumber. */ -extern JS_PUBLIC_API(bool) -ToNumberSlow(JSContext* cx, JS::HandleValue v, double* dp); - -/* DO NOT CALL THIS. Use JS::ToInt8. */ -extern JS_PUBLIC_API(bool) -ToInt8Slow(JSContext *cx, JS::HandleValue v, int8_t *out); - -/* DO NOT CALL THIS. Use JS::ToUint8. */ -extern JS_PUBLIC_API(bool) -ToUint8Slow(JSContext *cx, JS::HandleValue v, uint8_t *out); - -/* DO NOT CALL THIS. Use JS::ToInt16. */ -extern JS_PUBLIC_API(bool) -ToInt16Slow(JSContext *cx, JS::HandleValue v, int16_t *out); - -/* DO NOT CALL THIS. Use JS::ToInt32. */ -extern JS_PUBLIC_API(bool) -ToInt32Slow(JSContext* cx, JS::HandleValue v, int32_t* out); - -/* DO NOT CALL THIS. Use JS::ToUint32. */ -extern JS_PUBLIC_API(bool) -ToUint32Slow(JSContext* cx, JS::HandleValue v, uint32_t* out); - -/* DO NOT CALL THIS. Use JS::ToUint16. */ -extern JS_PUBLIC_API(bool) -ToUint16Slow(JSContext* cx, JS::HandleValue v, uint16_t* out); - -/* DO NOT CALL THIS. Use JS::ToInt64. */ -extern JS_PUBLIC_API(bool) -ToInt64Slow(JSContext* cx, JS::HandleValue v, int64_t* out); - -/* DO NOT CALL THIS. Use JS::ToUint64. */ -extern JS_PUBLIC_API(bool) -ToUint64Slow(JSContext* cx, JS::HandleValue v, uint64_t* out); - -/* DO NOT CALL THIS. Use JS::ToString. */ -extern JS_PUBLIC_API(JSString*) -ToStringSlow(JSContext* cx, JS::HandleValue v); - -/* DO NOT CALL THIS. Use JS::ToObject. */ -extern JS_PUBLIC_API(JSObject*) -ToObjectSlow(JSContext* cx, JS::HandleValue v, bool reportScanStack); - -} // namespace js - -namespace JS { - -namespace detail { - -#ifdef JS_DEBUG -/** - * Assert that we're not doing GC on cx, that we're in a request as - * needed, and that the compartments for cx and v are correct. - * Also check that GC would be safe at this point. - */ -extern JS_PUBLIC_API(void) -AssertArgumentsAreSane(JSContext* cx, HandleValue v); -#else -inline void AssertArgumentsAreSane(JSContext* cx, HandleValue v) -{} -#endif /* JS_DEBUG */ - -} // namespace detail - -/** - * ES6 draft 20141224, 7.1.1, second algorithm. - * - * Most users shouldn't call this -- use JS::ToBoolean, ToNumber, or ToString - * instead. This will typically only be called from custom convert hooks that - * wish to fall back to the ES6 default conversion behavior shared by most - * objects in JS, codified as OrdinaryToPrimitive. - */ -extern JS_PUBLIC_API(bool) -OrdinaryToPrimitive(JSContext* cx, HandleObject obj, JSType type, MutableHandleValue vp); - -/* ES6 draft 20141224, 7.1.2. */ -MOZ_ALWAYS_INLINE bool -ToBoolean(HandleValue v) -{ - if (v.isBoolean()) - return v.toBoolean(); - if (v.isInt32()) - return v.toInt32() != 0; - if (v.isNullOrUndefined()) - return false; - if (v.isDouble()) { - double d = v.toDouble(); - return !mozilla::IsNaN(d) && d != 0; - } - if (v.isSymbol()) - return true; - - /* The slow path handles strings and objects. */ - return js::ToBooleanSlow(v); -} - -/* ES6 draft 20141224, 7.1.3. */ -MOZ_ALWAYS_INLINE bool -ToNumber(JSContext* cx, HandleValue v, double* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isNumber()) { - *out = v.toNumber(); - return true; - } - return js::ToNumberSlow(cx, v, out); -} - -/* ES6 draft 20141224, ToInteger (specialized for doubles). */ -inline double -ToInteger(double d) -{ - if (d == 0) - return d; - - if (!mozilla::IsFinite(d)) { - if (mozilla::IsNaN(d)) - return 0; - return d; - } - - return d < 0 ? ceil(d) : floor(d); -} - -/* ES6 draft 20141224, 7.1.5. */ -MOZ_ALWAYS_INLINE bool -ToInt32(JSContext* cx, JS::HandleValue v, int32_t* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = v.toInt32(); - return true; - } - return js::ToInt32Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.6. */ -MOZ_ALWAYS_INLINE bool -ToUint32(JSContext* cx, HandleValue v, uint32_t* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = uint32_t(v.toInt32()); - return true; - } - return js::ToUint32Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.7. */ -MOZ_ALWAYS_INLINE bool -ToInt16(JSContext *cx, JS::HandleValue v, int16_t *out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = int16_t(v.toInt32()); - return true; - } - return js::ToInt16Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.8. */ -MOZ_ALWAYS_INLINE bool -ToUint16(JSContext* cx, HandleValue v, uint16_t* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = uint16_t(v.toInt32()); - return true; - } - return js::ToUint16Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.9 */ -MOZ_ALWAYS_INLINE bool -ToInt8(JSContext *cx, JS::HandleValue v, int8_t *out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = int8_t(v.toInt32()); - return true; - } - return js::ToInt8Slow(cx, v, out); -} - -/* ES6 ECMA-262, 7.1.10 */ -MOZ_ALWAYS_INLINE bool -ToUint8(JSContext *cx, JS::HandleValue v, uint8_t *out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = uint8_t(v.toInt32()); - return true; - } - return js::ToUint8Slow(cx, v, out); -} - -/* - * Non-standard, with behavior similar to that of ToInt32, except in its - * producing an int64_t. - */ -MOZ_ALWAYS_INLINE bool -ToInt64(JSContext* cx, HandleValue v, int64_t* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = int64_t(v.toInt32()); - return true; - } - return js::ToInt64Slow(cx, v, out); -} - -/* - * Non-standard, with behavior similar to that of ToUint32, except in its - * producing a uint64_t. - */ -MOZ_ALWAYS_INLINE bool -ToUint64(JSContext* cx, HandleValue v, uint64_t* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = uint64_t(v.toInt32()); - return true; - } - return js::ToUint64Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.12. */ -MOZ_ALWAYS_INLINE JSString* -ToString(JSContext* cx, HandleValue v) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isString()) - return v.toString(); - return js::ToStringSlow(cx, v); -} - -/* ES6 draft 20141224, 7.1.13. */ -inline JSObject* -ToObject(JSContext* cx, HandleValue v) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isObject()) - return &v.toObject(); - return js::ToObjectSlow(cx, v, false); -} - -namespace detail { - -/* - * Convert a double value to ResultType (an unsigned integral type) using - * ECMAScript-style semantics (that is, in like manner to how ECMAScript's - * ToInt32 converts to int32_t). - * - * If d is infinite or NaN, return 0. - * Otherwise compute d2 = sign(d) * floor(abs(d)), and return the ResultType - * value congruent to d2 mod 2**(bit width of ResultType). - * - * The algorithm below is inspired by that found in - * - * but has been generalized to all integer widths. - */ -template -inline ResultType -ToUintWidth(double d) -{ - static_assert(mozilla::IsUnsigned::value, - "ResultType must be an unsigned type"); - - uint64_t bits = mozilla::BitwiseCast(d); - unsigned DoubleExponentShift = mozilla::FloatingPoint::kExponentShift; - - // Extract the exponent component. (Be careful here! It's not technically - // the exponent in NaN, infinities, and subnormals.) - int_fast16_t exp = - int_fast16_t((bits & mozilla::FloatingPoint::kExponentBits) >> DoubleExponentShift) - - int_fast16_t(mozilla::FloatingPoint::kExponentBias); - - // If the exponent's less than zero, abs(d) < 1, so the result is 0. (This - // also handles subnormals.) - if (exp < 0) - return 0; - - uint_fast16_t exponent = mozilla::AssertedCast(exp); - - // If the exponent is greater than or equal to the bits of precision of a - // double plus ResultType's width, the number is either infinite, NaN, or - // too large to have lower-order bits in the congruent value. (Example: - // 2**84 is exactly representable as a double. The next exact double is - // 2**84 + 2**32. Thus if ResultType is int32_t, an exponent >= 84 implies - // floor(abs(d)) == 0 mod 2**32.) Return 0 in all these cases. - const size_t ResultWidth = CHAR_BIT * sizeof(ResultType); - if (exponent >= DoubleExponentShift + ResultWidth) - return 0; - - // The significand contains the bits that will determine the final result. - // Shift those bits left or right, according to the exponent, to their - // locations in the unsigned binary representation of floor(abs(d)). - static_assert(sizeof(ResultType) <= sizeof(uint64_t), - "Left-shifting below would lose upper bits"); - ResultType result = (exponent > DoubleExponentShift) - ? ResultType(bits << (exponent - DoubleExponentShift)) - : ResultType(bits >> (DoubleExponentShift - exponent)); - - // Two further complications remain. First, |result| may contain bogus - // sign/exponent bits. Second, IEEE-754 numbers' significands (excluding - // subnormals, but we already handled those) have an implicit leading 1 - // which may affect the final result. - // - // It may appear that there's complexity here depending on how ResultWidth - // and DoubleExponentShift relate, but it turns out there's not. - // - // Assume ResultWidth < DoubleExponentShift: - // Only right-shifts leave bogus bits in |result|. For this to happen, - // we must right-shift by > |DoubleExponentShift - ResultWidth|, implying - // |exponent < ResultWidth|. - // The implicit leading bit only matters if it appears in the final - // result -- if |2**exponent mod 2**ResultWidth != 0|. This implies - // |exponent < ResultWidth|. - // Otherwise assume ResultWidth >= DoubleExponentShift: - // Any left-shift less than |ResultWidth - DoubleExponentShift| leaves - // bogus bits in |result|. This implies |exponent < ResultWidth|. Any - // right-shift less than |ResultWidth| does too, which implies - // |DoubleExponentShift - ResultWidth < exponent|. By assumption, then, - // |exponent| is negative, but we excluded that above. So bogus bits - // need only |exponent < ResultWidth|. - // The implicit leading bit matters identically to the other case, so - // again, |exponent < ResultWidth|. - if (exponent < ResultWidth) { - ResultType implicitOne = ResultType(1) << exponent; - result &= implicitOne - 1; // remove bogus bits - result += implicitOne; // add the implicit bit - } - - // Compute the congruent value in the signed range. - return (bits & mozilla::FloatingPoint::kSignBit) ? ~result + 1 : result; -} - -template -inline ResultType -ToIntWidth(double d) -{ - static_assert(mozilla::IsSigned::value, - "ResultType must be a signed type"); - - const ResultType MaxValue = (1ULL << (CHAR_BIT * sizeof(ResultType) - 1)) - 1; - const ResultType MinValue = -MaxValue - 1; - - typedef typename mozilla::MakeUnsigned::Type UnsignedResult; - UnsignedResult u = ToUintWidth(d); - if (u <= UnsignedResult(MaxValue)) - return static_cast(u); - return (MinValue + static_cast(u - MaxValue)) - 1; -} - -} // namespace detail - -/* ES5 9.5 ToInt32 (specialized for doubles). */ -inline int32_t -ToInt32(double d) -{ - // clang crashes compiling this when targeting arm: - // https://llvm.org/bugs/show_bug.cgi?id=22974 -#if defined (__arm__) && defined (__GNUC__) && !defined(__clang__) - int32_t i; - uint32_t tmp0; - uint32_t tmp1; - uint32_t tmp2; - asm ( - // We use a pure integer solution here. In the 'softfp' ABI, the argument - // will start in r0 and r1, and VFP can't do all of the necessary ECMA - // conversions by itself so some integer code will be required anyway. A - // hybrid solution is faster on A9, but this pure integer solution is - // notably faster for A8. - - // %0 is the result register, and may alias either of the %[QR]1 registers. - // %Q4 holds the lower part of the mantissa. - // %R4 holds the sign, exponent, and the upper part of the mantissa. - // %1, %2 and %3 are used as temporary values. - - // Extract the exponent. -" mov %1, %R4, LSR #20\n" -" bic %1, %1, #(1 << 11)\n" // Clear the sign. - - // Set the implicit top bit of the mantissa. This clobbers a bit of the - // exponent, but we have already extracted that. -" orr %R4, %R4, #(1 << 20)\n" - - // Special Cases - // We should return zero in the following special cases: - // - Exponent is 0x000 - 1023: +/-0 or subnormal. - // - Exponent is 0x7ff - 1023: +/-INFINITY or NaN - // - This case is implicitly handled by the standard code path anyway, - // as shifting the mantissa up by the exponent will result in '0'. - // - // The result is composed of the mantissa, prepended with '1' and - // bit-shifted left by the (decoded) exponent. Note that because the r1[20] - // is the bit with value '1', r1 is effectively already shifted (left) by - // 20 bits, and r0 is already shifted by 52 bits. - - // Adjust the exponent to remove the encoding offset. If the decoded - // exponent is negative, quickly bail out with '0' as such values round to - // zero anyway. This also catches +/-0 and subnormals. -" sub %1, %1, #0xff\n" -" subs %1, %1, #0x300\n" -" bmi 8f\n" - - // %1 = (decoded) exponent >= 0 - // %R4 = upper mantissa and sign - - // ---- Lower Mantissa ---- -" subs %3, %1, #52\n" // Calculate exp-52 -" bmi 1f\n" - - // Shift r0 left by exp-52. - // Ensure that we don't overflow ARM's 8-bit shift operand range. - // We need to handle anything up to an 11-bit value here as we know that - // 52 <= exp <= 1024 (0x400). Any shift beyond 31 bits results in zero - // anyway, so as long as we don't touch the bottom 5 bits, we can use - // a logical OR to push long shifts into the 32 <= (exp&0xff) <= 255 range. -" bic %2, %3, #0xff\n" -" orr %3, %3, %2, LSR #3\n" - // We can now perform a straight shift, avoiding the need for any - // conditional instructions or extra branches. -" mov %Q4, %Q4, LSL %3\n" -" b 2f\n" -"1:\n" // Shift r0 right by 52-exp. - // We know that 0 <= exp < 52, and we can shift up to 255 bits so 52-exp - // will always be a valid shift and we can sk%3 the range check for this case. -" rsb %3, %1, #52\n" -" mov %Q4, %Q4, LSR %3\n" - - // %1 = (decoded) exponent - // %R4 = upper mantissa and sign - // %Q4 = partially-converted integer - -"2:\n" - // ---- Upper Mantissa ---- - // This is much the same as the lower mantissa, with a few different - // boundary checks and some masking to hide the exponent & sign bit in the - // upper word. - // Note that the upper mantissa is pre-shifted by 20 in %R4, but we shift - // it left more to remove the sign and exponent so it is effectively - // pre-shifted by 31 bits. -" subs %3, %1, #31\n" // Calculate exp-31 -" mov %1, %R4, LSL #11\n" // Re-use %1 as a temporary register. -" bmi 3f\n" - - // Shift %R4 left by exp-31. - // Avoid overflowing the 8-bit shift range, as before. -" bic %2, %3, #0xff\n" -" orr %3, %3, %2, LSR #3\n" - // Perform the shift. -" mov %2, %1, LSL %3\n" -" b 4f\n" -"3:\n" // Shift r1 right by 31-exp. - // We know that 0 <= exp < 31, and we can shift up to 255 bits so 31-exp - // will always be a valid shift and we can skip the range check for this case. -" rsb %3, %3, #0\n" // Calculate 31-exp from -(exp-31) -" mov %2, %1, LSR %3\n" // Thumb-2 can't do "LSR %3" in "orr". - - // %Q4 = partially-converted integer (lower) - // %R4 = upper mantissa and sign - // %2 = partially-converted integer (upper) - -"4:\n" - // Combine the converted parts. -" orr %Q4, %Q4, %2\n" - // Negate the result if we have to, and move it to %0 in the process. To - // avoid conditionals, we can do this by inverting on %R4[31], then adding - // %R4[31]>>31. -" eor %Q4, %Q4, %R4, ASR #31\n" -" add %0, %Q4, %R4, LSR #31\n" -" b 9f\n" -"8:\n" - // +/-INFINITY, +/-0, subnormals, NaNs, and anything else out-of-range that - // will result in a conversion of '0'. -" mov %0, #0\n" -"9:\n" - : "=r" (i), "=&r" (tmp0), "=&r" (tmp1), "=&r" (tmp2), "=&r" (d) - : "4" (d) - : "cc" - ); - return i; -#else - return detail::ToIntWidth(d); -#endif -} - -/* ES5 9.6 (specialized for doubles). */ -inline uint32_t -ToUint32(double d) -{ - return detail::ToUintWidth(d); -} - -/* WEBIDL 4.2.4 */ -inline int8_t -ToInt8(double d) -{ - return detail::ToIntWidth(d); -} - -/* ECMA-262 7.1.10 ToUInt8() specialized for doubles. */ -inline int8_t -ToUint8(double d) -{ - return detail::ToUintWidth(d); -} - -/* WEBIDL 4.2.6 */ -inline int16_t -ToInt16(double d) -{ - return detail::ToIntWidth(d); -} - -inline uint16_t -ToUint16(double d) -{ - return detail::ToUintWidth(d); -} - -/* WEBIDL 4.2.10 */ -inline int64_t -ToInt64(double d) -{ - return detail::ToIntWidth(d); -} - -/* WEBIDL 4.2.11 */ -inline uint64_t -ToUint64(double d) -{ - return detail::ToUintWidth(d); -} - -} // namespace JS - -#endif /* js_Conversions_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/Date.h b/android/armeabi-v7a/include/spidermonkey/js/Date.h deleted file mode 100644 index cba0ea87..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/Date.h +++ /dev/null @@ -1,170 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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/. */ - -/* JavaScript date/time computation and creation functions. */ - -#ifndef js_Date_h -#define js_Date_h - -/* - * Dates in JavaScript are defined by IEEE-754 double precision numbers from - * the set: - * - * { t ∈ ℕ : -8.64e15 ≤ t ≤ +8.64e15 } ∪ { NaN } - * - * The single NaN value represents any invalid-date value. All other values - * represent idealized durations in milliseconds since the UTC epoch. (Leap - * seconds are ignored; leap days are not.) +0 is the only zero in this set. - * The limit represented by 8.64e15 milliseconds is 100 million days either - * side of 00:00 January 1, 1970 UTC. - * - * Dates in the above set are represented by the |ClippedTime| class. The - * double type is a superset of the above set, so it *may* (but need not) - * represent a date. Use ECMAScript's |TimeClip| method to produce a date from - * a double. - * - * Date *objects* are simply wrappers around |TimeClip|'d numbers, with a bunch - * of accessor methods to the various aspects of the represented date. - */ - -#include "mozilla/FloatingPoint.h" -#include "mozilla/MathAlgorithms.h" - -#include "js/Conversions.h" -#include "js/Value.h" - -struct JSContext; - -namespace JS { - -/** - * Re-query the system to determine the current time zone adjustment from UTC, - * including any component due to DST. If the time zone has changed, this will - * cause all Date object non-UTC methods and formatting functions to produce - * appropriately adjusted results. - * - * Left to its own devices, SpiderMonkey itself may occasionally call this - * method to attempt to keep up with system time changes. However, no - * particular frequency of checking is guaranteed. Embedders unable to accept - * occasional inaccuracies should call this method in response to system time - * changes, or immediately before operations requiring instantaneous - * correctness, to guarantee correct behavior. - */ -extern JS_PUBLIC_API(void) -ResetTimeZone(); - -class ClippedTime; -inline ClippedTime TimeClip(double time); - -/* - * |ClippedTime| represents the limited subset of dates/times described above. - * - * An invalid date/time may be created through the |ClippedTime::invalid| - * method. Otherwise, a |ClippedTime| may be created using the |TimeClip| - * method. - * - * In typical use, the user might wish to manipulate a timestamp. The user - * performs a series of operations on it, but the final value might not be a - * date as defined above -- it could have overflowed, acquired a fractional - * component, &c. So as a *final* step, the user passes that value through - * |TimeClip| to produce a number restricted to JavaScript's date range. - * - * APIs that accept a JavaScript date value thus accept a |ClippedTime|, not a - * double. This ensures that date/time APIs will only ever receive acceptable - * JavaScript dates. This also forces users to perform any desired clipping, - * as only the user knows what behavior is desired when clipping occurs. - */ -class ClippedTime -{ - double t; - - explicit ClippedTime(double time) : t(time) {} - friend ClippedTime TimeClip(double time); - - public: - // Create an invalid date. - ClippedTime() : t(mozilla::UnspecifiedNaN()) {} - - // Create an invalid date/time, more explicitly; prefer this to the default - // constructor. - static ClippedTime invalid() { return ClippedTime(); } - - double toDouble() const { return t; } - - bool isValid() const { return !mozilla::IsNaN(t); } -}; - -// ES6 20.3.1.15. -// -// Clip a double to JavaScript's date range (or to an invalid date) using the -// ECMAScript TimeClip algorithm. -inline ClippedTime -TimeClip(double time) -{ - // Steps 1-2. - const double MaxTimeMagnitude = 8.64e15; - if (!mozilla::IsFinite(time) || mozilla::Abs(time) > MaxTimeMagnitude) - return ClippedTime(mozilla::UnspecifiedNaN()); - - // Step 3. - return ClippedTime(ToInteger(time) + (+0.0)); -} - -// Produce a double Value from the given time. Because times may be NaN, -// prefer using this to manual canonicalization. -inline Value -TimeValue(ClippedTime time) -{ - return DoubleValue(JS::CanonicalizeNaN(time.toDouble())); -} - -// Create a new Date object whose [[DateValue]] internal slot contains the -// clipped |time|. (Users who must represent times outside that range must use -// another representation.) -extern JS_PUBLIC_API(JSObject*) -NewDateObject(JSContext* cx, ClippedTime time); - -// Year is a year, month is 0-11, day is 1-based. The return value is a number -// of milliseconds since the epoch. -// -// Consistent with the MakeDate algorithm defined in ECMAScript, this value is -// *not* clipped! Use JS::TimeClip if you need a clipped date. -JS_PUBLIC_API(double) -MakeDate(double year, unsigned month, unsigned day); - -// Takes an integer number of milliseconds since the epoch and returns the -// year. Can return NaN, and will do so if NaN is passed in. -JS_PUBLIC_API(double) -YearFromTime(double time); - -// Takes an integer number of milliseconds since the epoch and returns the -// month (0-11). Can return NaN, and will do so if NaN is passed in. -JS_PUBLIC_API(double) -MonthFromTime(double time); - -// Takes an integer number of milliseconds since the epoch and returns the -// day (1-based). Can return NaN, and will do so if NaN is passed in. -JS_PUBLIC_API(double) -DayFromTime(double time); - -// Takes an integer year and returns the number of days from epoch to the given -// year. -// NOTE: The calculation performed by this function is literally that given in -// the ECMAScript specification. Nonfinite years, years containing fractional -// components, and years outside ECMAScript's date range are not handled with -// any particular intelligence. Garbage in, garbage out. -JS_PUBLIC_API(double) -DayFromYear(double year); - -// Takes an integer number of milliseconds since the epoch and an integer year, -// returns the number of days in that year. If |time| is nonfinite, returns NaN. -// Otherwise |time| *must* correspond to a time within the valid year |year|. -// This should usually be ensured by computing |year| as |JS::DayFromYear(time)|. -JS_PUBLIC_API(double) -DayWithinYear(double time, double year); - -} // namespace JS - -#endif /* js_Date_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/Debug.h b/android/armeabi-v7a/include/spidermonkey/js/Debug.h deleted file mode 100644 index 3e4183f0..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/Debug.h +++ /dev/null @@ -1,384 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -// Interfaces by which the embedding can interact with the Debugger API. - -#ifndef js_Debug_h -#define js_Debug_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/MemoryReporting.h" - -#include "jsapi.h" -#include "jspubtd.h" - -#include "js/GCAPI.h" -#include "js/RootingAPI.h" -#include "js/TypeDecls.h" - -namespace js { -class Debugger; -} // namespace js - -namespace JS { -namespace dbg { - -// Helping embedding code build objects for Debugger -// ------------------------------------------------- -// -// Some Debugger API features lean on the embedding application to construct -// their result values. For example, Debugger.Frame.prototype.scriptEntryReason -// calls hooks provided by the embedding to construct values explaining why it -// invoked JavaScript; if F is a frame called from a mouse click event handler, -// F.scriptEntryReason would return an object of the form: -// -// { eventType: "mousedown", event: } -// -// where is a Debugger.Object whose referent is the event being -// dispatched. -// -// However, Debugger implements a trust boundary. Debuggee code may be -// considered untrusted; debugger code needs to be protected from debuggee -// getters, setters, proxies, Object.watch watchpoints, and any other feature -// that might accidentally cause debugger code to set the debuggee running. The -// Debugger API tries to make it easy to write safe debugger code by only -// offering access to debuggee objects via Debugger.Object instances, which -// ensure that only those operations whose explicit purpose is to invoke -// debuggee code do so. But this protective membrane is only helpful if we -// interpose Debugger.Object instances in all the necessary spots. -// -// SpiderMonkey's compartment system also implements a trust boundary. The -// debuggee and debugger are always in different compartments. Inter-compartment -// work requires carefully tracking which compartment each JSObject or JS::Value -// belongs to, and ensuring that is is correctly wrapped for each operation. -// -// It seems precarious to expect the embedding's hooks to implement these trust -// boundaries. Instead, the JS::dbg::Builder API segregates the code which -// constructs trusted objects from that which deals with untrusted objects. -// Trusted objects have an entirely different C++ type, so code that improperly -// mixes trusted and untrusted objects is caught at compile time. -// -// In the structure shown above, there are two trusted objects, and one -// untrusted object: -// -// - The overall object, with the 'eventType' and 'event' properties, is a -// trusted object. We're going to return it to D.F.p.scriptEntryReason's -// caller, which will handle it directly. -// -// - The Debugger.Object instance appearing as the value of the 'event' property -// is a trusted object. It belongs to the same Debugger instance as the -// Debugger.Frame instance whose scriptEntryReason accessor was called, and -// presents a safe reflection-oriented API for inspecting its referent, which -// is: -// -// - The actual event object, an untrusted object, and the referent of the -// Debugger.Object above. (Content can do things like replacing accessors on -// Event.prototype.) -// -// Using JS::dbg::Builder, all objects and values the embedding deals with -// directly are considered untrusted, and are assumed to be debuggee values. The -// only way to construct trusted objects is to use Builder's own methods, which -// return a separate Object type. The only way to set a property on a trusted -// object is through that Object type. The actual trusted object is never -// exposed to the embedding. -// -// So, for example, the embedding might use code like the following to construct -// the object shown above, given a Builder passed to it by Debugger: -// -// bool -// MyScriptEntryReason::explain(JSContext* cx, -// Builder& builder, -// Builder::Object& result) -// { -// JSObject* eventObject = ... obtain debuggee event object somehow ...; -// if (!eventObject) -// return false; -// result = builder.newObject(cx); -// return result && -// result.defineProperty(cx, "eventType", SafelyFetchType(eventObject)) && -// result.defineProperty(cx, "event", eventObject); -// } -// -// -// Object::defineProperty also accepts an Object as the value to store on the -// property. By its type, we know that the value is trusted, so we set it -// directly as the property's value, without interposing a Debugger.Object -// wrapper. This allows the embedding to builted nested structures of trusted -// objects. -// -// The Builder and Builder::Object methods take care of doing whatever -// compartment switching and wrapping are necessary to construct the trusted -// values in the Debugger's compartment. -// -// The Object type is self-rooting. Construction, assignment, and destruction -// all properly root the referent object. - -class BuilderOrigin; - -class Builder { - // The Debugger instance whose client we are building a value for. We build - // objects in this object's compartment. - PersistentRootedObject debuggerObject; - - // debuggerObject's Debugger structure, for convenience. - js::Debugger* debugger; - - // Check that |thing| is in the same compartment as our debuggerObject. Used - // for assertions when constructing BuiltThings. We can overload this as we - // add more instantiations of BuiltThing. -#if DEBUG - void assertBuilt(JSObject* obj); -#else - void assertBuilt(JSObject* obj) { } -#endif - - protected: - // A reference to a trusted object or value. At the moment, we only use it - // with JSObject*. - template - class BuiltThing { - friend class BuilderOrigin; - - protected: - // The Builder to which this trusted thing belongs. - Builder& owner; - - // A rooted reference to our value. - PersistentRooted value; - - BuiltThing(JSContext* cx, Builder& owner_, T value_ = GCPolicy::initial()) - : owner(owner_), value(cx, value_) - { - owner.assertBuilt(value_); - } - - // Forward some things from our owner, for convenience. - js::Debugger* debugger() const { return owner.debugger; } - JSObject* debuggerObject() const { return owner.debuggerObject; } - - public: - BuiltThing(const BuiltThing& rhs) : owner(rhs.owner), value(rhs.value) { } - BuiltThing& operator=(const BuiltThing& rhs) { - MOZ_ASSERT(&owner == &rhs.owner); - owner.assertBuilt(rhs.value); - value = rhs.value; - return *this; - } - - explicit operator bool() const { - // If we ever instantiate BuiltThing, this might not suffice. - return value; - } - - private: - BuiltThing() = delete; - }; - - public: - // A reference to a trusted object, possibly null. Instances of Object are - // always properly rooted. They can be copied and assigned, as if they were - // pointers. - class Object: private BuiltThing { - friend class Builder; // for construction - friend class BuilderOrigin; // for unwrapping - - typedef BuiltThing Base; - - // This is private, because only Builders can create Objects that - // actually point to something (hence the 'friend' declaration). - Object(JSContext* cx, Builder& owner_, HandleObject obj) : Base(cx, owner_, obj.get()) { } - - bool definePropertyToTrusted(JSContext* cx, const char* name, - JS::MutableHandleValue value); - - public: - Object(JSContext* cx, Builder& owner_) : Base(cx, owner_, nullptr) { } - Object(const Object& rhs) : Base(rhs) { } - - // Our automatically-generated assignment operator can see our base - // class's assignment operator, so we don't need to write one out here. - - // Set the property named |name| on this object to |value|. - // - // If |value| is a string or primitive, re-wrap it for the debugger's - // compartment. - // - // If |value| is an object, assume it is a debuggee object and make a - // Debugger.Object instance referring to it. Set that as the propery's - // value. - // - // If |value| is another trusted object, store it directly as the - // property's value. - // - // On error, report the problem on cx and return false. - bool defineProperty(JSContext* cx, const char* name, JS::HandleValue value); - bool defineProperty(JSContext* cx, const char* name, JS::HandleObject value); - bool defineProperty(JSContext* cx, const char* name, Object& value); - - using Base::operator bool; - }; - - // Build an empty object for direct use by debugger code, owned by this - // Builder. If an error occurs, report it on cx and return a false Object. - Object newObject(JSContext* cx); - - protected: - Builder(JSContext* cx, js::Debugger* debugger); -}; - -// Debugger itself instantiates this subclass of Builder, which can unwrap -// BuiltThings that belong to it. -class BuilderOrigin : public Builder { - template - T unwrapAny(const BuiltThing& thing) { - MOZ_ASSERT(&thing.owner == this); - return thing.value.get(); - } - - public: - BuilderOrigin(JSContext* cx, js::Debugger* debugger_) - : Builder(cx, debugger_) - { } - - JSObject* unwrap(Object& object) { return unwrapAny(object); } -}; - - - -// Finding the size of blocks allocated with malloc -// ------------------------------------------------ -// -// Debugger.Memory wants to be able to report how many bytes items in memory are -// consuming. To do this, it needs a function that accepts a pointer to a block, -// and returns the number of bytes allocated to that block. SpiderMonkey itself -// doesn't know which function is appropriate to use, but the embedding does. - -// Tell Debuggers in |cx| to use |mallocSizeOf| to find the size of -// malloc'd blocks. -JS_PUBLIC_API(void) -SetDebuggerMallocSizeOf(JSContext* cx, mozilla::MallocSizeOf mallocSizeOf); - -// Get the MallocSizeOf function that the given context is using to find the -// size of malloc'd blocks. -JS_PUBLIC_API(mozilla::MallocSizeOf) -GetDebuggerMallocSizeOf(JSContext* cx); - - - -// Debugger and Garbage Collection Events -// -------------------------------------- -// -// The Debugger wants to report about its debuggees' GC cycles, however entering -// JS after a GC is troublesome since SpiderMonkey will often do something like -// force a GC and then rely on the nursery being empty. If we call into some -// Debugger's hook after the GC, then JS runs and the nursery won't be -// empty. Instead, we rely on embedders to call back into SpiderMonkey after a -// GC and notify Debuggers to call their onGarbageCollection hook. - - -// For each Debugger that observed a debuggee involved in the given GC event, -// call its `onGarbageCollection` hook. -JS_PUBLIC_API(bool) -FireOnGarbageCollectionHook(JSContext* cx, GarbageCollectionEvent::Ptr&& data); - - - -// Handlers for observing Promises -// ------------------------------- -// -// The Debugger wants to observe behavior of promises, which are implemented by -// Gecko with webidl and which SpiderMonkey knows nothing about. On the other -// hand, Gecko knows nothing about which (if any) debuggers are observing a -// promise's global. The compromise is that Gecko is responsible for calling -// these handlers at the appropriate times, and SpiderMonkey will handle -// notifying any Debugger instances that are observing the given promise's -// global. - -// Notify any Debugger instances observing this promise's global that a new -// promise was allocated. -JS_PUBLIC_API(void) -onNewPromise(JSContext* cx, HandleObject promise); - -// Notify any Debugger instances observing this promise's global that the -// promise has settled (ie, it has either been fulfilled or rejected). Note that -// this is *not* equivalent to the promise resolution (ie, the promise's fate -// getting locked in) because you can resolve a promise with another pending -// promise, in which case neither promise has settled yet. -// -// It is Gecko's responsibility to ensure that this is never called on the same -// promise more than once (because a promise can only make the transition from -// unsettled to settled once). -JS_PUBLIC_API(void) -onPromiseSettled(JSContext* cx, HandleObject promise); - - - -// Return true if the given value is a Debugger object, false otherwise. -JS_PUBLIC_API(bool) -IsDebugger(JSObject& obj); - -// Append each of the debuggee global objects observed by the Debugger object -// |dbgObj| to |vector|. Returns true on success, false on failure. -JS_PUBLIC_API(bool) -GetDebuggeeGlobals(JSContext* cx, JSObject& dbgObj, AutoObjectVector& vector); - - -// Hooks for reporting where JavaScript execution began. -// -// Our performance tools would like to be able to label blocks of JavaScript -// execution with the function name and source location where execution began: -// the event handler, the callback, etc. -// -// Construct an instance of this class on the stack, providing a JSContext -// belonging to the runtime in which execution will occur. Each time we enter -// JavaScript --- specifically, each time we push a JavaScript stack frame that -// has no older JS frames younger than this AutoEntryMonitor --- we will -// call the appropriate |Entry| member function to indicate where we've begun -// execution. - -class MOZ_STACK_CLASS AutoEntryMonitor { - JSRuntime* runtime_; - AutoEntryMonitor* savedMonitor_; - - public: - explicit AutoEntryMonitor(JSContext* cx); - ~AutoEntryMonitor(); - - // SpiderMonkey reports the JavaScript entry points occuring within this - // AutoEntryMonitor's scope to the following member functions, which the - // embedding is expected to override. - // - // It is important to note that |asyncCause| is owned by the caller and its - // lifetime must outlive the lifetime of the AutoEntryMonitor object. It is - // strongly encouraged that |asyncCause| be a string constant or similar - // statically allocated string. - - // We have begun executing |function|. Note that |function| may not be the - // actual closure we are running, but only the canonical function object to - // which the script refers. - virtual void Entry(JSContext* cx, JSFunction* function, - HandleValue asyncStack, - const char* asyncCause) = 0; - - // Execution has begun at the entry point of |script|, which is not a - // function body. (This is probably being executed by 'eval' or some - // JSAPI equivalent.) - virtual void Entry(JSContext* cx, JSScript* script, - HandleValue asyncStack, - const char* asyncCause) = 0; - - // Execution of the function or script has ended. - virtual void Exit(JSContext* cx) { } -}; - - - -} // namespace dbg -} // namespace JS - - -#endif /* js_Debug_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/GCAPI.h b/android/armeabi-v7a/include/spidermonkey/js/GCAPI.h deleted file mode 100644 index 7a6675ca..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/GCAPI.h +++ /dev/null @@ -1,723 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_GCAPI_h -#define js_GCAPI_h - -#include "mozilla/Vector.h" - -#include "js/GCAnnotations.h" -#include "js/HeapAPI.h" -#include "js/UniquePtr.h" - -namespace js { -namespace gc { -class GCRuntime; -} // namespace gc -namespace gcstats { -struct Statistics; -} // namespace gcstats -} // namespace js - -typedef enum JSGCMode { - /** Perform only global GCs. */ - JSGC_MODE_GLOBAL = 0, - - /** Perform per-zone GCs until too much garbage has accumulated. */ - JSGC_MODE_ZONE = 1, - - /** - * Collect in short time slices rather than all at once. Implies - * JSGC_MODE_ZONE. - */ - JSGC_MODE_INCREMENTAL = 2 -} JSGCMode; - -/** - * Kinds of js_GC invocation. - */ -typedef enum JSGCInvocationKind { - /* Normal invocation. */ - GC_NORMAL = 0, - - /* Minimize GC triggers and release empty GC chunks right away. */ - GC_SHRINK = 1 -} JSGCInvocationKind; - -namespace JS { - -#define GCREASONS(D) \ - /* Reasons internal to the JS engine */ \ - D(API) \ - D(EAGER_ALLOC_TRIGGER) \ - D(DESTROY_RUNTIME) \ - D(UNUSED0) \ - D(LAST_DITCH) \ - D(TOO_MUCH_MALLOC) \ - D(ALLOC_TRIGGER) \ - D(DEBUG_GC) \ - D(COMPARTMENT_REVIVED) \ - D(RESET) \ - D(OUT_OF_NURSERY) \ - D(EVICT_NURSERY) \ - D(FULL_STORE_BUFFER) \ - D(SHARED_MEMORY_LIMIT) \ - D(UNUSED1) \ - D(INCREMENTAL_TOO_SLOW) \ - D(ABORT_GC) \ - \ - /* These are reserved for future use. */ \ - D(RESERVED0) \ - D(RESERVED1) \ - D(RESERVED2) \ - D(RESERVED3) \ - D(RESERVED4) \ - D(RESERVED5) \ - D(RESERVED6) \ - D(RESERVED7) \ - D(RESERVED8) \ - D(RESERVED9) \ - D(RESERVED10) \ - D(RESERVED11) \ - D(RESERVED12) \ - D(RESERVED13) \ - D(RESERVED14) \ - D(RESERVED15) \ - \ - /* Reasons from Firefox */ \ - D(DOM_WINDOW_UTILS) \ - D(COMPONENT_UTILS) \ - D(MEM_PRESSURE) \ - D(CC_WAITING) \ - D(CC_FORCED) \ - D(LOAD_END) \ - D(POST_COMPARTMENT) \ - D(PAGE_HIDE) \ - D(NSJSCONTEXT_DESTROY) \ - D(SET_NEW_DOCUMENT) \ - D(SET_DOC_SHELL) \ - D(DOM_UTILS) \ - D(DOM_IPC) \ - D(DOM_WORKER) \ - D(INTER_SLICE_GC) \ - D(REFRESH_FRAME) \ - D(FULL_GC_TIMER) \ - D(SHUTDOWN_CC) \ - D(FINISH_LARGE_EVALUATE) \ - D(USER_INACTIVE) \ - D(XPCONNECT_SHUTDOWN) - -namespace gcreason { - -/* GCReasons will end up looking like JSGC_MAYBEGC */ -enum Reason { -#define MAKE_REASON(name) name, - GCREASONS(MAKE_REASON) -#undef MAKE_REASON - NO_REASON, - NUM_REASONS, - - /* - * For telemetry, we want to keep a fixed max bucket size over time so we - * don't have to switch histograms. 100 is conservative; as of this writing - * there are 52. But the cost of extra buckets seems to be low while the - * cost of switching histograms is high. - */ - NUM_TELEMETRY_REASONS = 100 -}; - -/** - * Get a statically allocated C string explaining the given GC reason. - */ -extern JS_PUBLIC_API(const char*) -ExplainReason(JS::gcreason::Reason reason); - -} /* namespace gcreason */ - -/* - * Zone GC: - * - * SpiderMonkey's GC is capable of performing a collection on an arbitrary - * subset of the zones in the system. This allows an embedding to minimize - * collection time by only collecting zones that have run code recently, - * ignoring the parts of the heap that are unlikely to have changed. - * - * When triggering a GC using one of the functions below, it is first necessary - * to select the zones to be collected. To do this, you can call - * PrepareZoneForGC on each zone, or you can call PrepareForFullGC to select - * all zones. Failing to select any zone is an error. - */ - -/** - * Schedule the given zone to be collected as part of the next GC. - */ -extern JS_PUBLIC_API(void) -PrepareZoneForGC(Zone* zone); - -/** - * Schedule all zones to be collected in the next GC. - */ -extern JS_PUBLIC_API(void) -PrepareForFullGC(JSContext* cx); - -/** - * When performing an incremental GC, the zones that were selected for the - * previous incremental slice must be selected in subsequent slices as well. - * This function selects those slices automatically. - */ -extern JS_PUBLIC_API(void) -PrepareForIncrementalGC(JSContext* cx); - -/** - * Returns true if any zone in the system has been scheduled for GC with one of - * the functions above or by the JS engine. - */ -extern JS_PUBLIC_API(bool) -IsGCScheduled(JSContext* cx); - -/** - * Undoes the effect of the Prepare methods above. The given zone will not be - * collected in the next GC. - */ -extern JS_PUBLIC_API(void) -SkipZoneForGC(Zone* zone); - -/* - * Non-Incremental GC: - * - * The following functions perform a non-incremental GC. - */ - -/** - * Performs a non-incremental collection of all selected zones. - * - * If the gckind argument is GC_NORMAL, then some objects that are unreachable - * from the program may still be alive afterwards because of internal - * references; if GC_SHRINK is passed then caches and other temporary references - * to objects will be cleared and all unreferenced objects will be removed from - * the system. - */ -extern JS_PUBLIC_API(void) -GCForReason(JSContext* cx, JSGCInvocationKind gckind, gcreason::Reason reason); - -/* - * Incremental GC: - * - * Incremental GC divides the full mark-and-sweep collection into multiple - * slices, allowing client JavaScript code to run between each slice. This - * allows interactive apps to avoid long collection pauses. Incremental GC does - * not make collection take less time, it merely spreads that time out so that - * the pauses are less noticable. - * - * For a collection to be carried out incrementally the following conditions - * must be met: - * - The collection must be run by calling JS::IncrementalGC() rather than - * JS_GC(). - * - The GC mode must have been set to JSGC_MODE_INCREMENTAL with - * JS_SetGCParameter(). - * - * Note: Even if incremental GC is enabled and working correctly, - * non-incremental collections can still happen when low on memory. - */ - -/** - * Begin an incremental collection and perform one slice worth of work. When - * this function returns, the collection may not be complete. - * IncrementalGCSlice() must be called repeatedly until - * !IsIncrementalGCInProgress(cx). - * - * Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or - * shorter than the requested interval. - */ -extern JS_PUBLIC_API(void) -StartIncrementalGC(JSContext* cx, JSGCInvocationKind gckind, gcreason::Reason reason, - int64_t millis = 0); - -/** - * Perform a slice of an ongoing incremental collection. When this function - * returns, the collection may not be complete. It must be called repeatedly - * until !IsIncrementalGCInProgress(cx). - * - * Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or - * shorter than the requested interval. - */ -extern JS_PUBLIC_API(void) -IncrementalGCSlice(JSContext* cx, gcreason::Reason reason, int64_t millis = 0); - -/** - * If IsIncrementalGCInProgress(cx), this call finishes the ongoing collection - * by performing an arbitrarily long slice. If !IsIncrementalGCInProgress(cx), - * this is equivalent to GCForReason. When this function returns, - * IsIncrementalGCInProgress(cx) will always be false. - */ -extern JS_PUBLIC_API(void) -FinishIncrementalGC(JSContext* cx, gcreason::Reason reason); - -/** - * If IsIncrementalGCInProgress(cx), this call aborts the ongoing collection and - * performs whatever work needs to be done to return the collector to its idle - * state. This may take an arbitrarily long time. When this function returns, - * IsIncrementalGCInProgress(cx) will always be false. - */ -extern JS_PUBLIC_API(void) -AbortIncrementalGC(JSContext* cx); - -namespace dbg { - -// The `JS::dbg::GarbageCollectionEvent` class is essentially a view of the -// `js::gcstats::Statistics` data without the uber implementation-specific bits. -// It should generally be palatable for web developers. -class GarbageCollectionEvent -{ - // The major GC number of the GC cycle this data pertains to. - uint64_t majorGCNumber_; - - // Reference to a non-owned, statically allocated C string. This is a very - // short reason explaining why a GC was triggered. - const char* reason; - - // Reference to a nullable, non-owned, statically allocated C string. If the - // collection was forced to be non-incremental, this is a short reason of - // why the GC could not perform an incremental collection. - const char* nonincrementalReason; - - // Represents a single slice of a possibly multi-slice incremental garbage - // collection. - struct Collection { - double startTimestamp; - double endTimestamp; - }; - - // The set of garbage collection slices that made up this GC cycle. - mozilla::Vector collections; - - GarbageCollectionEvent(const GarbageCollectionEvent& rhs) = delete; - GarbageCollectionEvent& operator=(const GarbageCollectionEvent& rhs) = delete; - - public: - explicit GarbageCollectionEvent(uint64_t majorGCNum) - : majorGCNumber_(majorGCNum) - , reason(nullptr) - , nonincrementalReason(nullptr) - , collections() - { } - - using Ptr = js::UniquePtr; - static Ptr Create(JSRuntime* rt, ::js::gcstats::Statistics& stats, uint64_t majorGCNumber); - - JSObject* toJSObject(JSContext* cx) const; - - uint64_t majorGCNumber() const { return majorGCNumber_; } -}; - -} // namespace dbg - -enum GCProgress { - /* - * During non-incremental GC, the GC is bracketed by JSGC_CYCLE_BEGIN/END - * callbacks. During an incremental GC, the sequence of callbacks is as - * follows: - * JSGC_CYCLE_BEGIN, JSGC_SLICE_END (first slice) - * JSGC_SLICE_BEGIN, JSGC_SLICE_END (second slice) - * ... - * JSGC_SLICE_BEGIN, JSGC_CYCLE_END (last slice) - */ - - GC_CYCLE_BEGIN, - GC_SLICE_BEGIN, - GC_SLICE_END, - GC_CYCLE_END -}; - -struct JS_PUBLIC_API(GCDescription) { - bool isZone_; - JSGCInvocationKind invocationKind_; - gcreason::Reason reason_; - - GCDescription(bool isZone, JSGCInvocationKind kind, gcreason::Reason reason) - : isZone_(isZone), invocationKind_(kind), reason_(reason) {} - - char16_t* formatSliceMessage(JSContext* cx) const; - char16_t* formatSummaryMessage(JSContext* cx) const; - char16_t* formatJSON(JSContext* cx, uint64_t timestamp) const; - - JS::dbg::GarbageCollectionEvent::Ptr toGCEvent(JSContext* cx) const; -}; - -typedef void -(* GCSliceCallback)(JSContext* cx, GCProgress progress, const GCDescription& desc); - -/** - * The GC slice callback is called at the beginning and end of each slice. This - * callback may be used for GC notifications as well as to perform additional - * marking. - */ -extern JS_PUBLIC_API(GCSliceCallback) -SetGCSliceCallback(JSContext* cx, GCSliceCallback callback); - -/** - * Describes the progress of an observed nursery collection. - */ -enum class GCNurseryProgress { - /** - * The nursery collection is starting. - */ - GC_NURSERY_COLLECTION_START, - /** - * The nursery collection is ending. - */ - GC_NURSERY_COLLECTION_END -}; - -/** - * A nursery collection callback receives the progress of the nursery collection - * and the reason for the collection. - */ -using GCNurseryCollectionCallback = void(*)(JSContext* cx, GCNurseryProgress progress, - gcreason::Reason reason); - -/** - * Set the nursery collection callback for the given runtime. When set, it will - * be called at the start and end of every nursery collection. - */ -extern JS_PUBLIC_API(GCNurseryCollectionCallback) -SetGCNurseryCollectionCallback(JSContext* cx, GCNurseryCollectionCallback callback); - -typedef void -(* DoCycleCollectionCallback)(JSContext* cx); - -/** - * The purge gray callback is called after any COMPARTMENT_REVIVED GC in which - * the majority of compartments have been marked gray. - */ -extern JS_PUBLIC_API(DoCycleCollectionCallback) -SetDoCycleCollectionCallback(JSContext* cx, DoCycleCollectionCallback callback); - -/** - * Incremental GC defaults to enabled, but may be disabled for testing or in - * embeddings that have not yet implemented barriers on their native classes. - * There is not currently a way to re-enable incremental GC once it has been - * disabled on the runtime. - */ -extern JS_PUBLIC_API(void) -DisableIncrementalGC(JSContext* cx); - -/** - * Returns true if incremental GC is enabled. Simply having incremental GC - * enabled is not sufficient to ensure incremental collections are happening. - * See the comment "Incremental GC" above for reasons why incremental GC may be - * suppressed. Inspection of the "nonincremental reason" field of the - * GCDescription returned by GCSliceCallback may help narrow down the cause if - * collections are not happening incrementally when expected. - */ -extern JS_PUBLIC_API(bool) -IsIncrementalGCEnabled(JSContext* cx); - -/** - * Returns true while an incremental GC is ongoing, both when actively - * collecting and between slices. - */ -extern JS_PUBLIC_API(bool) -IsIncrementalGCInProgress(JSContext* cx); - -/* - * Returns true when writes to GC things must call an incremental (pre) barrier. - * This is generally only true when running mutator code in-between GC slices. - * At other times, the barrier may be elided for performance. - */ -extern JS_PUBLIC_API(bool) -IsIncrementalBarrierNeeded(JSContext* cx); - -/* - * Notify the GC that a reference to a GC thing is about to be overwritten. - * These methods must be called if IsIncrementalBarrierNeeded. - */ -extern JS_PUBLIC_API(void) -IncrementalReferenceBarrier(GCCellPtr thing); - -extern JS_PUBLIC_API(void) -IncrementalValueBarrier(const Value& v); - -extern JS_PUBLIC_API(void) -IncrementalObjectBarrier(JSObject* obj); - -/** - * Returns true if the most recent GC ran incrementally. - */ -extern JS_PUBLIC_API(bool) -WasIncrementalGC(JSContext* cx); - -/* - * Generational GC: - * - * Note: Generational GC is not yet enabled by default. The following class - * is non-functional unless SpiderMonkey was configured with - * --enable-gcgenerational. - */ - -/** Ensure that generational GC is disabled within some scope. */ -class JS_PUBLIC_API(AutoDisableGenerationalGC) -{ - js::gc::GCRuntime* gc; - - public: - explicit AutoDisableGenerationalGC(JSRuntime* rt); - ~AutoDisableGenerationalGC(); -}; - -/** - * Returns true if generational allocation and collection is currently enabled - * on the given runtime. - */ -extern JS_PUBLIC_API(bool) -IsGenerationalGCEnabled(JSRuntime* rt); - -/** - * Returns the GC's "number". This does not correspond directly to the number - * of GCs that have been run, but is guaranteed to be monotonically increasing - * with GC activity. - */ -extern JS_PUBLIC_API(size_t) -GetGCNumber(); - -/** - * Pass a subclass of this "abstract" class to callees to require that they - * never GC. Subclasses can use assertions or the hazard analysis to ensure no - * GC happens. - */ -class JS_PUBLIC_API(AutoRequireNoGC) -{ - protected: - AutoRequireNoGC() {} - ~AutoRequireNoGC() {} -}; - -/** - * Diagnostic assert (see MOZ_DIAGNOSTIC_ASSERT) that GC cannot occur while this - * class is live. This class does not disable the static rooting hazard - * analysis. - * - * This works by entering a GC unsafe region, which is checked on allocation and - * on GC. - */ -class JS_PUBLIC_API(AutoAssertNoGC) : public AutoRequireNoGC -{ - js::gc::GCRuntime* gc; - size_t gcNumber; - - public: - AutoAssertNoGC(); - explicit AutoAssertNoGC(JSRuntime* rt); - explicit AutoAssertNoGC(JSContext* cx); - ~AutoAssertNoGC(); -}; - -/** - * Assert if an allocation of a GC thing occurs while this class is live. This - * class does not disable the static rooting hazard analysis. - */ -class JS_PUBLIC_API(AutoAssertNoAlloc) -{ -#ifdef JS_DEBUG - js::gc::GCRuntime* gc; - - public: - AutoAssertNoAlloc() : gc(nullptr) {} - explicit AutoAssertNoAlloc(JSContext* cx); - void disallowAlloc(JSRuntime* rt); - ~AutoAssertNoAlloc(); -#else - public: - AutoAssertNoAlloc() {} - explicit AutoAssertNoAlloc(JSContext* cx) {} - void disallowAlloc(JSRuntime* rt) {} -#endif -}; - -/** - * Assert if a GC barrier is invoked while this class is live. This class does - * not disable the static rooting hazard analysis. - */ -class JS_PUBLIC_API(AutoAssertOnBarrier) -{ - JSContext* context; - bool prev; - - public: - explicit AutoAssertOnBarrier(JSContext* cx); - ~AutoAssertOnBarrier(); -}; - -/** - * Disable the static rooting hazard analysis in the live region and assert if - * any allocation that could potentially trigger a GC occurs while this guard - * object is live. This is most useful to help the exact rooting hazard analysis - * in complex regions, since it cannot understand dataflow. - * - * Note: GC behavior is unpredictable even when deterministic and is generally - * non-deterministic in practice. The fact that this guard has not - * asserted is not a guarantee that a GC cannot happen in the guarded - * region. As a rule, anyone performing a GC unsafe action should - * understand the GC properties of all code in that region and ensure - * that the hazard analysis is correct for that code, rather than relying - * on this class. - */ -class JS_PUBLIC_API(AutoSuppressGCAnalysis) : public AutoAssertNoAlloc -{ - public: - AutoSuppressGCAnalysis() : AutoAssertNoAlloc() {} - explicit AutoSuppressGCAnalysis(JSContext* cx) : AutoAssertNoAlloc(cx) {} -} JS_HAZ_GC_SUPPRESSED; - -/** - * Assert that code is only ever called from a GC callback, disable the static - * rooting hazard analysis and assert if any allocation that could potentially - * trigger a GC occurs while this guard object is live. - * - * This is useful to make the static analysis ignore code that runs in GC - * callbacks. - */ -class JS_PUBLIC_API(AutoAssertGCCallback) : public AutoSuppressGCAnalysis -{ - public: - explicit AutoAssertGCCallback(JSObject* obj); -}; - -/** - * Place AutoCheckCannotGC in scopes that you believe can never GC. These - * annotations will be verified both dynamically via AutoAssertNoGC, and - * statically with the rooting hazard analysis (implemented by making the - * analysis consider AutoCheckCannotGC to be a GC pointer, and therefore - * complain if it is live across a GC call.) It is useful when dealing with - * internal pointers to GC things where the GC thing itself may not be present - * for the static analysis: e.g. acquiring inline chars from a JSString* on the - * heap. - * - * We only do the assertion checking in DEBUG builds. - */ -#ifdef DEBUG -class JS_PUBLIC_API(AutoCheckCannotGC) : public AutoAssertNoGC -{ - public: - AutoCheckCannotGC() : AutoAssertNoGC() {} - explicit AutoCheckCannotGC(JSContext* cx) : AutoAssertNoGC(cx) {} -} JS_HAZ_GC_INVALIDATED; -#else -class JS_PUBLIC_API(AutoCheckCannotGC) : public AutoRequireNoGC -{ - public: - AutoCheckCannotGC() {} - explicit AutoCheckCannotGC(JSContext* cx) {} -} JS_HAZ_GC_INVALIDATED; -#endif - -/** - * Unsets the gray bit for anything reachable from |thing|. |kind| should not be - * JS::TraceKind::Shape. |thing| should be non-null. The return value indicates - * if anything was unmarked. - */ -extern JS_FRIEND_API(bool) -UnmarkGrayGCThingRecursively(GCCellPtr thing); - -} /* namespace JS */ - -namespace js { -namespace gc { - -static MOZ_ALWAYS_INLINE void -ExposeGCThingToActiveJS(JS::GCCellPtr thing) -{ - // GC things residing in the nursery cannot be gray: they have no mark bits. - // All live objects in the nursery are moved to tenured at the beginning of - // each GC slice, so the gray marker never sees nursery things. - if (IsInsideNursery(thing.asCell())) - return; - - // There's nothing to do for permanent GC things that might be owned by - // another runtime. - if (thing.mayBeOwnedByOtherRuntime()) - return; - - JS::shadow::Runtime* rt = detail::GetCellRuntime(thing.asCell()); - MOZ_DIAGNOSTIC_ASSERT(rt->allowGCBarriers()); - - if (IsIncrementalBarrierNeededOnTenuredGCThing(rt, thing)) - JS::IncrementalReferenceBarrier(thing); - else if (!thing.mayBeOwnedByOtherRuntime() && js::gc::detail::CellIsMarkedGray(thing.asCell())) - JS::UnmarkGrayGCThingRecursively(thing); -} - -static MOZ_ALWAYS_INLINE void -MarkGCThingAsLive(JSRuntime* aRt, JS::GCCellPtr thing) -{ - // Any object in the nursery will not be freed during any GC running at that - // time. - if (IsInsideNursery(thing.asCell())) - return; - - // There's nothing to do for permanent GC things that might be owned by - // another runtime. - if (thing.mayBeOwnedByOtherRuntime()) - return; - - JS::shadow::Runtime* rt = JS::shadow::Runtime::asShadowRuntime(aRt); - MOZ_DIAGNOSTIC_ASSERT(rt->allowGCBarriers()); - - if (IsIncrementalBarrierNeededOnTenuredGCThing(rt, thing)) - JS::IncrementalReferenceBarrier(thing); -} - -} /* namespace gc */ -} /* namespace js */ - -namespace JS { - -/* - * This should be called when an object that is marked gray is exposed to the JS - * engine (by handing it to running JS code or writing it into live JS - * data). During incremental GC, since the gray bits haven't been computed yet, - * we conservatively mark the object black. - */ -static MOZ_ALWAYS_INLINE void -ExposeObjectToActiveJS(JSObject* obj) -{ - MOZ_ASSERT(obj); - js::gc::ExposeGCThingToActiveJS(GCCellPtr(obj)); -} - -static MOZ_ALWAYS_INLINE void -ExposeScriptToActiveJS(JSScript* script) -{ - js::gc::ExposeGCThingToActiveJS(GCCellPtr(script)); -} - -/* - * If a GC is currently marking, mark the string black. - */ -static MOZ_ALWAYS_INLINE void -MarkStringAsLive(Zone* zone, JSString* string) -{ - JSRuntime* rt = JS::shadow::Zone::asShadowZone(zone)->runtimeFromMainThread(); - js::gc::MarkGCThingAsLive(rt, GCCellPtr(string)); -} - -/* - * Internal to Firefox. - * - * Note: this is not related to the PokeGC in nsJSEnvironment. - */ -extern JS_FRIEND_API(void) -PokeGC(JSContext* cx); - -/* - * Internal to Firefox. - */ -extern JS_FRIEND_API(void) -NotifyDidPaint(JSContext* cx); - -} /* namespace JS */ - -#endif /* js_GCAPI_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/GCAnnotations.h b/android/armeabi-v7a/include/spidermonkey/js/GCAnnotations.h deleted file mode 100644 index 366d787b..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/GCAnnotations.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_GCAnnotations_h -#define js_GCAnnotations_h - -// Set of annotations for the rooting hazard analysis, used to categorize types -// and functions. -#ifdef XGILL_PLUGIN - -// Mark a type as being a GC thing (eg js::gc::Cell has this annotation). -# define JS_HAZ_GC_THING __attribute__((tag("GC Thing"))) - -// Mark a type as holding a pointer to a GC thing (eg JS::Value has this -// annotation.) -# define JS_HAZ_GC_POINTER __attribute__((tag("GC Pointer"))) - -// Mark a type as a rooted pointer, suitable for use on the stack (eg all -// Rooted instantiations should have this.) -# define JS_HAZ_ROOTED __attribute__((tag("Rooted Pointer"))) - -// Mark a type as something that should not be held live across a GC, but which -// is not itself a GC pointer. -# define JS_HAZ_GC_INVALIDATED __attribute__((tag("Invalidated by GC"))) - -// Mark a type that would otherwise be considered a GC Pointer (eg because it -// contains a JS::Value field) as a non-GC pointer. It is handled almost the -// same in the analysis as a rooted pointer, except it will not be reported as -// an unnecessary root if used across a GC call. This should rarely be used, -// but makes sense for something like ErrorResult, which only contains a GC -// pointer when it holds an exception (and it does its own rooting, -// conditionally.) -# define JS_HAZ_NON_GC_POINTER __attribute__((tag("Suppressed GC Pointer"))) - -// Mark a function as something that runs a garbage collection, potentially -// invalidating GC pointers. -# define JS_HAZ_GC_CALL __attribute__((tag("GC Call"))) - -// Mark an RAII class as suppressing GC within its scope. -# define JS_HAZ_GC_SUPPRESSED __attribute__((tag("Suppress GC"))) - -#else - -# define JS_HAZ_GC_THING -# define JS_HAZ_GC_POINTER -# define JS_HAZ_ROOTED -# define JS_HAZ_GC_INVALIDATED -# define JS_HAZ_NON_GC_POINTER -# define JS_HAZ_GC_CALL -# define JS_HAZ_GC_SUPPRESSED - -#endif - -#endif /* js_GCAnnotations_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/GCHashTable.h b/android/armeabi-v7a/include/spidermonkey/js/GCHashTable.h deleted file mode 100644 index d6c2ce75..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/GCHashTable.h +++ /dev/null @@ -1,399 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 GCHashTable_h -#define GCHashTable_h - -#include "js/GCPolicyAPI.h" -#include "js/HashTable.h" -#include "js/RootingAPI.h" -#include "js/SweepingAPI.h" -#include "js/TracingAPI.h" - -namespace JS { - -// Define a reasonable default GC policy for GC-aware Maps. -template -struct DefaultMapSweepPolicy { - static bool needsSweep(Key* key, Value* value) { - return GCPolicy::needsSweep(key) || GCPolicy::needsSweep(value); - } -}; - -// A GCHashMap is a GC-aware HashMap, meaning that it has additional trace and -// sweep methods that know how to visit all keys and values in the table. -// HashMaps that contain GC pointers will generally want to use this GCHashMap -// specialization instead of HashMap, because this conveniently supports tracing -// keys and values, and cleaning up weak entries. -// -// GCHashMap::trace applies GCPolicy::trace to each entry's key and value. -// Most types of GC pointers already have appropriate specializations of -// GCPolicy, so they should just work as keys and values. Any struct type with a -// default constructor and trace and sweep functions should work as well. If you -// need to define your own GCPolicy specialization, generic helpers can be found -// in js/public/TracingAPI.h. -// -// The MapSweepPolicy template parameter controls how the table drops entries -// when swept. GCHashMap::sweep applies MapSweepPolicy::needsSweep to each table -// entry; if it returns true, the entry is dropped. The default MapSweepPolicy -// drops the entry if either the key or value is about to be finalized, -// according to its GCPolicy::needsSweep method. (This default is almost -// always fine: it's hard to imagine keeping such an entry around anyway.) -// -// Note that this HashMap only knows *how* to trace and sweep, but it does not -// itself cause tracing or sweeping to be invoked. For tracing, it must be used -// with Rooted or PersistentRooted, or barriered and traced manually. For -// sweeping, currently it requires an explicit call to .sweep(). -template , - typename AllocPolicy = js::TempAllocPolicy, - typename MapSweepPolicy = DefaultMapSweepPolicy> -class GCHashMap : public js::HashMap -{ - using Base = js::HashMap; - - public: - explicit GCHashMap(AllocPolicy a = AllocPolicy()) : Base(a) {} - - static void trace(GCHashMap* map, JSTracer* trc) { map->trace(trc); } - void trace(JSTracer* trc) { - if (!this->initialized()) - return; - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - GCPolicy::trace(trc, &e.front().value(), "hashmap value"); - GCPolicy::trace(trc, &e.front().mutableKey(), "hashmap key"); - } - } - - void sweep() { - if (!this->initialized()) - return; - - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - if (MapSweepPolicy::needsSweep(&e.front().mutableKey(), &e.front().value())) - e.removeFront(); - } - } - - // GCHashMap is movable - GCHashMap(GCHashMap&& rhs) : Base(mozilla::Move(rhs)) {} - void operator=(GCHashMap&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - Base::operator=(mozilla::Move(rhs)); - } - - private: - // GCHashMap is not copyable or assignable - GCHashMap(const GCHashMap& hm) = delete; - GCHashMap& operator=(const GCHashMap& hm) = delete; -}; - -} // namespace JS - -namespace js { - -// HashMap that supports rekeying. -// -// If your keys are pointers to something like JSObject that can be tenured or -// compacted, prefer to use GCHashMap with MovableCellHasher, which takes -// advantage of the Zone's stable id table to make rekeying unnecessary. -template , - typename AllocPolicy = TempAllocPolicy, - typename MapSweepPolicy = JS::DefaultMapSweepPolicy> -class GCRekeyableHashMap : public JS::GCHashMap -{ - using Base = JS::GCHashMap; - - public: - explicit GCRekeyableHashMap(AllocPolicy a = AllocPolicy()) : Base(a) {} - - void sweep() { - if (!this->initialized()) - return; - - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - Key key(e.front().key()); - if (MapSweepPolicy::needsSweep(&key, &e.front().value())) - e.removeFront(); - else if (!HashPolicy::match(key, e.front().key())) - e.rekeyFront(key); - } - } - - // GCRekeyableHashMap is movable - GCRekeyableHashMap(GCRekeyableHashMap&& rhs) : Base(mozilla::Move(rhs)) {} - void operator=(GCRekeyableHashMap&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - Base::operator=(mozilla::Move(rhs)); - } -}; - -template -class GCHashMapOperations -{ - using Map = JS::GCHashMap; - using Lookup = typename Map::Lookup; - - const Map& map() const { return static_cast(this)->get(); } - - public: - using AddPtr = typename Map::AddPtr; - using Ptr = typename Map::Ptr; - using Range = typename Map::Range; - - bool initialized() const { return map().initialized(); } - Ptr lookup(const Lookup& l) const { return map().lookup(l); } - AddPtr lookupForAdd(const Lookup& l) const { return map().lookupForAdd(l); } - Range all() const { return map().all(); } - bool empty() const { return map().empty(); } - uint32_t count() const { return map().count(); } - size_t capacity() const { return map().capacity(); } - bool has(const Lookup& l) const { return map().lookup(l).found(); } - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return map().sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + map().sizeOfExcludingThis(mallocSizeOf); - } -}; - -template -class MutableGCHashMapOperations - : public GCHashMapOperations -{ - using Map = JS::GCHashMap; - using Lookup = typename Map::Lookup; - - Map& map() { return static_cast(this)->get(); } - - public: - using AddPtr = typename Map::AddPtr; - struct Enum : public Map::Enum { explicit Enum(Outer& o) : Map::Enum(o.map()) {} }; - using Ptr = typename Map::Ptr; - using Range = typename Map::Range; - - bool init(uint32_t len = 16) { return map().init(len); } - void clear() { map().clear(); } - void finish() { map().finish(); } - void remove(Ptr p) { map().remove(p); } - - template - bool add(AddPtr& p, KeyInput&& k, ValueInput&& v) { - return map().add(p, mozilla::Forward(k), mozilla::Forward(v)); - } - - template - bool add(AddPtr& p, KeyInput&& k) { - return map().add(p, mozilla::Forward(k), Map::Value()); - } - - template - bool relookupOrAdd(AddPtr& p, KeyInput&& k, ValueInput&& v) { - return map().relookupOrAdd(p, k, - mozilla::Forward(k), - mozilla::Forward(v)); - } - - template - bool put(KeyInput&& k, ValueInput&& v) { - return map().put(mozilla::Forward(k), mozilla::Forward(v)); - } - - template - bool putNew(KeyInput&& k, ValueInput&& v) { - return map().putNew(mozilla::Forward(k), mozilla::Forward(v)); - } -}; - -template -class RootedBase> - : public MutableGCHashMapOperations>, A,B,C,D,E> -{}; - -template -class MutableHandleBase> - : public MutableGCHashMapOperations>, A,B,C,D,E> -{}; - -template -class HandleBase> - : public GCHashMapOperations>, A,B,C,D,E> -{}; - -template -class WeakCacheBase> - : public MutableGCHashMapOperations>, A,B,C,D,E> -{}; - -} // namespace js - -namespace JS { - -// A GCHashSet is a HashSet with an additional trace method that knows -// be traced to be kept alive will generally want to use this GCHashSet -// specialization in lieu of HashSet. -// -// Most types of GC pointers can be traced with no extra infrastructure. For -// structs and non-gc-pointer members, ensure that there is a specialization of -// GCPolicy with an appropriate trace method available to handle the custom -// type. Generic helpers can be found in js/public/TracingAPI.h. -// -// Note that although this HashSet's trace will deal correctly with moved -// elements, it does not itself know when to barrier or trace elements. To -// function properly it must either be used with Rooted or barriered and traced -// manually. -template , - typename AllocPolicy = js::TempAllocPolicy> -class GCHashSet : public js::HashSet -{ - using Base = js::HashSet; - - public: - explicit GCHashSet(AllocPolicy a = AllocPolicy()) : Base(a) {} - - static void trace(GCHashSet* set, JSTracer* trc) { set->trace(trc); } - void trace(JSTracer* trc) { - if (!this->initialized()) - return; - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) - GCPolicy::trace(trc, &e.mutableFront(), "hashset element"); - } - - void sweep() { - if (!this->initialized()) - return; - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - if (GCPolicy::needsSweep(&e.mutableFront())) - e.removeFront(); - } - } - - // GCHashSet is movable - GCHashSet(GCHashSet&& rhs) : Base(mozilla::Move(rhs)) {} - void operator=(GCHashSet&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - Base::operator=(mozilla::Move(rhs)); - } - - private: - // GCHashSet is not copyable or assignable - GCHashSet(const GCHashSet& hs) = delete; - GCHashSet& operator=(const GCHashSet& hs) = delete; -}; - -} // namespace JS - -namespace js { - -template -class GCHashSetOperations -{ - using Set = JS::GCHashSet; - using Lookup = typename Set::Lookup; - - const Set& set() const { return static_cast(this)->get(); } - - public: - using AddPtr = typename Set::AddPtr; - using Entry = typename Set::Entry; - using Ptr = typename Set::Ptr; - using Range = typename Set::Range; - - bool initialized() const { return set().initialized(); } - Ptr lookup(const Lookup& l) const { return set().lookup(l); } - AddPtr lookupForAdd(const Lookup& l) const { return set().lookupForAdd(l); } - Range all() const { return set().all(); } - bool empty() const { return set().empty(); } - uint32_t count() const { return set().count(); } - size_t capacity() const { return set().capacity(); } - bool has(const Lookup& l) const { return set().lookup(l).found(); } - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return set().sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + set().sizeOfExcludingThis(mallocSizeOf); - } -}; - -template -class MutableGCHashSetOperations - : public GCHashSetOperations -{ - using Set = JS::GCHashSet; - using Lookup = typename Set::Lookup; - - Set& set() { return static_cast(this)->get(); } - - public: - using AddPtr = typename Set::AddPtr; - using Entry = typename Set::Entry; - struct Enum : public Set::Enum { explicit Enum(Outer& o) : Set::Enum(o.set()) {} }; - using Ptr = typename Set::Ptr; - using Range = typename Set::Range; - - bool init(uint32_t len = 16) { return set().init(len); } - void clear() { set().clear(); } - void finish() { set().finish(); } - void remove(Ptr p) { set().remove(p); } - void remove(const Lookup& l) { set().remove(l); } - - template - bool add(AddPtr& p, TInput&& t) { - return set().add(p, mozilla::Forward(t)); - } - - template - bool relookupOrAdd(AddPtr& p, const Lookup& l, TInput&& t) { - return set().relookupOrAdd(p, l, mozilla::Forward(t)); - } - - template - bool put(TInput&& t) { - return set().put(mozilla::Forward(t)); - } - - template - bool putNew(TInput&& t) { - return set().putNew(mozilla::Forward(t)); - } - - template - bool putNew(const Lookup& l, TInput&& t) { - return set().putNew(l, mozilla::Forward(t)); - } -}; - -template -class RootedBase> - : public MutableGCHashSetOperations>, T, HP, AP> -{ -}; - -template -class MutableHandleBase> - : public MutableGCHashSetOperations>, T, HP, AP> -{ -}; - -template -class HandleBase> - : public GCHashSetOperations>, T, HP, AP> -{ -}; - -template -class WeakCacheBase> - : public MutableGCHashSetOperations>, T, HP, AP> -{ -}; - -} /* namespace js */ - -#endif /* GCHashTable_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/GCPolicyAPI.h b/android/armeabi-v7a/include/spidermonkey/js/GCPolicyAPI.h deleted file mode 100644 index 054e397a..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/GCPolicyAPI.h +++ /dev/null @@ -1,164 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -// GC Policy Mechanism - -// A GCPolicy controls how the GC interacts with both direct pointers to GC -// things (e.g. JSObject* or JSString*), tagged and/or optional pointers to GC -// things (e.g. Value or jsid), and C++ container types (e.g. -// JSPropertyDescriptor or GCHashMap). -// -// The GCPolicy provides at a minimum: -// -// static T initial() -// - Construct and return an empty T. -// -// static void trace(JSTracer, T* tp, const char* name) -// - Trace the edge |*tp|, calling the edge |name|. Containers like -// GCHashMap and GCHashSet use this method to trace their children. -// -// static bool needsSweep(T* tp) -// - Return true if |*tp| is about to be finalized. Otherwise, update the -// edge for moving GC, and return false. Containers like GCHashMap and -// GCHashSet use this method to decide when to remove an entry: if this -// function returns true on a key/value/member/etc, its entry is dropped -// from the container. Specializing this method is the standard way to -// get custom weak behavior from a container type. -// -// The default GCPolicy assumes that T has a default constructor and |trace| -// and |needsSweep| methods, and forwards to them. GCPolicy has appropriate -// specializations for pointers to GC things and pointer-like types like -// JS::Heap and mozilla::UniquePtr. -// -// There are some stock structs your specializations can inherit from. -// IgnoreGCPolicy does nothing. StructGCPolicy forwards the methods to the -// referent type T. - -#ifndef GCPolicyAPI_h -#define GCPolicyAPI_h - -#include "mozilla/UniquePtr.h" - -#include "js/TraceKind.h" -#include "js/TracingAPI.h" - -// Expand the given macro D for each public GC pointer. -#define FOR_EACH_PUBLIC_GC_POINTER_TYPE(D) \ - D(JS::Symbol*) \ - D(JSAtom*) \ - D(JSFunction*) \ - D(JSObject*) \ - D(JSScript*) \ - D(JSString*) - -// Expand the given macro D for each public tagged GC pointer type. -#define FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(D) \ - D(JS::Value) \ - D(jsid) - -#define FOR_EACH_PUBLIC_AGGREGATE_GC_POINTER_TYPE(D) \ - D(JSPropertyDescriptor) - -class JSAtom; -class JSFunction; -class JSObject; -class JSScript; -class JSString; -namespace JS { -class Symbol; -} - -namespace JS { - -// Defines a policy for container types with non-GC, i.e. C storage. This -// policy dispatches to the underlying struct for GC interactions. -template -struct StructGCPolicy -{ - static T initial() { - return T(); - } - - static void trace(JSTracer* trc, T* tp, const char* name) { - tp->trace(trc); - } - - static void sweep(T* tp) { - return tp->sweep(); - } - - static bool needsSweep(T* tp) { - return tp->needsSweep(); - } -}; - -// The default GC policy attempts to defer to methods on the underlying type. -// Most C++ structures that contain a default constructor, a trace function and -// a sweep function will work out of the box with Rooted, Handle, GCVector, -// and GCHash{Set,Map}. -template struct GCPolicy : public StructGCPolicy {}; - -// This policy ignores any GC interaction, e.g. for non-GC types. -template -struct IgnoreGCPolicy { - static T initial() { return T(); } - static void trace(JSTracer* trc, T* t, const char* name) {} - static bool needsSweep(T* v) { return false; } -}; -template <> struct GCPolicy : public IgnoreGCPolicy {}; -template <> struct GCPolicy : public IgnoreGCPolicy {}; - -template -struct GCPointerPolicy -{ - static T initial() { return nullptr; } - static void trace(JSTracer* trc, T* vp, const char* name) { - if (*vp) - js::UnsafeTraceManuallyBarrieredEdge(trc, vp, name); - } - static bool needsSweep(T* vp) { - if (*vp) - return js::gc::IsAboutToBeFinalizedUnbarriered(vp); - return false; - } -}; -template <> struct GCPolicy : public GCPointerPolicy {}; -template <> struct GCPolicy : public GCPointerPolicy {}; -template <> struct GCPolicy : public GCPointerPolicy {}; -template <> struct GCPolicy : public GCPointerPolicy {}; -template <> struct GCPolicy : public GCPointerPolicy {}; -template <> struct GCPolicy : public GCPointerPolicy {}; - -template -struct GCPolicy> -{ - static void trace(JSTracer* trc, JS::Heap* thingp, const char* name) { - TraceEdge(trc, thingp, name); - } - static bool needsSweep(JS::Heap* thingp) { - return js::gc::EdgeNeedsSweep(thingp); - } -}; - -// GCPolicy> forwards the contained pointer to GCPolicy. -template -struct GCPolicy> -{ - static mozilla::UniquePtr initial() { return mozilla::UniquePtr(); } - static void trace(JSTracer* trc, mozilla::UniquePtr* tp, const char* name) { - if (tp->get()) - GCPolicy::trace(trc, tp->get(), name); - } - static bool needsSweep(mozilla::UniquePtr* tp) { - if (tp->get()) - return GCPolicy::needsSweep(tp->get()); - return false; - } -}; - -} // namespace JS - -#endif // GCPolicyAPI_h diff --git a/android/armeabi-v7a/include/spidermonkey/js/GCVariant.h b/android/armeabi-v7a/include/spidermonkey/js/GCVariant.h deleted file mode 100644 index 31ab23f5..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/GCVariant.h +++ /dev/null @@ -1,198 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_GCVariant_h -#define js_GCVariant_h - -#include "mozilla/Variant.h" - -#include "js/GCPolicyAPI.h" -#include "js/RootingAPI.h" -#include "js/TracingAPI.h" - -namespace JS { - -// These template specializations allow Variant to be used inside GC wrappers. -// -// When matching on GC wrappers around Variants, matching should be done on -// the wrapper itself. The matcher class's methods should take Handles or -// MutableHandles. For example, -// -// struct MyMatcher -// { -// using ReturnType = const char*; -// ReturnType match(HandleObject o) { return "object"; } -// ReturnType match(HandleScript s) { return "script"; } -// }; -// -// Rooted> v(cx, someScript); -// MyMatcher mm; -// v.match(mm); -// -// If you get compile errors about inability to upcast subclasses (e.g., from -// NativeObject* to JSObject*) and are inside js/src, be sure to also include -// "gc/Policy.h". - -namespace detail { - -template -struct GCVariantImplementation; - -// The base case. -template -struct GCVariantImplementation -{ - template - static void trace(JSTracer* trc, ConcreteVariant* v, const char* name) { - T& thing = v->template as(); - if (!mozilla::IsPointer::value || thing) - GCPolicy::trace(trc, &thing, name); - } - - template - static typename Matcher::ReturnType - match(Matcher& matcher, Handle v) { - const T& thing = v.get().template as(); - return matcher.match(Handle::fromMarkedLocation(&thing)); - } - - template - static typename Matcher::ReturnType - match(Matcher& matcher, MutableHandle v) { - T& thing = v.get().template as(); - return matcher.match(MutableHandle::fromMarkedLocation(&thing)); - } -}; - -// The inductive case. -template -struct GCVariantImplementation -{ - using Next = GCVariantImplementation; - - template - static void trace(JSTracer* trc, ConcreteVariant* v, const char* name) { - if (v->template is()) { - T& thing = v->template as(); - if (!mozilla::IsPointer::value || thing) - GCPolicy::trace(trc, &thing, name); - } else { - Next::trace(trc, v, name); - } - } - - template - static typename Matcher::ReturnType - match(Matcher& matcher, Handle v) { - if (v.get().template is()) { - const T& thing = v.get().template as(); - return matcher.match(Handle::fromMarkedLocation(&thing)); - } - return Next::match(matcher, v); - } - - template - static typename Matcher::ReturnType - match(Matcher& matcher, MutableHandle v) { - if (v.get().template is()) { - T& thing = v.get().template as(); - return matcher.match(MutableHandle::fromMarkedLocation(&thing)); - } - return Next::match(matcher, v); - } -}; - -} // namespace detail - -template -struct GCPolicy> -{ - using Impl = detail::GCVariantImplementation; - - // Variants do not provide initial(). They do not have a default initial - // value and one must be provided. - - static void trace(JSTracer* trc, mozilla::Variant* v, const char* name) { - Impl::trace(trc, v, name); - } -}; - -} // namespace JS - -namespace js { - -template -class GCVariantOperations -{ - using Impl = JS::detail::GCVariantImplementation; - using Variant = mozilla::Variant; - - const Variant& variant() const { return static_cast(this)->get(); } - - public: - template - bool is() const { - return variant().template is(); - } - - template - JS::Handle as() const { - return Handle::fromMarkedLocation(&variant().template as()); - } - - template - typename Matcher::ReturnType - match(Matcher& matcher) const { - return Impl::match(matcher, JS::Handle::fromMarkedLocation(&variant())); - } -}; - -template -class MutableGCVariantOperations - : public GCVariantOperations -{ - using Impl = JS::detail::GCVariantImplementation; - using Variant = mozilla::Variant; - - const Variant& variant() const { return static_cast(this)->get(); } - Variant& variant() { return static_cast(this)->get(); } - - public: - template - JS::MutableHandle as() { - return JS::MutableHandle::fromMarkedLocation(&variant().template as()); - } - - template - typename Matcher::ReturnType - match(Matcher& matcher) { - return Impl::match(matcher, JS::MutableHandle::fromMarkedLocation(&variant())); - } -}; - -template -class RootedBase> - : public MutableGCVariantOperations>, Ts...> -{ }; - -template -class MutableHandleBase> - : public MutableGCVariantOperations>, Ts...> -{ }; - -template -class HandleBase> - : public GCVariantOperations>, Ts...> -{ }; - -template -class PersistentRootedBase> - : public MutableGCVariantOperations>, Ts...> -{ }; - -} // namespace js - -#endif // js_GCVariant_h diff --git a/android/armeabi-v7a/include/spidermonkey/js/GCVector.h b/android/armeabi-v7a/include/spidermonkey/js/GCVector.h deleted file mode 100644 index 2668e65b..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/GCVector.h +++ /dev/null @@ -1,249 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_GCVector_h -#define js_GCVector_h - -#include "mozilla/Vector.h" - -#include "js/GCPolicyAPI.h" -#include "js/RootingAPI.h" -#include "js/TracingAPI.h" -#include "js/Vector.h" - -namespace JS { - -// A GCVector is a Vector with an additional trace method that knows how -// to visit all of the items stored in the Vector. For vectors that contain GC -// things, this is usually more convenient than manually iterating and marking -// the contents. -// -// Most types of GC pointers as keys and values can be traced with no extra -// infrastructure. For structs and non-gc-pointer members, ensure that there is -// a specialization of GCPolicy with an appropriate trace method available -// to handle the custom type. Generic helpers can be found in -// js/public/TracingAPI.h. -// -// Note that although this Vector's trace will deal correctly with moved items, -// it does not itself know when to barrier or trace items. To function properly -// it must either be used with Rooted, or barriered and traced manually. -template -class GCVector -{ - mozilla::Vector vector; - - public: - explicit GCVector(AllocPolicy alloc = AllocPolicy()) - : vector(alloc) - {} - - GCVector(GCVector&& vec) - : vector(mozilla::Move(vec.vector)) - {} - - GCVector& operator=(GCVector&& vec) { - vector = mozilla::Move(vec.vector); - return *this; - } - - size_t length() const { return vector.length(); } - bool empty() const { return vector.empty(); } - size_t capacity() const { return vector.capacity(); } - - T* begin() { return vector.begin(); } - const T* begin() const { return vector.begin(); } - - T* end() { return vector.end(); } - const T* end() const { return vector.end(); } - - T& operator[](size_t i) { return vector[i]; } - const T& operator[](size_t i) const { return vector[i]; } - - T& back() { return vector.back(); } - const T& back() const { return vector.back(); } - - bool initCapacity(size_t cap) { return vector.initCapacity(cap); } - bool reserve(size_t req) { return vector.reserve(req); } - void shrinkBy(size_t amount) { return vector.shrinkBy(amount); } - bool growBy(size_t amount) { return vector.growBy(amount); } - bool resize(size_t newLen) { return vector.resize(newLen); } - - void clear() { return vector.clear(); } - - template bool append(U&& item) { return vector.append(mozilla::Forward(item)); } - - template - bool - emplaceBack(Args&&... args) { - return vector.emplaceBack(mozilla::Forward(args)...); - } - - template - void infallibleAppend(U&& aU) { - return vector.infallibleAppend(mozilla::Forward(aU)); - } - void infallibleAppendN(const T& aT, size_t aN) { - return vector.infallibleAppendN(aT, aN); - } - template void - infallibleAppend(const U* aBegin, const U* aEnd) { - return vector.infallibleAppend(aBegin, aEnd); - } - template void infallibleAppend(const U* aBegin, size_t aLength) { - return vector.infallibleAppend(aBegin, aLength); - } - - template - bool appendAll(const mozilla::Vector& aU) { return vector.appendAll(aU); } - template - bool appendAll(const GCVector& aU) { return vector.append(aU.begin(), aU.length()); } - - bool appendN(const T& val, size_t count) { return vector.appendN(val, count); } - - template bool append(const U* aBegin, const U* aEnd) { - return vector.append(aBegin, aEnd); - } - template bool append(const U* aBegin, size_t aLength) { - return vector.append(aBegin, aLength); - } - - void popBack() { return vector.popBack(); } - T popCopy() { return vector.popCopy(); } - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return vector.sizeOfExcludingThis(mallocSizeOf); - } - - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return vector.sizeOfIncludingThis(mallocSizeOf); - } - - static void trace(GCVector* vec, JSTracer* trc) { vec->trace(trc); } - - void trace(JSTracer* trc) { - for (auto& elem : vector) - GCPolicy::trace(trc, &elem, "vector element"); - } -}; - -} // namespace JS - -namespace js { - -template -class GCVectorOperations -{ - using Vec = JS::GCVector; - const Vec& vec() const { return static_cast(this)->get(); } - - public: - const AllocPolicy& allocPolicy() const { return vec().allocPolicy(); } - size_t length() const { return vec().length(); } - bool empty() const { return vec().empty(); } - size_t capacity() const { return vec().capacity(); } - const T* begin() const { return vec().begin(); } - const T* end() const { return vec().end(); } - const T& back() const { return vec().back(); } - - JS::Handle operator[](size_t aIndex) const { - return JS::Handle::fromMarkedLocation(&vec().operator[](aIndex)); - } -}; - -template -class MutableGCVectorOperations - : public GCVectorOperations -{ - using Vec = JS::GCVector; - const Vec& vec() const { return static_cast(this)->get(); } - Vec& vec() { return static_cast(this)->get(); } - - public: - const AllocPolicy& allocPolicy() const { return vec().allocPolicy(); } - AllocPolicy& allocPolicy() { return vec().allocPolicy(); } - const T* begin() const { return vec().begin(); } - T* begin() { return vec().begin(); } - const T* end() const { return vec().end(); } - T* end() { return vec().end(); } - const T& back() const { return vec().back(); } - T& back() { return vec().back(); } - - JS::Handle operator[](size_t aIndex) const { - return JS::Handle::fromMarkedLocation(&vec().operator[](aIndex)); - } - JS::MutableHandle operator[](size_t aIndex) { - return JS::MutableHandle::fromMarkedLocation(&vec().operator[](aIndex)); - } - - bool initCapacity(size_t aRequest) { return vec().initCapacity(aRequest); } - bool reserve(size_t aRequest) { return vec().reserve(aRequest); } - void shrinkBy(size_t aIncr) { vec().shrinkBy(aIncr); } - bool growBy(size_t aIncr) { return vec().growBy(aIncr); } - bool resize(size_t aNewLength) { return vec().resize(aNewLength); } - bool growByUninitialized(size_t aIncr) { return vec().growByUninitialized(aIncr); } - void infallibleGrowByUninitialized(size_t aIncr) { vec().infallibleGrowByUninitialized(aIncr); } - bool resizeUninitialized(size_t aNewLength) { return vec().resizeUninitialized(aNewLength); } - void clear() { vec().clear(); } - void clearAndFree() { vec().clearAndFree(); } - template bool append(U&& aU) { return vec().append(mozilla::Forward(aU)); } - template bool emplaceBack(Args&&... aArgs) { - return vec().emplaceBack(mozilla::Forward(aArgs...)); - } - template - bool appendAll(const mozilla::Vector& aU) { return vec().appendAll(aU); } - template - bool appendAll(const JS::GCVector& aU) { return vec().appendAll(aU); } - bool appendN(const T& aT, size_t aN) { return vec().appendN(aT, aN); } - template bool append(const U* aBegin, const U* aEnd) { - return vec().append(aBegin, aEnd); - } - template bool append(const U* aBegin, size_t aLength) { - return vec().append(aBegin, aLength); - } - template void infallibleAppend(U&& aU) { - vec().infallibleAppend(mozilla::Forward(aU)); - } - void infallibleAppendN(const T& aT, size_t aN) { vec().infallibleAppendN(aT, aN); } - template void infallibleAppend(const U* aBegin, const U* aEnd) { - vec().infallibleAppend(aBegin, aEnd); - } - template void infallibleAppend(const U* aBegin, size_t aLength) { - vec().infallibleAppend(aBegin, aLength); - } - void popBack() { vec().popBack(); } - T popCopy() { return vec().popCopy(); } - template T* insert(T* aP, U&& aVal) { - return vec().insert(aP, mozilla::Forward(aVal)); - } - void erase(T* aT) { vec().erase(aT); } - void erase(T* aBegin, T* aEnd) { vec().erase(aBegin, aEnd); } -}; - -template -class RootedBase> - : public MutableGCVectorOperations>, T,N,AP> -{}; - -template -class MutableHandleBase> - : public MutableGCVectorOperations>, T,N,AP> -{}; - -template -class HandleBase> - : public GCVectorOperations>, T,N,AP> -{}; - -template -class PersistentRootedBase> - : public MutableGCVectorOperations>, T,N,AP> -{}; - -} // namespace js - -#endif // js_GCVector_h diff --git a/android/armeabi-v7a/include/spidermonkey/js/HashTable.h b/android/armeabi-v7a/include/spidermonkey/js/HashTable.h deleted file mode 100644 index 4ed73d94..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/HashTable.h +++ /dev/null @@ -1,1884 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_HashTable_h -#define js_HashTable_h - -#ifndef UINT64_C -#define UINT64_C(value) __CONCAT(value, ULL) -#endif - -#include "mozilla/Alignment.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Casting.h" -#include "mozilla/HashFunctions.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" -#include "mozilla/Opaque.h" -#include "mozilla/PodOperations.h" -#include "mozilla/ReentrancyGuard.h" -#include "mozilla/TemplateLib.h" -#include "mozilla/TypeTraits.h" -#include "mozilla/UniquePtr.h" - -#include "js/Utility.h" - -namespace js { - -class TempAllocPolicy; -template struct DefaultHasher; -template class HashMapEntry; -namespace detail { - template class HashTableEntry; - template class HashTable; -} // namespace detail - -/*****************************************************************************/ - -// The "generation" of a hash table is an opaque value indicating the state of -// modification of the hash table through its lifetime. If the generation of -// a hash table compares equal at times T1 and T2, then lookups in the hash -// table, pointers to (or into) hash table entries, etc. at time T1 are valid -// at time T2. If the generation compares unequal, these computations are all -// invalid and must be performed again to be used. -// -// Generations are meaningfully comparable only with respect to a single hash -// table. It's always nonsensical to compare the generation of distinct hash -// tables H1 and H2. -using Generation = mozilla::Opaque; - -// A JS-friendly, STL-like container providing a hash-based map from keys to -// values. In particular, HashMap calls constructors and destructors of all -// objects added so non-PODs may be used safely. -// -// Key/Value requirements: -// - movable, destructible, assignable -// HashPolicy requirements: -// - see Hash Policy section below -// AllocPolicy: -// - see jsalloc.h -// -// Note: -// - HashMap is not reentrant: Key/Value/HashPolicy/AllocPolicy members -// called by HashMap must not call back into the same HashMap object. -// - Due to the lack of exception handling, the user must call |init()|. -template , - class AllocPolicy = TempAllocPolicy> -class HashMap -{ - typedef HashMapEntry TableEntry; - - struct MapHashPolicy : HashPolicy - { - using Base = HashPolicy; - typedef Key KeyType; - static const Key& getKey(TableEntry& e) { return e.key(); } - static void setKey(TableEntry& e, Key& k) { HashPolicy::rekey(e.mutableKey(), k); } - }; - - typedef detail::HashTable Impl; - Impl impl; - - public: - typedef typename HashPolicy::Lookup Lookup; - typedef TableEntry Entry; - - // HashMap construction is fallible (due to OOM); thus the user must call - // init after constructing a HashMap and check the return value. - explicit HashMap(AllocPolicy a = AllocPolicy()) : impl(a) {} - MOZ_MUST_USE bool init(uint32_t len = 16) { return impl.init(len); } - bool initialized() const { return impl.initialized(); } - - // Return whether the given lookup value is present in the map. E.g.: - // - // typedef HashMap HM; - // HM h; - // if (HM::Ptr p = h.lookup(3)) { - // const HM::Entry& e = *p; // p acts like a pointer to Entry - // assert(p->key == 3); // Entry contains the key - // char val = p->value; // and value - // } - // - // Also see the definition of Ptr in HashTable above (with T = Entry). - typedef typename Impl::Ptr Ptr; - Ptr lookup(const Lookup& l) const { return impl.lookup(l); } - - // Like lookup, but does not assert if two threads call lookup at the same - // time. Only use this method when none of the threads will modify the map. - Ptr readonlyThreadsafeLookup(const Lookup& l) const { return impl.readonlyThreadsafeLookup(l); } - - // Assuming |p.found()|, remove |*p|. - void remove(Ptr p) { impl.remove(p); } - - // Like |lookup(l)|, but on miss, |p = lookupForAdd(l)| allows efficient - // insertion of Key |k| (where |HashPolicy::match(k,l) == true|) using - // |add(p,k,v)|. After |add(p,k,v)|, |p| points to the new Entry. E.g.: - // - // typedef HashMap HM; - // HM h; - // HM::AddPtr p = h.lookupForAdd(3); - // if (!p) { - // if (!h.add(p, 3, 'a')) - // return false; - // } - // const HM::Entry& e = *p; // p acts like a pointer to Entry - // assert(p->key == 3); // Entry contains the key - // char val = p->value; // and value - // - // Also see the definition of AddPtr in HashTable above (with T = Entry). - // - // N.B. The caller must ensure that no mutating hash table operations - // occur between a pair of |lookupForAdd| and |add| calls. To avoid - // looking up the key a second time, the caller may use the more efficient - // relookupOrAdd method. This method reuses part of the hashing computation - // to more efficiently insert the key if it has not been added. For - // example, a mutation-handling version of the previous example: - // - // HM::AddPtr p = h.lookupForAdd(3); - // if (!p) { - // call_that_may_mutate_h(); - // if (!h.relookupOrAdd(p, 3, 'a')) - // return false; - // } - // const HM::Entry& e = *p; - // assert(p->key == 3); - // char val = p->value; - typedef typename Impl::AddPtr AddPtr; - AddPtr lookupForAdd(const Lookup& l) const { - return impl.lookupForAdd(l); - } - - template - MOZ_MUST_USE bool add(AddPtr& p, KeyInput&& k, ValueInput&& v) { - return impl.add(p, - mozilla::Forward(k), - mozilla::Forward(v)); - } - - template - MOZ_MUST_USE bool add(AddPtr& p, KeyInput&& k) { - return impl.add(p, mozilla::Forward(k), Value()); - } - - template - MOZ_MUST_USE bool relookupOrAdd(AddPtr& p, KeyInput&& k, ValueInput&& v) { - return impl.relookupOrAdd(p, k, - mozilla::Forward(k), - mozilla::Forward(v)); - } - - // |all()| returns a Range containing |count()| elements. E.g.: - // - // typedef HashMap HM; - // HM h; - // for (HM::Range r = h.all(); !r.empty(); r.popFront()) - // char c = r.front().value(); - // - // Also see the definition of Range in HashTable above (with T = Entry). - typedef typename Impl::Range Range; - Range all() const { return impl.all(); } - - // Typedef for the enumeration class. An Enum may be used to examine and - // remove table entries: - // - // typedef HashMap HM; - // HM s; - // for (HM::Enum e(s); !e.empty(); e.popFront()) - // if (e.front().value() == 'l') - // e.removeFront(); - // - // Table resize may occur in Enum's destructor. Also see the definition of - // Enum in HashTable above (with T = Entry). - typedef typename Impl::Enum Enum; - - // Remove all entries. This does not shrink the table. For that consider - // using the finish() method. - void clear() { impl.clear(); } - - // Remove all the entries and release all internal buffers. The map must - // be initialized again before any use. - void finish() { impl.finish(); } - - // Does the table contain any entries? - bool empty() const { return impl.empty(); } - - // Number of live elements in the map. - uint32_t count() const { return impl.count(); } - - // Total number of allocation in the dynamic table. Note: resize will - // happen well before count() == capacity(). - size_t capacity() const { return impl.capacity(); } - - // Don't just call |impl.sizeOfExcludingThis()| because there's no - // guarantee that |impl| is the first field in HashMap. - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return impl.sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + impl.sizeOfExcludingThis(mallocSizeOf); - } - - Generation generation() const { - return impl.generation(); - } - - /************************************************** Shorthand operations */ - - bool has(const Lookup& l) const { - return impl.lookup(l).found(); - } - - // Overwrite existing value with v. Return false on oom. - template - MOZ_MUST_USE bool put(KeyInput&& k, ValueInput&& v) { - AddPtr p = lookupForAdd(k); - if (p) { - p->value() = mozilla::Forward(v); - return true; - } - return add(p, mozilla::Forward(k), mozilla::Forward(v)); - } - - // Like put, but assert that the given key is not already present. - template - MOZ_MUST_USE bool putNew(KeyInput&& k, ValueInput&& v) { - return impl.putNew(k, mozilla::Forward(k), mozilla::Forward(v)); - } - - // Only call this to populate an empty map after reserving space with init(). - template - void putNewInfallible(KeyInput&& k, ValueInput&& v) { - impl.putNewInfallible(k, mozilla::Forward(k), mozilla::Forward(v)); - } - - // Add (k,defaultValue) if |k| is not found. Return a false-y Ptr on oom. - Ptr lookupWithDefault(const Key& k, const Value& defaultValue) { - AddPtr p = lookupForAdd(k); - if (p) - return p; - bool ok = add(p, k, defaultValue); - MOZ_ASSERT_IF(!ok, !p); // p is left false-y on oom. - (void)ok; - return p; - } - - // Remove if present. - void remove(const Lookup& l) { - if (Ptr p = lookup(l)) - remove(p); - } - - // Infallibly rekey one entry, if necessary. - // Requires template parameters Key and HashPolicy::Lookup to be the same type. - void rekeyIfMoved(const Key& old_key, const Key& new_key) { - if (old_key != new_key) - rekeyAs(old_key, new_key, new_key); - } - - // Infallibly rekey one entry if present, and return whether that happened. - bool rekeyAs(const Lookup& old_lookup, const Lookup& new_lookup, const Key& new_key) { - if (Ptr p = lookup(old_lookup)) { - impl.rekeyAndMaybeRehash(p, new_lookup, new_key); - return true; - } - return false; - } - - // HashMap is movable - HashMap(HashMap&& rhs) : impl(mozilla::Move(rhs.impl)) {} - void operator=(HashMap&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - impl = mozilla::Move(rhs.impl); - } - - private: - // HashMap is not copyable or assignable - HashMap(const HashMap& hm) = delete; - HashMap& operator=(const HashMap& hm) = delete; - - friend class Impl::Enum; -}; - -/*****************************************************************************/ - -// A JS-friendly, STL-like container providing a hash-based set of values. In -// particular, HashSet calls constructors and destructors of all objects added -// so non-PODs may be used safely. -// -// T requirements: -// - movable, destructible, assignable -// HashPolicy requirements: -// - see Hash Policy section below -// AllocPolicy: -// - see jsalloc.h -// -// Note: -// - HashSet is not reentrant: T/HashPolicy/AllocPolicy members called by -// HashSet must not call back into the same HashSet object. -// - Due to the lack of exception handling, the user must call |init()|. -template , - class AllocPolicy = TempAllocPolicy> -class HashSet -{ - struct SetOps : HashPolicy - { - using Base = HashPolicy; - typedef T KeyType; - static const KeyType& getKey(const T& t) { return t; } - static void setKey(T& t, KeyType& k) { HashPolicy::rekey(t, k); } - }; - - typedef detail::HashTable Impl; - Impl impl; - - public: - typedef typename HashPolicy::Lookup Lookup; - typedef T Entry; - - // HashSet construction is fallible (due to OOM); thus the user must call - // init after constructing a HashSet and check the return value. - explicit HashSet(AllocPolicy a = AllocPolicy()) : impl(a) {} - MOZ_MUST_USE bool init(uint32_t len = 16) { return impl.init(len); } - bool initialized() const { return impl.initialized(); } - - // Return whether the given lookup value is present in the map. E.g.: - // - // typedef HashSet HS; - // HS h; - // if (HS::Ptr p = h.lookup(3)) { - // assert(*p == 3); // p acts like a pointer to int - // } - // - // Also see the definition of Ptr in HashTable above. - typedef typename Impl::Ptr Ptr; - Ptr lookup(const Lookup& l) const { return impl.lookup(l); } - - // Like lookup, but does not assert if two threads call lookup at the same - // time. Only use this method when none of the threads will modify the map. - Ptr readonlyThreadsafeLookup(const Lookup& l) const { return impl.readonlyThreadsafeLookup(l); } - - // Assuming |p.found()|, remove |*p|. - void remove(Ptr p) { impl.remove(p); } - - // Like |lookup(l)|, but on miss, |p = lookupForAdd(l)| allows efficient - // insertion of T value |t| (where |HashPolicy::match(t,l) == true|) using - // |add(p,t)|. After |add(p,t)|, |p| points to the new element. E.g.: - // - // typedef HashSet HS; - // HS h; - // HS::AddPtr p = h.lookupForAdd(3); - // if (!p) { - // if (!h.add(p, 3)) - // return false; - // } - // assert(*p == 3); // p acts like a pointer to int - // - // Also see the definition of AddPtr in HashTable above. - // - // N.B. The caller must ensure that no mutating hash table operations - // occur between a pair of |lookupForAdd| and |add| calls. To avoid - // looking up the key a second time, the caller may use the more efficient - // relookupOrAdd method. This method reuses part of the hashing computation - // to more efficiently insert the key if it has not been added. For - // example, a mutation-handling version of the previous example: - // - // HS::AddPtr p = h.lookupForAdd(3); - // if (!p) { - // call_that_may_mutate_h(); - // if (!h.relookupOrAdd(p, 3, 3)) - // return false; - // } - // assert(*p == 3); - // - // Note that relookupOrAdd(p,l,t) performs Lookup using |l| and adds the - // entry |t|, where the caller ensures match(l,t). - typedef typename Impl::AddPtr AddPtr; - AddPtr lookupForAdd(const Lookup& l) const { return impl.lookupForAdd(l); } - - template - MOZ_MUST_USE bool add(AddPtr& p, U&& u) { - return impl.add(p, mozilla::Forward(u)); - } - - template - MOZ_MUST_USE bool relookupOrAdd(AddPtr& p, const Lookup& l, U&& u) { - return impl.relookupOrAdd(p, l, mozilla::Forward(u)); - } - - // |all()| returns a Range containing |count()| elements: - // - // typedef HashSet HS; - // HS h; - // for (HS::Range r = h.all(); !r.empty(); r.popFront()) - // int i = r.front(); - // - // Also see the definition of Range in HashTable above. - typedef typename Impl::Range Range; - Range all() const { return impl.all(); } - - // Typedef for the enumeration class. An Enum may be used to examine and - // remove table entries: - // - // typedef HashSet HS; - // HS s; - // for (HS::Enum e(s); !e.empty(); e.popFront()) - // if (e.front() == 42) - // e.removeFront(); - // - // Table resize may occur in Enum's destructor. Also see the definition of - // Enum in HashTable above. - typedef typename Impl::Enum Enum; - - // Remove all entries. This does not shrink the table. For that consider - // using the finish() method. - void clear() { impl.clear(); } - - // Remove all the entries and release all internal buffers. The set must - // be initialized again before any use. - void finish() { impl.finish(); } - - // Does the table contain any entries? - bool empty() const { return impl.empty(); } - - // Number of live elements in the map. - uint32_t count() const { return impl.count(); } - - // Total number of allocation in the dynamic table. Note: resize will - // happen well before count() == capacity(). - size_t capacity() const { return impl.capacity(); } - - // Don't just call |impl.sizeOfExcludingThis()| because there's no - // guarantee that |impl| is the first field in HashSet. - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return impl.sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + impl.sizeOfExcludingThis(mallocSizeOf); - } - - Generation generation() const { - return impl.generation(); - } - - /************************************************** Shorthand operations */ - - bool has(const Lookup& l) const { - return impl.lookup(l).found(); - } - - // Add |u| if it is not present already. Return false on oom. - template - MOZ_MUST_USE bool put(U&& u) { - AddPtr p = lookupForAdd(u); - return p ? true : add(p, mozilla::Forward(u)); - } - - // Like put, but assert that the given key is not already present. - template - MOZ_MUST_USE bool putNew(U&& u) { - return impl.putNew(u, mozilla::Forward(u)); - } - - template - MOZ_MUST_USE bool putNew(const Lookup& l, U&& u) { - return impl.putNew(l, mozilla::Forward(u)); - } - - // Only call this to populate an empty set after reserving space with init(). - template - void putNewInfallible(const Lookup& l, U&& u) { - impl.putNewInfallible(l, mozilla::Forward(u)); - } - - void remove(const Lookup& l) { - if (Ptr p = lookup(l)) - remove(p); - } - - // Infallibly rekey one entry, if present. - // Requires template parameters T and HashPolicy::Lookup to be the same type. - void rekeyIfMoved(const Lookup& old_value, const T& new_value) { - if (old_value != new_value) - rekeyAs(old_value, new_value, new_value); - } - - // Infallibly rekey one entry if present, and return whether that happened. - bool rekeyAs(const Lookup& old_lookup, const Lookup& new_lookup, const T& new_value) { - if (Ptr p = lookup(old_lookup)) { - impl.rekeyAndMaybeRehash(p, new_lookup, new_value); - return true; - } - return false; - } - - // Infallibly replace the current key at |p| with an equivalent key. - // Specifically, both HashPolicy::hash and HashPolicy::match must return - // identical results for the new and old key when applied against all - // possible matching values. - void replaceKey(Ptr p, const T& new_value) { - MOZ_ASSERT(p.found()); - MOZ_ASSERT(*p != new_value); - MOZ_ASSERT(HashPolicy::hash(*p) == HashPolicy::hash(new_value)); - MOZ_ASSERT(HashPolicy::match(*p, new_value)); - const_cast(*p) = new_value; - } - - // HashSet is movable - HashSet(HashSet&& rhs) : impl(mozilla::Move(rhs.impl)) {} - void operator=(HashSet&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - impl = mozilla::Move(rhs.impl); - } - - private: - // HashSet is not copyable or assignable - HashSet(const HashSet& hs) = delete; - HashSet& operator=(const HashSet& hs) = delete; - - friend class Impl::Enum; -}; - -/*****************************************************************************/ - -// Hash Policy -// -// A hash policy P for a hash table with key-type Key must provide: -// - a type |P::Lookup| to use to lookup table entries; -// - a static member function |P::hash| with signature -// -// static js::HashNumber hash(Lookup) -// -// to use to hash the lookup type; and -// - a static member function |P::match| with signature -// -// static bool match(Key, Lookup) -// -// to use to test equality of key and lookup values. -// -// Normally, Lookup = Key. In general, though, different values and types of -// values can be used to lookup and store. If a Lookup value |l| is != to the -// added Key value |k|, the user must ensure that |P::match(k,l)|. E.g.: -// -// js::HashSet::AddPtr p = h.lookup(l); -// if (!p) { -// assert(P::match(k, l)); // must hold -// h.add(p, k); -// } - -// Pointer hashing policy that strips the lowest zeroBits when calculating the -// hash to improve key distribution. -template -struct PointerHasher -{ - typedef Key Lookup; - static HashNumber hash(const Lookup& l) { - size_t word = reinterpret_cast(l) >> zeroBits; - static_assert(sizeof(HashNumber) == 4, - "subsequent code assumes a four-byte hash"); -#if JS_BITS_PER_WORD == 32 - return HashNumber(word); -#else - static_assert(sizeof(word) == 8, - "unexpected word size, new hashing strategy required to " - "properly incorporate all bits"); - return HashNumber((word >> 32) ^ word); -#endif - } - static bool match(const Key& k, const Lookup& l) { - return k == l; - } - static void rekey(Key& k, const Key& newKey) { - k = newKey; - } -}; - -// Default hash policy: just use the 'lookup' value. This of course only -// works if the lookup value is integral. HashTable applies ScrambleHashCode to -// the result of the 'hash' which means that it is 'ok' if the lookup value is -// not well distributed over the HashNumber domain. -template -struct DefaultHasher -{ - typedef Key Lookup; - static HashNumber hash(const Lookup& l) { - // Hash if can implicitly cast to hash number type. - return l; - } - static bool match(const Key& k, const Lookup& l) { - // Use builtin or overloaded operator==. - return k == l; - } - static void rekey(Key& k, const Key& newKey) { - k = newKey; - } -}; - -// Specialize hashing policy for pointer types. It assumes that the type is -// at least word-aligned. For types with smaller size use PointerHasher. -template -struct DefaultHasher : PointerHasher::value> -{}; - -// Specialize hashing policy for mozilla::UniquePtr to proxy the UniquePtr's -// raw pointer to PointerHasher. -template -struct DefaultHasher> -{ - using Lookup = mozilla::UniquePtr; - using PtrHasher = PointerHasher::value>; - - static HashNumber hash(const Lookup& l) { - return PtrHasher::hash(l.get()); - } - static bool match(const mozilla::UniquePtr& k, const Lookup& l) { - return PtrHasher::match(k.get(), l.get()); - } - static void rekey(mozilla::UniquePtr& k, mozilla::UniquePtr&& newKey) { - k = mozilla::Move(newKey); - } -}; - -// For doubles, we can xor the two uint32s. -template <> -struct DefaultHasher -{ - typedef double Lookup; - static HashNumber hash(double d) { - static_assert(sizeof(HashNumber) == 4, - "subsequent code assumes a four-byte hash"); - uint64_t u = mozilla::BitwiseCast(d); - return HashNumber(u ^ (u >> 32)); - } - static bool match(double lhs, double rhs) { - return mozilla::BitwiseCast(lhs) == mozilla::BitwiseCast(rhs); - } -}; - -template <> -struct DefaultHasher -{ - typedef float Lookup; - static HashNumber hash(float f) { - static_assert(sizeof(HashNumber) == 4, - "subsequent code assumes a four-byte hash"); - return HashNumber(mozilla::BitwiseCast(f)); - } - static bool match(float lhs, float rhs) { - return mozilla::BitwiseCast(lhs) == mozilla::BitwiseCast(rhs); - } -}; - -// A hash policy that compares C strings. -struct CStringHasher -{ - typedef const char* Lookup; - static js::HashNumber hash(Lookup l) { - return mozilla::HashString(l); - } - static bool match(const char* key, Lookup lookup) { - return strcmp(key, lookup) == 0; - } -}; - -// Fallible hashing interface. -// -// Most of the time generating a hash code is infallible so this class provides -// default methods that always succeed. Specialize this class for your own hash -// policy to provide fallible hashing. -// -// This is used by MovableCellHasher to handle the fact that generating a unique -// ID for cell pointer may fail due to OOM. -template -struct FallibleHashMethods -{ - // Return true if a hashcode is already available for its argument. Once - // this returns true for a specific argument it must continue to do so. - template static bool hasHash(Lookup&& l) { return true; } - - // Fallible method to ensure a hashcode exists for its argument and create - // one if not. Returns false on error, e.g. out of memory. - template static bool ensureHash(Lookup&& l) { return true; } -}; - -template -static bool -HasHash(Lookup&& l) { - return FallibleHashMethods::hasHash(mozilla::Forward(l)); -} - -template -static bool -EnsureHash(Lookup&& l) { - return FallibleHashMethods::ensureHash(mozilla::Forward(l)); -} - -/*****************************************************************************/ - -// Both HashMap and HashSet are implemented by a single HashTable that is even -// more heavily parameterized than the other two. This leaves HashTable gnarly -// and extremely coupled to HashMap and HashSet; thus code should not use -// HashTable directly. - -template -class HashMapEntry -{ - Key key_; - Value value_; - - template friend class detail::HashTable; - template friend class detail::HashTableEntry; - template friend class HashMap; - - public: - template - HashMapEntry(KeyInput&& k, ValueInput&& v) - : key_(mozilla::Forward(k)), - value_(mozilla::Forward(v)) - {} - - HashMapEntry(HashMapEntry&& rhs) - : key_(mozilla::Move(rhs.key_)), - value_(mozilla::Move(rhs.value_)) - {} - - void operator=(HashMapEntry&& rhs) { - key_ = mozilla::Move(rhs.key_); - value_ = mozilla::Move(rhs.value_); - } - - typedef Key KeyType; - typedef Value ValueType; - - const Key& key() const { return key_; } - Key& mutableKey() { return key_; } - const Value& value() const { return value_; } - Value& value() { return value_; } - - private: - HashMapEntry(const HashMapEntry&) = delete; - void operator=(const HashMapEntry&) = delete; -}; - -} // namespace js - -namespace mozilla { - -template -struct IsPod > : IsPod {}; - -template -struct IsPod > - : IntegralConstant::value && IsPod::value> -{}; - -} // namespace mozilla - -namespace js { - -namespace detail { - -template -class HashTable; - -template -class HashTableEntry -{ - template friend class HashTable; - typedef typename mozilla::RemoveConst::Type NonConstT; - - HashNumber keyHash; - mozilla::AlignedStorage2 mem; - - static const HashNumber sFreeKey = 0; - static const HashNumber sRemovedKey = 1; - static const HashNumber sCollisionBit = 1; - - static bool isLiveHash(HashNumber hash) - { - return hash > sRemovedKey; - } - - HashTableEntry(const HashTableEntry&) = delete; - void operator=(const HashTableEntry&) = delete; - ~HashTableEntry() = delete; - - public: - // NB: HashTableEntry is treated as a POD: no constructor or destructor calls. - - void destroyIfLive() { - if (isLive()) - mem.addr()->~T(); - } - - void destroy() { - MOZ_ASSERT(isLive()); - mem.addr()->~T(); - } - - void swap(HashTableEntry* other) { - if (this == other) - return; - MOZ_ASSERT(isLive()); - if (other->isLive()) { - mozilla::Swap(*mem.addr(), *other->mem.addr()); - } else { - *other->mem.addr() = mozilla::Move(*mem.addr()); - destroy(); - } - mozilla::Swap(keyHash, other->keyHash); - } - - T& get() { MOZ_ASSERT(isLive()); return *mem.addr(); } - NonConstT& getMutable() { MOZ_ASSERT(isLive()); return *mem.addr(); } - - bool isFree() const { return keyHash == sFreeKey; } - void clearLive() { MOZ_ASSERT(isLive()); keyHash = sFreeKey; mem.addr()->~T(); } - void clear() { if (isLive()) mem.addr()->~T(); keyHash = sFreeKey; } - bool isRemoved() const { return keyHash == sRemovedKey; } - void removeLive() { MOZ_ASSERT(isLive()); keyHash = sRemovedKey; mem.addr()->~T(); } - bool isLive() const { return isLiveHash(keyHash); } - void setCollision() { MOZ_ASSERT(isLive()); keyHash |= sCollisionBit; } - void unsetCollision() { keyHash &= ~sCollisionBit; } - bool hasCollision() const { return keyHash & sCollisionBit; } - bool matchHash(HashNumber hn) { return (keyHash & ~sCollisionBit) == hn; } - HashNumber getKeyHash() const { return keyHash & ~sCollisionBit; } - - template - void setLive(HashNumber hn, Args&&... args) - { - MOZ_ASSERT(!isLive()); - keyHash = hn; - new(mem.addr()) T(mozilla::Forward(args)...); - MOZ_ASSERT(isLive()); - } -}; - -template -class HashTable : private AllocPolicy -{ - friend class mozilla::ReentrancyGuard; - - typedef typename mozilla::RemoveConst::Type NonConstT; - typedef typename HashPolicy::KeyType Key; - typedef typename HashPolicy::Lookup Lookup; - - public: - typedef HashTableEntry Entry; - - // A nullable pointer to a hash table element. A Ptr |p| can be tested - // either explicitly |if (p.found()) p->...| or using boolean conversion - // |if (p) p->...|. Ptr objects must not be used after any mutating hash - // table operations unless |generation()| is tested. - class Ptr - { - friend class HashTable; - - Entry* entry_; -#ifdef JS_DEBUG - const HashTable* table_; - Generation generation; -#endif - - protected: - Ptr(Entry& entry, const HashTable& tableArg) - : entry_(&entry) -#ifdef JS_DEBUG - , table_(&tableArg) - , generation(tableArg.generation()) -#endif - {} - - public: - Ptr() - : entry_(nullptr) -#ifdef JS_DEBUG - , table_(nullptr) - , generation(0) -#endif - {} - - bool isValid() const { - return !entry_; - } - - bool found() const { - if (isValid()) - return false; -#ifdef JS_DEBUG - MOZ_ASSERT(generation == table_->generation()); -#endif - return entry_->isLive(); - } - - explicit operator bool() const { - return found(); - } - - bool operator==(const Ptr& rhs) const { - MOZ_ASSERT(found() && rhs.found()); - return entry_ == rhs.entry_; - } - - bool operator!=(const Ptr& rhs) const { -#ifdef JS_DEBUG - MOZ_ASSERT(generation == table_->generation()); -#endif - return !(*this == rhs); - } - - T& operator*() const { -#ifdef JS_DEBUG - MOZ_ASSERT(found()); - MOZ_ASSERT(generation == table_->generation()); -#endif - return entry_->get(); - } - - T* operator->() const { -#ifdef JS_DEBUG - MOZ_ASSERT(found()); - MOZ_ASSERT(generation == table_->generation()); -#endif - return &entry_->get(); - } - }; - - // A Ptr that can be used to add a key after a failed lookup. - class AddPtr : public Ptr - { - friend class HashTable; - HashNumber keyHash; -#ifdef JS_DEBUG - uint64_t mutationCount; -#endif - - AddPtr(Entry& entry, const HashTable& tableArg, HashNumber hn) - : Ptr(entry, tableArg) - , keyHash(hn) -#ifdef JS_DEBUG - , mutationCount(tableArg.mutationCount) -#endif - {} - - public: - AddPtr() : keyHash(0) {} - }; - - // A collection of hash table entries. The collection is enumerated by - // calling |front()| followed by |popFront()| as long as |!empty()|. As - // with Ptr/AddPtr, Range objects must not be used after any mutating hash - // table operation unless the |generation()| is tested. - class Range - { - protected: - friend class HashTable; - - Range(const HashTable& tableArg, Entry* c, Entry* e) - : cur(c) - , end(e) -#ifdef JS_DEBUG - , table_(&tableArg) - , mutationCount(tableArg.mutationCount) - , generation(tableArg.generation()) - , validEntry(true) -#endif - { - while (cur < end && !cur->isLive()) - ++cur; - } - - Entry* cur; - Entry* end; -#ifdef JS_DEBUG - const HashTable* table_; - uint64_t mutationCount; - Generation generation; - bool validEntry; -#endif - - public: - Range() - : cur(nullptr) - , end(nullptr) -#ifdef JS_DEBUG - , table_(nullptr) - , mutationCount(0) - , generation(0) - , validEntry(false) -#endif - {} - - bool empty() const { -#ifdef JS_DEBUG - MOZ_ASSERT(generation == table_->generation()); - MOZ_ASSERT(mutationCount == table_->mutationCount); -#endif - return cur == end; - } - - T& front() const { - MOZ_ASSERT(!empty()); -#ifdef JS_DEBUG - MOZ_ASSERT(validEntry); - MOZ_ASSERT(generation == table_->generation()); - MOZ_ASSERT(mutationCount == table_->mutationCount); -#endif - return cur->get(); - } - - void popFront() { - MOZ_ASSERT(!empty()); -#ifdef JS_DEBUG - MOZ_ASSERT(generation == table_->generation()); - MOZ_ASSERT(mutationCount == table_->mutationCount); -#endif - while (++cur < end && !cur->isLive()) - continue; -#ifdef JS_DEBUG - validEntry = true; -#endif - } - }; - - // A Range whose lifetime delimits a mutating enumeration of a hash table. - // Since rehashing when elements were removed during enumeration would be - // bad, it is postponed until the Enum is destructed. Since the Enum's - // destructor touches the hash table, the user must ensure that the hash - // table is still alive when the destructor runs. - class Enum : public Range - { - friend class HashTable; - - HashTable& table_; - bool rekeyed; - bool removed; - - /* Not copyable. */ - Enum(const Enum&) = delete; - void operator=(const Enum&) = delete; - - public: - template explicit - Enum(Map& map) : Range(map.all()), table_(map.impl), rekeyed(false), removed(false) {} - - // Removes the |front()| element from the table, leaving |front()| - // invalid until the next call to |popFront()|. For example: - // - // HashSet s; - // for (HashSet::Enum e(s); !e.empty(); e.popFront()) - // if (e.front() == 42) - // e.removeFront(); - void removeFront() { - table_.remove(*this->cur); - removed = true; -#ifdef JS_DEBUG - this->validEntry = false; - this->mutationCount = table_.mutationCount; -#endif - } - - NonConstT& mutableFront() { - MOZ_ASSERT(!this->empty()); -#ifdef JS_DEBUG - MOZ_ASSERT(this->validEntry); - MOZ_ASSERT(this->generation == this->Range::table_->generation()); - MOZ_ASSERT(this->mutationCount == this->Range::table_->mutationCount); -#endif - return this->cur->getMutable(); - } - - // Removes the |front()| element and re-inserts it into the table with - // a new key at the new Lookup position. |front()| is invalid after - // this operation until the next call to |popFront()|. - void rekeyFront(const Lookup& l, const Key& k) { - MOZ_ASSERT(&k != &HashPolicy::getKey(this->cur->get())); - Ptr p(*this->cur, table_); - table_.rekeyWithoutRehash(p, l, k); - rekeyed = true; -#ifdef JS_DEBUG - this->validEntry = false; - this->mutationCount = table_.mutationCount; -#endif - } - - void rekeyFront(const Key& k) { - rekeyFront(k, k); - } - - // Potentially rehashes the table. - ~Enum() { - if (rekeyed) { - table_.gen++; - table_.checkOverRemoved(); - } - - if (removed) - table_.compactIfUnderloaded(); - } - }; - - // HashTable is movable - HashTable(HashTable&& rhs) - : AllocPolicy(rhs) - { - mozilla::PodAssign(this, &rhs); - rhs.table = nullptr; - } - void operator=(HashTable&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - if (table) - destroyTable(*this, table, capacity()); - mozilla::PodAssign(this, &rhs); - rhs.table = nullptr; - } - - private: - // HashTable is not copyable or assignable - HashTable(const HashTable&) = delete; - void operator=(const HashTable&) = delete; - - private: - static const size_t CAP_BITS = 30; - - public: - uint64_t gen:56; // entry storage generation number - uint64_t hashShift:8; // multiplicative hash shift - Entry* table; // entry storage - uint32_t entryCount; // number of entries in table - uint32_t removedCount; // removed entry sentinels in table - -#ifdef JS_DEBUG - uint64_t mutationCount; - mutable bool mEntered; - // Note that some updates to these stats are not thread-safe. See the - // comment on the three-argument overloading of HashTable::lookup(). - mutable struct Stats - { - uint32_t searches; // total number of table searches - uint32_t steps; // hash chain links traversed - uint32_t hits; // searches that found key - uint32_t misses; // searches that didn't find key - uint32_t addOverRemoved; // adds that recycled a removed entry - uint32_t removes; // calls to remove - uint32_t removeFrees; // calls to remove that freed the entry - uint32_t grows; // table expansions - uint32_t shrinks; // table contractions - uint32_t compresses; // table compressions - uint32_t rehashes; // tombstone decontaminations - } stats; -# define METER(x) x -#else -# define METER(x) -#endif - - // The default initial capacity is 32 (enough to hold 16 elements), but it - // can be as low as 4. - static const unsigned sMinCapacityLog2 = 2; - static const unsigned sMinCapacity = 1 << sMinCapacityLog2; - static const unsigned sMaxInit = JS_BIT(CAP_BITS - 1); - static const unsigned sMaxCapacity = JS_BIT(CAP_BITS); - static const unsigned sHashBits = mozilla::tl::BitSize::value; - - // Hash-table alpha is conceptually a fraction, but to avoid floating-point - // math we implement it as a ratio of integers. - static const uint8_t sAlphaDenominator = 4; - static const uint8_t sMinAlphaNumerator = 1; // min alpha: 1/4 - static const uint8_t sMaxAlphaNumerator = 3; // max alpha: 3/4 - - static const HashNumber sFreeKey = Entry::sFreeKey; - static const HashNumber sRemovedKey = Entry::sRemovedKey; - static const HashNumber sCollisionBit = Entry::sCollisionBit; - - void setTableSizeLog2(unsigned sizeLog2) - { - hashShift = sHashBits - sizeLog2; - } - - static bool isLiveHash(HashNumber hash) - { - return Entry::isLiveHash(hash); - } - - static HashNumber prepareHash(const Lookup& l) - { - HashNumber keyHash = ScrambleHashCode(HashPolicy::hash(l)); - - // Avoid reserved hash codes. - if (!isLiveHash(keyHash)) - keyHash -= (sRemovedKey + 1); - return keyHash & ~sCollisionBit; - } - - enum FailureBehavior { DontReportFailure = false, ReportFailure = true }; - - static Entry* createTable(AllocPolicy& alloc, uint32_t capacity, - FailureBehavior reportFailure = ReportFailure) - { - static_assert(sFreeKey == 0, - "newly-calloc'd tables have to be considered empty"); - if (reportFailure) - return alloc.template pod_calloc(capacity); - - return alloc.template maybe_pod_calloc(capacity); - } - - static Entry* maybeCreateTable(AllocPolicy& alloc, uint32_t capacity) - { - static_assert(sFreeKey == 0, - "newly-calloc'd tables have to be considered empty"); - return alloc.template maybe_pod_calloc(capacity); - } - - static void destroyTable(AllocPolicy& alloc, Entry* oldTable, uint32_t capacity) - { - Entry* end = oldTable + capacity; - for (Entry* e = oldTable; e < end; ++e) - e->destroyIfLive(); - alloc.free_(oldTable); - } - - public: - explicit HashTable(AllocPolicy ap) - : AllocPolicy(ap) - , gen(0) - , hashShift(sHashBits) - , table(nullptr) - , entryCount(0) - , removedCount(0) -#ifdef JS_DEBUG - , mutationCount(0) - , mEntered(false) -#endif - {} - - MOZ_MUST_USE bool init(uint32_t length) - { - MOZ_ASSERT(!initialized()); - - // Reject all lengths whose initial computed capacity would exceed - // sMaxCapacity. Round that maximum length down to the nearest power - // of two for speedier code. - if (MOZ_UNLIKELY(length > sMaxInit)) { - this->reportAllocOverflow(); - return false; - } - - static_assert((sMaxInit * sAlphaDenominator) / sAlphaDenominator == sMaxInit, - "multiplication in numerator below could overflow"); - static_assert(sMaxInit * sAlphaDenominator <= UINT32_MAX - sMaxAlphaNumerator, - "numerator calculation below could potentially overflow"); - - // Compute the smallest capacity allowing |length| elements to be - // inserted without rehashing: ceil(length / max-alpha). (Ceiling - // integral division: .) - uint32_t newCapacity = - (length * sAlphaDenominator + sMaxAlphaNumerator - 1) / sMaxAlphaNumerator; - if (newCapacity < sMinCapacity) - newCapacity = sMinCapacity; - - // FIXME: use JS_CEILING_LOG2 when PGO stops crashing (bug 543034). - uint32_t roundUp = sMinCapacity, roundUpLog2 = sMinCapacityLog2; - while (roundUp < newCapacity) { - roundUp <<= 1; - ++roundUpLog2; - } - - newCapacity = roundUp; - MOZ_ASSERT(newCapacity >= length); - MOZ_ASSERT(newCapacity <= sMaxCapacity); - - table = createTable(*this, newCapacity); - if (!table) - return false; - - setTableSizeLog2(roundUpLog2); - METER(memset(&stats, 0, sizeof(stats))); - return true; - } - - bool initialized() const - { - return !!table; - } - - ~HashTable() - { - if (table) - destroyTable(*this, table, capacity()); - } - - private: - HashNumber hash1(HashNumber hash0) const - { - return hash0 >> hashShift; - } - - struct DoubleHash - { - HashNumber h2; - HashNumber sizeMask; - }; - - DoubleHash hash2(HashNumber curKeyHash) const - { - unsigned sizeLog2 = sHashBits - hashShift; - DoubleHash dh = { - ((curKeyHash << sizeLog2) >> hashShift) | 1, - (HashNumber(1) << sizeLog2) - 1 - }; - return dh; - } - - static HashNumber applyDoubleHash(HashNumber h1, const DoubleHash& dh) - { - return (h1 - dh.h2) & dh.sizeMask; - } - - bool overloaded() - { - static_assert(sMaxCapacity <= UINT32_MAX / sMaxAlphaNumerator, - "multiplication below could overflow"); - return entryCount + removedCount >= - capacity() * sMaxAlphaNumerator / sAlphaDenominator; - } - - // Would the table be underloaded if it had the given capacity and entryCount? - static bool wouldBeUnderloaded(uint32_t capacity, uint32_t entryCount) - { - static_assert(sMaxCapacity <= UINT32_MAX / sMinAlphaNumerator, - "multiplication below could overflow"); - return capacity > sMinCapacity && - entryCount <= capacity * sMinAlphaNumerator / sAlphaDenominator; - } - - bool underloaded() - { - return wouldBeUnderloaded(capacity(), entryCount); - } - - static bool match(Entry& e, const Lookup& l) - { - return HashPolicy::match(HashPolicy::getKey(e.get()), l); - } - - // Warning: in order for readonlyThreadsafeLookup() to be safe this - // function must not modify the table in any way when |collisionBit| is 0. - // (The use of the METER() macro to increment stats violates this - // restriction but we will live with that for now because it's enabled so - // rarely.) - Entry& lookup(const Lookup& l, HashNumber keyHash, unsigned collisionBit) const - { - MOZ_ASSERT(isLiveHash(keyHash)); - MOZ_ASSERT(!(keyHash & sCollisionBit)); - MOZ_ASSERT(collisionBit == 0 || collisionBit == sCollisionBit); - MOZ_ASSERT(table); - METER(stats.searches++); - - // Compute the primary hash address. - HashNumber h1 = hash1(keyHash); - Entry* entry = &table[h1]; - - // Miss: return space for a new entry. - if (entry->isFree()) { - METER(stats.misses++); - return *entry; - } - - // Hit: return entry. - if (entry->matchHash(keyHash) && match(*entry, l)) { - METER(stats.hits++); - return *entry; - } - - // Collision: double hash. - DoubleHash dh = hash2(keyHash); - - // Save the first removed entry pointer so we can recycle later. - Entry* firstRemoved = nullptr; - - while (true) { - if (MOZ_UNLIKELY(entry->isRemoved())) { - if (!firstRemoved) - firstRemoved = entry; - } else { - if (collisionBit == sCollisionBit) - entry->setCollision(); - } - - METER(stats.steps++); - h1 = applyDoubleHash(h1, dh); - - entry = &table[h1]; - if (entry->isFree()) { - METER(stats.misses++); - return firstRemoved ? *firstRemoved : *entry; - } - - if (entry->matchHash(keyHash) && match(*entry, l)) { - METER(stats.hits++); - return *entry; - } - } - } - - // This is a copy of lookup hardcoded to the assumptions: - // 1. the lookup is a lookupForAdd - // 2. the key, whose |keyHash| has been passed is not in the table, - // 3. no entries have been removed from the table. - // This specialized search avoids the need for recovering lookup values - // from entries, which allows more flexible Lookup/Key types. - Entry& findFreeEntry(HashNumber keyHash) - { - MOZ_ASSERT(!(keyHash & sCollisionBit)); - MOZ_ASSERT(table); - METER(stats.searches++); - - // We assume 'keyHash' has already been distributed. - - // Compute the primary hash address. - HashNumber h1 = hash1(keyHash); - Entry* entry = &table[h1]; - - // Miss: return space for a new entry. - if (!entry->isLive()) { - METER(stats.misses++); - return *entry; - } - - // Collision: double hash. - DoubleHash dh = hash2(keyHash); - - while (true) { - MOZ_ASSERT(!entry->isRemoved()); - entry->setCollision(); - - METER(stats.steps++); - h1 = applyDoubleHash(h1, dh); - - entry = &table[h1]; - if (!entry->isLive()) { - METER(stats.misses++); - return *entry; - } - } - } - - enum RebuildStatus { NotOverloaded, Rehashed, RehashFailed }; - - RebuildStatus changeTableSize(int deltaLog2, FailureBehavior reportFailure = ReportFailure) - { - // Look, but don't touch, until we succeed in getting new entry store. - Entry* oldTable = table; - uint32_t oldCap = capacity(); - uint32_t newLog2 = sHashBits - hashShift + deltaLog2; - uint32_t newCapacity = JS_BIT(newLog2); - if (MOZ_UNLIKELY(newCapacity > sMaxCapacity)) { - if (reportFailure) - this->reportAllocOverflow(); - return RehashFailed; - } - - Entry* newTable = createTable(*this, newCapacity, reportFailure); - if (!newTable) - return RehashFailed; - - // We can't fail from here on, so update table parameters. - setTableSizeLog2(newLog2); - removedCount = 0; - gen++; - table = newTable; - - // Copy only live entries, leaving removed ones behind. - Entry* end = oldTable + oldCap; - for (Entry* src = oldTable; src < end; ++src) { - if (src->isLive()) { - HashNumber hn = src->getKeyHash(); - findFreeEntry(hn).setLive( - hn, mozilla::Move(const_cast(src->get()))); - src->destroy(); - } - } - - // All entries have been destroyed, no need to destroyTable. - this->free_(oldTable); - return Rehashed; - } - - bool shouldCompressTable() - { - // Compress if a quarter or more of all entries are removed. - return removedCount >= (capacity() >> 2); - } - - RebuildStatus checkOverloaded(FailureBehavior reportFailure = ReportFailure) - { - if (!overloaded()) - return NotOverloaded; - - int deltaLog2; - if (shouldCompressTable()) { - METER(stats.compresses++); - deltaLog2 = 0; - } else { - METER(stats.grows++); - deltaLog2 = 1; - } - - return changeTableSize(deltaLog2, reportFailure); - } - - // Infallibly rehash the table if we are overloaded with removals. - void checkOverRemoved() - { - if (overloaded()) { - if (checkOverloaded(DontReportFailure) == RehashFailed) - rehashTableInPlace(); - } - } - - void remove(Entry& e) - { - MOZ_ASSERT(table); - METER(stats.removes++); - - if (e.hasCollision()) { - e.removeLive(); - removedCount++; - } else { - METER(stats.removeFrees++); - e.clearLive(); - } - entryCount--; -#ifdef JS_DEBUG - mutationCount++; -#endif - } - - void checkUnderloaded() - { - if (underloaded()) { - METER(stats.shrinks++); - (void) changeTableSize(-1, DontReportFailure); - } - } - - // Resize the table down to the largest capacity which doesn't underload the - // table. Since we call checkUnderloaded() on every remove, you only need - // to call this after a bulk removal of items done without calling remove(). - void compactIfUnderloaded() - { - int32_t resizeLog2 = 0; - uint32_t newCapacity = capacity(); - while (wouldBeUnderloaded(newCapacity, entryCount)) { - newCapacity = newCapacity >> 1; - resizeLog2--; - } - - if (resizeLog2 != 0) - (void) changeTableSize(resizeLog2, DontReportFailure); - } - - // This is identical to changeTableSize(currentSize), but without requiring - // a second table. We do this by recycling the collision bits to tell us if - // the element is already inserted or still waiting to be inserted. Since - // already-inserted elements win any conflicts, we get the same table as we - // would have gotten through random insertion order. - void rehashTableInPlace() - { - METER(stats.rehashes++); - removedCount = 0; - for (size_t i = 0; i < capacity(); ++i) - table[i].unsetCollision(); - - for (size_t i = 0; i < capacity();) { - Entry* src = &table[i]; - - if (!src->isLive() || src->hasCollision()) { - ++i; - continue; - } - - HashNumber keyHash = src->getKeyHash(); - HashNumber h1 = hash1(keyHash); - DoubleHash dh = hash2(keyHash); - Entry* tgt = &table[h1]; - while (true) { - if (!tgt->hasCollision()) { - src->swap(tgt); - tgt->setCollision(); - break; - } - - h1 = applyDoubleHash(h1, dh); - tgt = &table[h1]; - } - } - - // TODO: this algorithm leaves collision bits on *all* elements, even if - // they are on no collision path. We have the option of setting the - // collision bits correctly on a subsequent pass or skipping the rehash - // unless we are totally filled with tombstones: benchmark to find out - // which approach is best. - } - - // Note: |l| may be a reference to a piece of |u|, so this function - // must take care not to use |l| after moving |u|. - // - // Prefer to use putNewInfallible; this function does not check - // invariants. - template - void putNewInfallibleInternal(const Lookup& l, Args&&... args) - { - MOZ_ASSERT(table); - - HashNumber keyHash = prepareHash(l); - Entry* entry = &findFreeEntry(keyHash); - MOZ_ASSERT(entry); - - if (entry->isRemoved()) { - METER(stats.addOverRemoved++); - removedCount--; - keyHash |= sCollisionBit; - } - - entry->setLive(keyHash, mozilla::Forward(args)...); - entryCount++; -#ifdef JS_DEBUG - mutationCount++; -#endif - } - - public: - void clear() - { - if (mozilla::IsPod::value) { - memset(table, 0, sizeof(*table) * capacity()); - } else { - uint32_t tableCapacity = capacity(); - Entry* end = table + tableCapacity; - for (Entry* e = table; e < end; ++e) - e->clear(); - } - removedCount = 0; - entryCount = 0; -#ifdef JS_DEBUG - mutationCount++; -#endif - } - - void finish() - { -#ifdef JS_DEBUG - MOZ_ASSERT(!mEntered); -#endif - if (!table) - return; - - destroyTable(*this, table, capacity()); - table = nullptr; - gen++; - entryCount = 0; - removedCount = 0; -#ifdef JS_DEBUG - mutationCount++; -#endif - } - - Range all() const - { - MOZ_ASSERT(table); - return Range(*this, table, table + capacity()); - } - - bool empty() const - { - MOZ_ASSERT(table); - return !entryCount; - } - - uint32_t count() const - { - MOZ_ASSERT(table); - return entryCount; - } - - uint32_t capacity() const - { - MOZ_ASSERT(table); - return JS_BIT(sHashBits - hashShift); - } - - Generation generation() const - { - MOZ_ASSERT(table); - return Generation(gen); - } - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const - { - return mallocSizeOf(table); - } - - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const - { - return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf); - } - - Ptr lookup(const Lookup& l) const - { - mozilla::ReentrancyGuard g(*this); - if (!HasHash(l)) - return Ptr(); - HashNumber keyHash = prepareHash(l); - return Ptr(lookup(l, keyHash, 0), *this); - } - - Ptr readonlyThreadsafeLookup(const Lookup& l) const - { - if (!HasHash(l)) - return Ptr(); - HashNumber keyHash = prepareHash(l); - return Ptr(lookup(l, keyHash, 0), *this); - } - - AddPtr lookupForAdd(const Lookup& l) const - { - mozilla::ReentrancyGuard g(*this); - if (!EnsureHash(l)) - return AddPtr(); - HashNumber keyHash = prepareHash(l); - Entry& entry = lookup(l, keyHash, sCollisionBit); - AddPtr p(entry, *this, keyHash); - return p; - } - - template - MOZ_MUST_USE bool add(AddPtr& p, Args&&... args) - { - mozilla::ReentrancyGuard g(*this); - MOZ_ASSERT(table); - MOZ_ASSERT(!p.found()); - MOZ_ASSERT(!(p.keyHash & sCollisionBit)); - - // Check for error from ensureHash() here. - if (p.isValid()) - return false; - - // Changing an entry from removed to live does not affect whether we - // are overloaded and can be handled separately. - if (p.entry_->isRemoved()) { - if (!this->checkSimulatedOOM()) - return false; - METER(stats.addOverRemoved++); - removedCount--; - p.keyHash |= sCollisionBit; - } else { - // Preserve the validity of |p.entry_|. - RebuildStatus status = checkOverloaded(); - if (status == RehashFailed) - return false; - if (status == NotOverloaded && !this->checkSimulatedOOM()) - return false; - if (status == Rehashed) - p.entry_ = &findFreeEntry(p.keyHash); - } - - p.entry_->setLive(p.keyHash, mozilla::Forward(args)...); - entryCount++; -#ifdef JS_DEBUG - mutationCount++; - p.generation = generation(); - p.mutationCount = mutationCount; -#endif - return true; - } - - // Note: |l| may be a reference to a piece of |u|, so this function - // must take care not to use |l| after moving |u|. - template - void putNewInfallible(const Lookup& l, Args&&... args) - { - MOZ_ASSERT(!lookup(l).found()); - mozilla::ReentrancyGuard g(*this); - putNewInfallibleInternal(l, mozilla::Forward(args)...); - } - - // Note: |l| may be alias arguments in |args|, so this function must take - // care not to use |l| after moving |args|. - template - MOZ_MUST_USE bool putNew(const Lookup& l, Args&&... args) - { - if (!this->checkSimulatedOOM()) - return false; - - if (!EnsureHash(l)) - return false; - - if (checkOverloaded() == RehashFailed) - return false; - - putNewInfallible(l, mozilla::Forward(args)...); - return true; - } - - // Note: |l| may be a reference to a piece of |u|, so this function - // must take care not to use |l| after moving |u|. - template - MOZ_MUST_USE bool relookupOrAdd(AddPtr& p, const Lookup& l, Args&&... args) - { - // Check for error from ensureHash() here. - if (p.isValid()) - return false; - -#ifdef JS_DEBUG - p.generation = generation(); - p.mutationCount = mutationCount; -#endif - { - mozilla::ReentrancyGuard g(*this); - MOZ_ASSERT(prepareHash(l) == p.keyHash); // l has not been destroyed - p.entry_ = &lookup(l, p.keyHash, sCollisionBit); - } - return p.found() || add(p, mozilla::Forward(args)...); - } - - void remove(Ptr p) - { - MOZ_ASSERT(table); - mozilla::ReentrancyGuard g(*this); - MOZ_ASSERT(p.found()); - remove(*p.entry_); - checkUnderloaded(); - } - - void rekeyWithoutRehash(Ptr p, const Lookup& l, const Key& k) - { - MOZ_ASSERT(table); - mozilla::ReentrancyGuard g(*this); - MOZ_ASSERT(p.found()); - typename HashTableEntry::NonConstT t(mozilla::Move(*p)); - HashPolicy::setKey(t, const_cast(k)); - remove(*p.entry_); - putNewInfallibleInternal(l, mozilla::Move(t)); - } - - void rekeyAndMaybeRehash(Ptr p, const Lookup& l, const Key& k) - { - rekeyWithoutRehash(p, l, k); - checkOverRemoved(); - } - -#undef METER -}; - -} // namespace detail -} // namespace js - -#endif /* js_HashTable_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/HeapAPI.h b/android/armeabi-v7a/include/spidermonkey/js/HeapAPI.h deleted file mode 100644 index e37d13e9..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/HeapAPI.h +++ /dev/null @@ -1,406 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_HeapAPI_h -#define js_HeapAPI_h - -#include - -#include "jspubtd.h" - -#include "js/TraceKind.h" -#include "js/Utility.h" - -/* These values are private to the JS engine. */ -namespace js { - -JS_FRIEND_API(bool) -CurrentThreadCanAccessZone(JS::Zone* zone); - -namespace gc { - -struct Cell; - -const size_t ArenaShift = 12; -const size_t ArenaSize = size_t(1) << ArenaShift; -const size_t ArenaMask = ArenaSize - 1; - -#ifdef JS_GC_SMALL_CHUNK_SIZE -const size_t ChunkShift = 18; -#else -const size_t ChunkShift = 20; -#endif -const size_t ChunkSize = size_t(1) << ChunkShift; -const size_t ChunkMask = ChunkSize - 1; - -const size_t CellShift = 3; -const size_t CellSize = size_t(1) << CellShift; -const size_t CellMask = CellSize - 1; - -/* These are magic constants derived from actual offsets in gc/Heap.h. */ -#ifdef JS_GC_SMALL_CHUNK_SIZE -const size_t ChunkMarkBitmapOffset = 258104; -const size_t ChunkMarkBitmapBits = 31744; -#else -const size_t ChunkMarkBitmapOffset = 1032352; -const size_t ChunkMarkBitmapBits = 129024; -#endif -const size_t ChunkRuntimeOffset = ChunkSize - sizeof(void*); -const size_t ChunkTrailerSize = 2 * sizeof(uintptr_t) + sizeof(uint64_t); -const size_t ChunkLocationOffset = ChunkSize - ChunkTrailerSize; -const size_t ArenaZoneOffset = sizeof(size_t); -const size_t ArenaHeaderSize = sizeof(size_t) + 2 * sizeof(uintptr_t) + - sizeof(size_t) + sizeof(uintptr_t); - -/* - * Live objects are marked black. How many other additional colors are available - * depends on the size of the GCThing. Objects marked gray are eligible for - * cycle collection. - */ -static const uint32_t BLACK = 0; -static const uint32_t GRAY = 1; - -/* - * The "location" field in the Chunk trailer is a enum indicating various roles - * of the chunk. - */ -enum class ChunkLocation : uint32_t -{ - Invalid = 0, - Nursery = 1, - TenuredHeap = 2 -}; - -#ifdef JS_DEBUG -/* When downcasting, ensure we are actually the right type. */ -extern JS_FRIEND_API(void) -AssertGCThingHasType(js::gc::Cell* cell, JS::TraceKind kind); -#else -inline void -AssertGCThingHasType(js::gc::Cell* cell, JS::TraceKind kind) {} -#endif - -MOZ_ALWAYS_INLINE bool IsInsideNursery(const js::gc::Cell* cell); - -} /* namespace gc */ -} /* namespace js */ - -namespace JS { -struct Zone; - -/* Default size for the generational nursery in bytes. */ -const uint32_t DefaultNurseryBytes = 16 * js::gc::ChunkSize; - -/* Default maximum heap size in bytes to pass to JS_NewRuntime(). */ -const uint32_t DefaultHeapMaxBytes = 32 * 1024 * 1024; - -namespace shadow { - -struct Zone -{ - protected: - JSRuntime* const runtime_; - JSTracer* const barrierTracer_; // A pointer to the JSRuntime's |gcMarker|. - - public: - // Stack GC roots for Rooted GC pointers. - js::RootedListHeads stackRoots_; - template friend class JS::Rooted; - - bool needsIncrementalBarrier_; - - Zone(JSRuntime* runtime, JSTracer* barrierTracerArg) - : runtime_(runtime), - barrierTracer_(barrierTracerArg), - needsIncrementalBarrier_(false) - { - for (auto& stackRootPtr : stackRoots_) - stackRootPtr = nullptr; - } - - bool needsIncrementalBarrier() const { - return needsIncrementalBarrier_; - } - - JSTracer* barrierTracer() { - MOZ_ASSERT(needsIncrementalBarrier_); - MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_)); - return barrierTracer_; - } - - JSRuntime* runtimeFromMainThread() const { - MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_)); - return runtime_; - } - - // Note: Unrestricted access to the zone's runtime from an arbitrary - // thread can easily lead to races. Use this method very carefully. - JSRuntime* runtimeFromAnyThread() const { - return runtime_; - } - - static MOZ_ALWAYS_INLINE JS::shadow::Zone* asShadowZone(JS::Zone* zone) { - return reinterpret_cast(zone); - } -}; - -} /* namespace shadow */ - -/** - * A GC pointer, tagged with the trace kind. - * - * In general, a GC pointer should be stored with an exact type. This class - * is for use when that is not possible because a single pointer must point - * to several kinds of GC thing. - */ -class JS_FRIEND_API(GCCellPtr) -{ - public: - // Construction from a void* and trace kind. - GCCellPtr(void* gcthing, JS::TraceKind traceKind) : ptr(checkedCast(gcthing, traceKind)) {} - - // Automatically construct a null GCCellPtr from nullptr. - MOZ_IMPLICIT GCCellPtr(decltype(nullptr)) : ptr(checkedCast(nullptr, JS::TraceKind::Null)) {} - - // Construction from an explicit type. - template - explicit GCCellPtr(T* p) : ptr(checkedCast(p, JS::MapTypeToTraceKind::kind)) { } - explicit GCCellPtr(JSFunction* p) : ptr(checkedCast(p, JS::TraceKind::Object)) { } - explicit GCCellPtr(JSFlatString* str) : ptr(checkedCast(str, JS::TraceKind::String)) { } - explicit GCCellPtr(const Value& v); - - JS::TraceKind kind() const { - JS::TraceKind traceKind = JS::TraceKind(ptr & OutOfLineTraceKindMask); - if (uintptr_t(traceKind) != OutOfLineTraceKindMask) - return traceKind; - return outOfLineKind(); - } - - // Allow GCCellPtr to be used in a boolean context. - explicit operator bool() const { - MOZ_ASSERT(bool(asCell()) == (kind() != JS::TraceKind::Null)); - return asCell(); - } - - // Simplify checks to the kind. - template - bool is() const { return kind() == JS::MapTypeToTraceKind::kind; } - - // Conversions to more specific types must match the kind. Access to - // further refined types is not allowed directly from a GCCellPtr. - template - T& as() const { - MOZ_ASSERT(kind() == JS::MapTypeToTraceKind::kind); - // We can't use static_cast here, because the fact that JSObject - // inherits from js::gc::Cell is not part of the public API. - return *reinterpret_cast(asCell()); - } - - // Return a pointer to the cell this |GCCellPtr| refers to, or |nullptr|. - // (It would be more symmetrical with |to| for this to return a |Cell&|, but - // the result can be |nullptr|, and null references are undefined behavior.) - js::gc::Cell* asCell() const { - return reinterpret_cast(ptr & ~OutOfLineTraceKindMask); - } - - // The CC's trace logger needs an identity that is XPIDL serializable. - uint64_t unsafeAsInteger() const { - return static_cast(unsafeAsUIntPtr()); - } - // Inline mark bitmap access requires direct pointer arithmetic. - uintptr_t unsafeAsUIntPtr() const { - MOZ_ASSERT(asCell()); - MOZ_ASSERT(!js::gc::IsInsideNursery(asCell())); - return reinterpret_cast(asCell()); - } - - bool mayBeOwnedByOtherRuntime() const; - - private: - static uintptr_t checkedCast(void* p, JS::TraceKind traceKind) { - js::gc::Cell* cell = static_cast(p); - MOZ_ASSERT((uintptr_t(p) & OutOfLineTraceKindMask) == 0); - AssertGCThingHasType(cell, traceKind); - // Note: the OutOfLineTraceKindMask bits are set on all out-of-line kinds - // so that we can mask instead of branching. - MOZ_ASSERT_IF(uintptr_t(traceKind) >= OutOfLineTraceKindMask, - (uintptr_t(traceKind) & OutOfLineTraceKindMask) == OutOfLineTraceKindMask); - return uintptr_t(p) | (uintptr_t(traceKind) & OutOfLineTraceKindMask); - } - - JS::TraceKind outOfLineKind() const; - - uintptr_t ptr; -}; - -inline bool -operator==(const GCCellPtr& ptr1, const GCCellPtr& ptr2) -{ - return ptr1.asCell() == ptr2.asCell(); -} - -inline bool -operator!=(const GCCellPtr& ptr1, const GCCellPtr& ptr2) -{ - return !(ptr1 == ptr2); -} - -// Unwraps the given GCCellPtr and calls the given functor with a template -// argument of the actual type of the pointer. -template -auto -DispatchTyped(F f, GCCellPtr thing, Args&&... args) - -> decltype(f(static_cast(nullptr), mozilla::Forward(args)...)) -{ - switch (thing.kind()) { -#define JS_EXPAND_DEF(name, type, _) \ - case JS::TraceKind::name: \ - return f(&thing.as(), mozilla::Forward(args)...); - JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF); -#undef JS_EXPAND_DEF - default: - MOZ_CRASH("Invalid trace kind in DispatchTyped for GCCellPtr."); - } -} - -} /* namespace JS */ - -namespace js { -namespace gc { -namespace detail { - -static MOZ_ALWAYS_INLINE uintptr_t* -GetGCThingMarkBitmap(const uintptr_t addr) -{ - MOZ_ASSERT(addr); - const uintptr_t bmap_addr = (addr & ~ChunkMask) | ChunkMarkBitmapOffset; - return reinterpret_cast(bmap_addr); -} - -static MOZ_ALWAYS_INLINE void -GetGCThingMarkWordAndMask(const uintptr_t addr, uint32_t color, - uintptr_t** wordp, uintptr_t* maskp) -{ - MOZ_ASSERT(addr); - const size_t bit = (addr & js::gc::ChunkMask) / js::gc::CellSize + color; - MOZ_ASSERT(bit < js::gc::ChunkMarkBitmapBits); - uintptr_t* bitmap = GetGCThingMarkBitmap(addr); - const uintptr_t nbits = sizeof(*bitmap) * CHAR_BIT; - *maskp = uintptr_t(1) << (bit % nbits); - *wordp = &bitmap[bit / nbits]; -} - -static MOZ_ALWAYS_INLINE JS::Zone* -GetGCThingZone(const uintptr_t addr) -{ - MOZ_ASSERT(addr); - const uintptr_t zone_addr = (addr & ~ArenaMask) | ArenaZoneOffset; - return *reinterpret_cast(zone_addr); - -} - -static MOZ_ALWAYS_INLINE JS::shadow::Runtime* -GetCellRuntime(const Cell* cell) -{ - MOZ_ASSERT(cell); - const uintptr_t addr = uintptr_t(cell); - const uintptr_t rt_addr = (addr & ~ChunkMask) | ChunkRuntimeOffset; - return *reinterpret_cast(rt_addr); -} - -static MOZ_ALWAYS_INLINE bool -CellIsMarkedGray(const Cell* cell) -{ - MOZ_ASSERT(cell); - if (js::gc::IsInsideNursery(cell)) - return false; - - uintptr_t* word, mask; - js::gc::detail::GetGCThingMarkWordAndMask(uintptr_t(cell), js::gc::GRAY, &word, &mask); - return *word & mask; -} - -extern JS_PUBLIC_API(bool) -CellIsMarkedGrayIfKnown(const Cell* cell); - -} /* namespace detail */ - -MOZ_ALWAYS_INLINE bool -IsInsideNursery(const js::gc::Cell* cell) -{ - if (!cell) - return false; - uintptr_t addr = uintptr_t(cell); - addr &= ~js::gc::ChunkMask; - addr |= js::gc::ChunkLocationOffset; - auto location = *reinterpret_cast(addr); - MOZ_ASSERT(location == ChunkLocation::Nursery || location == ChunkLocation::TenuredHeap); - return location == ChunkLocation::Nursery; -} - -} /* namespace gc */ -} /* namespace js */ - -namespace JS { - -static MOZ_ALWAYS_INLINE Zone* -GetTenuredGCThingZone(GCCellPtr thing) -{ - MOZ_ASSERT(!js::gc::IsInsideNursery(thing.asCell())); - return js::gc::detail::GetGCThingZone(thing.unsafeAsUIntPtr()); -} - -static MOZ_ALWAYS_INLINE Zone* -GetStringZone(JSString* str) -{ - return js::gc::detail::GetGCThingZone(uintptr_t(str)); -} - -extern JS_PUBLIC_API(Zone*) -GetObjectZone(JSObject* obj); - -static MOZ_ALWAYS_INLINE bool -GCThingIsMarkedGray(GCCellPtr thing) -{ - if (thing.mayBeOwnedByOtherRuntime()) - return false; - return js::gc::detail::CellIsMarkedGrayIfKnown(thing.asCell()); -} - -extern JS_PUBLIC_API(JS::TraceKind) -GCThingTraceKind(void* thing); - -} /* namespace JS */ - -namespace js { -namespace gc { - -static MOZ_ALWAYS_INLINE bool -IsIncrementalBarrierNeededOnTenuredGCThing(JS::shadow::Runtime* rt, const JS::GCCellPtr thing) -{ - MOZ_ASSERT(thing); - MOZ_ASSERT(!js::gc::IsInsideNursery(thing.asCell())); - - // TODO: I'd like to assert !isHeapBusy() here but this gets called while we - // are tracing the heap, e.g. during memory reporting (see bug 1313318). - MOZ_ASSERT(!rt->isHeapCollecting()); - - JS::Zone* zone = JS::GetTenuredGCThingZone(thing); - return JS::shadow::Zone::asShadowZone(zone)->needsIncrementalBarrier(); -} - -/** - * Create an object providing access to the garbage collector's internal notion - * of the current state of memory (both GC heap memory and GCthing-controlled - * malloc memory. - */ -extern JS_PUBLIC_API(JSObject*) -NewMemoryInfoObject(JSContext* cx); - -} /* namespace gc */ -} /* namespace js */ - -#endif /* js_HeapAPI_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/Id.h b/android/armeabi-v7a/include/spidermonkey/js/Id.h deleted file mode 100644 index d474e784..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/Id.h +++ /dev/null @@ -1,207 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_Id_h -#define js_Id_h - -// A jsid is an identifier for a property or method of an object which is -// either a 31-bit unsigned integer, interned string or symbol. -// -// Also, there is an additional jsid value, JSID_VOID, which does not occur in -// JS scripts but may be used to indicate the absence of a valid jsid. A void -// jsid is not a valid id and only arises as an exceptional API return value, -// such as in JS_NextProperty. Embeddings must not pass JSID_VOID into JSAPI -// entry points expecting a jsid and do not need to handle JSID_VOID in hooks -// receiving a jsid except when explicitly noted in the API contract. -// -// A jsid is not implicitly convertible to or from a Value; JS_ValueToId or -// JS_IdToValue must be used instead. - -#include "jstypes.h" - -#include "js/HeapAPI.h" -#include "js/RootingAPI.h" -#include "js/TypeDecls.h" -#include "js/Utility.h" - -struct jsid -{ - size_t asBits; - bool operator==(const jsid& rhs) const { return asBits == rhs.asBits; } - bool operator!=(const jsid& rhs) const { return asBits != rhs.asBits; } -} JS_HAZ_GC_POINTER; -#define JSID_BITS(id) (id.asBits) - -#define JSID_TYPE_STRING 0x0 -#define JSID_TYPE_INT 0x1 -#define JSID_TYPE_VOID 0x2 -#define JSID_TYPE_SYMBOL 0x4 -#define JSID_TYPE_MASK 0x7 - -// Avoid using canonical 'id' for jsid parameters since this is a magic word in -// Objective-C++ which, apparently, wants to be able to #include jsapi.h. -#define id iden - -static MOZ_ALWAYS_INLINE bool -JSID_IS_STRING(jsid id) -{ - return (JSID_BITS(id) & JSID_TYPE_MASK) == 0; -} - -static MOZ_ALWAYS_INLINE JSString* -JSID_TO_STRING(jsid id) -{ - MOZ_ASSERT(JSID_IS_STRING(id)); - return (JSString*)JSID_BITS(id); -} - -/** - * Only JSStrings that have been interned via the JSAPI can be turned into - * jsids by API clients. - * - * N.B. if a jsid is backed by a string which has not been interned, that - * string must be appropriately rooted to avoid being collected by the GC. - */ -JS_PUBLIC_API(jsid) -INTERNED_STRING_TO_JSID(JSContext* cx, JSString* str); - -static MOZ_ALWAYS_INLINE bool -JSID_IS_INT(jsid id) -{ - return !!(JSID_BITS(id) & JSID_TYPE_INT); -} - -static MOZ_ALWAYS_INLINE int32_t -JSID_TO_INT(jsid id) -{ - MOZ_ASSERT(JSID_IS_INT(id)); - return ((uint32_t)JSID_BITS(id)) >> 1; -} - -#define JSID_INT_MIN 0 -#define JSID_INT_MAX INT32_MAX - -static MOZ_ALWAYS_INLINE bool -INT_FITS_IN_JSID(int32_t i) -{ - return i >= 0; -} - -static MOZ_ALWAYS_INLINE jsid -INT_TO_JSID(int32_t i) -{ - jsid id; - MOZ_ASSERT(INT_FITS_IN_JSID(i)); - JSID_BITS(id) = ((i << 1) | JSID_TYPE_INT); - return id; -} - -static MOZ_ALWAYS_INLINE bool -JSID_IS_SYMBOL(jsid id) -{ - return (JSID_BITS(id) & JSID_TYPE_MASK) == JSID_TYPE_SYMBOL && - JSID_BITS(id) != JSID_TYPE_SYMBOL; -} - -static MOZ_ALWAYS_INLINE JS::Symbol* -JSID_TO_SYMBOL(jsid id) -{ - MOZ_ASSERT(JSID_IS_SYMBOL(id)); - return (JS::Symbol*)(JSID_BITS(id) & ~(size_t)JSID_TYPE_MASK); -} - -static MOZ_ALWAYS_INLINE jsid -SYMBOL_TO_JSID(JS::Symbol* sym) -{ - jsid id; - MOZ_ASSERT(sym != nullptr); - MOZ_ASSERT((size_t(sym) & JSID_TYPE_MASK) == 0); - MOZ_ASSERT(!js::gc::IsInsideNursery(reinterpret_cast(sym))); - JSID_BITS(id) = (size_t(sym) | JSID_TYPE_SYMBOL); - return id; -} - -static MOZ_ALWAYS_INLINE bool -JSID_IS_GCTHING(jsid id) -{ - return JSID_IS_STRING(id) || JSID_IS_SYMBOL(id); -} - -static MOZ_ALWAYS_INLINE JS::GCCellPtr -JSID_TO_GCTHING(jsid id) -{ - void* thing = (void*)(JSID_BITS(id) & ~(size_t)JSID_TYPE_MASK); - if (JSID_IS_STRING(id)) - return JS::GCCellPtr(thing, JS::TraceKind::String); - MOZ_ASSERT(JSID_IS_SYMBOL(id)); - return JS::GCCellPtr(thing, JS::TraceKind::Symbol); -} - -static MOZ_ALWAYS_INLINE bool -JSID_IS_VOID(const jsid id) -{ - MOZ_ASSERT_IF(((size_t)JSID_BITS(id) & JSID_TYPE_MASK) == JSID_TYPE_VOID, - JSID_BITS(id) == JSID_TYPE_VOID); - return (size_t)JSID_BITS(id) == JSID_TYPE_VOID; -} - -static MOZ_ALWAYS_INLINE bool -JSID_IS_EMPTY(const jsid id) -{ - return (size_t)JSID_BITS(id) == JSID_TYPE_SYMBOL; -} - -extern JS_PUBLIC_DATA(const jsid) JSID_VOID; -extern JS_PUBLIC_DATA(const jsid) JSID_EMPTY; - -extern JS_PUBLIC_DATA(const JS::HandleId) JSID_VOIDHANDLE; -extern JS_PUBLIC_DATA(const JS::HandleId) JSID_EMPTYHANDLE; - -namespace JS { - -template <> -struct GCPolicy -{ - static jsid initial() { return JSID_VOID; } - static void trace(JSTracer* trc, jsid* idp, const char* name) { - js::UnsafeTraceManuallyBarrieredEdge(trc, idp, name); - } -}; - -} // namespace JS - -namespace js { - -template <> -struct BarrierMethods -{ - static void postBarrier(jsid* idp, jsid prev, jsid next) {} - static void exposeToJS(jsid id) { - if (JSID_IS_GCTHING(id)) - js::gc::ExposeGCThingToActiveJS(JSID_TO_GCTHING(id)); - } -}; - -// If the jsid is a GC pointer type, convert to that type and call |f| with -// the pointer. If the jsid is not a GC type, calls F::defaultValue. -template -auto -DispatchTyped(F f, const jsid& id, Args&&... args) - -> decltype(f(static_cast(nullptr), mozilla::Forward(args)...)) -{ - if (JSID_IS_STRING(id)) - return f(JSID_TO_STRING(id), mozilla::Forward(args)...); - if (JSID_IS_SYMBOL(id)) - return f(JSID_TO_SYMBOL(id), mozilla::Forward(args)...); - MOZ_ASSERT(!JSID_IS_GCTHING(id)); - return F::defaultValue(id); -} - -#undef id - -} // namespace js - -#endif /* js_Id_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/Initialization.h b/android/armeabi-v7a/include/spidermonkey/js/Initialization.h deleted file mode 100644 index 8a1cf910..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/Initialization.h +++ /dev/null @@ -1,125 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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/. */ - -/* SpiderMonkey initialization and shutdown APIs. */ - -#ifndef js_Initialization_h -#define js_Initialization_h - -#include "jstypes.h" - -namespace JS { -namespace detail { - -enum class InitState { Uninitialized = 0, Running, ShutDown }; - -/** - * SpiderMonkey's initialization status is tracked here, and it controls things - * that should happen only once across all runtimes. It's an API requirement - * that JS_Init (and JS_ShutDown, if called) be called in a thread-aware - * manner, so this (internal -- embedders, don't use!) variable doesn't need to - * be atomic. - */ -extern JS_PUBLIC_DATA(InitState) -libraryInitState; - -extern JS_PUBLIC_API(const char*) -InitWithFailureDiagnostic(bool isDebugBuild); - -} // namespace detail -} // namespace JS - -// These are equivalent to ICU's |UMemAllocFn|, |UMemReallocFn|, and -// |UMemFreeFn| types. The first argument (called |context| in the ICU docs) -// will always be nullptr and should be ignored. -typedef void* (*JS_ICUAllocFn)(const void*, size_t size); -typedef void* (*JS_ICUReallocFn)(const void*, void* p, size_t size); -typedef void (*JS_ICUFreeFn)(const void*, void* p); - -/** - * This function can be used to track memory used by ICU. If it is called, it - * *must* be called before JS_Init. Don't use it unless you know what you're - * doing! - */ -extern JS_PUBLIC_API(bool) -JS_SetICUMemoryFunctions(JS_ICUAllocFn allocFn, - JS_ICUReallocFn reallocFn, - JS_ICUFreeFn freeFn); - -/** - * Initialize SpiderMonkey, returning true only if initialization succeeded. - * Once this method has succeeded, it is safe to call JS_NewRuntime and other - * JSAPI methods. - * - * This method must be called before any other JSAPI method is used on any - * thread. Once it has been used, it is safe to call any JSAPI method, and it - * remains safe to do so until JS_ShutDown is correctly called. - * - * It is currently not possible to initialize SpiderMonkey multiple times (that - * is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so - * again). This restriction may eventually be lifted. - */ -inline bool -JS_Init(void) -{ -#ifdef DEBUG - return !JS::detail::InitWithFailureDiagnostic(true); -#else - return !JS::detail::InitWithFailureDiagnostic(false); -#endif -} - -/** - * A variant of JS_Init. On success it returns nullptr. On failure it returns a - * pointer to a string literal that describes how initialization failed, which - * can be useful for debugging purposes. - */ -inline const char* -JS_InitWithFailureDiagnostic(void) -{ -#ifdef DEBUG - return JS::detail::InitWithFailureDiagnostic(true); -#else - return JS::detail::InitWithFailureDiagnostic(false); -#endif -} - -/* - * Returns true if SpiderMonkey has been initialized successfully, even if it has - * possibly been shut down. - * - * Note that it is the responsibility of the embedder to call JS_Init() and - * JS_ShutDown() at the correct times, and therefore this API should ideally not - * be necessary to use. This is only intended to be used in cases where the - * embedder isn't in full control of deciding whether to initialize SpiderMonkey - * or hand off the task to another consumer. - */ -inline bool -JS_IsInitialized(void) -{ - return JS::detail::libraryInitState != JS::detail::InitState::Uninitialized; -} - -/** - * Destroy free-standing resources allocated by SpiderMonkey, not associated - * with any runtime, context, or other structure. - * - * This method should be called after all other JSAPI data has been properly - * cleaned up: every new runtime must have been destroyed, every new context - * must have been destroyed, and so on. Calling this method before all other - * resources have been destroyed has undefined behavior. - * - * Failure to call this method, at present, has no adverse effects other than - * leaking memory. This may not always be the case; it's recommended that all - * embedders call this method when all other JSAPI operations have completed. - * - * It is currently not possible to initialize SpiderMonkey multiple times (that - * is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so - * again). This restriction may eventually be lifted. - */ -extern JS_PUBLIC_API(void) -JS_ShutDown(void); - -#endif /* js_Initialization_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/LegacyIntTypes.h b/android/armeabi-v7a/include/spidermonkey/js/LegacyIntTypes.h deleted file mode 100644 index 2c8498c8..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/LegacyIntTypes.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* - * This section typedefs the old 'native' types to the new types. - * These redefinitions are provided solely to allow JSAPI users to more easily - * transition to types. They are not to be used in the JSAPI, and - * new JSAPI user code should not use them. This mapping file may eventually - * be removed from SpiderMonkey, so don't depend on it in the long run. - */ - -/* - * BEWARE: Comity with other implementers of these types is not guaranteed. - * Indeed, if you use this header and third-party code defining these - * types, *expect* to encounter either compile errors or link errors, - * depending how these types are used and on the order of inclusion. - * It is safest to use only the types. - */ -#ifndef js_LegacyIntTypes_h -#define js_LegacyIntTypes_h - -#include - -#include "js-config.h" - -typedef uint8_t uint8; -typedef uint16_t uint16; -typedef uint32_t uint32; -typedef uint64_t uint64; - -/* - * On AIX 4.3, sys/inttypes.h (which is included by sys/types.h, a very - * common header file) defines the types int8, int16, int32, and int64. - * So we don't define these four types here to avoid conflicts in case - * the code also includes sys/types.h. - */ -#if defined(AIX) && defined(HAVE_SYS_INTTYPES_H) -#include -#else -typedef int8_t int8; -typedef int16_t int16; -typedef int32_t int32; -typedef int64_t int64; -#endif /* AIX && HAVE_SYS_INTTYPES_H */ - -typedef uint8_t JSUint8; -typedef uint16_t JSUint16; -typedef uint32_t JSUint32; -typedef uint64_t JSUint64; - -typedef int8_t JSInt8; -typedef int16_t JSInt16; -typedef int32_t JSInt32; -typedef int64_t JSInt64; - -#endif /* js_LegacyIntTypes_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/MemoryMetrics.h b/android/armeabi-v7a/include/spidermonkey/js/MemoryMetrics.h deleted file mode 100644 index 9b5caa24..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/MemoryMetrics.h +++ /dev/null @@ -1,971 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_MemoryMetrics_h -#define js_MemoryMetrics_h - -// These declarations are highly likely to change in the future. Depend on them -// at your own risk. - -#include "mozilla/MemoryReporting.h" -#include "mozilla/PodOperations.h" -#include "mozilla/TypeTraits.h" - -#include - -#include "jsalloc.h" -#include "jspubtd.h" - -#include "js/HashTable.h" -#include "js/TracingAPI.h" -#include "js/Utility.h" -#include "js/Vector.h" - -class nsISupports; // Needed for ObjectPrivateVisitor. - -namespace JS { - -struct TabSizes -{ - enum Kind { - Objects, - Strings, - Private, - Other - }; - - TabSizes() { mozilla::PodZero(this); } - - void add(Kind kind, size_t n) { - switch (kind) { - case Objects: objects += n; break; - case Strings: strings += n; break; - case Private: private_ += n; break; - case Other: other += n; break; - default: MOZ_CRASH("bad TabSizes kind"); - } - } - - size_t objects; - size_t strings; - size_t private_; - size_t other; -}; - -/** These are the measurements used by Servo. */ -struct ServoSizes -{ - enum Kind { - GCHeapUsed, - GCHeapUnused, - GCHeapAdmin, - GCHeapDecommitted, - MallocHeap, - NonHeap, - Ignore - }; - - ServoSizes() { mozilla::PodZero(this); } - - void add(Kind kind, size_t n) { - switch (kind) { - case GCHeapUsed: gcHeapUsed += n; break; - case GCHeapUnused: gcHeapUnused += n; break; - case GCHeapAdmin: gcHeapAdmin += n; break; - case GCHeapDecommitted: gcHeapDecommitted += n; break; - case MallocHeap: mallocHeap += n; break; - case NonHeap: nonHeap += n; break; - case Ignore: /* do nothing */ break; - default: MOZ_CRASH("bad ServoSizes kind"); - } - } - - size_t gcHeapUsed; - size_t gcHeapUnused; - size_t gcHeapAdmin; - size_t gcHeapDecommitted; - size_t mallocHeap; - size_t nonHeap; -}; - -} // namespace JS - -namespace js { - -/** - * In memory reporting, we have concept of "sundries", line items which are too - * small to be worth reporting individually. Under some circumstances, a memory - * reporter gets tossed into the sundries bucket if it's smaller than - * MemoryReportingSundriesThreshold() bytes. - * - * We need to define this value here, rather than in the code which actually - * generates the memory reports, because NotableStringInfo uses this value. - */ -JS_FRIEND_API(size_t) MemoryReportingSundriesThreshold(); - -/** - * This hash policy avoids flattening ropes (which perturbs the site being - * measured and requires a JSContext) at the expense of doing a FULL ROPE COPY - * on every hash and match! Beware. - */ -struct InefficientNonFlatteningStringHashPolicy -{ - typedef JSString* Lookup; - static HashNumber hash(const Lookup& l); - static bool match(const JSString* const& k, const Lookup& l); -}; - -struct CStringHashPolicy -{ - typedef const char* Lookup; - static HashNumber hash(const Lookup& l); - static bool match(const char* const& k, const Lookup& l); -}; - -// This file features many classes with numerous size_t fields, and each such -// class has one or more methods that need to operate on all of these fields. -// Writing these individually is error-prone -- it's easy to add a new field -// without updating all the required methods. So we define a single macro list -// in each class to name the fields (and notable characteristics of them), and -// then use the following macros to transform those lists into the required -// methods. -// -// - The |tabKind| value is used when measuring TabSizes. -// -// - The |servoKind| value is used when measuring ServoSizes and also for -// the various sizeOfLiveGCThings() methods. -// -// In some classes, one or more of the macro arguments aren't used. We use '_' -// for those. -// -#define DECL_SIZE(tabKind, servoKind, mSize) size_t mSize; -#define ZERO_SIZE(tabKind, servoKind, mSize) mSize(0), -#define COPY_OTHER_SIZE(tabKind, servoKind, mSize) mSize(other.mSize), -#define ADD_OTHER_SIZE(tabKind, servoKind, mSize) mSize += other.mSize; -#define SUB_OTHER_SIZE(tabKind, servoKind, mSize) \ - MOZ_ASSERT(mSize >= other.mSize); \ - mSize -= other.mSize; -#define ADD_SIZE_TO_N(tabKind, servoKind, mSize) n += mSize; -#define ADD_SIZE_TO_N_IF_LIVE_GC_THING(tabKind, servoKind, mSize) \ - /* Avoid self-comparison warnings by comparing enums indirectly. */ \ - n += (mozilla::IsSame::value) \ - ? mSize \ - : 0; -#define ADD_TO_TAB_SIZES(tabKind, servoKind, mSize) sizes->add(JS::TabSizes::tabKind, mSize); -#define ADD_TO_SERVO_SIZES(tabKind, servoKind, mSize) sizes->add(JS::ServoSizes::servoKind, mSize); - -} // namespace js - -namespace JS { - -struct ClassInfo -{ -#define FOR_EACH_SIZE(macro) \ - macro(Objects, GCHeapUsed, objectsGCHeap) \ - macro(Objects, MallocHeap, objectsMallocHeapSlots) \ - macro(Objects, MallocHeap, objectsMallocHeapElementsNormal) \ - macro(Objects, MallocHeap, objectsMallocHeapElementsAsmJS) \ - macro(Objects, MallocHeap, objectsMallocHeapMisc) \ - macro(Objects, NonHeap, objectsNonHeapElementsNormal) \ - macro(Objects, NonHeap, objectsNonHeapElementsShared) \ - macro(Objects, NonHeap, objectsNonHeapElementsWasm) \ - macro(Objects, NonHeap, objectsNonHeapCodeWasm) - - ClassInfo() - : FOR_EACH_SIZE(ZERO_SIZE) - wasmGuardPages(0) - {} - - void add(const ClassInfo& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE) - } - - void subtract(const ClassInfo& other) { - FOR_EACH_SIZE(SUB_OTHER_SIZE) - } - - size_t sizeOfAllThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N) - return n; - } - - bool isNotable() const { - static const size_t NotabilityThreshold = 16 * 1024; - return sizeOfAllThings() >= NotabilityThreshold; - } - - size_t sizeOfLiveGCThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) - return n; - } - - void addToTabSizes(TabSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_TAB_SIZES) - } - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - size_t wasmGuardPages; - -#undef FOR_EACH_SIZE -}; - -struct ShapeInfo -{ -#define FOR_EACH_SIZE(macro) \ - macro(Other, GCHeapUsed, shapesGCHeapTree) \ - macro(Other, GCHeapUsed, shapesGCHeapDict) \ - macro(Other, GCHeapUsed, shapesGCHeapBase) \ - macro(Other, MallocHeap, shapesMallocHeapTreeTables) \ - macro(Other, MallocHeap, shapesMallocHeapDictTables) \ - macro(Other, MallocHeap, shapesMallocHeapTreeKids) - - ShapeInfo() - : FOR_EACH_SIZE(ZERO_SIZE) - dummy() - {} - - void add(const ShapeInfo& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE) - } - - void subtract(const ShapeInfo& other) { - FOR_EACH_SIZE(SUB_OTHER_SIZE) - } - - size_t sizeOfAllThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N) - return n; - } - - size_t sizeOfLiveGCThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) - return n; - } - - void addToTabSizes(TabSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_TAB_SIZES) - } - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE) - -#undef FOR_EACH_SIZE -}; - -/** - * Holds data about a notable class (one whose combined object and shape - * instances use more than a certain amount of memory) so we can report it - * individually. - * - * The only difference between this class and ClassInfo is that this class - * holds a copy of the filename. - */ -struct NotableClassInfo : public ClassInfo -{ - NotableClassInfo(); - NotableClassInfo(const char* className, const ClassInfo& info); - NotableClassInfo(NotableClassInfo&& info); - NotableClassInfo& operator=(NotableClassInfo&& info); - - ~NotableClassInfo() { - js_free(className_); - } - - char* className_; - - private: - NotableClassInfo(const NotableClassInfo& info) = delete; -}; - -/** Data for tracking JIT-code memory usage. */ -struct CodeSizes -{ -#define FOR_EACH_SIZE(macro) \ - macro(_, NonHeap, ion) \ - macro(_, NonHeap, baseline) \ - macro(_, NonHeap, regexp) \ - macro(_, NonHeap, other) \ - macro(_, NonHeap, unused) - - CodeSizes() - : FOR_EACH_SIZE(ZERO_SIZE) - dummy() - {} - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE) - -#undef FOR_EACH_SIZE -}; - -/** Data for tracking GC memory usage. */ -struct GCSizes -{ - // |nurseryDecommitted| is marked as NonHeap rather than GCHeapDecommitted - // because we don't consider the nursery to be part of the GC heap. -#define FOR_EACH_SIZE(macro) \ - macro(_, MallocHeap, marker) \ - macro(_, NonHeap, nurseryCommitted) \ - macro(_, MallocHeap, nurseryMallocedBuffers) \ - macro(_, MallocHeap, storeBufferVals) \ - macro(_, MallocHeap, storeBufferCells) \ - macro(_, MallocHeap, storeBufferSlots) \ - macro(_, MallocHeap, storeBufferWholeCells) \ - macro(_, MallocHeap, storeBufferGenerics) - - GCSizes() - : FOR_EACH_SIZE(ZERO_SIZE) - dummy() - {} - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE) - -#undef FOR_EACH_SIZE -}; - -/** - * This class holds information about the memory taken up by identical copies of - * a particular string. Multiple JSStrings may have their sizes aggregated - * together into one StringInfo object. Note that two strings with identical - * chars will not be aggregated together if one is a short string and the other - * is not. - */ -struct StringInfo -{ -#define FOR_EACH_SIZE(macro) \ - macro(Strings, GCHeapUsed, gcHeapLatin1) \ - macro(Strings, GCHeapUsed, gcHeapTwoByte) \ - macro(Strings, MallocHeap, mallocHeapLatin1) \ - macro(Strings, MallocHeap, mallocHeapTwoByte) - - StringInfo() - : FOR_EACH_SIZE(ZERO_SIZE) - numCopies(0) - {} - - void add(const StringInfo& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE); - numCopies++; - } - - void subtract(const StringInfo& other) { - FOR_EACH_SIZE(SUB_OTHER_SIZE); - numCopies--; - } - - bool isNotable() const { - static const size_t NotabilityThreshold = 16 * 1024; - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N) - return n >= NotabilityThreshold; - } - - size_t sizeOfLiveGCThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) - return n; - } - - void addToTabSizes(TabSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_TAB_SIZES) - } - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - uint32_t numCopies; // How many copies of the string have we seen? - -#undef FOR_EACH_SIZE -}; - -/** - * Holds data about a notable string (one which, counting all duplicates, uses - * more than a certain amount of memory) so we can report it individually. - * - * The only difference between this class and StringInfo is that - * NotableStringInfo holds a copy of some or all of the string's chars. - */ -struct NotableStringInfo : public StringInfo -{ - static const size_t MAX_SAVED_CHARS = 1024; - - NotableStringInfo(); - NotableStringInfo(JSString* str, const StringInfo& info); - NotableStringInfo(NotableStringInfo&& info); - NotableStringInfo& operator=(NotableStringInfo&& info); - - ~NotableStringInfo() { - js_free(buffer); - } - - char* buffer; - size_t length; - - private: - NotableStringInfo(const NotableStringInfo& info) = delete; -}; - -/** - * This class holds information about the memory taken up by script sources - * from a particular file. - */ -struct ScriptSourceInfo -{ -#define FOR_EACH_SIZE(macro) \ - macro(_, MallocHeap, misc) - - ScriptSourceInfo() - : FOR_EACH_SIZE(ZERO_SIZE) - numScripts(0) - {} - - void add(const ScriptSourceInfo& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE) - numScripts++; - } - - void subtract(const ScriptSourceInfo& other) { - FOR_EACH_SIZE(SUB_OTHER_SIZE) - numScripts--; - } - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - bool isNotable() const { - static const size_t NotabilityThreshold = 16 * 1024; - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N) - return n >= NotabilityThreshold; - } - - FOR_EACH_SIZE(DECL_SIZE) - uint32_t numScripts; // How many ScriptSources come from this file? (It - // can be more than one in XML files that have - // multiple scripts in CDATA sections.) -#undef FOR_EACH_SIZE -}; - -/** - * Holds data about a notable script source file (one whose combined - * script sources use more than a certain amount of memory) so we can report it - * individually. - * - * The only difference between this class and ScriptSourceInfo is that this - * class holds a copy of the filename. - */ -struct NotableScriptSourceInfo : public ScriptSourceInfo -{ - NotableScriptSourceInfo(); - NotableScriptSourceInfo(const char* filename, const ScriptSourceInfo& info); - NotableScriptSourceInfo(NotableScriptSourceInfo&& info); - NotableScriptSourceInfo& operator=(NotableScriptSourceInfo&& info); - - ~NotableScriptSourceInfo() { - js_free(filename_); - } - - char* filename_; - - private: - NotableScriptSourceInfo(const NotableScriptSourceInfo& info) = delete; -}; - -/** - * These measurements relate directly to the JSRuntime, and not to zones and - * compartments within it. - */ -struct RuntimeSizes -{ -#define FOR_EACH_SIZE(macro) \ - macro(_, MallocHeap, object) \ - macro(_, MallocHeap, atomsTable) \ - macro(_, MallocHeap, contexts) \ - macro(_, MallocHeap, temporary) \ - macro(_, MallocHeap, interpreterStack) \ - macro(_, MallocHeap, mathCache) \ - macro(_, MallocHeap, sharedImmutableStringsCache) \ - macro(_, MallocHeap, sharedIntlData) \ - macro(_, MallocHeap, uncompressedSourceCache) \ - macro(_, MallocHeap, scriptData) - - RuntimeSizes() - : FOR_EACH_SIZE(ZERO_SIZE) - scriptSourceInfo(), - code(), - gc(), - notableScriptSources() - { - allScriptSources = js_new(); - if (!allScriptSources || !allScriptSources->init()) - MOZ_CRASH("oom"); - } - - ~RuntimeSizes() { - // |allScriptSources| is usually deleted and set to nullptr before this - // destructor runs. But there are failure cases due to OOMs that may - // prevent that, so it doesn't hurt to try again here. - js_delete(allScriptSources); - } - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - scriptSourceInfo.addToServoSizes(sizes); - code.addToServoSizes(sizes); - gc.addToServoSizes(sizes); - } - - // The script source measurements in |scriptSourceInfo| are initially for - // all script sources. At the end, if the measurement granularity is - // FineGrained, we subtract the measurements of the notable script sources - // and move them into |notableScriptSources|. - FOR_EACH_SIZE(DECL_SIZE) - ScriptSourceInfo scriptSourceInfo; - CodeSizes code; - GCSizes gc; - - typedef js::HashMap ScriptSourcesHashMap; - - // |allScriptSources| is only used transiently. During the reporting phase - // it is filled with info about every script source in the runtime. It's - // then used to fill in |notableScriptSources| (which actually gets - // reported), and immediately discarded afterwards. - ScriptSourcesHashMap* allScriptSources; - js::Vector notableScriptSources; - -#undef FOR_EACH_SIZE -}; - -struct UnusedGCThingSizes -{ -#define FOR_EACH_SIZE(macro) \ - macro(Other, GCHeapUnused, object) \ - macro(Other, GCHeapUnused, script) \ - macro(Other, GCHeapUnused, lazyScript) \ - macro(Other, GCHeapUnused, shape) \ - macro(Other, GCHeapUnused, baseShape) \ - macro(Other, GCHeapUnused, objectGroup) \ - macro(Other, GCHeapUnused, string) \ - macro(Other, GCHeapUnused, symbol) \ - macro(Other, GCHeapUnused, jitcode) \ - macro(Other, GCHeapUnused, scope) - - UnusedGCThingSizes() - : FOR_EACH_SIZE(ZERO_SIZE) - dummy() - {} - - UnusedGCThingSizes(UnusedGCThingSizes&& other) - : FOR_EACH_SIZE(COPY_OTHER_SIZE) - dummy() - {} - - void addToKind(JS::TraceKind kind, intptr_t n) { - switch (kind) { - case JS::TraceKind::Object: object += n; break; - case JS::TraceKind::String: string += n; break; - case JS::TraceKind::Symbol: symbol += n; break; - case JS::TraceKind::Script: script += n; break; - case JS::TraceKind::Shape: shape += n; break; - case JS::TraceKind::BaseShape: baseShape += n; break; - case JS::TraceKind::JitCode: jitcode += n; break; - case JS::TraceKind::LazyScript: lazyScript += n; break; - case JS::TraceKind::ObjectGroup: objectGroup += n; break; - case JS::TraceKind::Scope: scope += n; break; - default: - MOZ_CRASH("Bad trace kind for UnusedGCThingSizes"); - } - } - - void addSizes(const UnusedGCThingSizes& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE) - } - - size_t totalSize() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N) - return n; - } - - void addToTabSizes(JS::TabSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_TAB_SIZES) - } - - void addToServoSizes(JS::ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE) - -#undef FOR_EACH_SIZE -}; - -struct ZoneStats -{ -#define FOR_EACH_SIZE(macro) \ - macro(Other, GCHeapUsed, symbolsGCHeap) \ - macro(Other, GCHeapAdmin, gcHeapArenaAdmin) \ - macro(Other, GCHeapUsed, lazyScriptsGCHeap) \ - macro(Other, MallocHeap, lazyScriptsMallocHeap) \ - macro(Other, GCHeapUsed, jitCodesGCHeap) \ - macro(Other, GCHeapUsed, objectGroupsGCHeap) \ - macro(Other, MallocHeap, objectGroupsMallocHeap) \ - macro(Other, GCHeapUsed, scopesGCHeap) \ - macro(Other, MallocHeap, scopesMallocHeap) \ - macro(Other, MallocHeap, typePool) \ - macro(Other, MallocHeap, baselineStubsOptimized) \ - macro(Other, MallocHeap, uniqueIdMap) \ - macro(Other, MallocHeap, shapeTables) - - ZoneStats() - : FOR_EACH_SIZE(ZERO_SIZE) - unusedGCThings(), - stringInfo(), - shapeInfo(), - extra(), - allStrings(nullptr), - notableStrings(), - isTotals(true) - {} - - ZoneStats(ZoneStats&& other) - : FOR_EACH_SIZE(COPY_OTHER_SIZE) - unusedGCThings(mozilla::Move(other.unusedGCThings)), - stringInfo(mozilla::Move(other.stringInfo)), - shapeInfo(mozilla::Move(other.shapeInfo)), - extra(other.extra), - allStrings(other.allStrings), - notableStrings(mozilla::Move(other.notableStrings)), - isTotals(other.isTotals) - { - other.allStrings = nullptr; - MOZ_ASSERT(!other.isTotals); - } - - ~ZoneStats() { - // |allStrings| is usually deleted and set to nullptr before this - // destructor runs. But there are failure cases due to OOMs that may - // prevent that, so it doesn't hurt to try again here. - js_delete(allStrings); - } - - bool initStrings(JSRuntime* rt); - - void addSizes(const ZoneStats& other) { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_OTHER_SIZE) - unusedGCThings.addSizes(other.unusedGCThings); - stringInfo.add(other.stringInfo); - shapeInfo.add(other.shapeInfo); - } - - size_t sizeOfLiveGCThings() const { - MOZ_ASSERT(isTotals); - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) - n += stringInfo.sizeOfLiveGCThings(); - n += shapeInfo.sizeOfLiveGCThings(); - return n; - } - - void addToTabSizes(JS::TabSizes* sizes) const { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_TO_TAB_SIZES) - unusedGCThings.addToTabSizes(sizes); - stringInfo.addToTabSizes(sizes); - shapeInfo.addToTabSizes(sizes); - } - - void addToServoSizes(JS::ServoSizes *sizes) const { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - unusedGCThings.addToServoSizes(sizes); - stringInfo.addToServoSizes(sizes); - shapeInfo.addToServoSizes(sizes); - } - - // These string measurements are initially for all strings. At the end, - // if the measurement granularity is FineGrained, we subtract the - // measurements of the notable script sources and move them into - // |notableStrings|. - FOR_EACH_SIZE(DECL_SIZE) - UnusedGCThingSizes unusedGCThings; - StringInfo stringInfo; - ShapeInfo shapeInfo; - void* extra; // This field can be used by embedders. - - typedef js::HashMap StringsHashMap; - - // |allStrings| is only used transiently. During the zone traversal it is - // filled with info about every string in the zone. It's then used to fill - // in |notableStrings| (which actually gets reported), and immediately - // discarded afterwards. - StringsHashMap* allStrings; - js::Vector notableStrings; - bool isTotals; - -#undef FOR_EACH_SIZE -}; - -struct CompartmentStats -{ - // We assume that |objectsPrivate| is on the malloc heap, but it's not - // actually guaranteed. But for Servo, at least, it's a moot point because - // it doesn't provide an ObjectPrivateVisitor so the value will always be - // zero. -#define FOR_EACH_SIZE(macro) \ - macro(Private, MallocHeap, objectsPrivate) \ - macro(Other, GCHeapUsed, scriptsGCHeap) \ - macro(Other, MallocHeap, scriptsMallocHeapData) \ - macro(Other, MallocHeap, baselineData) \ - macro(Other, MallocHeap, baselineStubsFallback) \ - macro(Other, MallocHeap, ionData) \ - macro(Other, MallocHeap, typeInferenceTypeScripts) \ - macro(Other, MallocHeap, typeInferenceAllocationSiteTables) \ - macro(Other, MallocHeap, typeInferenceArrayTypeTables) \ - macro(Other, MallocHeap, typeInferenceObjectTypeTables) \ - macro(Other, MallocHeap, compartmentObject) \ - macro(Other, MallocHeap, compartmentTables) \ - macro(Other, MallocHeap, innerViewsTable) \ - macro(Other, MallocHeap, lazyArrayBuffersTable) \ - macro(Other, MallocHeap, objectMetadataTable) \ - macro(Other, MallocHeap, crossCompartmentWrappersTable) \ - macro(Other, MallocHeap, regexpCompartment) \ - macro(Other, MallocHeap, savedStacksSet) \ - macro(Other, MallocHeap, varNamesSet) \ - macro(Other, MallocHeap, nonSyntacticLexicalScopesTable) \ - macro(Other, MallocHeap, jitCompartment) \ - macro(Other, MallocHeap, privateData) - - CompartmentStats() - : FOR_EACH_SIZE(ZERO_SIZE) - classInfo(), - extra(), - allClasses(nullptr), - notableClasses(), - isTotals(true) - {} - - CompartmentStats(CompartmentStats&& other) - : FOR_EACH_SIZE(COPY_OTHER_SIZE) - classInfo(mozilla::Move(other.classInfo)), - extra(other.extra), - allClasses(other.allClasses), - notableClasses(mozilla::Move(other.notableClasses)), - isTotals(other.isTotals) - { - other.allClasses = nullptr; - MOZ_ASSERT(!other.isTotals); - } - - CompartmentStats(const CompartmentStats&) = delete; // disallow copying - - ~CompartmentStats() { - // |allClasses| is usually deleted and set to nullptr before this - // destructor runs. But there are failure cases due to OOMs that may - // prevent that, so it doesn't hurt to try again here. - js_delete(allClasses); - } - - bool initClasses(JSRuntime* rt); - - void addSizes(const CompartmentStats& other) { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_OTHER_SIZE) - classInfo.add(other.classInfo); - } - - size_t sizeOfLiveGCThings() const { - MOZ_ASSERT(isTotals); - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) - n += classInfo.sizeOfLiveGCThings(); - return n; - } - - void addToTabSizes(TabSizes* sizes) const { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_TO_TAB_SIZES); - classInfo.addToTabSizes(sizes); - } - - void addToServoSizes(ServoSizes *sizes) const { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES); - classInfo.addToServoSizes(sizes); - } - - // The class measurements in |classInfo| are initially for all classes. At - // the end, if the measurement granularity is FineGrained, we subtract the - // measurements of the notable classes and move them into |notableClasses|. - FOR_EACH_SIZE(DECL_SIZE) - ClassInfo classInfo; - void* extra; // This field can be used by embedders. - - typedef js::HashMap ClassesHashMap; - - // These are similar to |allStrings| and |notableStrings| in ZoneStats. - ClassesHashMap* allClasses; - js::Vector notableClasses; - bool isTotals; - -#undef FOR_EACH_SIZE -}; - -typedef js::Vector CompartmentStatsVector; -typedef js::Vector ZoneStatsVector; - -struct RuntimeStats -{ - // |gcHeapChunkTotal| is ignored because it's the sum of all the other - // values. |gcHeapGCThings| is ignored because it's the sum of some of the - // values from the zones and compartments. Both of those values are not - // reported directly, but are just present for sanity-checking other - // values. -#define FOR_EACH_SIZE(macro) \ - macro(_, Ignore, gcHeapChunkTotal) \ - macro(_, GCHeapDecommitted, gcHeapDecommittedArenas) \ - macro(_, GCHeapUnused, gcHeapUnusedChunks) \ - macro(_, GCHeapUnused, gcHeapUnusedArenas) \ - macro(_, GCHeapAdmin, gcHeapChunkAdmin) \ - macro(_, Ignore, gcHeapGCThings) - - explicit RuntimeStats(mozilla::MallocSizeOf mallocSizeOf) - : FOR_EACH_SIZE(ZERO_SIZE) - runtime(), - cTotals(), - zTotals(), - compartmentStatsVector(), - zoneStatsVector(), - currZoneStats(nullptr), - mallocSizeOf_(mallocSizeOf) - {} - - // Here's a useful breakdown of the GC heap. - // - // - rtStats.gcHeapChunkTotal - // - decommitted bytes - // - rtStats.gcHeapDecommittedArenas (decommitted arenas in non-empty chunks) - // - unused bytes - // - rtStats.gcHeapUnusedChunks (empty chunks) - // - rtStats.gcHeapUnusedArenas (empty arenas within non-empty chunks) - // - rtStats.zTotals.unusedGCThings.totalSize() (empty GC thing slots within non-empty arenas) - // - used bytes - // - rtStats.gcHeapChunkAdmin - // - rtStats.zTotals.gcHeapArenaAdmin - // - rtStats.gcHeapGCThings (in-use GC things) - // == rtStats.zTotals.sizeOfLiveGCThings() + rtStats.cTotals.sizeOfLiveGCThings() - // - // It's possible that some arenas in empty chunks may be decommitted, but - // we don't count those under rtStats.gcHeapDecommittedArenas because (a) - // it's rare, and (b) this means that rtStats.gcHeapUnusedChunks is a - // multiple of the chunk size, which is good. - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - runtime.addToServoSizes(sizes); - } - - FOR_EACH_SIZE(DECL_SIZE) - - RuntimeSizes runtime; - - CompartmentStats cTotals; // The sum of this runtime's compartments' measurements. - ZoneStats zTotals; // The sum of this runtime's zones' measurements. - - CompartmentStatsVector compartmentStatsVector; - ZoneStatsVector zoneStatsVector; - - ZoneStats* currZoneStats; - - mozilla::MallocSizeOf mallocSizeOf_; - - virtual void initExtraCompartmentStats(JSCompartment* c, CompartmentStats* cstats) = 0; - virtual void initExtraZoneStats(JS::Zone* zone, ZoneStats* zstats) = 0; - -#undef FOR_EACH_SIZE -}; - -class ObjectPrivateVisitor -{ - public: - // Within CollectRuntimeStats, this method is called for each JS object - // that has an nsISupports pointer. - virtual size_t sizeOfIncludingThis(nsISupports* aSupports) = 0; - - // A callback that gets a JSObject's nsISupports pointer, if it has one. - // Note: this function does *not* addref |iface|. - typedef bool(*GetISupportsFun)(JSObject* obj, nsISupports** iface); - GetISupportsFun getISupports_; - - explicit ObjectPrivateVisitor(GetISupportsFun getISupports) - : getISupports_(getISupports) - {} -}; - -extern JS_PUBLIC_API(bool) -CollectRuntimeStats(JSContext* cx, RuntimeStats* rtStats, ObjectPrivateVisitor* opv, bool anonymize); - -extern JS_PUBLIC_API(size_t) -SystemCompartmentCount(JSContext* cx); - -extern JS_PUBLIC_API(size_t) -UserCompartmentCount(JSContext* cx); - -extern JS_PUBLIC_API(size_t) -PeakSizeOfTemporary(const JSContext* cx); - -extern JS_PUBLIC_API(bool) -AddSizeOfTab(JSContext* cx, JS::HandleObject obj, mozilla::MallocSizeOf mallocSizeOf, - ObjectPrivateVisitor* opv, TabSizes* sizes); - -extern JS_PUBLIC_API(bool) -AddServoSizeOf(JSContext* cx, mozilla::MallocSizeOf mallocSizeOf, - ObjectPrivateVisitor *opv, ServoSizes *sizes); - -} // namespace JS - -#undef DECL_SIZE -#undef ZERO_SIZE -#undef COPY_OTHER_SIZE -#undef ADD_OTHER_SIZE -#undef SUB_OTHER_SIZE -#undef ADD_SIZE_TO_N -#undef ADD_SIZE_TO_N_IF_LIVE_GC_THING -#undef ADD_TO_TAB_SIZES - -#endif /* js_MemoryMetrics_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/Principals.h b/android/armeabi-v7a/include/spidermonkey/js/Principals.h deleted file mode 100644 index cf6c813a..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/Principals.h +++ /dev/null @@ -1,132 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* JSPrincipals and related interfaces. */ - -#ifndef js_Principals_h -#define js_Principals_h - -#include "mozilla/Atomics.h" - -#include - -#include "jspubtd.h" - -#include "js/StructuredClone.h" - -namespace js { - struct PerformanceGroup; -} // namespace js - -struct JSPrincipals { - /* Don't call "destroy"; use reference counting macros below. */ - mozilla::Atomic refcount; - -#ifdef JS_DEBUG - /* A helper to facilitate principals debugging. */ - uint32_t debugToken; -#endif - - JSPrincipals() : refcount(0) {} - - void setDebugToken(uint32_t token) { -# ifdef JS_DEBUG - debugToken = token; -# endif - } - - /* - * Write the principals with the given |writer|. Return false on failure, - * true on success. - */ - virtual bool write(JSContext* cx, JSStructuredCloneWriter* writer) = 0; - - /* - * This is not defined by the JS engine but should be provided by the - * embedding. - */ - JS_PUBLIC_API(void) dump(); -}; - -extern JS_PUBLIC_API(void) -JS_HoldPrincipals(JSPrincipals* principals); - -extern JS_PUBLIC_API(void) -JS_DropPrincipals(JSContext* cx, JSPrincipals* principals); - -// Return whether the first principal subsumes the second. The exact meaning of -// 'subsumes' is left up to the browser. Subsumption is checked inside the JS -// engine when determining, e.g., which stack frames to display in a backtrace. -typedef bool -(* JSSubsumesOp)(JSPrincipals* first, JSPrincipals* second); - -/* - * Used to check if a CSP instance wants to disable eval() and friends. - * See js_CheckCSPPermitsJSAction() in jsobj. - */ -typedef bool -(* JSCSPEvalChecker)(JSContext* cx); - -struct JSSecurityCallbacks { - JSCSPEvalChecker contentSecurityPolicyAllows; - JSSubsumesOp subsumes; -}; - -extern JS_PUBLIC_API(void) -JS_SetSecurityCallbacks(JSContext* cx, const JSSecurityCallbacks* callbacks); - -extern JS_PUBLIC_API(const JSSecurityCallbacks*) -JS_GetSecurityCallbacks(JSContext* cx); - -/* - * Code running with "trusted" principals will be given a deeper stack - * allocation than ordinary scripts. This allows trusted script to run after - * untrusted script has exhausted the stack. This function sets the - * runtime-wide trusted principal. - * - * This principals is not held (via JS_HoldPrincipals/JS_DropPrincipals). - * Instead, the caller must ensure that the given principals stays valid for as - * long as 'cx' may point to it. If the principals would be destroyed before - * 'cx', JS_SetTrustedPrincipals must be called again, passing nullptr for - * 'prin'. - */ -extern JS_PUBLIC_API(void) -JS_SetTrustedPrincipals(JSContext* cx, JSPrincipals* prin); - -typedef void -(* JSDestroyPrincipalsOp)(JSPrincipals* principals); - -/* - * Initialize the callback that is called to destroy JSPrincipals instance - * when its reference counter drops to zero. The initialization can be done - * only once per JS runtime. - */ -extern JS_PUBLIC_API(void) -JS_InitDestroyPrincipalsCallback(JSContext* cx, JSDestroyPrincipalsOp destroyPrincipals); - -/* - * Read a JSPrincipals instance from the given |reader| and initialize the out - * paratemer |outPrincipals| to the JSPrincipals instance read. - * - * Return false on failure, true on success. The |outPrincipals| parameter - * should not be modified if false is returned. - * - * The caller is not responsible for calling JS_HoldPrincipals on the resulting - * JSPrincipals instance, the JSReadPrincipalsOp must increment the refcount of - * the resulting JSPrincipals on behalf of the caller. - */ -using JSReadPrincipalsOp = bool (*)(JSContext* cx, JSStructuredCloneReader* reader, - JSPrincipals** outPrincipals); - -/* - * Initialize the callback that is called to read JSPrincipals instances from a - * buffer. The initialization can be done only once per JS runtime. - */ -extern JS_PUBLIC_API(void) -JS_InitReadPrincipalsCallback(JSContext* cx, JSReadPrincipalsOp read); - - -#endif /* js_Principals_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/ProfilingFrameIterator.h b/android/armeabi-v7a/include/spidermonkey/js/ProfilingFrameIterator.h deleted file mode 100644 index d082213d..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/ProfilingFrameIterator.h +++ /dev/null @@ -1,203 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_ProfilingFrameIterator_h -#define js_ProfilingFrameIterator_h - -#include "mozilla/Alignment.h" -#include "mozilla/Maybe.h" - -#include "jsbytecode.h" -#include "js/GCAPI.h" -#include "js/TypeDecls.h" -#include "js/Utility.h" - -struct JSContext; -struct JSRuntime; -class JSScript; - -namespace js { - class Activation; - namespace jit { - class JitActivation; - class JitProfilingFrameIterator; - class JitcodeGlobalEntry; - } // namespace jit - namespace wasm { - class ProfilingFrameIterator; - } // namespace wasm -} // namespace js - -namespace JS { - -struct ForEachTrackedOptimizationAttemptOp; -struct ForEachTrackedOptimizationTypeInfoOp; - -// This iterator can be used to walk the stack of a thread suspended at an -// arbitrary pc. To provide acurate results, profiling must have been enabled -// (via EnableRuntimeProfilingStack) before executing the callstack being -// unwound. -// -// Note that the caller must not do anything that could cause GC to happen while -// the iterator is alive, since this could invalidate Ion code and cause its -// contents to become out of date. -class JS_PUBLIC_API(ProfilingFrameIterator) -{ - JSRuntime* rt_; - uint32_t sampleBufferGen_; - js::Activation* activation_; - - // When moving past a JitActivation, we need to save the prevJitTop - // from it to use as the exit-frame pointer when the next caller jit - // activation (if any) comes around. - void* savedPrevJitTop_; - - JS::AutoCheckCannotGC nogc_; - - static const unsigned StorageSpace = 8 * sizeof(void*); - mozilla::AlignedStorage storage_; - js::wasm::ProfilingFrameIterator& wasmIter() { - MOZ_ASSERT(!done()); - MOZ_ASSERT(isWasm()); - return *reinterpret_cast(storage_.addr()); - } - const js::wasm::ProfilingFrameIterator& wasmIter() const { - MOZ_ASSERT(!done()); - MOZ_ASSERT(isWasm()); - return *reinterpret_cast(storage_.addr()); - } - - js::jit::JitProfilingFrameIterator& jitIter() { - MOZ_ASSERT(!done()); - MOZ_ASSERT(isJit()); - return *reinterpret_cast(storage_.addr()); - } - - const js::jit::JitProfilingFrameIterator& jitIter() const { - MOZ_ASSERT(!done()); - MOZ_ASSERT(isJit()); - return *reinterpret_cast(storage_.addr()); - } - - void settle(); - - bool hasSampleBufferGen() const { - return sampleBufferGen_ != UINT32_MAX; - } - - public: - struct RegisterState - { - RegisterState() : pc(nullptr), sp(nullptr), lr(nullptr) {} - void* pc; - void* sp; - void* lr; - }; - - ProfilingFrameIterator(JSContext* cx, const RegisterState& state, - uint32_t sampleBufferGen = UINT32_MAX); - ~ProfilingFrameIterator(); - void operator++(); - bool done() const { return !activation_; } - - // Assuming the stack grows down (we do), the return value: - // - always points into the stack - // - is weakly monotonically increasing (may be equal for successive frames) - // - will compare greater than newer native and psuedo-stack frame addresses - // and less than older native and psuedo-stack frame addresses - void* stackAddress() const; - - enum FrameKind - { - Frame_Baseline, - Frame_Ion, - Frame_Wasm - }; - - struct Frame - { - FrameKind kind; - void* stackAddress; - void* returnAddress; - void* activation; - UniqueChars label; - }; - - bool isWasm() const; - bool isJit() const; - - uint32_t extractStack(Frame* frames, uint32_t offset, uint32_t end) const; - - mozilla::Maybe getPhysicalFrameWithoutLabel() const; - - private: - mozilla::Maybe getPhysicalFrameAndEntry(js::jit::JitcodeGlobalEntry* entry) const; - - void iteratorConstruct(const RegisterState& state); - void iteratorConstruct(); - void iteratorDestroy(); - bool iteratorDone(); -}; - -JS_FRIEND_API(bool) -IsProfilingEnabledForContext(JSContext* cx); - -/** - * After each sample run, this method should be called with the latest sample - * buffer generation, and the lapCount. It will update corresponding fields on - * JSRuntime. - * - * See fields |profilerSampleBufferGen|, |profilerSampleBufferLapCount| on - * JSRuntime for documentation about what these values are used for. - */ -JS_FRIEND_API(void) -UpdateJSContextProfilerSampleBufferGen(JSContext* cx, uint32_t generation, - uint32_t lapCount); - -struct ForEachProfiledFrameOp -{ - // A handle to the underlying JitcodeGlobalEntry, so as to avoid repeated - // lookups on JitcodeGlobalTable. - class MOZ_STACK_CLASS FrameHandle - { - friend JS_PUBLIC_API(void) ForEachProfiledFrame(JSContext* cx, void* addr, - ForEachProfiledFrameOp& op); - - JSRuntime* rt_; - js::jit::JitcodeGlobalEntry& entry_; - void* addr_; - void* canonicalAddr_; - const char* label_; - uint32_t depth_; - mozilla::Maybe optsIndex_; - - FrameHandle(JSRuntime* rt, js::jit::JitcodeGlobalEntry& entry, void* addr, - const char* label, uint32_t depth); - - void updateHasTrackedOptimizations(); - - public: - const char* label() const { return label_; } - uint32_t depth() const { return depth_; } - bool hasTrackedOptimizations() const { return optsIndex_.isSome(); } - void* canonicalAddress() const { return canonicalAddr_; } - - ProfilingFrameIterator::FrameKind frameKind() const; - void forEachOptimizationAttempt(ForEachTrackedOptimizationAttemptOp& op, - JSScript** scriptOut, jsbytecode** pcOut) const; - void forEachOptimizationTypeInfo(ForEachTrackedOptimizationTypeInfoOp& op) const; - }; - - // Called once per frame. - virtual void operator()(const FrameHandle& frame) = 0; -}; - -JS_PUBLIC_API(void) -ForEachProfiledFrame(JSContext* cx, void* addr, ForEachProfiledFrameOp& op); - -} // namespace JS - -#endif /* js_ProfilingFrameIterator_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/ProfilingStack.h b/android/armeabi-v7a/include/spidermonkey/js/ProfilingStack.h deleted file mode 100644 index 6b6c9701..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/ProfilingStack.h +++ /dev/null @@ -1,208 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_ProfilingStack_h -#define js_ProfilingStack_h - -#include "jsbytecode.h" -#include "jstypes.h" -#include "js/TypeDecls.h" - -#include "js/Utility.h" - -struct JSRuntime; -class JSTracer; - -namespace js { - -// A call stack can be specified to the JS engine such that all JS entry/exits -// to functions push/pop an entry to/from the specified stack. -// -// For more detailed information, see vm/SPSProfiler.h. -// -class ProfileEntry -{ - // All fields are marked volatile to prevent the compiler from re-ordering - // instructions. Namely this sequence: - // - // entry[size] = ...; - // size++; - // - // If the size modification were somehow reordered before the stores, then - // if a sample were taken it would be examining bogus information. - // - // A ProfileEntry represents both a C++ profile entry and a JS one. - - // Descriptive string of this entry. - const char * volatile string; - - // Stack pointer for non-JS entries, the script pointer otherwise. - void * volatile spOrScript; - - // Line number for non-JS entries, the bytecode offset otherwise. - int32_t volatile lineOrPcOffset; - - // General purpose storage describing this frame. - uint32_t volatile flags_; - - public: - // These traits are bit masks. Make sure they're powers of 2. - enum Flags : uint32_t { - // Indicate whether a profile entry represents a CPP frame. If not set, - // a JS frame is assumed by default. You're not allowed to publicly - // change the frame type. Instead, initialize the ProfileEntry as either - // a JS or CPP frame with `initJsFrame` or `initCppFrame` respectively. - IS_CPP_ENTRY = 0x01, - - // Indicate that copying the frame label is not necessary when taking a - // sample of the pseudostack. - FRAME_LABEL_COPY = 0x02, - - // This ProfileEntry is a dummy entry indicating the start of a run - // of JS pseudostack entries. - BEGIN_PSEUDO_JS = 0x04, - - // This flag is used to indicate that an interpreter JS entry has OSR-ed - // into baseline. - OSR = 0x08, - - // Union of all flags. - ALL = IS_CPP_ENTRY|FRAME_LABEL_COPY|BEGIN_PSEUDO_JS|OSR, - - // Mask for removing all flags except the category information. - CATEGORY_MASK = ~ALL - }; - - // Keep these in sync with devtools/client/performance/modules/categories.js - enum class Category : uint32_t { - OTHER = 0x10, - CSS = 0x20, - JS = 0x40, - GC = 0x80, - CC = 0x100, - NETWORK = 0x200, - GRAPHICS = 0x400, - STORAGE = 0x800, - EVENTS = 0x1000, - - FIRST = OTHER, - LAST = EVENTS - }; - - static_assert((static_cast(Category::FIRST) & Flags::ALL) == 0, - "The category bitflags should not intersect with the other flags!"); - - // All of these methods are marked with the 'volatile' keyword because SPS's - // representation of the stack is stored such that all ProfileEntry - // instances are volatile. These methods would not be available unless they - // were marked as volatile as well. - - bool isCpp() const volatile { return hasFlag(IS_CPP_ENTRY); } - bool isJs() const volatile { return !isCpp(); } - - bool isCopyLabel() const volatile { return hasFlag(FRAME_LABEL_COPY); } - - void setLabel(const char* aString) volatile { string = aString; } - const char* label() const volatile { return string; } - - void initJsFrame(JSScript* aScript, jsbytecode* aPc) volatile { - flags_ = 0; - spOrScript = aScript; - setPC(aPc); - } - void initCppFrame(void* aSp, uint32_t aLine) volatile { - flags_ = IS_CPP_ENTRY; - spOrScript = aSp; - lineOrPcOffset = static_cast(aLine); - } - - void setFlag(uint32_t flag) volatile { - MOZ_ASSERT(flag != IS_CPP_ENTRY); - flags_ |= flag; - } - void unsetFlag(uint32_t flag) volatile { - MOZ_ASSERT(flag != IS_CPP_ENTRY); - flags_ &= ~flag; - } - bool hasFlag(uint32_t flag) const volatile { - return bool(flags_ & flag); - } - - uint32_t flags() const volatile { - return flags_; - } - - uint32_t category() const volatile { - return flags_ & CATEGORY_MASK; - } - void setCategory(Category c) volatile { - MOZ_ASSERT(c >= Category::FIRST); - MOZ_ASSERT(c <= Category::LAST); - flags_ &= ~CATEGORY_MASK; - setFlag(static_cast(c)); - } - - void setOSR() volatile { - MOZ_ASSERT(isJs()); - setFlag(OSR); - } - void unsetOSR() volatile { - MOZ_ASSERT(isJs()); - unsetFlag(OSR); - } - bool isOSR() const volatile { - return hasFlag(OSR); - } - - void* stackAddress() const volatile { - MOZ_ASSERT(!isJs()); - return spOrScript; - } - JSScript* script() const volatile; - uint32_t line() const volatile { - MOZ_ASSERT(!isJs()); - return static_cast(lineOrPcOffset); - } - - // Note that the pointer returned might be invalid. - JSScript* rawScript() const volatile { - MOZ_ASSERT(isJs()); - return (JSScript*)spOrScript; - } - - // We can't know the layout of JSScript, so look in vm/SPSProfiler.cpp. - JS_FRIEND_API(jsbytecode*) pc() const volatile; - JS_FRIEND_API(void) setPC(jsbytecode* pc) volatile; - - void trace(JSTracer* trc); - - // The offset of a pc into a script's code can actually be 0, so to - // signify a nullptr pc, use a -1 index. This is checked against in - // pc() and setPC() to set/get the right pc. - static const int32_t NullPCOffset = -1; - - static size_t offsetOfLabel() { return offsetof(ProfileEntry, string); } - static size_t offsetOfSpOrScript() { return offsetof(ProfileEntry, spOrScript); } - static size_t offsetOfLineOrPcOffset() { return offsetof(ProfileEntry, lineOrPcOffset); } - static size_t offsetOfFlags() { return offsetof(ProfileEntry, flags_); } -}; - -JS_FRIEND_API(void) -SetContextProfilingStack(JSContext* cx, ProfileEntry* stack, uint32_t* size, - uint32_t max); - -JS_FRIEND_API(void) -EnableContextProfilingStack(JSContext* cx, bool enabled); - -JS_FRIEND_API(void) -RegisterContextProfilingEventMarker(JSContext* cx, void (*fn)(const char*)); - -JS_FRIEND_API(jsbytecode*) -ProfilingGetPC(JSContext* cx, JSScript* script, void* ip); - -} // namespace js - -#endif /* js_ProfilingStack_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/Proxy.h b/android/armeabi-v7a/include/spidermonkey/js/Proxy.h deleted file mode 100644 index 3e95538d..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/Proxy.h +++ /dev/null @@ -1,632 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_Proxy_h -#define js_Proxy_h - -#include "mozilla/Maybe.h" - -#include "jsfriendapi.h" - -#include "js/CallNonGenericMethod.h" -#include "js/Class.h" - -namespace js { - -using JS::AutoIdVector; -using JS::CallArgs; -using JS::Handle; -using JS::HandleId; -using JS::HandleObject; -using JS::HandleValue; -using JS::IsAcceptableThis; -using JS::MutableHandle; -using JS::MutableHandleObject; -using JS::MutableHandleValue; -using JS::NativeImpl; -using JS::ObjectOpResult; -using JS::PrivateValue; -using JS::PropertyDescriptor; -using JS::Value; - -class RegExpGuard; -class JS_FRIEND_API(Wrapper); - -/* - * A proxy is a JSObject with highly customizable behavior. ES6 specifies a - * single kind of proxy, but the customization mechanisms we use to implement - * ES6 Proxy objects are also useful wherever an object with weird behavior is - * wanted. Proxies are used to implement: - * - * - the scope objects used by the Debugger's frame.eval() method - * (see js::GetDebugScopeForFunction) - * - * - the khuey hack, whereby a whole compartment can be blown away - * even if other compartments hold references to objects in it - * (see js::NukeCrossCompartmentWrappers) - * - * - XPConnect security wrappers, which protect chrome from malicious content - * (js/xpconnect/wrappers) - * - * - DOM objects with special property behavior, like named getters - * (dom/bindings/Codegen.py generates these proxies from WebIDL) - * - * - semi-transparent use of objects that live in other processes - * (CPOWs, implemented in js/ipc) - * - * ### Proxies and internal methods - * - * ES2016 specifies 13 internal methods. The runtime semantics of just - * about everything a script can do to an object is specified in terms - * of these internal methods. For example: - * - * JS code ES6 internal method that gets called - * --------------------------- -------------------------------- - * obj.prop obj.[[Get]](obj, "prop") - * "prop" in obj obj.[[HasProperty]]("prop") - * new obj() obj.[[Construct]]() - * - * With regard to the implementation of these internal methods, there are three - * very different kinds of object in SpiderMonkey. - * - * 1. Native objects' internal methods are implemented in vm/NativeObject.cpp, - * with duplicate (but functionally identical) implementations scattered - * through the ICs and JITs. - * - * 2. Certain non-native objects have internal methods that are implemented as - * magical js::ObjectOps hooks. We're trying to get rid of these. - * - * 3. All other objects are proxies. A proxy's internal methods are - * implemented in C++, as the virtual methods of a C++ object stored on the - * proxy, known as its handler. - * - * This means that just about anything you do to a proxy will end up going - * through a C++ virtual method call. Possibly several. There's no reason the - * JITs and ICs can't specialize for particular proxies, based on the handler; - * but currently we don't do much of this, so the virtual method overhead - * typically is actually incurred. - * - * ### The proxy handler hierarchy - * - * A major use case for proxies is to forward each internal method call to - * another object, known as its target. The target can be an arbitrary JS - * object. Not every proxy has the notion of a target, however. - * - * To minimize code duplication, a set of abstract proxy handler classes is - * provided, from which other handlers may inherit. These abstract classes are - * organized in the following hierarchy: - * - * BaseProxyHandler - * | - * Wrapper // has a target, can be unwrapped to reveal - * | // target (see js::CheckedUnwrap) - * | - * CrossCompartmentWrapper // target is in another compartment; - * // implements membrane between compartments - * - * Example: Some DOM objects (including all the arraylike DOM objects) are - * implemented as proxies. Since these objects don't need to forward operations - * to any underlying JS object, DOMJSProxyHandler directly subclasses - * BaseProxyHandler. - * - * Gecko's security wrappers are examples of cross-compartment wrappers. - * - * ### Proxy prototype chains - * - * In addition to the normal methods, there are two models for proxy prototype - * chains. - * - * 1. Proxies can use the standard prototype mechanism used throughout the - * engine. To do so, simply pass a prototype to NewProxyObject() at - * creation time. All prototype accesses will then "just work" to treat the - * proxy as a "normal" object. - * - * 2. A proxy can implement more complicated prototype semantics (if, for - * example, it wants to delegate the prototype lookup to a wrapped object) - * by passing Proxy::LazyProto as the prototype at create time. This - * guarantees that the getPrototype() handler method will be called every - * time the object's prototype chain is accessed. - * - * This system is implemented with two methods: {get,set}Prototype. The - * default implementation of setPrototype throws a TypeError. Since it is - * not possible to create an object without a sense of prototype chain, - * handlers must implement getPrototype if opting in to the dynamic - * prototype system. - */ - -/* - * BaseProxyHandler is the most generic kind of proxy handler. It does not make - * any assumptions about the target. Consequently, it does not provide any - * default implementation for most methods. As a convenience, a few high-level - * methods, like get() and set(), are given default implementations that work by - * calling the low-level methods, like getOwnPropertyDescriptor(). - * - * Important: If you add a method here, you should probably also add a - * Proxy::foo entry point with an AutoEnterPolicy. If you don't, you need an - * explicit override for the method in SecurityWrapper. See bug 945826 comment 0. - */ -class JS_FRIEND_API(BaseProxyHandler) -{ - /* - * Sometimes it's desirable to designate groups of proxy handlers as "similar". - * For this, we use the notion of a "family": A consumer-provided opaque pointer - * that designates the larger group to which this proxy belongs. - * - * If it will never be important to differentiate this proxy from others as - * part of a distinct group, nullptr may be used instead. - */ - const void* mFamily; - - /* - * Proxy handlers can use mHasPrototype to request the following special - * treatment from the JS engine: - * - * - When mHasPrototype is true, the engine never calls these methods: - * getPropertyDescriptor, has, set, enumerate, iterate. Instead, for - * these operations, it calls the "own" methods like - * getOwnPropertyDescriptor, hasOwn, defineProperty, - * getOwnEnumerablePropertyKeys, etc., and consults the prototype chain - * if needed. - * - * - When mHasPrototype is true, the engine calls handler->get() only if - * handler->hasOwn() says an own property exists on the proxy. If not, - * it consults the prototype chain. - * - * This is useful because it frees the ProxyHandler from having to implement - * any behavior having to do with the prototype chain. - */ - bool mHasPrototype; - - /* - * All proxies indicate whether they have any sort of interesting security - * policy that might prevent the caller from doing something it wants to - * the object. In the case of wrappers, this distinction is used to - * determine whether the caller may strip off the wrapper if it so desires. - */ - bool mHasSecurityPolicy; - - public: - explicit constexpr BaseProxyHandler(const void* aFamily, bool aHasPrototype = false, - bool aHasSecurityPolicy = false) - : mFamily(aFamily), - mHasPrototype(aHasPrototype), - mHasSecurityPolicy(aHasSecurityPolicy) - { } - - bool hasPrototype() const { - return mHasPrototype; - } - - bool hasSecurityPolicy() const { - return mHasSecurityPolicy; - } - - inline const void* family() const { - return mFamily; - } - static size_t offsetOfFamily() { - return offsetof(BaseProxyHandler, mFamily); - } - - virtual bool finalizeInBackground(const Value& priv) const { - /* - * Called on creation of a proxy to determine whether its finalize - * method can be finalized on the background thread. - */ - return true; - } - - virtual bool canNurseryAllocate() const { - /* - * Nursery allocation is allowed if and only if it is safe to not - * run |finalize| when the ProxyObject dies. - */ - return false; - } - - /* Policy enforcement methods. - * - * enter() allows the policy to specify whether the caller may perform |act| - * on the proxy's |id| property. In the case when |act| is CALL, |id| is - * generally JSID_VOID. - * - * The |act| parameter to enter() specifies the action being performed. - * If |bp| is false, the method suggests that the caller throw (though it - * may still decide to squelch the error). - * - * We make these OR-able so that assertEnteredPolicy can pass a union of them. - * For example, get{,Own}PropertyDescriptor is invoked by calls to ::get() - * ::set(), in addition to being invoked on its own, so there are several - * valid Actions that could have been entered. - */ - typedef uint32_t Action; - enum { - NONE = 0x00, - GET = 0x01, - SET = 0x02, - CALL = 0x04, - ENUMERATE = 0x08, - GET_PROPERTY_DESCRIPTOR = 0x10 - }; - - virtual bool enter(JSContext* cx, HandleObject wrapper, HandleId id, Action act, - bool* bp) const; - - /* Standard internal methods. */ - virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id, - MutableHandle desc) const = 0; - virtual bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id, - Handle desc, - ObjectOpResult& result) const = 0; - virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy, - AutoIdVector& props) const = 0; - virtual bool delete_(JSContext* cx, HandleObject proxy, HandleId id, - ObjectOpResult& result) const = 0; - - /* - * These methods are standard, but the engine does not normally call them. - * They're opt-in. See "Proxy prototype chains" above. - * - * getPrototype() crashes if called. setPrototype() throws a TypeError. - */ - virtual bool getPrototype(JSContext* cx, HandleObject proxy, MutableHandleObject protop) const; - virtual bool setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto, - ObjectOpResult& result) const; - - /* Non-standard but conceptual kin to {g,s}etPrototype, so these live here. */ - virtual bool getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy, bool* isOrdinary, - MutableHandleObject protop) const = 0; - virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy, bool* succeeded) const; - - virtual bool preventExtensions(JSContext* cx, HandleObject proxy, - ObjectOpResult& result) const = 0; - virtual bool isExtensible(JSContext* cx, HandleObject proxy, bool* extensible) const = 0; - - /* - * These standard internal methods are implemented, as a convenience, so - * that ProxyHandler subclasses don't have to provide every single method. - * - * The base-class implementations work by calling getPropertyDescriptor(). - * They do not follow any standard. When in doubt, override them. - */ - virtual bool has(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const; - virtual bool get(JSContext* cx, HandleObject proxy, HandleValue receiver, - HandleId id, MutableHandleValue vp) const; - virtual bool set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v, - HandleValue receiver, ObjectOpResult& result) const; - - /* - * [[Call]] and [[Construct]] are standard internal methods but according - * to the spec, they are not present on every object. - * - * SpiderMonkey never calls a proxy's call()/construct() internal method - * unless isCallable()/isConstructor() returns true for that proxy. - * - * BaseProxyHandler::isCallable()/isConstructor() always return false, and - * BaseProxyHandler::call()/construct() crash if called. So if you're - * creating a kind of that is never callable, you don't have to override - * anything, but otherwise you probably want to override all four. - */ - virtual bool call(JSContext* cx, HandleObject proxy, const CallArgs& args) const; - virtual bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const; - - /* SpiderMonkey extensions. */ - virtual bool enumerate(JSContext* cx, HandleObject proxy, MutableHandleObject objp) const; - virtual bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id, - MutableHandle desc) const; - virtual bool hasOwn(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const; - virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject proxy, - AutoIdVector& props) const; - virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl, - const CallArgs& args) const; - virtual bool hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v, bool* bp) const; - virtual bool getBuiltinClass(JSContext* cx, HandleObject proxy, - ESClass* cls) const; - virtual bool isArray(JSContext* cx, HandleObject proxy, JS::IsArrayAnswer* answer) const; - virtual const char* className(JSContext* cx, HandleObject proxy) const; - virtual JSString* fun_toString(JSContext* cx, HandleObject proxy, unsigned indent) const; - virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const; - virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const; - virtual void trace(JSTracer* trc, JSObject* proxy) const; - virtual void finalize(JSFreeOp* fop, JSObject* proxy) const; - virtual void objectMoved(JSObject* proxy, const JSObject* old) const; - - // Allow proxies, wrappers in particular, to specify callability at runtime. - // Note: These do not take const JSObject*, but they do in spirit. - // We are not prepared to do this, as there's little const correctness - // in the external APIs that handle proxies. - virtual bool isCallable(JSObject* obj) const; - virtual bool isConstructor(JSObject* obj) const; - - // These two hooks must be overridden, or not overridden, in tandem -- no - // overriding just one! - virtual bool watch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, - JS::HandleObject callable) const; - virtual bool unwatch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id) const; - - virtual bool getElements(JSContext* cx, HandleObject proxy, uint32_t begin, uint32_t end, - ElementAdder* adder) const; - - /* See comment for weakmapKeyDelegateOp in js/Class.h. */ - virtual JSObject* weakmapKeyDelegate(JSObject* proxy) const; - virtual bool isScripted() const { return false; } -}; - -extern JS_FRIEND_DATA(const js::Class* const) ProxyClassPtr; - -inline bool IsProxy(const JSObject* obj) -{ - return GetObjectClass(obj)->isProxy(); -} - -namespace detail { -const uint32_t PROXY_EXTRA_SLOTS = 2; - -// Layout of the values stored by a proxy. Note that API clients require the -// private slot to be the first slot in the proxy's values, so that the private -// slot can be accessed in the same fashion as the first reserved slot, via -// {Get,Set}ReservedOrProxyPrivateSlot. - -struct ProxyValueArray -{ - Value privateSlot; - Value extraSlots[PROXY_EXTRA_SLOTS]; - - ProxyValueArray() - : privateSlot(JS::UndefinedValue()) - { - for (size_t i = 0; i < PROXY_EXTRA_SLOTS; i++) - extraSlots[i] = JS::UndefinedValue(); - } -}; - -// All proxies share the same data layout. Following the object's shape and -// type, the proxy has a ProxyDataLayout structure with a pointer to an array -// of values and the proxy's handler. This is designed both so that proxies can -// be easily swapped with other objects (via RemapWrapper) and to mimic the -// layout of other objects (proxies and other objects have the same size) so -// that common code can access either type of object. -// -// See GetReservedOrProxyPrivateSlot below. -struct ProxyDataLayout -{ - ProxyValueArray* values; - const BaseProxyHandler* handler; -}; - -const uint32_t ProxyDataOffset = 2 * sizeof(void*); - -inline ProxyDataLayout* -GetProxyDataLayout(JSObject* obj) -{ - MOZ_ASSERT(IsProxy(obj)); - return reinterpret_cast(reinterpret_cast(obj) + ProxyDataOffset); -} - -inline const ProxyDataLayout* -GetProxyDataLayout(const JSObject* obj) -{ - MOZ_ASSERT(IsProxy(obj)); - return reinterpret_cast(reinterpret_cast(obj) + - ProxyDataOffset); -} -} // namespace detail - -inline const BaseProxyHandler* -GetProxyHandler(const JSObject* obj) -{ - return detail::GetProxyDataLayout(obj)->handler; -} - -inline const Value& -GetProxyPrivate(const JSObject* obj) -{ - return detail::GetProxyDataLayout(obj)->values->privateSlot; -} - -inline JSObject* -GetProxyTargetObject(JSObject* obj) -{ - return GetProxyPrivate(obj).toObjectOrNull(); -} - -inline const Value& -GetProxyExtra(const JSObject* obj, size_t n) -{ - MOZ_ASSERT(n < detail::PROXY_EXTRA_SLOTS); - return detail::GetProxyDataLayout(obj)->values->extraSlots[n]; -} - -inline void -SetProxyHandler(JSObject* obj, const BaseProxyHandler* handler) -{ - detail::GetProxyDataLayout(obj)->handler = handler; -} - -JS_FRIEND_API(void) -SetValueInProxy(Value* slot, const Value& value); - -inline void -SetProxyExtra(JSObject* obj, size_t n, const Value& extra) -{ - MOZ_ASSERT(n < detail::PROXY_EXTRA_SLOTS); - Value* vp = &detail::GetProxyDataLayout(obj)->values->extraSlots[n]; - - // Trigger a barrier before writing the slot. - if (vp->isMarkable() || extra.isMarkable()) - SetValueInProxy(vp, extra); - else - *vp = extra; -} - -inline bool -IsScriptedProxy(const JSObject* obj) -{ - return IsProxy(obj) && GetProxyHandler(obj)->isScripted(); -} - -inline const Value& -GetReservedOrProxyPrivateSlot(const JSObject* obj, size_t slot) -{ - MOZ_ASSERT(slot == 0); - MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj)) || IsProxy(obj)); - return reinterpret_cast(obj)->slotRef(slot); -} - -inline void -SetReservedOrProxyPrivateSlot(JSObject* obj, size_t slot, const Value& value) -{ - MOZ_ASSERT(slot == 0); - MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj)) || IsProxy(obj)); - shadow::Object* sobj = reinterpret_cast(obj); - if (sobj->slotRef(slot).isMarkable() || value.isMarkable()) - SetReservedOrProxyPrivateSlotWithBarrier(obj, slot, value); - else - sobj->slotRef(slot) = value; -} - -class MOZ_STACK_CLASS ProxyOptions { - protected: - /* protected constructor for subclass */ - explicit ProxyOptions(bool singletonArg, bool lazyProtoArg = false) - : singleton_(singletonArg), - lazyProto_(lazyProtoArg), - clasp_(ProxyClassPtr) - {} - - public: - ProxyOptions() : singleton_(false), - lazyProto_(false), - clasp_(ProxyClassPtr) - {} - - bool singleton() const { return singleton_; } - ProxyOptions& setSingleton(bool flag) { - singleton_ = flag; - return *this; - } - - bool lazyProto() const { return lazyProto_; } - ProxyOptions& setLazyProto(bool flag) { - lazyProto_ = flag; - return *this; - } - - const Class* clasp() const { - return clasp_; - } - ProxyOptions& setClass(const Class* claspArg) { - clasp_ = claspArg; - return *this; - } - - private: - bool singleton_; - bool lazyProto_; - const Class* clasp_; -}; - -JS_FRIEND_API(JSObject*) -NewProxyObject(JSContext* cx, const BaseProxyHandler* handler, HandleValue priv, - JSObject* proto, const ProxyOptions& options = ProxyOptions()); - -JSObject* -RenewProxyObject(JSContext* cx, JSObject* obj, BaseProxyHandler* handler, const Value& priv); - -class JS_FRIEND_API(AutoEnterPolicy) -{ - public: - typedef BaseProxyHandler::Action Action; - AutoEnterPolicy(JSContext* cx, const BaseProxyHandler* handler, - HandleObject wrapper, HandleId id, Action act, bool mayThrow) -#ifdef JS_DEBUG - : context(nullptr) -#endif - { - allow = handler->hasSecurityPolicy() ? handler->enter(cx, wrapper, id, act, &rv) - : true; - recordEnter(cx, wrapper, id, act); - // We want to throw an exception if all of the following are true: - // * The policy disallowed access. - // * The policy set rv to false, indicating that we should throw. - // * The caller did not instruct us to ignore exceptions. - // * The policy did not throw itself. - if (!allow && !rv && mayThrow) - reportErrorIfExceptionIsNotPending(cx, id); - } - - virtual ~AutoEnterPolicy() { recordLeave(); } - inline bool allowed() { return allow; } - inline bool returnValue() { MOZ_ASSERT(!allowed()); return rv; } - - protected: - // no-op constructor for subclass - AutoEnterPolicy() -#ifdef JS_DEBUG - : context(nullptr) - , enteredAction(BaseProxyHandler::NONE) -#endif - {} - void reportErrorIfExceptionIsNotPending(JSContext* cx, jsid id); - bool allow; - bool rv; - -#ifdef JS_DEBUG - JSContext* context; - mozilla::Maybe enteredProxy; - mozilla::Maybe enteredId; - Action enteredAction; - - // NB: We explicitly don't track the entered action here, because sometimes - // set() methods do an implicit get() during their implementation, leading - // to spurious assertions. - AutoEnterPolicy* prev; - void recordEnter(JSContext* cx, HandleObject proxy, HandleId id, Action act); - void recordLeave(); - - friend JS_FRIEND_API(void) assertEnteredPolicy(JSContext* cx, JSObject* proxy, jsid id, Action act); -#else - inline void recordEnter(JSContext* cx, JSObject* proxy, jsid id, Action act) {} - inline void recordLeave() {} -#endif - -}; - -#ifdef JS_DEBUG -class JS_FRIEND_API(AutoWaivePolicy) : public AutoEnterPolicy { -public: - AutoWaivePolicy(JSContext* cx, HandleObject proxy, HandleId id, - BaseProxyHandler::Action act) - { - allow = true; - recordEnter(cx, proxy, id, act); - } -}; -#else -class JS_FRIEND_API(AutoWaivePolicy) { - public: - AutoWaivePolicy(JSContext* cx, HandleObject proxy, HandleId id, - BaseProxyHandler::Action act) - {} -}; -#endif - -#ifdef JS_DEBUG -extern JS_FRIEND_API(void) -assertEnteredPolicy(JSContext* cx, JSObject* obj, jsid id, - BaseProxyHandler::Action act); -#else -inline void assertEnteredPolicy(JSContext* cx, JSObject* obj, jsid id, - BaseProxyHandler::Action act) -{} -#endif - -extern JS_FRIEND_API(JSObject*) -InitProxyClass(JSContext* cx, JS::HandleObject obj); - -} /* namespace js */ - -#endif /* js_Proxy_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/Realm.h b/android/armeabi-v7a/include/spidermonkey/js/Realm.h deleted file mode 100644 index 13a22c70..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/Realm.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* - * Ways to get various per-Realm objects. All the getters declared in this - * header operate on the Realm corresponding to the current compartment on the - * JSContext. - */ - -#ifndef js_Realm_h -#define js_Realm_h - -#include "jstypes.h" - -struct JSContext; -class JSObject; - -namespace JS { - -extern JS_PUBLIC_API(JSObject*) -GetRealmObjectPrototype(JSContext* cx); - -extern JS_PUBLIC_API(JSObject*) -GetRealmFunctionPrototype(JSContext* cx); - -extern JS_PUBLIC_API(JSObject*) -GetRealmArrayPrototype(JSContext* cx); - -extern JS_PUBLIC_API(JSObject*) -GetRealmErrorPrototype(JSContext* cx); - -extern JS_PUBLIC_API(JSObject*) -GetRealmIteratorPrototype(JSContext* cx); - -} // namespace JS - -#endif // js_Realm_h - - diff --git a/android/armeabi-v7a/include/spidermonkey/js/RequiredDefines.h b/android/armeabi-v7a/include/spidermonkey/js/RequiredDefines.h deleted file mode 100644 index 308fd7d6..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/RequiredDefines.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* - * Various #defines required to build SpiderMonkey. Embedders should add this - * file to the start of the command line via -include or a similar mechanism, - * or SpiderMonkey public headers may not work correctly. - */ - -#ifndef js_RequiredDefines_h -#define js_RequiredDefines_h - -/* - * The c99 defining the limit macros (UINT32_MAX for example), says: - * - * C++ implementations should define these macros only when - * __STDC_LIMIT_MACROS is defined before is included. - * - * The same also occurs with __STDC_CONSTANT_MACROS for the constant macros - * (INT8_C for example) used to specify a literal constant of the proper type, - * and with __STDC_FORMAT_MACROS for the format macros (PRId32 for example) used - * with the fprintf function family. - */ -#define __STDC_LIMIT_MACROS -#define __STDC_CONSTANT_MACROS -#define __STDC_FORMAT_MACROS - -/* Also define a char16_t type if not provided by the compiler. */ -#include "mozilla/Char16.h" - -#endif /* js_RequiredDefines_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/RootingAPI.h b/android/armeabi-v7a/include/spidermonkey/js/RootingAPI.h deleted file mode 100644 index a99ac4ec..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/RootingAPI.h +++ /dev/null @@ -1,1308 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_RootingAPI_h -#define js_RootingAPI_h - -#include "mozilla/Attributes.h" -#include "mozilla/DebugOnly.h" -#include "mozilla/GuardObjects.h" -#include "mozilla/LinkedList.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -#include - -#include "jspubtd.h" - -#include "js/GCAnnotations.h" -#include "js/GCAPI.h" -#include "js/GCPolicyAPI.h" -#include "js/HeapAPI.h" -#include "js/TypeDecls.h" -#include "js/UniquePtr.h" -#include "js/Utility.h" - -/* - * Moving GC Stack Rooting - * - * A moving GC may change the physical location of GC allocated things, even - * when they are rooted, updating all pointers to the thing to refer to its new - * location. The GC must therefore know about all live pointers to a thing, - * not just one of them, in order to behave correctly. - * - * The |Rooted| and |Handle| classes below are used to root stack locations - * whose value may be held live across a call that can trigger GC. For a - * code fragment such as: - * - * JSObject* obj = NewObject(cx); - * DoSomething(cx); - * ... = obj->lastProperty(); - * - * If |DoSomething()| can trigger a GC, the stack location of |obj| must be - * rooted to ensure that the GC does not move the JSObject referred to by - * |obj| without updating |obj|'s location itself. This rooting must happen - * regardless of whether there are other roots which ensure that the object - * itself will not be collected. - * - * If |DoSomething()| cannot trigger a GC, and the same holds for all other - * calls made between |obj|'s definitions and its last uses, then no rooting - * is required. - * - * SpiderMonkey can trigger a GC at almost any time and in ways that are not - * always clear. For example, the following innocuous-looking actions can - * cause a GC: allocation of any new GC thing; JSObject::hasProperty; - * JS_ReportError and friends; and ToNumber, among many others. The following - * dangerous-looking actions cannot trigger a GC: js_malloc, cx->malloc_, - * rt->malloc_, and friends and JS_ReportOutOfMemory. - * - * The following family of three classes will exactly root a stack location. - * Incorrect usage of these classes will result in a compile error in almost - * all cases. Therefore, it is very hard to be incorrectly rooted if you use - * these classes exclusively. These classes are all templated on the type T of - * the value being rooted. - * - * - Rooted declares a variable of type T, whose value is always rooted. - * Rooted may be automatically coerced to a Handle, below. Rooted - * should be used whenever a local variable's value may be held live across a - * call which can trigger a GC. - * - * - Handle is a const reference to a Rooted. Functions which take GC - * things or values as arguments and need to root those arguments should - * generally use handles for those arguments and avoid any explicit rooting. - * This has two benefits. First, when several such functions call each other - * then redundant rooting of multiple copies of the GC thing can be avoided. - * Second, if the caller does not pass a rooted value a compile error will be - * generated, which is quicker and easier to fix than when relying on a - * separate rooting analysis. - * - * - MutableHandle is a non-const reference to Rooted. It is used in the - * same way as Handle and includes a |set(const T& v)| method to allow - * updating the value of the referenced Rooted. A MutableHandle can be - * created with an implicit cast from a Rooted*. - * - * In some cases the small performance overhead of exact rooting (measured to - * be a few nanoseconds on desktop) is too much. In these cases, try the - * following: - * - * - Move all Rooted above inner loops: this allows you to re-use the root - * on each iteration of the loop. - * - * - Pass Handle through your hot call stack to avoid re-rooting costs at - * every invocation. - * - * The following diagram explains the list of supported, implicit type - * conversions between classes of this family: - * - * Rooted ----> Handle - * | ^ - * | | - * | | - * +---> MutableHandle - * (via &) - * - * All of these types have an implicit conversion to raw pointers. - */ - -namespace js { - -template -struct BarrierMethods { -}; - -template -class RootedBase {}; - -template -class HandleBase {}; - -template -class MutableHandleBase {}; - -template -class HeapBase {}; - -// Cannot use FOR_EACH_HEAP_ABLE_GC_POINTER_TYPE, as this would import too many macros into scope -template struct IsHeapConstructibleType { static constexpr bool value = false; }; -#define DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE(T) \ - template <> struct IsHeapConstructibleType { static constexpr bool value = true; }; -FOR_EACH_PUBLIC_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE) -FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE) -#undef DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE - -template -class PersistentRootedBase {}; - -static void* const ConstNullValue = nullptr; - -namespace gc { -struct Cell; -template -struct PersistentRootedMarker; -} /* namespace gc */ - -#define DECLARE_POINTER_COMPARISON_OPS(T) \ - bool operator==(const T& other) const { return get() == other; } \ - bool operator!=(const T& other) const { return get() != other; } - -// Important: Return a reference so passing a Rooted, etc. to -// something that takes a |const T&| is not a GC hazard. -#define DECLARE_POINTER_CONSTREF_OPS(T) \ - operator const T&() const { return get(); } \ - const T& operator->() const { return get(); } - -// Assignment operators on a base class are hidden by the implicitly defined -// operator= on the derived class. Thus, define the operator= directly on the -// class as we would need to manually pass it through anyway. -#define DECLARE_POINTER_ASSIGN_OPS(Wrapper, T) \ - Wrapper& operator=(const T& p) { \ - set(p); \ - return *this; \ - } \ - Wrapper& operator=(const Wrapper& other) { \ - set(other.get()); \ - return *this; \ - } \ - -#define DELETE_ASSIGNMENT_OPS(Wrapper, T) \ - template Wrapper& operator=(S) = delete; \ - Wrapper& operator=(const Wrapper&) = delete; - -#define DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr) \ - const T* address() const { return &(ptr); } \ - const T& get() const { return (ptr); } \ - -#define DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr) \ - T* address() { return &(ptr); } \ - T& get() { return (ptr); } \ - -} /* namespace js */ - -namespace JS { - -template class Rooted; -template class PersistentRooted; - -/* This is exposing internal state of the GC for inlining purposes. */ -JS_FRIEND_API(bool) isGCEnabled(); - -JS_FRIEND_API(void) HeapObjectPostBarrier(JSObject** objp, JSObject* prev, JSObject* next); - -#ifdef JS_DEBUG -/** - * For generational GC, assert that an object is in the tenured generation as - * opposed to being in the nursery. - */ -extern JS_FRIEND_API(void) -AssertGCThingMustBeTenured(JSObject* obj); -extern JS_FRIEND_API(void) -AssertGCThingIsNotAnObjectSubclass(js::gc::Cell* cell); -#else -inline void -AssertGCThingMustBeTenured(JSObject* obj) {} -inline void -AssertGCThingIsNotAnObjectSubclass(js::gc::Cell* cell) {} -#endif - -/** - * The Heap class is a heap-stored reference to a JS GC thing. All members of - * heap classes that refer to GC things should use Heap (or possibly - * TenuredHeap, described below). - * - * Heap is an abstraction that hides some of the complexity required to - * maintain GC invariants for the contained reference. It uses operator - * overloading to provide a normal pointer interface, but notifies the GC every - * time the value it contains is updated. This is necessary for generational GC, - * which keeps track of all pointers into the nursery. - * - * Heap instances must be traced when their containing object is traced to - * keep the pointed-to GC thing alive. - * - * Heap objects should only be used on the heap. GC references stored on the - * C/C++ stack must use Rooted/Handle/MutableHandle instead. - * - * Type T must be a public GC pointer type. - */ -template -class Heap : public js::HeapBase -{ - // Please note: this can actually also be used by nsXBLMaybeCompiled, for legacy reasons. - static_assert(js::IsHeapConstructibleType::value, - "Type T must be a public GC pointer type"); - public: - Heap() { - static_assert(sizeof(T) == sizeof(Heap), - "Heap must be binary compatible with T."); - init(GCPolicy::initial()); - } - explicit Heap(const T& p) { init(p); } - - /* - * For Heap, move semantics are equivalent to copy semantics. In C++, a - * copy constructor taking const-ref is the way to get a single function - * that will be used for both lvalue and rvalue copies, so we can simply - * omit the rvalue variant. - */ - explicit Heap(const Heap& p) { init(p.ptr); } - - ~Heap() { - post(ptr, GCPolicy::initial()); - } - - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_POINTER_ASSIGN_OPS(Heap, T); - - const T* address() const { return &ptr; } - - void exposeToActiveJS() const { - js::BarrierMethods::exposeToJS(ptr); - } - const T& get() const { - exposeToActiveJS(); - return ptr; - } - const T& unbarrieredGet() const { - return ptr; - } - - T* unsafeGet() { return &ptr; } - - explicit operator bool() const { - return bool(js::BarrierMethods::asGCThingOrNull(ptr)); - } - explicit operator bool() { - return bool(js::BarrierMethods::asGCThingOrNull(ptr)); - } - - private: - void init(const T& newPtr) { - ptr = newPtr; - post(GCPolicy::initial(), ptr); - } - - void set(const T& newPtr) { - T tmp = ptr; - ptr = newPtr; - post(tmp, ptr); - } - - void post(const T& prev, const T& next) { - js::BarrierMethods::postBarrier(&ptr, prev, next); - } - - T ptr; -}; - -static MOZ_ALWAYS_INLINE bool -ObjectIsTenured(JSObject* obj) -{ - return !js::gc::IsInsideNursery(reinterpret_cast(obj)); -} - -static MOZ_ALWAYS_INLINE bool -ObjectIsTenured(const Heap& obj) -{ - return ObjectIsTenured(obj.unbarrieredGet()); -} - -static MOZ_ALWAYS_INLINE bool -ObjectIsMarkedGray(JSObject* obj) -{ - auto cell = reinterpret_cast(obj); - return js::gc::detail::CellIsMarkedGrayIfKnown(cell); -} - -static MOZ_ALWAYS_INLINE bool -ObjectIsMarkedGray(const JS::Heap& obj) -{ - return ObjectIsMarkedGray(obj.unbarrieredGet()); -} - -static MOZ_ALWAYS_INLINE bool -ScriptIsMarkedGray(JSScript* script) -{ - auto cell = reinterpret_cast(script); - return js::gc::detail::CellIsMarkedGrayIfKnown(cell); -} - -static MOZ_ALWAYS_INLINE bool -ScriptIsMarkedGray(const Heap& script) -{ - return ScriptIsMarkedGray(script.unbarrieredGet()); -} - -/** - * The TenuredHeap class is similar to the Heap class above in that it - * encapsulates the GC concerns of an on-heap reference to a JS object. However, - * it has two important differences: - * - * 1) Pointers which are statically known to only reference "tenured" objects - * can avoid the extra overhead of SpiderMonkey's write barriers. - * - * 2) Objects in the "tenured" heap have stronger alignment restrictions than - * those in the "nursery", so it is possible to store flags in the lower - * bits of pointers known to be tenured. TenuredHeap wraps a normal tagged - * pointer with a nice API for accessing the flag bits and adds various - * assertions to ensure that it is not mis-used. - * - * GC things are said to be "tenured" when they are located in the long-lived - * heap: e.g. they have gained tenure as an object by surviving past at least - * one GC. For performance, SpiderMonkey allocates some things which are known - * to normally be long lived directly into the tenured generation; for example, - * global objects. Additionally, SpiderMonkey does not visit individual objects - * when deleting non-tenured objects, so object with finalizers are also always - * tenured; for instance, this includes most DOM objects. - * - * The considerations to keep in mind when using a TenuredHeap vs a normal - * Heap are: - * - * - It is invalid for a TenuredHeap to refer to a non-tenured thing. - * - It is however valid for a Heap to refer to a tenured thing. - * - It is not possible to store flag bits in a Heap. - */ -template -class TenuredHeap : public js::HeapBase -{ - public: - TenuredHeap() : bits(0) { - static_assert(sizeof(T) == sizeof(TenuredHeap), - "TenuredHeap must be binary compatible with T."); - } - explicit TenuredHeap(T p) : bits(0) { setPtr(p); } - explicit TenuredHeap(const TenuredHeap& p) : bits(0) { setPtr(p.getPtr()); } - - bool operator==(const TenuredHeap& other) { return bits == other.bits; } - bool operator!=(const TenuredHeap& other) { return bits != other.bits; } - - void setPtr(T newPtr) { - MOZ_ASSERT((reinterpret_cast(newPtr) & flagsMask) == 0); - if (newPtr) - AssertGCThingMustBeTenured(newPtr); - bits = (bits & flagsMask) | reinterpret_cast(newPtr); - } - - void setFlags(uintptr_t flagsToSet) { - MOZ_ASSERT((flagsToSet & ~flagsMask) == 0); - bits |= flagsToSet; - } - - void unsetFlags(uintptr_t flagsToUnset) { - MOZ_ASSERT((flagsToUnset & ~flagsMask) == 0); - bits &= ~flagsToUnset; - } - - bool hasFlag(uintptr_t flag) const { - MOZ_ASSERT((flag & ~flagsMask) == 0); - return (bits & flag) != 0; - } - - T unbarrieredGetPtr() const { return reinterpret_cast(bits & ~flagsMask); } - uintptr_t getFlags() const { return bits & flagsMask; } - - void exposeToActiveJS() const { - js::BarrierMethods::exposeToJS(unbarrieredGetPtr()); - } - T getPtr() const { - exposeToActiveJS(); - return unbarrieredGetPtr(); - } - - operator T() const { return getPtr(); } - T operator->() const { return getPtr(); } - - explicit operator bool() const { - return bool(js::BarrierMethods::asGCThingOrNull(unbarrieredGetPtr())); - } - explicit operator bool() { - return bool(js::BarrierMethods::asGCThingOrNull(unbarrieredGetPtr())); - } - - TenuredHeap& operator=(T p) { - setPtr(p); - return *this; - } - - TenuredHeap& operator=(const TenuredHeap& other) { - bits = other.bits; - return *this; - } - - private: - enum { - maskBits = 3, - flagsMask = (1 << maskBits) - 1, - }; - - uintptr_t bits; -}; - -/** - * Reference to a T that has been rooted elsewhere. This is most useful - * as a parameter type, which guarantees that the T lvalue is properly - * rooted. See "Move GC Stack Rooting" above. - * - * If you want to add additional methods to Handle for a specific - * specialization, define a HandleBase specialization containing them. - */ -template -class MOZ_NONHEAP_CLASS Handle : public js::HandleBase -{ - friend class JS::MutableHandle; - - public: - /* Creates a handle from a handle of a type convertible to T. */ - template - MOZ_IMPLICIT Handle(Handle handle, - typename mozilla::EnableIf::value, int>::Type dummy = 0) - { - static_assert(sizeof(Handle) == sizeof(T*), - "Handle must be binary compatible with T*."); - ptr = reinterpret_cast(handle.address()); - } - - MOZ_IMPLICIT Handle(decltype(nullptr)) { - static_assert(mozilla::IsPointer::value, - "nullptr_t overload not valid for non-pointer types"); - ptr = reinterpret_cast(&js::ConstNullValue); - } - - MOZ_IMPLICIT Handle(MutableHandle handle) { - ptr = handle.address(); - } - - /* - * Take care when calling this method! - * - * This creates a Handle from the raw location of a T. - * - * It should be called only if the following conditions hold: - * - * 1) the location of the T is guaranteed to be marked (for some reason - * other than being a Rooted), e.g., if it is guaranteed to be reachable - * from an implicit root. - * - * 2) the contents of the location are immutable, or at least cannot change - * for the lifetime of the handle, as its users may not expect its value - * to change underneath them. - */ - static constexpr Handle fromMarkedLocation(const T* p) { - return Handle(p, DeliberatelyChoosingThisOverload, - ImUsingThisOnlyInFromFromMarkedLocation); - } - - /* - * Construct a handle from an explicitly rooted location. This is the - * normal way to create a handle, and normally happens implicitly. - */ - template - inline - MOZ_IMPLICIT Handle(const Rooted& root, - typename mozilla::EnableIf::value, int>::Type dummy = 0); - - template - inline - MOZ_IMPLICIT Handle(const PersistentRooted& root, - typename mozilla::EnableIf::value, int>::Type dummy = 0); - - /* Construct a read only handle from a mutable handle. */ - template - inline - MOZ_IMPLICIT Handle(MutableHandle& root, - typename mozilla::EnableIf::value, int>::Type dummy = 0); - - DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr); - - private: - Handle() {} - DELETE_ASSIGNMENT_OPS(Handle, T); - - enum Disambiguator { DeliberatelyChoosingThisOverload = 42 }; - enum CallerIdentity { ImUsingThisOnlyInFromFromMarkedLocation = 17 }; - constexpr Handle(const T* p, Disambiguator, CallerIdentity) : ptr(p) {} - - const T* ptr; -}; - -/** - * Similar to a handle, but the underlying storage can be changed. This is - * useful for outparams. - * - * If you want to add additional methods to MutableHandle for a specific - * specialization, define a MutableHandleBase specialization containing - * them. - */ -template -class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase -{ - public: - inline MOZ_IMPLICIT MutableHandle(Rooted* root); - inline MOZ_IMPLICIT MutableHandle(PersistentRooted* root); - - private: - // Disallow nullptr for overloading purposes. - MutableHandle(decltype(nullptr)) = delete; - - public: - void set(const T& v) { - *ptr = v; - } - - /* - * This may be called only if the location of the T is guaranteed - * to be marked (for some reason other than being a Rooted), - * e.g., if it is guaranteed to be reachable from an implicit root. - * - * Create a MutableHandle from a raw location of a T. - */ - static MutableHandle fromMarkedLocation(T* p) { - MutableHandle h; - h.ptr = p; - return h; - } - - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr); - DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(*ptr); - - private: - MutableHandle() {} - DELETE_ASSIGNMENT_OPS(MutableHandle, T); - - T* ptr; -}; - -} /* namespace JS */ - -namespace js { - -template -struct BarrierMethods -{ - static T* initial() { return nullptr; } - static gc::Cell* asGCThingOrNull(T* v) { - if (!v) - return nullptr; - MOZ_ASSERT(uintptr_t(v) > 32); - return reinterpret_cast(v); - } - static void postBarrier(T** vp, T* prev, T* next) { - if (next) - JS::AssertGCThingIsNotAnObjectSubclass(reinterpret_cast(next)); - } - static void exposeToJS(T* t) { - if (t) - js::gc::ExposeGCThingToActiveJS(JS::GCCellPtr(t)); - } -}; - -template <> -struct BarrierMethods -{ - static JSObject* initial() { return nullptr; } - static gc::Cell* asGCThingOrNull(JSObject* v) { - if (!v) - return nullptr; - MOZ_ASSERT(uintptr_t(v) > 32); - return reinterpret_cast(v); - } - static void postBarrier(JSObject** vp, JSObject* prev, JSObject* next) { - JS::HeapObjectPostBarrier(vp, prev, next); - } - static void exposeToJS(JSObject* obj) { - if (obj) - JS::ExposeObjectToActiveJS(obj); - } -}; - -template <> -struct BarrierMethods -{ - static JSFunction* initial() { return nullptr; } - static gc::Cell* asGCThingOrNull(JSFunction* v) { - if (!v) - return nullptr; - MOZ_ASSERT(uintptr_t(v) > 32); - return reinterpret_cast(v); - } - static void postBarrier(JSFunction** vp, JSFunction* prev, JSFunction* next) { - JS::HeapObjectPostBarrier(reinterpret_cast(vp), - reinterpret_cast(prev), - reinterpret_cast(next)); - } - static void exposeToJS(JSFunction* fun) { - if (fun) - JS::ExposeObjectToActiveJS(reinterpret_cast(fun)); - } -}; - -// Provide hash codes for Cell kinds that may be relocated and, thus, not have -// a stable address to use as the base for a hash code. Instead of the address, -// this hasher uses Cell::getUniqueId to provide exact matches and as a base -// for generating hash codes. -// -// Note: this hasher, like PointerHasher can "hash" a nullptr. While a nullptr -// would not likely be a useful key, there are some cases where being able to -// hash a nullptr is useful, either on purpose or because of bugs: -// (1) existence checks where the key may happen to be null and (2) some -// aggregate Lookup kinds embed a JSObject* that is frequently null and do not -// null test before dispatching to the hasher. -template -struct JS_PUBLIC_API(MovableCellHasher) -{ - using Key = T; - using Lookup = T; - - static bool hasHash(const Lookup& l); - static bool ensureHash(const Lookup& l); - static HashNumber hash(const Lookup& l); - static bool match(const Key& k, const Lookup& l); - static void rekey(Key& k, const Key& newKey) { k = newKey; } -}; - -template -struct JS_PUBLIC_API(MovableCellHasher>) -{ - using Key = JS::Heap; - using Lookup = T; - - static bool hasHash(const Lookup& l) { return MovableCellHasher::hasHash(l); } - static bool ensureHash(const Lookup& l) { return MovableCellHasher::ensureHash(l); } - static HashNumber hash(const Lookup& l) { return MovableCellHasher::hash(l); } - static bool match(const Key& k, const Lookup& l) { - return MovableCellHasher::match(k.unbarrieredGet(), l); - } - static void rekey(Key& k, const Key& newKey) { k.unsafeSet(newKey); } -}; - -template -struct FallibleHashMethods> -{ - template static bool hasHash(Lookup&& l) { - return MovableCellHasher::hasHash(mozilla::Forward(l)); - } - template static bool ensureHash(Lookup&& l) { - return MovableCellHasher::ensureHash(mozilla::Forward(l)); - } -}; - -} /* namespace js */ - -namespace js { - -// The alignment must be set because the Rooted and PersistentRooted ptr fields -// may be accessed through reinterpret_cast*>, and -// the compiler may choose a different alignment for the ptr field when it -// knows the actual type stored in DispatchWrapper. -// -// It would make more sense to align only those specific fields of type -// DispatchWrapper, rather than DispatchWrapper itself, but that causes MSVC to -// fail when Rooted is used in an IsConvertible test. -template -class alignas(8) DispatchWrapper -{ - static_assert(JS::MapTypeToRootKind::kind == JS::RootKind::Traceable, - "DispatchWrapper is intended only for usage with a Traceable"); - - using TraceFn = void (*)(JSTracer*, T*, const char*); - TraceFn tracer; - alignas(gc::CellSize) T storage; - - public: - template - MOZ_IMPLICIT DispatchWrapper(U&& initial) - : tracer(&JS::GCPolicy::trace), - storage(mozilla::Forward(initial)) - { } - - // Mimic a pointer type, so that we can drop into Rooted. - T* operator &() { return &storage; } - const T* operator &() const { return &storage; } - operator T&() { return storage; } - operator const T&() const { return storage; } - - // Trace the contained storage (of unknown type) using the trace function - // we set aside when we did know the type. - static void TraceWrapped(JSTracer* trc, T* thingp, const char* name) { - auto wrapper = reinterpret_cast( - uintptr_t(thingp) - offsetof(DispatchWrapper, storage)); - wrapper->tracer(trc, &wrapper->storage, name); - } -}; - -} /* namespace js */ - -namespace JS { - -/** - * Local variable of type T whose value is always rooted. This is typically - * used for local variables, or for non-rooted values being passed to a - * function that requires a handle, e.g. Foo(Root(cx, x)). - * - * If you want to add additional methods to Rooted for a specific - * specialization, define a RootedBase specialization containing them. - */ -template -class MOZ_RAII Rooted : public js::RootedBase -{ - inline void registerWithRootLists(js::RootedListHeads& roots) { - this->stack = &roots[JS::MapTypeToRootKind::kind]; - this->prev = *stack; - *stack = reinterpret_cast*>(this); - } - - inline js::RootedListHeads& rootLists(JS::RootingContext* cx) { - return rootLists(static_cast(cx)); - } - inline js::RootedListHeads& rootLists(js::ContextFriendFields* cx) { - if (JS::Zone* zone = cx->zone_) - return JS::shadow::Zone::asShadowZone(zone)->stackRoots_; - MOZ_ASSERT(cx->isJSContext); - return cx->roots.stackRoots_; - } - inline js::RootedListHeads& rootLists(JSContext* cx) { - return rootLists(js::ContextFriendFields::get(cx)); - } - - public: - template - explicit Rooted(const RootingContext& cx) - : ptr(GCPolicy::initial()) - { - registerWithRootLists(rootLists(cx)); - } - - template - Rooted(const RootingContext& cx, S&& initial) - : ptr(mozilla::Forward(initial)) - { - registerWithRootLists(rootLists(cx)); - } - - ~Rooted() { - MOZ_ASSERT(*stack == reinterpret_cast*>(this)); - *stack = prev; - } - - Rooted* previous() { return reinterpret_cast*>(prev); } - - /* - * This method is public for Rooted so that Codegen.py can use a Rooted - * interchangeably with a MutableHandleValue. - */ - void set(const T& value) { - ptr = value; - } - - DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_POINTER_ASSIGN_OPS(Rooted, T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr); - DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr); - - private: - /* - * These need to be templated on void* to avoid aliasing issues between, for - * example, Rooted and Rooted, which use the same - * stack head pointer for different classes. - */ - Rooted** stack; - Rooted* prev; - - /* - * For pointer types, the TraceKind for tracing is based on the list it is - * in (selected via MapTypeToRootKind), so no additional storage is - * required here. Non-pointer types, however, share the same list, so the - * function to call for tracing is stored adjacent to the struct. Since C++ - * cannot templatize on storage class, this is implemented via the wrapper - * class DispatchWrapper. - */ - using MaybeWrapped = typename mozilla::Conditional< - MapTypeToRootKind::kind == JS::RootKind::Traceable, - js::DispatchWrapper, - T>::Type; - MaybeWrapped ptr; - - Rooted(const Rooted&) = delete; -} JS_HAZ_ROOTED; - -} /* namespace JS */ - -namespace js { - -/** - * Augment the generic Rooted interface when T = JSObject* with - * class-querying and downcasting operations. - * - * Given a Rooted obj, one can view - * Handle h = obj.as(); - * as an optimization of - * Rooted rooted(cx, &obj->as()); - * Handle h = rooted; - */ -template <> -class RootedBase -{ - public: - template - JS::Handle as() const; -}; - -/** - * Augment the generic Handle interface when T = JSObject* with - * downcasting operations. - * - * Given a Handle obj, one can view - * Handle h = obj.as(); - * as an optimization of - * Rooted rooted(cx, &obj->as()); - * Handle h = rooted; - */ -template <> -class HandleBase -{ - public: - template - JS::Handle as() const; -}; - -/** Interface substitute for Rooted which does not root the variable's memory. */ -template -class MOZ_RAII FakeRooted : public RootedBase -{ - public: - template - explicit FakeRooted(CX* cx) : ptr(JS::GCPolicy::initial()) {} - - template - FakeRooted(CX* cx, T initial) : ptr(initial) {} - - DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_POINTER_ASSIGN_OPS(FakeRooted, T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr); - DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr); - - private: - T ptr; - - void set(const T& value) { - ptr = value; - } - - FakeRooted(const FakeRooted&) = delete; -}; - -/** Interface substitute for MutableHandle which is not required to point to rooted memory. */ -template -class FakeMutableHandle : public js::MutableHandleBase -{ - public: - MOZ_IMPLICIT FakeMutableHandle(T* t) { - ptr = t; - } - - MOZ_IMPLICIT FakeMutableHandle(FakeRooted* root) { - ptr = root->address(); - } - - void set(const T& v) { - *ptr = v; - } - - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr); - DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(*ptr); - - private: - FakeMutableHandle() {} - DELETE_ASSIGNMENT_OPS(FakeMutableHandle, T); - - T* ptr; -}; - -/** - * Types for a variable that either should or shouldn't be rooted, depending on - * the template parameter allowGC. Used for implementing functions that can - * operate on either rooted or unrooted data. - * - * The toHandle() and toMutableHandle() functions are for calling functions - * which require handle types and are only called in the CanGC case. These - * allow the calling code to type check. - */ -enum AllowGC { - NoGC = 0, - CanGC = 1 -}; -template -class MaybeRooted -{ -}; - -template class MaybeRooted -{ - public: - typedef JS::Handle HandleType; - typedef JS::Rooted RootType; - typedef JS::MutableHandle MutableHandleType; - - static inline JS::Handle toHandle(HandleType v) { - return v; - } - - static inline JS::MutableHandle toMutableHandle(MutableHandleType v) { - return v; - } - - template - static inline JS::Handle downcastHandle(HandleType v) { - return v.template as(); - } -}; - -template class MaybeRooted -{ - public: - typedef const T& HandleType; - typedef FakeRooted RootType; - typedef FakeMutableHandle MutableHandleType; - - static JS::Handle toHandle(HandleType v) { - MOZ_CRASH("Bad conversion"); - } - - static JS::MutableHandle toMutableHandle(MutableHandleType v) { - MOZ_CRASH("Bad conversion"); - } - - template - static inline T2* downcastHandle(HandleType v) { - return &v->template as(); - } -}; - -} /* namespace js */ - -namespace JS { - -template template -inline -Handle::Handle(const Rooted& root, - typename mozilla::EnableIf::value, int>::Type dummy) -{ - ptr = reinterpret_cast(root.address()); -} - -template template -inline -Handle::Handle(const PersistentRooted& root, - typename mozilla::EnableIf::value, int>::Type dummy) -{ - ptr = reinterpret_cast(root.address()); -} - -template template -inline -Handle::Handle(MutableHandle& root, - typename mozilla::EnableIf::value, int>::Type dummy) -{ - ptr = reinterpret_cast(root.address()); -} - -template -inline -MutableHandle::MutableHandle(Rooted* root) -{ - static_assert(sizeof(MutableHandle) == sizeof(T*), - "MutableHandle must be binary compatible with T*."); - ptr = root->address(); -} - -template -inline -MutableHandle::MutableHandle(PersistentRooted* root) -{ - static_assert(sizeof(MutableHandle) == sizeof(T*), - "MutableHandle must be binary compatible with T*."); - ptr = root->address(); -} - -/** - * A copyable, assignable global GC root type with arbitrary lifetime, an - * infallible constructor, and automatic unrooting on destruction. - * - * These roots can be used in heap-allocated data structures, so they are not - * associated with any particular JSContext or stack. They are registered with - * the JSRuntime itself, without locking, so they require a full JSContext to be - * initialized, not one of its more restricted superclasses. Initialization may - * take place on construction, or in two phases if the no-argument constructor - * is called followed by init(). - * - * Note that you must not use an PersistentRooted in an object owned by a JS - * object: - * - * Whenever one object whose lifetime is decided by the GC refers to another - * such object, that edge must be traced only if the owning JS object is traced. - * This applies not only to JS objects (which obviously are managed by the GC) - * but also to C++ objects owned by JS objects. - * - * If you put a PersistentRooted in such a C++ object, that is almost certainly - * a leak. When a GC begins, the referent of the PersistentRooted is treated as - * live, unconditionally (because a PersistentRooted is a *root*), even if the - * JS object that owns it is unreachable. If there is any path from that - * referent back to the JS object, then the C++ object containing the - * PersistentRooted will not be destructed, and the whole blob of objects will - * not be freed, even if there are no references to them from the outside. - * - * In the context of Firefox, this is a severe restriction: almost everything in - * Firefox is owned by some JS object or another, so using PersistentRooted in - * such objects would introduce leaks. For these kinds of edges, Heap or - * TenuredHeap would be better types. It's up to the implementor of the type - * containing Heap or TenuredHeap members to make sure their referents get - * marked when the object itself is marked. - */ -template -class PersistentRooted : public js::PersistentRootedBase, - private mozilla::LinkedListElement> -{ - using ListBase = mozilla::LinkedListElement>; - - friend class mozilla::LinkedList; - friend class mozilla::LinkedListElement; - - void registerWithRootLists(js::RootLists& roots) { - MOZ_ASSERT(!initialized()); - JS::RootKind kind = JS::MapTypeToRootKind::kind; - roots.heapRoots_[kind].insertBack(reinterpret_cast*>(this)); - } - - js::RootLists& rootLists(JSContext* cx) { - return rootLists(JS::RootingContext::get(cx)); - } - js::RootLists& rootLists(JS::RootingContext* cx) { - MOZ_ASSERT(cx->isJSContext); - return cx->roots; - } - - // Disallow ExclusiveContext*. - js::RootLists& rootLists(js::ContextFriendFields* cx) = delete; - - public: - PersistentRooted() : ptr(GCPolicy::initial()) {} - - template - explicit PersistentRooted(const RootingContext& cx) - : ptr(GCPolicy::initial()) - { - registerWithRootLists(rootLists(cx)); - } - - template - PersistentRooted(const RootingContext& cx, U&& initial) - : ptr(mozilla::Forward(initial)) - { - registerWithRootLists(rootLists(cx)); - } - - PersistentRooted(const PersistentRooted& rhs) - : mozilla::LinkedListElement>(), - ptr(rhs.ptr) - { - /* - * Copy construction takes advantage of the fact that the original - * is already inserted, and simply adds itself to whatever list the - * original was on - no JSRuntime pointer needed. - * - * This requires mutating rhs's links, but those should be 'mutable' - * anyway. C++ doesn't let us declare mutable base classes. - */ - const_cast(rhs).setNext(this); - } - - bool initialized() { - return ListBase::isInList(); - } - - template - void init(const RootingContext& cx) { - init(cx, GCPolicy::initial()); - } - - template - void init(const RootingContext& cx, U&& initial) { - ptr = mozilla::Forward(initial); - registerWithRootLists(rootLists(cx)); - } - - void reset() { - if (initialized()) { - set(GCPolicy::initial()); - ListBase::remove(); - } - } - - DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_POINTER_ASSIGN_OPS(PersistentRooted, T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr); - - // These are the same as DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS, except - // they check that |this| is initialized in case the caller later stores - // something in |ptr|. - T* address() { - MOZ_ASSERT(initialized()); - return &ptr; - } - T& get() { - MOZ_ASSERT(initialized()); - return ptr; - } - - private: - template - void set(U&& value) { - MOZ_ASSERT(initialized()); - ptr = mozilla::Forward(value); - } - - // See the comment above Rooted::ptr. - using MaybeWrapped = typename mozilla::Conditional< - MapTypeToRootKind::kind == JS::RootKind::Traceable, - js::DispatchWrapper, - T>::Type; - MaybeWrapped ptr; -} JS_HAZ_ROOTED; - -class JS_PUBLIC_API(ObjectPtr) -{ - Heap value; - - public: - ObjectPtr() : value(nullptr) {} - - explicit ObjectPtr(JSObject* obj) : value(obj) {} - - /* Always call finalize before the destructor. */ - ~ObjectPtr() { MOZ_ASSERT(!value); } - - void finalize(JSRuntime* rt); - void finalize(JSContext* cx); - - void init(JSObject* obj) { value = obj; } - - JSObject* get() const { return value; } - JSObject* unbarrieredGet() const { return value.unbarrieredGet(); } - - void writeBarrierPre(JSContext* cx) { - IncrementalObjectBarrier(value); - } - - void updateWeakPointerAfterGC(); - - ObjectPtr& operator=(JSObject* obj) { - IncrementalObjectBarrier(value); - value = obj; - return *this; - } - - void trace(JSTracer* trc, const char* name); - - JSObject& operator*() const { return *value; } - JSObject* operator->() const { return value; } - operator JSObject*() const { return value; } - - explicit operator bool() const { return value.unbarrieredGet(); } - explicit operator bool() { return value.unbarrieredGet(); } -}; - -} /* namespace JS */ - -namespace js { - -template -class UniquePtrOperations -{ - const UniquePtr& uniquePtr() const { return static_cast(this)->get(); } - - public: - explicit operator bool() const { return !!uniquePtr(); } -}; - -template -class MutableUniquePtrOperations : public UniquePtrOperations -{ - UniquePtr& uniquePtr() { return static_cast(this)->get(); } - - public: - MOZ_MUST_USE typename UniquePtr::Pointer release() { return uniquePtr().release(); } -}; - -template -class RootedBase> - : public MutableUniquePtrOperations>, T, D> -{ }; - -template -class MutableHandleBase> - : public MutableUniquePtrOperations>, T, D> -{ }; - -template -class HandleBase> - : public UniquePtrOperations>, T, D> -{ }; - -template -class PersistentRootedBase> - : public MutableUniquePtrOperations>, T, D> -{ }; - -namespace gc { - -template -void -CallTraceCallbackOnNonHeap(T* v, const TraceCallbacks& aCallbacks, const char* aName, void* aClosure) -{ - static_assert(sizeof(T) == sizeof(JS::Heap), "T and Heap must be compatible."); - MOZ_ASSERT(v); - mozilla::DebugOnly cell = BarrierMethods::asGCThingOrNull(*v); - MOZ_ASSERT(cell); - MOZ_ASSERT(!IsInsideNursery(cell)); - JS::Heap* asHeapT = reinterpret_cast*>(v); - aCallbacks.Trace(asHeapT, aName, aClosure); -} - -} /* namespace gc */ -} /* namespace js */ - -// mozilla::Swap uses a stack temporary, which prevents classes like Heap -// from being declared MOZ_HEAP_CLASS. -namespace mozilla { - -template -inline void -Swap(JS::Heap& aX, JS::Heap& aY) -{ - T tmp = aX; - aX = aY; - aY = tmp; -} - -template -inline void -Swap(JS::TenuredHeap& aX, JS::TenuredHeap& aY) -{ - T tmp = aX; - aX = aY; - aY = tmp; -} - -} /* namespace mozilla */ - -#undef DELETE_ASSIGNMENT_OPS - -#endif /* js_RootingAPI_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/SliceBudget.h b/android/armeabi-v7a/include/spidermonkey/js/SliceBudget.h deleted file mode 100644 index 78982df0..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/SliceBudget.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_SliceBudget_h -#define js_SliceBudget_h - -#include - -namespace js { - -struct JS_PUBLIC_API(TimeBudget) -{ - int64_t budget; - - explicit TimeBudget(int64_t milliseconds) { budget = milliseconds; } -}; - -struct JS_PUBLIC_API(WorkBudget) -{ - int64_t budget; - - explicit WorkBudget(int64_t work) { budget = work; } -}; - -/* - * This class records how much work has been done in a given collection slice, - * so that we can return before pausing for too long. Some slices are allowed - * to run for unlimited time, and others are bounded. To reduce the number of - * gettimeofday calls, we only check the time every 1000 operations. - */ -class JS_PUBLIC_API(SliceBudget) -{ - static const int64_t unlimitedDeadline = INT64_MAX; - static const intptr_t unlimitedStartCounter = INTPTR_MAX; - - bool checkOverBudget(); - - SliceBudget(); - - public: - // Memory of the originally requested budget. If isUnlimited, neither of - // these are in use. If deadline==0, then workBudget is valid. Otherwise - // timeBudget is valid. - TimeBudget timeBudget; - WorkBudget workBudget; - - int64_t deadline; /* in microseconds */ - intptr_t counter; - - static const intptr_t CounterReset = 1000; - - static const int64_t UnlimitedTimeBudget = -1; - static const int64_t UnlimitedWorkBudget = -1; - - /* Use to create an unlimited budget. */ - static SliceBudget unlimited() { return SliceBudget(); } - - /* Instantiate as SliceBudget(TimeBudget(n)). */ - explicit SliceBudget(TimeBudget time); - - /* Instantiate as SliceBudget(WorkBudget(n)). */ - explicit SliceBudget(WorkBudget work); - - void makeUnlimited() { - deadline = unlimitedDeadline; - counter = unlimitedStartCounter; - } - - void step(intptr_t amt = 1) { - counter -= amt; - } - - bool isOverBudget() { - if (counter > 0) - return false; - return checkOverBudget(); - } - - bool isWorkBudget() const { return deadline == 0; } - bool isTimeBudget() const { return deadline > 0 && !isUnlimited(); } - bool isUnlimited() const { return deadline == unlimitedDeadline; } - - int describe(char* buffer, size_t maxlen) const; -}; - -} // namespace js - -#endif /* js_SliceBudget_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/StructuredClone.h b/android/armeabi-v7a/include/spidermonkey/js/StructuredClone.h deleted file mode 100644 index e10a3073..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/StructuredClone.h +++ /dev/null @@ -1,358 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_StructuredClone_h -#define js_StructuredClone_h - -#include "mozilla/Attributes.h" -#include "mozilla/BufferList.h" - -#include - -#include "jstypes.h" - -#include "js/RootingAPI.h" -#include "js/TypeDecls.h" -#include "js/Value.h" - -struct JSRuntime; -struct JSStructuredCloneReader; -struct JSStructuredCloneWriter; - -// API for the HTML5 internal structured cloning algorithm. - -namespace JS { - -enum class StructuredCloneScope : uint32_t { - SameProcessSameThread, - SameProcessDifferentThread, - DifferentProcess -}; - -enum TransferableOwnership { - /** Transferable data has not been filled in yet */ - SCTAG_TMO_UNFILLED = 0, - - /** Structured clone buffer does not yet own the data */ - SCTAG_TMO_UNOWNED = 1, - - /** All values at least this large are owned by the clone buffer */ - SCTAG_TMO_FIRST_OWNED = 2, - - /** Data is a pointer that can be freed */ - SCTAG_TMO_ALLOC_DATA = 2, - - /** Data is a memory mapped pointer */ - SCTAG_TMO_MAPPED_DATA = 3, - - /** - * Data is embedding-specific. The engine can free it by calling the - * freeTransfer op. The embedding can also use SCTAG_TMO_USER_MIN and - * greater, up to 32 bits, to distinguish specific ownership variants. - */ - SCTAG_TMO_CUSTOM = 4, - - SCTAG_TMO_USER_MIN -}; - -class CloneDataPolicy -{ - bool sharedArrayBuffer_; - - public: - // The default is to allow all policy-controlled aspects. - - CloneDataPolicy() : - sharedArrayBuffer_(true) - {} - - // In the JS engine, SharedArrayBuffers can only be cloned intra-process - // because the shared memory areas are allocated in process-private memory. - // Clients should therefore deny SharedArrayBuffers when cloning data that - // are to be transmitted inter-process. - // - // Clients should also deny SharedArrayBuffers when cloning data that are to - // be transmitted intra-process if policy needs dictate such denial. - - CloneDataPolicy& denySharedArrayBuffer() { - sharedArrayBuffer_ = false; - return *this; - } - - bool isSharedArrayBufferAllowed() const { - return sharedArrayBuffer_; - } -}; - -} /* namespace JS */ - -/** - * Read structured data from the reader r. This hook is used to read a value - * previously serialized by a call to the WriteStructuredCloneOp hook. - * - * tag and data are the pair of uint32_t values from the header. The callback - * may use the JS_Read* APIs to read any other relevant parts of the object - * from the reader r. closure is any value passed to the JS_ReadStructuredClone - * function. Return the new object on success, nullptr on error/exception. - */ -typedef JSObject* (*ReadStructuredCloneOp)(JSContext* cx, JSStructuredCloneReader* r, - uint32_t tag, uint32_t data, void* closure); - -/** - * Structured data serialization hook. The engine can write primitive values, - * Objects, Arrays, Dates, RegExps, TypedArrays, ArrayBuffers, Sets, Maps, - * and SharedTypedArrays. Any other type of object requires application support. - * This callback must first use the JS_WriteUint32Pair API to write an object - * header, passing a value greater than JS_SCTAG_USER to the tag parameter. - * Then it can use the JS_Write* APIs to write any other relevant parts of - * the value v to the writer w. closure is any value passed to the - * JS_WriteStructuredClone function. - * - * Return true on success, false on error/exception. - */ -typedef bool (*WriteStructuredCloneOp)(JSContext* cx, JSStructuredCloneWriter* w, - JS::HandleObject obj, void* closure); - -/** - * This is called when JS_WriteStructuredClone is given an invalid transferable. - * To follow HTML5, the application must throw a DATA_CLONE_ERR DOMException - * with error set to one of the JS_SCERR_* values. - */ -typedef void (*StructuredCloneErrorOp)(JSContext* cx, uint32_t errorid); - -/** - * This is called when JS_ReadStructuredClone receives a transferable object - * not known to the engine. If this hook does not exist or returns false, the - * JS engine calls the reportError op if set, otherwise it throws a - * DATA_CLONE_ERR DOM Exception. This method is called before any other - * callback and must return a non-null object in returnObject on success. - */ -typedef bool (*ReadTransferStructuredCloneOp)(JSContext* cx, JSStructuredCloneReader* r, - uint32_t tag, void* content, uint64_t extraData, - void* closure, - JS::MutableHandleObject returnObject); - -/** - * Called when JS_WriteStructuredClone receives a transferable object not - * handled by the engine. If this hook does not exist or returns false, the JS - * engine will call the reportError hook or fall back to throwing a - * DATA_CLONE_ERR DOM Exception. This method is called before any other - * callback. - * - * tag: indicates what type of transferable this is. Must be greater than - * 0xFFFF0201 (value of the internal SCTAG_TRANSFER_MAP_PENDING_ENTRY) - * - * ownership: see TransferableOwnership, above. Used to communicate any needed - * ownership info to the FreeTransferStructuredCloneOp. - * - * content, extraData: what the ReadTransferStructuredCloneOp will receive - */ -typedef bool (*TransferStructuredCloneOp)(JSContext* cx, - JS::Handle obj, - void* closure, - // Output: - uint32_t* tag, - JS::TransferableOwnership* ownership, - void** content, - uint64_t* extraData); - -/** - * Called when freeing an unknown transferable object. Note that it - * should never trigger a garbage collection (and will assert in a - * debug build if it does.) - */ -typedef void (*FreeTransferStructuredCloneOp)(uint32_t tag, JS::TransferableOwnership ownership, - void* content, uint64_t extraData, void* closure); - -// The maximum supported structured-clone serialization format version. -// Increment this when anything at all changes in the serialization format. -// (Note that this does not need to be bumped for Transferable-only changes, -// since they are never saved to persistent storage.) -#define JS_STRUCTURED_CLONE_VERSION 8 - -struct JSStructuredCloneCallbacks { - ReadStructuredCloneOp read; - WriteStructuredCloneOp write; - StructuredCloneErrorOp reportError; - ReadTransferStructuredCloneOp readTransfer; - TransferStructuredCloneOp writeTransfer; - FreeTransferStructuredCloneOp freeTransfer; -}; - -enum OwnTransferablePolicy { - OwnsTransferablesIfAny, - IgnoreTransferablesIfAny, - NoTransferables -}; - -class MOZ_NON_MEMMOVABLE JSStructuredCloneData : public mozilla::BufferList -{ - typedef js::SystemAllocPolicy AllocPolicy; - typedef mozilla::BufferList BufferList; - - static const size_t kInitialSize = 0; - static const size_t kInitialCapacity = 4096; - static const size_t kStandardCapacity = 4096; - - const JSStructuredCloneCallbacks* callbacks_; - void* closure_; - OwnTransferablePolicy ownTransferables_; - - void setOptionalCallbacks(const JSStructuredCloneCallbacks* callbacks, - void* closure, - OwnTransferablePolicy policy) { - callbacks_ = callbacks; - closure_ = closure; - ownTransferables_ = policy; - } - - friend struct JSStructuredCloneWriter; - friend class JS_PUBLIC_API(JSAutoStructuredCloneBuffer); - -public: - explicit JSStructuredCloneData(AllocPolicy aAP = AllocPolicy()) - : BufferList(kInitialSize, kInitialCapacity, kStandardCapacity, aAP) - , callbacks_(nullptr) - , closure_(nullptr) - , ownTransferables_(OwnTransferablePolicy::NoTransferables) - {} - MOZ_IMPLICIT JSStructuredCloneData(BufferList&& buffers) - : BufferList(Move(buffers)) - , callbacks_(nullptr) - , closure_(nullptr) - , ownTransferables_(OwnTransferablePolicy::NoTransferables) - {} - JSStructuredCloneData(JSStructuredCloneData&& other) = default; - JSStructuredCloneData& operator=(JSStructuredCloneData&& other) = default; - ~JSStructuredCloneData(); - - using BufferList::BufferList; -}; - -/** Note: if the *data contains transferable objects, it can be read only once. */ -JS_PUBLIC_API(bool) -JS_ReadStructuredClone(JSContext* cx, JSStructuredCloneData& data, uint32_t version, - JS::StructuredCloneScope scope, - JS::MutableHandleValue vp, - const JSStructuredCloneCallbacks* optionalCallbacks, void* closure); - -JS_PUBLIC_API(bool) -JS_WriteStructuredClone(JSContext* cx, JS::HandleValue v, JSStructuredCloneData* data, - JS::StructuredCloneScope scope, - JS::CloneDataPolicy cloneDataPolicy, - const JSStructuredCloneCallbacks* optionalCallbacks, - void* closure, JS::HandleValue transferable); - -JS_PUBLIC_API(bool) -JS_StructuredCloneHasTransferables(JSStructuredCloneData& data, bool* hasTransferable); - -JS_PUBLIC_API(bool) -JS_StructuredClone(JSContext* cx, JS::HandleValue v, JS::MutableHandleValue vp, - const JSStructuredCloneCallbacks* optionalCallbacks, void* closure); - -/** RAII sugar for JS_WriteStructuredClone. */ -class JS_PUBLIC_API(JSAutoStructuredCloneBuffer) { - const JS::StructuredCloneScope scope_; - JSStructuredCloneData data_; - uint32_t version_; - - public: - JSAutoStructuredCloneBuffer(JS::StructuredCloneScope scope, - const JSStructuredCloneCallbacks* callbacks, void* closure) - : scope_(scope), version_(JS_STRUCTURED_CLONE_VERSION) - { - data_.setOptionalCallbacks(callbacks, closure, OwnTransferablePolicy::NoTransferables); - } - - JSAutoStructuredCloneBuffer(JSAutoStructuredCloneBuffer&& other); - JSAutoStructuredCloneBuffer& operator=(JSAutoStructuredCloneBuffer&& other); - - ~JSAutoStructuredCloneBuffer() { clear(); } - - JSStructuredCloneData& data() { return data_; } - bool empty() const { return !data_.Size(); } - - void clear(const JSStructuredCloneCallbacks* optionalCallbacks=nullptr, void* closure=nullptr); - - /** Copy some memory. It will be automatically freed by the destructor. */ - bool copy(const JSStructuredCloneData& data, uint32_t version=JS_STRUCTURED_CLONE_VERSION, - const JSStructuredCloneCallbacks* callbacks=nullptr, void* closure=nullptr); - - /** - * Adopt some memory. It will be automatically freed by the destructor. - * data must have been allocated by the JS engine (e.g., extracted via - * JSAutoStructuredCloneBuffer::steal). - */ - void adopt(JSStructuredCloneData&& data, uint32_t version=JS_STRUCTURED_CLONE_VERSION, - const JSStructuredCloneCallbacks* callbacks=nullptr, void* closure=nullptr); - - /** - * Release the buffer and transfer ownership to the caller. - */ - void steal(JSStructuredCloneData* data, uint32_t* versionp=nullptr, - const JSStructuredCloneCallbacks** callbacks=nullptr, void** closure=nullptr); - - /** - * Abandon ownership of any transferable objects stored in the buffer, - * without freeing the buffer itself. Useful when copying the data out into - * an external container, though note that you will need to use adopt() to - * properly release that data eventually. - */ - void abandon() { data_.ownTransferables_ = OwnTransferablePolicy::IgnoreTransferablesIfAny; } - - bool read(JSContext* cx, JS::MutableHandleValue vp, - const JSStructuredCloneCallbacks* optionalCallbacks=nullptr, void* closure=nullptr); - - bool write(JSContext* cx, JS::HandleValue v, - const JSStructuredCloneCallbacks* optionalCallbacks=nullptr, void* closure=nullptr); - - bool write(JSContext* cx, JS::HandleValue v, JS::HandleValue transferable, - JS::CloneDataPolicy cloneDataPolicy, - const JSStructuredCloneCallbacks* optionalCallbacks=nullptr, void* closure=nullptr); - - private: - // Copy and assignment are not supported. - JSAutoStructuredCloneBuffer(const JSAutoStructuredCloneBuffer& other) = delete; - JSAutoStructuredCloneBuffer& operator=(const JSAutoStructuredCloneBuffer& other) = delete; -}; - -// The range of tag values the application may use for its own custom object types. -#define JS_SCTAG_USER_MIN ((uint32_t) 0xFFFF8000) -#define JS_SCTAG_USER_MAX ((uint32_t) 0xFFFFFFFF) - -#define JS_SCERR_RECURSION 0 -#define JS_SCERR_TRANSFERABLE 1 -#define JS_SCERR_DUP_TRANSFERABLE 2 -#define JS_SCERR_UNSUPPORTED_TYPE 3 - -JS_PUBLIC_API(bool) -JS_ReadUint32Pair(JSStructuredCloneReader* r, uint32_t* p1, uint32_t* p2); - -JS_PUBLIC_API(bool) -JS_ReadBytes(JSStructuredCloneReader* r, void* p, size_t len); - -JS_PUBLIC_API(bool) -JS_ReadTypedArray(JSStructuredCloneReader* r, JS::MutableHandleValue vp); - -JS_PUBLIC_API(bool) -JS_WriteUint32Pair(JSStructuredCloneWriter* w, uint32_t tag, uint32_t data); - -JS_PUBLIC_API(bool) -JS_WriteBytes(JSStructuredCloneWriter* w, const void* p, size_t len); - -JS_PUBLIC_API(bool) -JS_WriteString(JSStructuredCloneWriter* w, JS::HandleString str); - -JS_PUBLIC_API(bool) -JS_WriteTypedArray(JSStructuredCloneWriter* w, JS::HandleValue v); - -JS_PUBLIC_API(bool) -JS_ObjectNotWritten(JSStructuredCloneWriter* w, JS::HandleObject obj); - -JS_PUBLIC_API(JS::StructuredCloneScope) -JS_GetStructuredCloneScope(JSStructuredCloneWriter* w); - -#endif /* js_StructuredClone_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/SweepingAPI.h b/android/armeabi-v7a/include/spidermonkey/js/SweepingAPI.h deleted file mode 100644 index 0eb29ae4..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/SweepingAPI.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_SweepingAPI_h -#define js_SweepingAPI_h - -#include "js/HeapAPI.h" - -namespace js { -template -class WeakCacheBase {}; -} // namespace js - -namespace JS { -template class WeakCache; - -namespace shadow { -JS_PUBLIC_API(void) -RegisterWeakCache(JS::Zone* zone, JS::WeakCache* cachep); -} // namespace shadow - -// A WeakCache stores the given Sweepable container and links itself into a -// list of such caches that are swept during each GC. -template -class WeakCache : public js::WeakCacheBase, - private mozilla::LinkedListElement> -{ - friend class mozilla::LinkedListElement>; - friend class mozilla::LinkedList>; - - WeakCache() = delete; - WeakCache(const WeakCache&) = delete; - - using SweepFn = void (*)(T*); - SweepFn sweeper; - T cache; - - public: - using Type = T; - - template - WeakCache(Zone* zone, U&& initial) - : cache(mozilla::Forward(initial)) - { - sweeper = GCPolicy::sweep; - shadow::RegisterWeakCache(zone, reinterpret_cast*>(this)); - } - WeakCache(WeakCache&& other) - : sweeper(other.sweeper), - cache(mozilla::Move(other.cache)) - { - } - - const T& get() const { return cache; } - T& get() { return cache; } - - void sweep() { sweeper(&cache); } -}; - -} // namespace JS - -#endif // js_SweepingAPI_h diff --git a/android/armeabi-v7a/include/spidermonkey/js/TraceKind.h b/android/armeabi-v7a/include/spidermonkey/js/TraceKind.h deleted file mode 100644 index 2eda9cb2..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/TraceKind.h +++ /dev/null @@ -1,212 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_TraceKind_h -#define js_TraceKind_h - -#include "mozilla/UniquePtr.h" - -#include "js/TypeDecls.h" - -// Forward declarations of all the types a TraceKind can denote. -namespace js { -class BaseShape; -class LazyScript; -class ObjectGroup; -class Shape; -class Scope; -namespace jit { -class JitCode; -} // namespace jit -} // namespace js - -namespace JS { - -// When tracing a thing, the GC needs to know about the layout of the object it -// is looking at. There are a fixed number of different layouts that the GC -// knows about. The "trace kind" is a static map which tells which layout a GC -// thing has. -// -// Although this map is public, the details are completely hidden. Not all of -// the matching C++ types are exposed, and those that are, are opaque. -// -// See Value::gcKind() and JSTraceCallback in Tracer.h for more details. -enum class TraceKind -{ - // These trace kinds have a publicly exposed, although opaque, C++ type. - // Note: The order here is determined by our Value packing. Other users - // should sort alphabetically, for consistency. - Object = 0x00, - String = 0x01, - Symbol = 0x02, - Script = 0x03, - - // Shape details are exposed through JS_TraceShapeCycleCollectorChildren. - Shape = 0x04, - - // ObjectGroup details are exposed through JS_TraceObjectGroupCycleCollectorChildren. - ObjectGroup = 0x05, - - // The kind associated with a nullptr. - Null = 0x06, - - // The following kinds do not have an exposed C++ idiom. - BaseShape = 0x0F, - JitCode = 0x1F, - LazyScript = 0x2F, - Scope = 0x3F -}; -const static uintptr_t OutOfLineTraceKindMask = 0x07; -static_assert(uintptr_t(JS::TraceKind::BaseShape) & OutOfLineTraceKindMask, "mask bits are set"); -static_assert(uintptr_t(JS::TraceKind::JitCode) & OutOfLineTraceKindMask, "mask bits are set"); -static_assert(uintptr_t(JS::TraceKind::LazyScript) & OutOfLineTraceKindMask, "mask bits are set"); -static_assert(uintptr_t(JS::TraceKind::Scope) & OutOfLineTraceKindMask, "mask bits are set"); - -// When this header is imported inside SpiderMonkey, the class definitions are -// available and we can query those definitions to find the correct kind -// directly from the class hierarchy. -template -struct MapTypeToTraceKind { - static const JS::TraceKind kind = T::TraceKind; -}; - -// When this header is used outside SpiderMonkey, the class definitions are not -// available, so the following table containing all public GC types is used. -#define JS_FOR_EACH_TRACEKIND(D) \ - /* PrettyName TypeName AddToCCKind */ \ - D(BaseShape, js::BaseShape, true) \ - D(JitCode, js::jit::JitCode, true) \ - D(LazyScript, js::LazyScript, true) \ - D(Scope, js::Scope, true) \ - D(Object, JSObject, true) \ - D(ObjectGroup, js::ObjectGroup, true) \ - D(Script, JSScript, true) \ - D(Shape, js::Shape, true) \ - D(String, JSString, false) \ - D(Symbol, JS::Symbol, false) - -// Map from all public types to their trace kind. -#define JS_EXPAND_DEF(name, type, _) \ - template <> struct MapTypeToTraceKind { \ - static const JS::TraceKind kind = JS::TraceKind::name; \ - }; -JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF); -#undef JS_EXPAND_DEF - -// RootKind is closely related to TraceKind. Whereas TraceKind's indices are -// laid out for convenient embedding as a pointer tag, the indicies of RootKind -// are designed for use as array keys via EnumeratedArray. -enum class RootKind : int8_t -{ - // These map 1:1 with trace kinds. -#define EXPAND_ROOT_KIND(name, _0, _1) \ - name, -JS_FOR_EACH_TRACEKIND(EXPAND_ROOT_KIND) -#undef EXPAND_ROOT_KIND - - // These tagged pointers are special-cased for performance. - Id, - Value, - - // Everything else. - Traceable, - - Limit -}; - -// Most RootKind correspond directly to a trace kind. -template struct MapTraceKindToRootKind {}; -#define JS_EXPAND_DEF(name, _0, _1) \ - template <> struct MapTraceKindToRootKind { \ - static const JS::RootKind kind = JS::RootKind::name; \ - }; -JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF) -#undef JS_EXPAND_DEF - -// Specify the RootKind for all types. Value and jsid map to special cases; -// pointer types we can derive directly from the TraceKind; everything else -// should go in the Traceable list and use GCPolicy::trace for tracing. -template -struct MapTypeToRootKind { - static const JS::RootKind kind = JS::RootKind::Traceable; -}; -template -struct MapTypeToRootKind { - static const JS::RootKind kind = - JS::MapTraceKindToRootKind::kind>::kind; -}; -template -struct MapTypeToRootKind> { - static const JS::RootKind kind = JS::MapTypeToRootKind::kind; -}; -template <> struct MapTypeToRootKind { - static const JS::RootKind kind = JS::RootKind::Value; -}; -template <> struct MapTypeToRootKind { - static const JS::RootKind kind = JS::RootKind::Id; -}; -template <> struct MapTypeToRootKind : public MapTypeToRootKind {}; - -// Fortunately, few places in the system need to deal with fully abstract -// cells. In those places that do, we generally want to move to a layout -// templated function as soon as possible. This template wraps the upcast -// for that dispatch. -// -// Given a call: -// -// DispatchTraceKindTyped(f, thing, traceKind, ... args) -// -// Downcast the |void *thing| to the specific type designated by |traceKind|, -// and pass it to the functor |f| along with |... args|, forwarded. Pass the -// type designated by |traceKind| as the functor's template argument. The -// |thing| parameter is optional; without it, we simply pass through |... args|. - -// GCC and Clang require an explicit template declaration in front of the -// specialization of operator() because it is a dependent template. MSVC, on -// the other hand, gets very confused if we have a |template| token there. -// The clang-cl front end defines _MSC_VER, but still requires the explicit -// template declaration, so we must test for __clang__ here as well. -#if defined(_MSC_VER) && !defined(__clang__) -# define JS_DEPENDENT_TEMPLATE_HINT -#else -# define JS_DEPENDENT_TEMPLATE_HINT template -#endif -template -auto -DispatchTraceKindTyped(F f, JS::TraceKind traceKind, Args&&... args) - -> decltype(f. JS_DEPENDENT_TEMPLATE_HINT operator()(mozilla::Forward(args)...)) -{ - switch (traceKind) { -#define JS_EXPAND_DEF(name, type, _) \ - case JS::TraceKind::name: \ - return f. JS_DEPENDENT_TEMPLATE_HINT operator()(mozilla::Forward(args)...); - JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF); -#undef JS_EXPAND_DEF - default: - MOZ_CRASH("Invalid trace kind in DispatchTraceKindTyped."); - } -} -#undef JS_DEPENDENT_TEMPLATE_HINT - -template -auto -DispatchTraceKindTyped(F f, void* thing, JS::TraceKind traceKind, Args&&... args) - -> decltype(f(static_cast(nullptr), mozilla::Forward(args)...)) -{ - switch (traceKind) { -#define JS_EXPAND_DEF(name, type, _) \ - case JS::TraceKind::name: \ - return f(static_cast(thing), mozilla::Forward(args)...); - JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF); -#undef JS_EXPAND_DEF - default: - MOZ_CRASH("Invalid trace kind in DispatchTraceKindTyped."); - } -} - -} // namespace JS - -#endif // js_TraceKind_h diff --git a/android/armeabi-v7a/include/spidermonkey/js/TracingAPI.h b/android/armeabi-v7a/include/spidermonkey/js/TracingAPI.h deleted file mode 100644 index 37c69aca..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/TracingAPI.h +++ /dev/null @@ -1,403 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_TracingAPI_h -#define js_TracingAPI_h - -#include "jsalloc.h" - -#include "js/HashTable.h" -#include "js/HeapAPI.h" -#include "js/TraceKind.h" - -class JS_PUBLIC_API(JSTracer); - -namespace JS { -class JS_PUBLIC_API(CallbackTracer); -template class Heap; -template class TenuredHeap; - -/** Returns a static string equivalent of |kind|. */ -JS_FRIEND_API(const char*) -GCTraceKindToAscii(JS::TraceKind kind); - -} // namespace JS - -enum WeakMapTraceKind { - /** - * Do not trace into weak map keys or values during traversal. Users must - * handle weak maps manually. - */ - DoNotTraceWeakMaps, - - /** - * Do true ephemeron marking with a weak key lookup marking phase. This is - * the default for GCMarker. - */ - ExpandWeakMaps, - - /** - * Trace through to all values, irrespective of whether the keys are live - * or not. Used for non-marking tracers. - */ - TraceWeakMapValues, - - /** - * Trace through to all keys and values, irrespective of whether the keys - * are live or not. Used for non-marking tracers. - */ - TraceWeakMapKeysValues -}; - -class JS_PUBLIC_API(JSTracer) -{ - public: - // Return the runtime set on the tracer. - JSRuntime* runtime() const { return runtime_; } - - // Return the weak map tracing behavior currently set on this tracer. - WeakMapTraceKind weakMapAction() const { return weakMapAction_; } - - enum class TracerKindTag { - // Marking path: a tracer used only for marking liveness of cells, not - // for moving them. The kind will transition to WeakMarking after - // everything reachable by regular edges has been marked. - Marking, - - // Same as Marking, except we have now moved on to the "weak marking - // phase", in which every marked obj/script is immediately looked up to - // see if it is a weak map key (and therefore might require marking its - // weak map value). - WeakMarking, - - // A tracer that traverses the graph for the purposes of moving objects - // from the nursery to the tenured area. - Tenuring, - - // General-purpose traversal that invokes a callback on each cell. - // Traversing children is the responsibility of the callback. - Callback - }; - bool isMarkingTracer() const { return tag_ == TracerKindTag::Marking || tag_ == TracerKindTag::WeakMarking; } - bool isWeakMarkingTracer() const { return tag_ == TracerKindTag::WeakMarking; } - bool isTenuringTracer() const { return tag_ == TracerKindTag::Tenuring; } - bool isCallbackTracer() const { return tag_ == TracerKindTag::Callback; } - inline JS::CallbackTracer* asCallbackTracer(); -#ifdef DEBUG - bool checkEdges() { return checkEdges_; } -#endif - - protected: - JSTracer(JSRuntime* rt, TracerKindTag tag, - WeakMapTraceKind weakTraceKind = TraceWeakMapValues) - : runtime_(rt) - , weakMapAction_(weakTraceKind) -#ifdef DEBUG - , checkEdges_(true) -#endif - , tag_(tag) - {} - -#ifdef DEBUG - // Set whether to check edges are valid in debug builds. - void setCheckEdges(bool check) { - checkEdges_ = check; - } -#endif - - private: - JSRuntime* runtime_; - WeakMapTraceKind weakMapAction_; -#ifdef DEBUG - bool checkEdges_; -#endif - - protected: - TracerKindTag tag_; -}; - -namespace JS { - -class AutoTracingName; -class AutoTracingIndex; -class AutoTracingCallback; - -class JS_PUBLIC_API(CallbackTracer) : public JSTracer -{ - public: - CallbackTracer(JSRuntime* rt, WeakMapTraceKind weakTraceKind = TraceWeakMapValues) - : JSTracer(rt, JSTracer::TracerKindTag::Callback, weakTraceKind), - contextName_(nullptr), contextIndex_(InvalidIndex), contextFunctor_(nullptr) - {} - CallbackTracer(JSContext* cx, WeakMapTraceKind weakTraceKind = TraceWeakMapValues); - - // Override these methods to receive notification when an edge is visited - // with the type contained in the callback. The default implementation - // dispatches to the fully-generic onChild implementation, so for cases that - // do not care about boxing overhead and do not need the actual edges, - // just override the generic onChild. - virtual void onObjectEdge(JSObject** objp) { onChild(JS::GCCellPtr(*objp)); } - virtual void onStringEdge(JSString** strp) { onChild(JS::GCCellPtr(*strp)); } - virtual void onSymbolEdge(JS::Symbol** symp) { onChild(JS::GCCellPtr(*symp)); } - virtual void onScriptEdge(JSScript** scriptp) { onChild(JS::GCCellPtr(*scriptp)); } - virtual void onShapeEdge(js::Shape** shapep) { - onChild(JS::GCCellPtr(*shapep, JS::TraceKind::Shape)); - } - virtual void onObjectGroupEdge(js::ObjectGroup** groupp) { - onChild(JS::GCCellPtr(*groupp, JS::TraceKind::ObjectGroup)); - } - virtual void onBaseShapeEdge(js::BaseShape** basep) { - onChild(JS::GCCellPtr(*basep, JS::TraceKind::BaseShape)); - } - virtual void onJitCodeEdge(js::jit::JitCode** codep) { - onChild(JS::GCCellPtr(*codep, JS::TraceKind::JitCode)); - } - virtual void onLazyScriptEdge(js::LazyScript** lazyp) { - onChild(JS::GCCellPtr(*lazyp, JS::TraceKind::LazyScript)); - } - virtual void onScopeEdge(js::Scope** scopep) { - onChild(JS::GCCellPtr(*scopep, JS::TraceKind::Scope)); - } - - // Override this method to receive notification when a node in the GC - // heap graph is visited. - virtual void onChild(const JS::GCCellPtr& thing) = 0; - - // Access to the tracing context: - // When tracing with a JS::CallbackTracer, we invoke the callback with the - // edge location and the type of target. This is useful for operating on - // the edge in the abstract or on the target thing, satisfying most common - // use cases. However, some tracers need additional detail about the - // specific edge that is being traced in order to be useful. Unfortunately, - // the raw pointer to the edge that we provide is not enough information to - // infer much of anything useful about that edge. - // - // In order to better support use cases that care in particular about edges - // -- as opposed to the target thing -- tracing implementations are - // responsible for providing extra context information about each edge they - // trace, as it is traced. This contains, at a minimum, an edge name and, - // when tracing an array, the index. Further specialization can be achived - // (with some complexity), by associating a functor with the tracer so - // that, when requested, the user can generate totally custom edge - // descriptions. - - // Returns the current edge's name. It is only valid to call this when - // inside the trace callback, however, the edge name will always be set. - const char* contextName() const { MOZ_ASSERT(contextName_); return contextName_; } - - // Returns the current edge's index, if marked as part of an array of edges. - // This must be called only inside the trace callback. When not tracing an - // array, the value will be InvalidIndex. - const static size_t InvalidIndex = size_t(-1); - size_t contextIndex() const { return contextIndex_; } - - // Build a description of this edge in the heap graph. This call may invoke - // the context functor, if set, which may inspect arbitrary areas of the - // heap. On the other hand, the description provided by this method may be - // substantially more accurate and useful than those provided by only the - // contextName and contextIndex. - void getTracingEdgeName(char* buffer, size_t bufferSize); - - // The trace implementation may associate a callback with one or more edges - // using AutoTracingDetails. This functor is called by getTracingEdgeName - // and is responsible for providing a textual representation of the - // currently being traced edge. The callback has access to the full heap, - // including the currently set tracing context. - class ContextFunctor { - public: - virtual void operator()(CallbackTracer* trc, char* buf, size_t bufsize) = 0; - }; - -#ifdef DEBUG - enum class TracerKind { DoNotCare, Moving, GrayBuffering, VerifyTraceProtoAndIface }; - virtual TracerKind getTracerKind() const { return TracerKind::DoNotCare; } -#endif - - // In C++, overriding a method hides all methods in the base class with - // that name, not just methods with that signature. Thus, the typed edge - // methods have to have distinct names to allow us to override them - // individually, which is freqently useful if, for example, we only want to - // process only one type of edge. - void dispatchToOnEdge(JSObject** objp) { onObjectEdge(objp); } - void dispatchToOnEdge(JSString** strp) { onStringEdge(strp); } - void dispatchToOnEdge(JS::Symbol** symp) { onSymbolEdge(symp); } - void dispatchToOnEdge(JSScript** scriptp) { onScriptEdge(scriptp); } - void dispatchToOnEdge(js::Shape** shapep) { onShapeEdge(shapep); } - void dispatchToOnEdge(js::ObjectGroup** groupp) { onObjectGroupEdge(groupp); } - void dispatchToOnEdge(js::BaseShape** basep) { onBaseShapeEdge(basep); } - void dispatchToOnEdge(js::jit::JitCode** codep) { onJitCodeEdge(codep); } - void dispatchToOnEdge(js::LazyScript** lazyp) { onLazyScriptEdge(lazyp); } - void dispatchToOnEdge(js::Scope** scopep) { onScopeEdge(scopep); } - - private: - friend class AutoTracingName; - const char* contextName_; - - friend class AutoTracingIndex; - size_t contextIndex_; - - friend class AutoTracingDetails; - ContextFunctor* contextFunctor_; -}; - -// Set the name portion of the tracer's context for the current edge. -class MOZ_RAII AutoTracingName -{ - CallbackTracer* trc_; - const char* prior_; - - public: - AutoTracingName(CallbackTracer* trc, const char* name) : trc_(trc), prior_(trc->contextName_) { - MOZ_ASSERT(name); - trc->contextName_ = name; - } - ~AutoTracingName() { - MOZ_ASSERT(trc_->contextName_); - trc_->contextName_ = prior_; - } -}; - -// Set the index portion of the tracer's context for the current range. -class MOZ_RAII AutoTracingIndex -{ - CallbackTracer* trc_; - - public: - explicit AutoTracingIndex(JSTracer* trc, size_t initial = 0) : trc_(nullptr) { - if (trc->isCallbackTracer()) { - trc_ = trc->asCallbackTracer(); - MOZ_ASSERT(trc_->contextIndex_ == CallbackTracer::InvalidIndex); - trc_->contextIndex_ = initial; - } - } - ~AutoTracingIndex() { - if (trc_) { - MOZ_ASSERT(trc_->contextIndex_ != CallbackTracer::InvalidIndex); - trc_->contextIndex_ = CallbackTracer::InvalidIndex; - } - } - - void operator++() { - if (trc_) { - MOZ_ASSERT(trc_->contextIndex_ != CallbackTracer::InvalidIndex); - ++trc_->contextIndex_; - } - } -}; - -// Set a context callback for the trace callback to use, if it needs a detailed -// edge description. -class MOZ_RAII AutoTracingDetails -{ - CallbackTracer* trc_; - - public: - AutoTracingDetails(JSTracer* trc, CallbackTracer::ContextFunctor& func) : trc_(nullptr) { - if (trc->isCallbackTracer()) { - trc_ = trc->asCallbackTracer(); - MOZ_ASSERT(trc_->contextFunctor_ == nullptr); - trc_->contextFunctor_ = &func; - } - } - ~AutoTracingDetails() { - if (trc_) { - MOZ_ASSERT(trc_->contextFunctor_); - trc_->contextFunctor_ = nullptr; - } - } -}; - -} // namespace JS - -JS::CallbackTracer* -JSTracer::asCallbackTracer() -{ - MOZ_ASSERT(isCallbackTracer()); - return static_cast(this); -} - -namespace JS { - -// The JS::TraceEdge family of functions traces the given GC thing reference. -// This performs the tracing action configured on the given JSTracer: typically -// calling the JSTracer::callback or marking the thing as live. -// -// The argument to JS::TraceEdge is an in-out param: when the function returns, -// the garbage collector might have moved the GC thing. In this case, the -// reference passed to JS::TraceEdge will be updated to the thing's new -// location. Callers of this method are responsible for updating any state that -// is dependent on the object's address. For example, if the object's address -// is used as a key in a hashtable, then the object must be removed and -// re-inserted with the correct hash. -// -// Note that while |edgep| must never be null, it is fine for |*edgep| to be -// nullptr. -template -extern JS_PUBLIC_API(void) -TraceEdge(JSTracer* trc, JS::Heap* edgep, const char* name); - -extern JS_PUBLIC_API(void) -TraceEdge(JSTracer* trc, JS::TenuredHeap* edgep, const char* name); - -// Edges that are always traced as part of root marking do not require -// incremental barriers. This function allows for marking non-barriered -// pointers, but asserts that this happens during root marking. -// -// Note that while |edgep| must never be null, it is fine for |*edgep| to be -// nullptr. -template -extern JS_PUBLIC_API(void) -UnsafeTraceRoot(JSTracer* trc, T* edgep, const char* name); - -extern JS_PUBLIC_API(void) -TraceChildren(JSTracer* trc, GCCellPtr thing); - -using ZoneSet = js::HashSet, js::SystemAllocPolicy>; -using CompartmentSet = js::HashSet, - js::SystemAllocPolicy>; - -/** - * Trace every value within |compartments| that is wrapped by a - * cross-compartment wrapper from a compartment that is not an element of - * |compartments|. - */ -extern JS_PUBLIC_API(void) -TraceIncomingCCWs(JSTracer* trc, const JS::CompartmentSet& compartments); - -} // namespace JS - -extern JS_PUBLIC_API(void) -JS_GetTraceThingInfo(char* buf, size_t bufsize, JSTracer* trc, - void* thing, JS::TraceKind kind, bool includeDetails); - -namespace js { - -// Trace an edge that is not a GC root and is not wrapped in a barriered -// wrapper for some reason. -// -// This method does not check if |*edgep| is non-null before tracing through -// it, so callers must check any nullable pointer before calling this method. -template -extern JS_PUBLIC_API(void) -UnsafeTraceManuallyBarrieredEdge(JSTracer* trc, T* edgep, const char* name); - -namespace gc { - -// Return true if the given edge is not live and is about to be swept. -template -extern JS_PUBLIC_API(bool) -EdgeNeedsSweep(JS::Heap* edgep); - -// Not part of the public API, but declared here so we can use it in GCPolicy -// which is. -template -bool -IsAboutToBeFinalizedUnbarriered(T* thingp); - -} // namespace gc -} // namespace js - -#endif /* js_TracingAPI_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/TrackedOptimizationInfo.h b/android/armeabi-v7a/include/spidermonkey/js/TrackedOptimizationInfo.h deleted file mode 100644 index b697765c..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/TrackedOptimizationInfo.h +++ /dev/null @@ -1,285 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_TrackedOptimizationInfo_h -#define js_TrackedOptimizationInfo_h - -#include "mozilla/Maybe.h" - -namespace JS { - -#define TRACKED_STRATEGY_LIST(_) \ - _(GetProp_ArgumentsLength) \ - _(GetProp_ArgumentsCallee) \ - _(GetProp_InferredConstant) \ - _(GetProp_Constant) \ - _(GetProp_NotDefined) \ - _(GetProp_StaticName) \ - _(GetProp_SimdGetter) \ - _(GetProp_TypedObject) \ - _(GetProp_DefiniteSlot) \ - _(GetProp_Unboxed) \ - _(GetProp_CommonGetter) \ - _(GetProp_InlineAccess) \ - _(GetProp_Innerize) \ - _(GetProp_InlineCache) \ - _(GetProp_SharedCache) \ - _(GetProp_ModuleNamespace) \ - \ - _(SetProp_CommonSetter) \ - _(SetProp_TypedObject) \ - _(SetProp_DefiniteSlot) \ - _(SetProp_Unboxed) \ - _(SetProp_InlineAccess) \ - _(SetProp_InlineCache) \ - \ - _(GetElem_TypedObject) \ - _(GetElem_Dense) \ - _(GetElem_TypedStatic) \ - _(GetElem_TypedArray) \ - _(GetElem_String) \ - _(GetElem_Arguments) \ - _(GetElem_ArgumentsInlined) \ - _(GetElem_InlineCache) \ - \ - _(SetElem_TypedObject) \ - _(SetElem_TypedStatic) \ - _(SetElem_TypedArray) \ - _(SetElem_Dense) \ - _(SetElem_Arguments) \ - _(SetElem_InlineCache) \ - \ - _(BinaryArith_Concat) \ - _(BinaryArith_SpecializedTypes) \ - _(BinaryArith_SpecializedOnBaselineTypes) \ - _(BinaryArith_SharedCache) \ - _(BinaryArith_Call) \ - \ - _(InlineCache_OptimizedStub) \ - \ - _(Call_Inline) - - -// Ordering is important below. All outcomes before GenericSuccess will be -// considered failures, and all outcomes after GenericSuccess will be -// considered successes. -#define TRACKED_OUTCOME_LIST(_) \ - _(GenericFailure) \ - _(Disabled) \ - _(NoTypeInfo) \ - _(NoAnalysisInfo) \ - _(NoShapeInfo) \ - _(UnknownObject) \ - _(UnknownProperties) \ - _(Singleton) \ - _(NotSingleton) \ - _(NotFixedSlot) \ - _(InconsistentFixedSlot) \ - _(NotObject) \ - _(NotStruct) \ - _(NotUnboxed) \ - _(NotUndefined) \ - _(UnboxedConvertedToNative) \ - _(StructNoField) \ - _(InconsistentFieldType) \ - _(InconsistentFieldOffset) \ - _(NeedsTypeBarrier) \ - _(InDictionaryMode) \ - _(NoProtoFound) \ - _(MultiProtoPaths) \ - _(NonWritableProperty) \ - _(ProtoIndexedProps) \ - _(ArrayBadFlags) \ - _(ArrayDoubleConversion) \ - _(ArrayRange) \ - _(ArraySeenNegativeIndex) \ - _(TypedObjectHasDetachedBuffer) \ - _(TypedObjectArrayRange) \ - _(AccessNotDense) \ - _(AccessNotSimdObject) \ - _(AccessNotTypedObject) \ - _(AccessNotTypedArray) \ - _(AccessNotString) \ - _(OperandNotString) \ - _(OperandNotNumber) \ - _(OperandNotStringOrNumber) \ - _(OperandNotSimpleArith) \ - _(StaticTypedArrayUint32) \ - _(StaticTypedArrayCantComputeMask) \ - _(OutOfBounds) \ - _(GetElemStringNotCached) \ - _(NonNativeReceiver) \ - _(IndexType) \ - _(SetElemNonDenseNonTANotCached) \ - _(NoSimdJitSupport) \ - _(SimdTypeNotOptimized) \ - _(UnknownSimdProperty) \ - _(NotModuleNamespace) \ - _(UnknownProperty) \ - \ - _(ICOptStub_GenericSuccess) \ - \ - _(ICGetPropStub_ReadSlot) \ - _(ICGetPropStub_CallGetter) \ - _(ICGetPropStub_ArrayLength) \ - _(ICGetPropStub_UnboxedRead) \ - _(ICGetPropStub_UnboxedReadExpando) \ - _(ICGetPropStub_UnboxedArrayLength) \ - _(ICGetPropStub_TypedArrayLength) \ - _(ICGetPropStub_DOMProxyShadowed) \ - _(ICGetPropStub_DOMProxyUnshadowed) \ - _(ICGetPropStub_GenericProxy) \ - _(ICGetPropStub_ArgumentsLength) \ - \ - _(ICSetPropStub_Slot) \ - _(ICSetPropStub_GenericProxy) \ - _(ICSetPropStub_DOMProxyShadowed) \ - _(ICSetPropStub_DOMProxyUnshadowed) \ - _(ICSetPropStub_CallSetter) \ - _(ICSetPropStub_AddSlot) \ - _(ICSetPropStub_SetUnboxed) \ - \ - _(ICGetElemStub_ReadSlot) \ - _(ICGetElemStub_CallGetter) \ - _(ICGetElemStub_ReadUnboxed) \ - _(ICGetElemStub_Dense) \ - _(ICGetElemStub_DenseHole) \ - _(ICGetElemStub_TypedArray) \ - _(ICGetElemStub_ArgsElementMapped) \ - _(ICGetElemStub_ArgsElementUnmapped) \ - \ - _(ICSetElemStub_Dense) \ - _(ICSetElemStub_TypedArray) \ - \ - _(ICNameStub_ReadSlot) \ - _(ICNameStub_CallGetter) \ - _(ICNameStub_TypeOfNoProperty) \ - \ - _(CantInlineGeneric) \ - _(CantInlineNoTarget) \ - _(CantInlineNotInterpreted) \ - _(CantInlineNoBaseline) \ - _(CantInlineLazy) \ - _(CantInlineNotConstructor) \ - _(CantInlineClassConstructor) \ - _(CantInlineDisabledIon) \ - _(CantInlineTooManyArgs) \ - _(CantInlineNeedsArgsObj) \ - _(CantInlineDebuggee) \ - _(CantInlineUnknownProps) \ - _(CantInlineExceededDepth) \ - _(CantInlineExceededTotalBytecodeLength) \ - _(CantInlineBigCaller) \ - _(CantInlineBigCallee) \ - _(CantInlineBigCalleeInlinedBytecodeLength) \ - _(CantInlineNotHot) \ - _(CantInlineNotInDispatch) \ - _(CantInlineUnreachable) \ - _(CantInlineNativeBadForm) \ - _(CantInlineNativeBadType) \ - _(CantInlineNativeNoTemplateObj) \ - _(CantInlineBound) \ - _(CantInlineNativeNoSpecialization) \ - _(HasCommonInliningPath) \ - \ - _(GenericSuccess) \ - _(Inlined) \ - _(DOM) \ - _(Monomorphic) \ - _(Polymorphic) - -#define TRACKED_TYPESITE_LIST(_) \ - _(Receiver) \ - _(Operand) \ - _(Index) \ - _(Value) \ - _(Call_Target) \ - _(Call_This) \ - _(Call_Arg) \ - _(Call_Return) - -enum class TrackedStrategy : uint32_t { -#define STRATEGY_OP(name) name, - TRACKED_STRATEGY_LIST(STRATEGY_OP) -#undef STRATEGY_OPT - - Count -}; - -enum class TrackedOutcome : uint32_t { -#define OUTCOME_OP(name) name, - TRACKED_OUTCOME_LIST(OUTCOME_OP) -#undef OUTCOME_OP - - Count -}; - -enum class TrackedTypeSite : uint32_t { -#define TYPESITE_OP(name) name, - TRACKED_TYPESITE_LIST(TYPESITE_OP) -#undef TYPESITE_OP - - Count -}; - -JS_PUBLIC_API(const char*) -TrackedStrategyString(TrackedStrategy strategy); - -JS_PUBLIC_API(const char*) -TrackedOutcomeString(TrackedOutcome outcome); - -JS_PUBLIC_API(const char*) -TrackedTypeSiteString(TrackedTypeSite site); - -struct ForEachTrackedOptimizationAttemptOp -{ - virtual void operator()(TrackedStrategy strategy, TrackedOutcome outcome) = 0; -}; - -struct ForEachTrackedOptimizationTypeInfoOp -{ - // Called 0+ times per entry, once for each type in the type set that Ion - // saw during MIR construction. readType is always called _before_ - // operator() on the same entry. - // - // The keyedBy parameter describes how the type is keyed: - // - "primitive" for primitive types - // - "constructor" for object types tied to a scripted constructor - // function. - // - "alloc site" for object types tied to an allocation site. - // - "prototype" for object types tied neither to a constructor nor - // to an allocation site, but to a prototype. - // - "singleton" for object types which only has a single value. - // - "function" for object types referring to scripted functions. - // - "native" for object types referring to native functions. - // - // The name parameter is the string representation of the type. If the - // type is keyed by "constructor", or if the type itself refers to a - // scripted function, the name is the function's displayAtom. If the type - // is keyed by "native", this is nullptr. - // - // The location parameter is the filename if the type is keyed by - // "constructor", "alloc site", or if the type itself refers to a scripted - // function. If the type is keyed by "native", it is the offset of the - // native function, suitable for use with addr2line on Linux or atos on OS - // X. Otherwise it is nullptr. - // - // The lineno parameter is the line number if the type is keyed by - // "constructor", "alloc site", or if the type itself refers to a scripted - // function. Otherwise it is Nothing(). - // - // The location parameter is the only one that may need escaping if being - // quoted. - virtual void readType(const char* keyedBy, const char* name, - const char* location, mozilla::Maybe lineno) = 0; - - // Called once per entry. - virtual void operator()(TrackedTypeSite site, const char* mirType) = 0; -}; - -} // namespace JS - -#endif // js_TrackedOptimizationInfo_h diff --git a/android/armeabi-v7a/include/spidermonkey/js/TypeDecls.h b/android/armeabi-v7a/include/spidermonkey/js/TypeDecls.h deleted file mode 100644 index acb93f97..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/TypeDecls.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -// This file contains public type declarations that are used *frequently*. If -// it doesn't occur at least 10 times in Gecko, it probably shouldn't be in -// here. -// -// It includes only: -// - forward declarations of structs and classes; -// - typedefs; -// - enums (maybe). -// It does *not* contain any struct or class definitions. - -#ifndef js_TypeDecls_h -#define js_TypeDecls_h - -#include -#include - -#include "js-config.h" - -struct JSContext; -class JSFunction; -class JSObject; -class JSScript; -class JSString; -class JSAddonId; - -struct jsid; - -namespace JS { - -typedef unsigned char Latin1Char; - -class Symbol; -class Value; -template class Handle; -template class MutableHandle; -template class Rooted; -template class PersistentRooted; - -typedef Handle HandleFunction; -typedef Handle HandleId; -typedef Handle HandleObject; -typedef Handle HandleScript; -typedef Handle HandleString; -typedef Handle HandleSymbol; -typedef Handle HandleValue; - -typedef MutableHandle MutableHandleFunction; -typedef MutableHandle MutableHandleId; -typedef MutableHandle MutableHandleObject; -typedef MutableHandle MutableHandleScript; -typedef MutableHandle MutableHandleString; -typedef MutableHandle MutableHandleSymbol; -typedef MutableHandle MutableHandleValue; - -typedef Rooted RootedObject; -typedef Rooted RootedFunction; -typedef Rooted RootedScript; -typedef Rooted RootedString; -typedef Rooted RootedSymbol; -typedef Rooted RootedId; -typedef Rooted RootedValue; - -typedef PersistentRooted PersistentRootedFunction; -typedef PersistentRooted PersistentRootedId; -typedef PersistentRooted PersistentRootedObject; -typedef PersistentRooted PersistentRootedScript; -typedef PersistentRooted PersistentRootedString; -typedef PersistentRooted PersistentRootedSymbol; -typedef PersistentRooted PersistentRootedValue; - -} // namespace JS - -#endif /* js_TypeDecls_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/UbiNode.h b/android/armeabi-v7a/include/spidermonkey/js/UbiNode.h deleted file mode 100644 index c8742f33..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/UbiNode.h +++ /dev/null @@ -1,1144 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNode_h -#define js_UbiNode_h - -#include "mozilla/Alignment.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Maybe.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" -#include "mozilla/RangedPtr.h" -#include "mozilla/TypeTraits.h" -#include "mozilla/Variant.h" - -#include "jspubtd.h" - -#include "js/GCAPI.h" -#include "js/HashTable.h" -#include "js/RootingAPI.h" -#include "js/TracingAPI.h" -#include "js/TypeDecls.h" -#include "js/UniquePtr.h" -#include "js/Value.h" -#include "js/Vector.h" - -// JS::ubi::Node -// -// JS::ubi::Node is a pointer-like type designed for internal use by heap -// analysis tools. A ubi::Node can refer to: -// -// - a JS value, like a string, object, or symbol; -// - an internal SpiderMonkey structure, like a shape or a scope chain object -// - an instance of some embedding-provided type: in Firefox, an XPCOM -// object, or an internal DOM node class instance -// -// A ubi::Node instance provides metadata about its referent, and can -// enumerate its referent's outgoing edges, so you can implement heap analysis -// algorithms that walk the graph - finding paths between objects, or -// computing heap dominator trees, say - using ubi::Node, while remaining -// ignorant of the details of the types you're operating on. -// -// Of course, when it comes to presenting the results in a developer-facing -// tool, you'll need to stop being ignorant of those details, because you have -// to discuss the ubi::Nodes' referents with the developer. Here, ubi::Node -// can hand you dynamically checked, properly typed pointers to the original -// objects via the as method, or generate descriptions of the referent -// itself. -// -// ubi::Node instances are lightweight (two-word) value types. Instances: -// - compare equal if and only if they refer to the same object; -// - have hash values that respect their equality relation; and -// - have serializations that are only equal if the ubi::Nodes are equal. -// -// A ubi::Node is only valid for as long as its referent is alive; if its -// referent goes away, the ubi::Node becomes a dangling pointer. A ubi::Node -// that refers to a GC-managed object is not automatically a GC root; if the -// GC frees or relocates its referent, the ubi::Node becomes invalid. A -// ubi::Node that refers to a reference-counted object does not bump the -// reference count. -// -// ubi::Node values require no supporting data structures, making them -// feasible for use in memory-constrained devices --- ideally, the memory -// requirements of the algorithm which uses them will be the limiting factor, -// not the demands of ubi::Node itself. -// -// One can construct a ubi::Node value given a pointer to a type that ubi::Node -// supports. In the other direction, one can convert a ubi::Node back to a -// pointer; these downcasts are checked dynamically. In particular, one can -// convert a 'JSContext*' to a ubi::Node, yielding a node with an outgoing edge -// for every root registered with the runtime; starting from this, one can walk -// the entire heap. (Of course, one could also start traversal at any other kind -// of type to which one has a pointer.) -// -// -// Extending ubi::Node To Handle Your Embedding's Types -// -// To add support for a new ubi::Node referent type R, you must define a -// specialization of the ubi::Concrete template, ubi::Concrete, which -// inherits from ubi::Base. ubi::Node itself uses the specialization for -// compile-time information (i.e. the checked conversions between R * and -// ubi::Node), and the inheritance for run-time dispatching. -// -// -// ubi::Node Exposes Implementation Details -// -// In many cases, a JavaScript developer's view of their data differs -// substantially from its actual implementation. For example, while the -// ECMAScript specification describes objects as maps from property names to -// sets of attributes (like ECMAScript's [[Value]]), in practice many objects -// have only a pointer to a shape, shared with other similar objects, and -// indexed slots that contain the [[Value]] attributes. As another example, a -// string produced by concatenating two other strings may sometimes be -// represented by a "rope", a structure that points to the two original -// strings. -// -// We intend to use ubi::Node to write tools that report memory usage, so it's -// important that ubi::Node accurately portray how much memory nodes consume. -// Thus, for example, when data that apparently belongs to multiple nodes is -// in fact shared in a common structure, ubi::Node's graph uses a separate -// node for that shared structure, and presents edges to it from the data's -// apparent owners. For example, ubi::Node exposes SpiderMonkey objects' -// shapes and base shapes, and exposes rope string and substring structure, -// because these optimizations become visible when a tool reports how much -// memory a structure consumes. -// -// However, fine granularity is not a goal. When a particular object is the -// exclusive owner of a separate block of memory, ubi::Node may present the -// object and its block as a single node, and add their sizes together when -// reporting the node's size, as there is no meaningful loss of data in this -// case. Thus, for example, a ubi::Node referring to a JavaScript object, when -// asked for the object's size in bytes, includes the object's slot and -// element arrays' sizes in the total. There is no separate ubi::Node value -// representing the slot and element arrays, since they are owned exclusively -// by the object. -// -// -// Presenting Analysis Results To JavaScript Developers -// -// If an analysis provides its results in terms of ubi::Node values, a user -// interface presenting those results will generally need to clean them up -// before they can be understood by JavaScript developers. For example, -// JavaScript developers should not need to understand shapes, only JavaScript -// objects. Similarly, they should not need to understand the distinction -// between DOM nodes and the JavaScript shadow objects that represent them. -// -// -// Rooting Restrictions -// -// At present there is no way to root ubi::Node instances, so instances can't be -// live across any operation that might GC. Analyses using ubi::Node must either -// run to completion and convert their results to some other rootable type, or -// save their intermediate state in some rooted structure if they must GC before -// they complete. (For algorithms like path-finding and dominator tree -// computation, we implement the algorithm avoiding any operation that could -// cause a GC --- and use AutoCheckCannotGC to verify this.) -// -// If this restriction prevents us from implementing interesting tools, we may -// teach the GC how to root ubi::Nodes, fix up hash tables that use them as -// keys, etc. -// -// -// Hostile Graph Structure -// -// Analyses consuming ubi::Node graphs must be robust when presented with graphs -// that are deliberately constructed to exploit their weaknesses. When operating -// on live graphs, web content has control over the object graph, and less -// direct control over shape and string structure, and analyses should be -// prepared to handle extreme cases gracefully. For example, if an analysis were -// to use the C++ stack in a depth-first traversal, carefully constructed -// content could cause the analysis to overflow the stack. -// -// When ubi::Nodes refer to nodes deserialized from a heap snapshot, analyses -// must be even more careful: since snapshots often come from potentially -// compromised e10s content processes, even properties normally guaranteed by -// the platform (the proper linking of DOM nodes, for example) might be -// corrupted. While it is the deserializer's responsibility to check the basic -// structure of the snapshot file, the analyses should be prepared for ubi::Node -// graphs constructed from snapshots to be even more bizarre. - -class JSAtom; - -namespace JS { -namespace ubi { - -class Edge; -class EdgeRange; -class StackFrame; - -} // namespace ubi -} // namespace JS - -namespace JS { -namespace ubi { - -using mozilla::Forward; -using mozilla::Maybe; -using mozilla::Move; -using mozilla::RangedPtr; -using mozilla::Variant; - -template -using Vector = mozilla::Vector; - -/*** ubi::StackFrame ******************************************************************************/ - -// Concrete JS::ubi::StackFrame instances backed by a live SavedFrame object -// store their strings as JSAtom*, while deserialized stack frames from offline -// heap snapshots store their strings as const char16_t*. In order to provide -// zero-cost accessors to these strings in a single interface that works with -// both cases, we use this variant type. -class AtomOrTwoByteChars : public Variant { - using Base = Variant; - - public: - template - MOZ_IMPLICIT AtomOrTwoByteChars(T&& rhs) : Base(Forward(rhs)) { } - - template - AtomOrTwoByteChars& operator=(T&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move disallowed"); - this->~AtomOrTwoByteChars(); - new (this) AtomOrTwoByteChars(Forward(rhs)); - return *this; - } - - // Return the length of the given AtomOrTwoByteChars string. - size_t length(); - - // Copy the given AtomOrTwoByteChars string into the destination buffer, - // inflating if necessary. Does NOT null terminate. Returns the number of - // characters written to destination. - size_t copyToBuffer(RangedPtr destination, size_t length); -}; - -// The base class implemented by each ConcreteStackFrame type. Subclasses -// must not add data members to this class. -class BaseStackFrame { - friend class StackFrame; - - BaseStackFrame(const StackFrame&) = delete; - BaseStackFrame& operator=(const StackFrame&) = delete; - - protected: - void* ptr; - explicit BaseStackFrame(void* ptr) : ptr(ptr) { } - - public: - // This is a value type that should not have a virtual destructor. Don't add - // destructors in subclasses! - - // Get a unique identifier for this StackFrame. The identifier is not valid - // across garbage collections. - virtual uint64_t identifier() const { return uint64_t(uintptr_t(ptr)); } - - // Get this frame's parent frame. - virtual StackFrame parent() const = 0; - - // Get this frame's line number. - virtual uint32_t line() const = 0; - - // Get this frame's column number. - virtual uint32_t column() const = 0; - - // Get this frame's source name. Never null. - virtual AtomOrTwoByteChars source() const = 0; - - // Return this frame's function name if named, otherwise the inferred - // display name. Can be null. - virtual AtomOrTwoByteChars functionDisplayName() const = 0; - - // Returns true if this frame's function is system JavaScript running with - // trusted principals, false otherwise. - virtual bool isSystem() const = 0; - - // Return true if this frame's function is a self-hosted JavaScript builtin, - // false otherwise. - virtual bool isSelfHosted(JSContext* cx) const = 0; - - // Construct a SavedFrame stack for the stack starting with this frame and - // containing all of its parents. The SavedFrame objects will be placed into - // cx's current compartment. - // - // Note that the process of - // - // SavedFrame - // | - // V - // JS::ubi::StackFrame - // | - // V - // offline heap snapshot - // | - // V - // JS::ubi::StackFrame - // | - // V - // SavedFrame - // - // is lossy because we cannot serialize and deserialize the SavedFrame's - // principals in the offline heap snapshot, so JS::ubi::StackFrame - // simplifies the principals check into the boolean isSystem() state. This - // is fine because we only expose JS::ubi::Stack to devtools and chrome - // code, and not to the web platform. - virtual MOZ_MUST_USE bool constructSavedFrameStack(JSContext* cx, - MutableHandleObject outSavedFrameStack) - const = 0; - - // Trace the concrete implementation of JS::ubi::StackFrame. - virtual void trace(JSTracer* trc) = 0; -}; - -// A traits template with a specialization for each backing type that implements -// the ubi::BaseStackFrame interface. Each specialization must be the a subclass -// of ubi::BaseStackFrame. -template class ConcreteStackFrame; - -// A JS::ubi::StackFrame represents a frame in a recorded stack. It can be -// backed either by a live SavedFrame object or by a structure deserialized from -// an offline heap snapshot. -// -// It is a value type that may be memcpy'd hither and thither without worrying -// about constructors or destructors, similar to POD types. -// -// Its lifetime is the same as the lifetime of the graph that is being analyzed -// by the JS::ubi::Node that the JS::ubi::StackFrame came from. That is, if the -// graph being analyzed is the live heap graph, the JS::ubi::StackFrame is only -// valid within the scope of an AutoCheckCannotGC; if the graph being analyzed -// is an offline heap snapshot, the JS::ubi::StackFrame is valid as long as the -// offline heap snapshot is alive. -class StackFrame { - // Storage in which we allocate BaseStackFrame subclasses. - mozilla::AlignedStorage2 storage; - - BaseStackFrame* base() { return storage.addr(); } - const BaseStackFrame* base() const { return storage.addr(); } - - template - void construct(T* ptr) { - static_assert(mozilla::IsBaseOf>::value, - "ConcreteStackFrame must inherit from BaseStackFrame"); - static_assert(sizeof(ConcreteStackFrame) == sizeof(*base()), - "ubi::ConcreteStackFrame specializations must be the same size as " - "ubi::BaseStackFrame"); - ConcreteStackFrame::construct(base(), ptr); - } - struct ConstructFunctor; - - public: - StackFrame() { construct(nullptr); } - - template - MOZ_IMPLICIT StackFrame(T* ptr) { - construct(ptr); - } - - template - StackFrame& operator=(T* ptr) { - construct(ptr); - return *this; - } - - // Constructors accepting SpiderMonkey's generic-pointer-ish types. - - template - explicit StackFrame(const JS::Handle& handle) { - construct(handle.get()); - } - - template - StackFrame& operator=(const JS::Handle& handle) { - construct(handle.get()); - return *this; - } - - template - explicit StackFrame(const JS::Rooted& root) { - construct(root.get()); - } - - template - StackFrame& operator=(const JS::Rooted& root) { - construct(root.get()); - return *this; - } - - // Because StackFrame is just a vtable pointer and an instance pointer, we - // can memcpy everything around instead of making concrete classes define - // virtual constructors. See the comment above Node's copy constructor for - // more details; that comment applies here as well. - StackFrame(const StackFrame& rhs) { - memcpy(storage.u.mBytes, rhs.storage.u.mBytes, sizeof(storage.u)); - } - - StackFrame& operator=(const StackFrame& rhs) { - memcpy(storage.u.mBytes, rhs.storage.u.mBytes, sizeof(storage.u)); - return *this; - } - - bool operator==(const StackFrame& rhs) const { return base()->ptr == rhs.base()->ptr; } - bool operator!=(const StackFrame& rhs) const { return !(*this == rhs); } - - explicit operator bool() const { - return base()->ptr != nullptr; - } - - // Copy this StackFrame's source name into the given |destination| - // buffer. Copy no more than |length| characters. The result is *not* null - // terminated. Returns how many characters were written into the buffer. - size_t source(RangedPtr destination, size_t length) const; - - // Copy this StackFrame's function display name into the given |destination| - // buffer. Copy no more than |length| characters. The result is *not* null - // terminated. Returns how many characters were written into the buffer. - size_t functionDisplayName(RangedPtr destination, size_t length) const; - - // Get the size of the respective strings. 0 is returned for null strings. - size_t sourceLength(); - size_t functionDisplayNameLength(); - - // Methods that forward to virtual calls through BaseStackFrame. - - void trace(JSTracer* trc) { base()->trace(trc); } - uint64_t identifier() const { - auto id = base()->identifier(); - MOZ_ASSERT(JS::Value::isNumberRepresentable(id)); - return id; - } - uint32_t line() const { return base()->line(); } - uint32_t column() const { return base()->column(); } - AtomOrTwoByteChars source() const { return base()->source(); } - AtomOrTwoByteChars functionDisplayName() const { return base()->functionDisplayName(); } - StackFrame parent() const { return base()->parent(); } - bool isSystem() const { return base()->isSystem(); } - bool isSelfHosted(JSContext* cx) const { return base()->isSelfHosted(cx); } - MOZ_MUST_USE bool constructSavedFrameStack(JSContext* cx, - MutableHandleObject outSavedFrameStack) const { - return base()->constructSavedFrameStack(cx, outSavedFrameStack); - } - - struct HashPolicy { - using Lookup = JS::ubi::StackFrame; - - static js::HashNumber hash(const Lookup& lookup) { - return lookup.identifier(); - } - - static bool match(const StackFrame& key, const Lookup& lookup) { - return key == lookup; - } - - static void rekey(StackFrame& k, const StackFrame& newKey) { - k = newKey; - } - }; -}; - -// The ubi::StackFrame null pointer. Any attempt to operate on a null -// ubi::StackFrame crashes. -template<> -class ConcreteStackFrame : public BaseStackFrame { - explicit ConcreteStackFrame(void* ptr) : BaseStackFrame(ptr) { } - - public: - static void construct(void* storage, void*) { new (storage) ConcreteStackFrame(nullptr); } - - uint64_t identifier() const override { return 0; } - void trace(JSTracer* trc) override { } - MOZ_MUST_USE bool constructSavedFrameStack(JSContext* cx, MutableHandleObject out) - const override - { - out.set(nullptr); - return true; - } - - uint32_t line() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - uint32_t column() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - AtomOrTwoByteChars source() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - AtomOrTwoByteChars functionDisplayName() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - StackFrame parent() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - bool isSystem() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - bool isSelfHosted(JSContext* cx) const override { MOZ_CRASH("null JS::ubi::StackFrame"); } -}; - -MOZ_MUST_USE bool ConstructSavedFrameStackSlow(JSContext* cx, JS::ubi::StackFrame& frame, - MutableHandleObject outSavedFrameStack); - - -/*** ubi::Node ************************************************************************************/ - -// A concrete node specialization can claim its referent is a member of a -// particular "coarse type" which is less specific than the actual -// implementation type but generally more palatable for web developers. For -// example, JitCode can be considered to have a coarse type of "Script". This is -// used by some analyses for putting nodes into different buckets. The default, -// if a concrete specialization does not provide its own mapping to a CoarseType -// variant, is "Other". -// -// NB: the values associated with a particular enum variant must not change or -// be reused for new variants. Doing so will cause inspecting ubi::Nodes backed -// by an offline heap snapshot from an older SpiderMonkey/Firefox version to -// break. Consider this enum append only. -enum class CoarseType: uint32_t { - Other = 0, - Object = 1, - Script = 2, - String = 3, - - FIRST = Other, - LAST = String -}; - -inline uint32_t -CoarseTypeToUint32(CoarseType type) -{ - return static_cast(type); -} - -inline bool -Uint32IsValidCoarseType(uint32_t n) -{ - auto first = static_cast(CoarseType::FIRST); - auto last = static_cast(CoarseType::LAST); - MOZ_ASSERT(first < last); - return first <= n && n <= last; -} - -inline CoarseType -Uint32ToCoarseType(uint32_t n) -{ - MOZ_ASSERT(Uint32IsValidCoarseType(n)); - return static_cast(n); -} - -// The base class implemented by each ubi::Node referent type. Subclasses must -// not add data members to this class. -class Base { - friend class Node; - - // For performance's sake, we'd prefer to avoid a virtual destructor; and - // an empty constructor seems consistent with the 'lightweight value type' - // visible behavior we're trying to achieve. But if the destructor isn't - // virtual, and a subclass overrides it, the subclass's destructor will be - // ignored. Is there a way to make the compiler catch that error? - - protected: - // Space for the actual pointer. Concrete subclasses should define a - // properly typed 'get' member function to access this. - void* ptr; - - explicit Base(void* ptr) : ptr(ptr) { } - - public: - bool operator==(const Base& rhs) const { - // Some compilers will indeed place objects of different types at - // the same address, so technically, we should include the vtable - // in this comparison. But it seems unlikely to cause problems in - // practice. - return ptr == rhs.ptr; - } - bool operator!=(const Base& rhs) const { return !(*this == rhs); } - - // An identifier for this node, guaranteed to be stable and unique for as - // long as this ubi::Node's referent is alive and at the same address. - // - // This is probably suitable for use in serializations, as it is an integral - // type. It may also help save memory when constructing HashSets of - // ubi::Nodes: since a uint64_t will always be smaller-or-equal-to the size - // of a ubi::Node, a HashSet may use less space per element - // than a HashSet. - // - // (Note that 'unique' only means 'up to equality on ubi::Node'; see the - // caveats about multiple objects allocated at the same address for - // 'ubi::Node::operator=='.) - using Id = uint64_t; - virtual Id identifier() const { return Id(uintptr_t(ptr)); } - - // Returns true if this node is pointing to something on the live heap, as - // opposed to something from a deserialized core dump. Returns false, - // otherwise. - virtual bool isLive() const { return true; }; - - // Return the coarse-grained type-of-thing that this node represents. - virtual CoarseType coarseType() const { return CoarseType::Other; } - - // Return a human-readable name for the referent's type. The result should - // be statically allocated. (You can use u"strings" for this.) - // - // This must always return Concrete::concreteTypeName; we use that - // pointer as a tag for this particular referent type. - virtual const char16_t* typeName() const = 0; - - // Return the size of this node, in bytes. Include any structures that this - // node owns exclusively that are not exposed as their own ubi::Nodes. - // |mallocSizeOf| should be a malloc block sizing function; see - // |mfbt/MemoryReporting.h|. - // - // Because we can use |JS::ubi::Node|s backed by a snapshot that was taken - // on a 64-bit platform when we are currently on a 32-bit platform, we - // cannot rely on |size_t| for node sizes. Instead, |Size| is uint64_t on - // all platforms. - using Size = uint64_t; - virtual Size size(mozilla::MallocSizeOf mallocSizeof) const { return 1; } - - // Return an EdgeRange that initially contains all the referent's outgoing - // edges. The caller takes ownership of the EdgeRange. - // - // If wantNames is true, compute names for edges. Doing so can be expensive - // in time and memory. - virtual js::UniquePtr edges(JSContext* cx, bool wantNames) const = 0; - - // Return the Zone to which this node's referent belongs, or nullptr if the - // referent is not of a type allocated in SpiderMonkey Zones. - virtual JS::Zone* zone() const { return nullptr; } - - // Return the compartment for this node. Some ubi::Node referents are not - // associated with JSCompartments, such as JSStrings (which are associated - // with Zones). When the referent is not associated with a compartment, - // nullptr is returned. - virtual JSCompartment* compartment() const { return nullptr; } - - // Return whether this node's referent's allocation stack was captured. - virtual bool hasAllocationStack() const { return false; } - - // Get the stack recorded at the time this node's referent was - // allocated. This must only be called when hasAllocationStack() is true. - virtual StackFrame allocationStack() const { - MOZ_CRASH("Concrete classes that have an allocation stack must override both " - "hasAllocationStack and allocationStack."); - } - - // Methods for JSObject Referents - // - // These methods are only semantically valid if the referent is either a - // JSObject in the live heap, or represents a previously existing JSObject - // from some deserialized heap snapshot. - - // Return the object's [[Class]]'s name. - virtual const char* jsObjectClassName() const { return nullptr; } - - // If this object was constructed with `new` and we have the data available, - // place the contructor function's display name in the out parameter. - // Otherwise, place nullptr in the out parameter. Caller maintains ownership - // of the out parameter. True is returned on success, false is returned on - // OOM. - virtual MOZ_MUST_USE bool jsObjectConstructorName(JSContext* cx, UniqueTwoByteChars& outName) - const - { - outName.reset(nullptr); - return true; - } - - // Methods for CoarseType::Script referents - - // Return the script's source's filename if available. If unavailable, - // return nullptr. - virtual const char* scriptFilename() const { return nullptr; } - - private: - Base(const Base& rhs) = delete; - Base& operator=(const Base& rhs) = delete; -}; - -// A traits template with a specialization for each referent type that -// ubi::Node supports. The specialization must be the concrete subclass of Base -// that represents a pointer to the referent type. It must include these -// members: -// -// // The specific char16_t array returned by Concrete::typeName(). -// static const char16_t concreteTypeName[]; -// -// // Construct an instance of this concrete class in |storage| referring -// // to |referent|. Implementations typically use a placement 'new'. -// // -// // In some cases, |referent| will contain dynamic type information that -// // identifies it a some more specific subclass of |Referent|. For -// // example, when |Referent| is |JSObject|, then |referent->getClass()| -// // could tell us that it's actually a JSFunction. Similarly, if -// // |Referent| is |nsISupports|, we would like a ubi::Node that knows its -// // final implementation type. -// // -// // So we delegate the actual construction to this specialization, which -// // knows Referent's details. -// static void construct(void* storage, Referent* referent); -template -class Concrete; - -// A container for a Base instance; all members simply forward to the contained -// instance. This container allows us to pass ubi::Node instances by value. -class Node { - // Storage in which we allocate Base subclasses. - mozilla::AlignedStorage2 storage; - Base* base() { return storage.addr(); } - const Base* base() const { return storage.addr(); } - - template - void construct(T* ptr) { - static_assert(sizeof(Concrete) == sizeof(*base()), - "ubi::Base specializations must be the same size as ubi::Base"); - static_assert(mozilla::IsBaseOf>::value, - "ubi::Concrete must inherit from ubi::Base"); - Concrete::construct(base(), ptr); - } - struct ConstructFunctor; - - public: - Node() { construct(nullptr); } - - template - MOZ_IMPLICIT Node(T* ptr) { - construct(ptr); - } - template - Node& operator=(T* ptr) { - construct(ptr); - return *this; - } - - // We can construct and assign from rooted forms of pointers. - template - MOZ_IMPLICIT Node(const Rooted& root) { - construct(root.get()); - } - template - Node& operator=(const Rooted& root) { - construct(root.get()); - return *this; - } - - // Constructors accepting SpiderMonkey's other generic-pointer-ish types. - // Note that we *do* want an implicit constructor here: JS::Value and - // JS::ubi::Node are both essentially tagged references to other sorts of - // objects, so letting conversions happen automatically is appropriate. - MOZ_IMPLICIT Node(JS::HandleValue value); - explicit Node(const JS::GCCellPtr& thing); - - // copy construction and copy assignment just use memcpy, since we know - // instances contain nothing but a vtable pointer and a data pointer. - // - // To be completely correct, concrete classes could provide a virtual - // 'construct' member function, which we could invoke on rhs to construct an - // instance in our storage. But this is good enough; there's no need to jump - // through vtables for copying and assignment that are just going to move - // two words around. The compiler knows how to optimize memcpy. - Node(const Node& rhs) { - memcpy(storage.u.mBytes, rhs.storage.u.mBytes, sizeof(storage.u)); - } - - Node& operator=(const Node& rhs) { - memcpy(storage.u.mBytes, rhs.storage.u.mBytes, sizeof(storage.u)); - return *this; - } - - bool operator==(const Node& rhs) const { return *base() == *rhs.base(); } - bool operator!=(const Node& rhs) const { return *base() != *rhs.base(); } - - explicit operator bool() const { - return base()->ptr != nullptr; - } - - bool isLive() const { return base()->isLive(); } - - // Get the canonical type name for the given type T. - template - static const char16_t* canonicalTypeName() { return Concrete::concreteTypeName; } - - template - bool is() const { - return base()->typeName() == canonicalTypeName(); - } - - template - T* as() const { - MOZ_ASSERT(isLive()); - MOZ_ASSERT(is()); - return static_cast(base()->ptr); - } - - template - T* asOrNull() const { - MOZ_ASSERT(isLive()); - return is() ? static_cast(base()->ptr) : nullptr; - } - - // If this node refers to something that can be represented as a JavaScript - // value that is safe to expose to JavaScript code, return that value. - // Otherwise return UndefinedValue(). JSStrings, JS::Symbols, and some (but - // not all!) JSObjects can be exposed. - JS::Value exposeToJS() const; - - CoarseType coarseType() const { return base()->coarseType(); } - const char16_t* typeName() const { return base()->typeName(); } - JS::Zone* zone() const { return base()->zone(); } - JSCompartment* compartment() const { return base()->compartment(); } - const char* jsObjectClassName() const { return base()->jsObjectClassName(); } - MOZ_MUST_USE bool jsObjectConstructorName(JSContext* cx, UniqueTwoByteChars& outName) const { - return base()->jsObjectConstructorName(cx, outName); - } - - const char* scriptFilename() const { return base()->scriptFilename(); } - - using Size = Base::Size; - Size size(mozilla::MallocSizeOf mallocSizeof) const { - auto size = base()->size(mallocSizeof); - MOZ_ASSERT(size > 0, - "C++ does not have zero-sized types! Choose 1 if you just need a " - "conservative default."); - return size; - } - - js::UniquePtr edges(JSContext* cx, bool wantNames = true) const { - return base()->edges(cx, wantNames); - } - - bool hasAllocationStack() const { return base()->hasAllocationStack(); } - StackFrame allocationStack() const { - return base()->allocationStack(); - } - - using Id = Base::Id; - Id identifier() const { - auto id = base()->identifier(); - MOZ_ASSERT(JS::Value::isNumberRepresentable(id)); - return id; - } - - // A hash policy for ubi::Nodes. - // This simply uses the stock PointerHasher on the ubi::Node's pointer. - // We specialize DefaultHasher below to make this the default. - class HashPolicy { - typedef js::PointerHasher::value> PtrHash; - - public: - typedef Node Lookup; - - static js::HashNumber hash(const Lookup& l) { return PtrHash::hash(l.base()->ptr); } - static bool match(const Node& k, const Lookup& l) { return k == l; } - static void rekey(Node& k, const Node& newKey) { k = newKey; } - }; -}; - -using NodeSet = js::HashSet, js::SystemAllocPolicy>; -using NodeSetPtr = mozilla::UniquePtr>; - -/*** Edge and EdgeRange ***************************************************************************/ - -using EdgeName = UniqueTwoByteChars; - -// An outgoing edge to a referent node. -class Edge { - public: - Edge() : name(nullptr), referent() { } - - // Construct an initialized Edge, taking ownership of |name|. - Edge(char16_t* name, const Node& referent) - : name(name) - , referent(referent) - { } - - // Move construction and assignment. - Edge(Edge&& rhs) - : name(mozilla::Move(rhs.name)) - , referent(rhs.referent) - { } - - Edge& operator=(Edge&& rhs) { - MOZ_ASSERT(&rhs != this); - this->~Edge(); - new (this) Edge(mozilla::Move(rhs)); - return *this; - } - - Edge(const Edge&) = delete; - Edge& operator=(const Edge&) = delete; - - // This edge's name. This may be nullptr, if Node::edges was called with - // false as the wantNames parameter. - // - // The storage is owned by this Edge, and will be freed when this Edge is - // destructed. You may take ownership of the name by `mozilla::Move`ing it - // out of the edge; it is just a UniquePtr. - // - // (In real life we'll want a better representation for names, to avoid - // creating tons of strings when the names follow a pattern; and we'll need - // to think about lifetimes carefully to ensure traversal stays cheap.) - EdgeName name; - - // This edge's referent. - Node referent; -}; - -// EdgeRange is an abstract base class for iterating over a node's outgoing -// edges. (This is modeled after js::HashTable::Range.) -// -// Concrete instances of this class need not be as lightweight as Node itself, -// since they're usually only instantiated while iterating over a particular -// object's edges. For example, a dumb implementation for JS Cells might use -// JS::TraceChildren to to get the outgoing edges, and then store them in an -// array internal to the EdgeRange. -class EdgeRange { - protected: - // The current front edge of this range, or nullptr if this range is empty. - Edge* front_; - - EdgeRange() : front_(nullptr) { } - - public: - virtual ~EdgeRange() { } - - // True if there are no more edges in this range. - bool empty() const { return !front_; } - - // The front edge of this range. This is owned by the EdgeRange, and is - // only guaranteed to live until the next call to popFront, or until - // the EdgeRange is destructed. - const Edge& front() const { return *front_; } - Edge& front() { return *front_; } - - // Remove the front edge from this range. This should only be called if - // !empty(). - virtual void popFront() = 0; - - private: - EdgeRange(const EdgeRange&) = delete; - EdgeRange& operator=(const EdgeRange&) = delete; -}; - - -typedef mozilla::Vector EdgeVector; - -// An EdgeRange concrete class that holds a pre-existing vector of -// Edges. A PreComputedEdgeRange does not take ownership of its -// EdgeVector; it is up to the PreComputedEdgeRange's consumer to manage -// that lifetime. -class PreComputedEdgeRange : public EdgeRange { - EdgeVector& edges; - size_t i; - - void settle() { - front_ = i < edges.length() ? &edges[i] : nullptr; - } - - public: - explicit PreComputedEdgeRange(EdgeVector& edges) - : edges(edges), - i(0) - { - settle(); - } - - void popFront() override { - MOZ_ASSERT(!empty()); - i++; - settle(); - } -}; - -/*** RootList *************************************************************************************/ - -// RootList is a class that can be pointed to by a |ubi::Node|, creating a -// fictional root-of-roots which has edges to every GC root in the JS -// runtime. Having a single root |ubi::Node| is useful for algorithms written -// with the assumption that there aren't multiple roots (such as computing -// dominator trees) and you want a single point of entry. It also ensures that -// the roots themselves get visited by |ubi::BreadthFirst| (they would otherwise -// only be used as starting points). -// -// RootList::init itself causes a minor collection, but once the list of roots -// has been created, GC must not occur, as the referent ubi::Nodes are not -// stable across GC. The init calls emplace on |noGC|'s AutoCheckCannotGC, whose -// lifetime must extend at least as long as the RootList itself. -// -// Example usage: -// -// { -// mozilla::Maybe maybeNoGC; -// JS::ubi::RootList rootList(cx, maybeNoGC); -// if (!rootList.init()) -// return false; -// -// // The AutoCheckCannotGC is guaranteed to exist if init returned true. -// MOZ_ASSERT(maybeNoGC.isSome()); -// -// JS::ubi::Node root(&rootList); -// -// ... -// } -class MOZ_STACK_CLASS RootList { - Maybe& noGC; - - public: - JSContext* cx; - EdgeVector edges; - bool wantNames; - - RootList(JSContext* cx, Maybe& noGC, bool wantNames = false); - - // Find all GC roots. - MOZ_MUST_USE bool init(); - // Find only GC roots in the provided set of |JSCompartment|s. - MOZ_MUST_USE bool init(CompartmentSet& debuggees); - // Find only GC roots in the given Debugger object's set of debuggee - // compartments. - MOZ_MUST_USE bool init(HandleObject debuggees); - - // Returns true if the RootList has been initialized successfully, false - // otherwise. - bool initialized() { return noGC.isSome(); } - - // Explicitly add the given Node as a root in this RootList. If wantNames is - // true, you must pass an edgeName. The RootList does not take ownership of - // edgeName. - MOZ_MUST_USE bool addRoot(Node node, const char16_t* edgeName = nullptr); -}; - - -/*** Concrete classes for ubi::Node referent types ************************************************/ - -template<> -class Concrete : public Base { - protected: - explicit Concrete(RootList* ptr) : Base(ptr) { } - RootList& get() const { return *static_cast(ptr); } - - public: - static void construct(void* storage, RootList* ptr) { new (storage) Concrete(ptr); } - - js::UniquePtr edges(JSContext* cx, bool wantNames) const override; - - const char16_t* typeName() const override { return concreteTypeName; } - static const char16_t concreteTypeName[]; -}; - -// A reusable ubi::Concrete specialization base class for types supported by -// JS::TraceChildren. -template -class TracerConcrete : public Base { - js::UniquePtr edges(JSContext* cx, bool wantNames) const override; - JS::Zone* zone() const override; - - protected: - explicit TracerConcrete(Referent* ptr) : Base(ptr) { } - Referent& get() const { return *static_cast(ptr); } -}; - -// For JS::TraceChildren-based types that have a 'compartment' method. -template -class TracerConcreteWithCompartment : public TracerConcrete { - typedef TracerConcrete TracerBase; - JSCompartment* compartment() const override; - - protected: - explicit TracerConcreteWithCompartment(Referent* ptr) : TracerBase(ptr) { } -}; - -// Define specializations for some commonly-used public JSAPI types. -// These can use the generic templates above. -template<> -class Concrete : TracerConcrete { - protected: - explicit Concrete(JS::Symbol* ptr) : TracerConcrete(ptr) { } - - public: - static void construct(void* storage, JS::Symbol* ptr) { - new (storage) Concrete(ptr); - } - - Size size(mozilla::MallocSizeOf mallocSizeOf) const override; - - const char16_t* typeName() const override { return concreteTypeName; } - static const char16_t concreteTypeName[]; -}; - -template<> -class Concrete : TracerConcreteWithCompartment { - protected: - explicit Concrete(JSScript *ptr) : TracerConcreteWithCompartment(ptr) { } - - public: - static void construct(void *storage, JSScript *ptr) { new (storage) Concrete(ptr); } - - CoarseType coarseType() const final { return CoarseType::Script; } - Size size(mozilla::MallocSizeOf mallocSizeOf) const override; - const char* scriptFilename() const final; - - const char16_t* typeName() const override { return concreteTypeName; } - static const char16_t concreteTypeName[]; -}; - -// The JSObject specialization. -template<> -class Concrete : public TracerConcreteWithCompartment { - protected: - explicit Concrete(JSObject* ptr) : TracerConcreteWithCompartment(ptr) { } - - public: - static void construct(void* storage, JSObject* ptr) { - new (storage) Concrete(ptr); - } - - const char* jsObjectClassName() const override; - MOZ_MUST_USE bool jsObjectConstructorName(JSContext* cx, UniqueTwoByteChars& outName) - const override; - Size size(mozilla::MallocSizeOf mallocSizeOf) const override; - - bool hasAllocationStack() const override; - StackFrame allocationStack() const override; - - CoarseType coarseType() const final { return CoarseType::Object; } - - const char16_t* typeName() const override { return concreteTypeName; } - static const char16_t concreteTypeName[]; -}; - -// For JSString, we extend the generic template with a 'size' implementation. -template<> -class Concrete : TracerConcrete { - protected: - explicit Concrete(JSString *ptr) : TracerConcrete(ptr) { } - - public: - static void construct(void *storage, JSString *ptr) { new (storage) Concrete(ptr); } - - Size size(mozilla::MallocSizeOf mallocSizeOf) const override; - - CoarseType coarseType() const final { return CoarseType::String; } - - const char16_t* typeName() const override { return concreteTypeName; } - static const char16_t concreteTypeName[]; -}; - -// The ubi::Node null pointer. Any attempt to operate on a null ubi::Node asserts. -template<> -class Concrete : public Base { - const char16_t* typeName() const override; - Size size(mozilla::MallocSizeOf mallocSizeOf) const override; - js::UniquePtr edges(JSContext* cx, bool wantNames) const override; - JS::Zone* zone() const override; - JSCompartment* compartment() const override; - CoarseType coarseType() const final; - - explicit Concrete(void* ptr) : Base(ptr) { } - - public: - static void construct(void* storage, void* ptr) { new (storage) Concrete(ptr); } -}; - - -} // namespace ubi -} // namespace JS - -namespace js { - -// Make ubi::Node::HashPolicy the default hash policy for ubi::Node. -template<> struct DefaultHasher : JS::ubi::Node::HashPolicy { }; -template<> struct DefaultHasher : JS::ubi::StackFrame::HashPolicy { }; - -} // namespace js - -#endif // js_UbiNode_h diff --git a/android/armeabi-v7a/include/spidermonkey/js/UbiNodeBreadthFirst.h b/android/armeabi-v7a/include/spidermonkey/js/UbiNodeBreadthFirst.h deleted file mode 100644 index 8446dbc6..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/UbiNodeBreadthFirst.h +++ /dev/null @@ -1,244 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNodeBreadthFirst_h -#define js_UbiNodeBreadthFirst_h - -#include "js/UbiNode.h" -#include "js/Utility.h" -#include "js/Vector.h" - -namespace JS { -namespace ubi { - -// A breadth-first traversal template for graphs of ubi::Nodes. -// -// No GC may occur while an instance of this template is live. -// -// The provided Handler type should have two members: -// -// typename NodeData; -// -// The value type of |BreadthFirst::visited|, the HashMap of -// ubi::Nodes that have been visited so far. Since the algorithm needs a -// hash table like this for its own use anyway, it is simple to let -// Handler store its own metadata about each node in the same table. -// -// For example, if you want to find a shortest path to each node from any -// traversal starting point, your |NodeData| type could record the first -// edge to reach each node, and the node from which it originates. Then, -// when the traversal is complete, you can walk backwards from any node -// to some starting point, and the path recorded will be a shortest path. -// -// This type must have a default constructor. If this type owns any other -// resources, move constructors and assignment operators are probably a -// good idea, too. -// -// bool operator() (BreadthFirst& traversal, -// Node origin, const Edge& edge, -// Handler::NodeData* referentData, bool first); -// -// The visitor function, called to report that we have traversed -// |edge| from |origin|. This is called once for each edge we traverse. -// As this is a breadth-first search, any prior calls to the visitor function -// were for origin nodes not further from the start nodes than |origin|. -// -// |traversal| is this traversal object, passed along for convenience. -// -// |referentData| is a pointer to the value of the entry in -// |traversal.visited| for |edge.referent|; the visitor function can -// store whatever metadata it likes about |edge.referent| there. -// -// |first| is true if this is the first time we have visited an edge -// leading to |edge.referent|. This could be stored in NodeData, but -// the algorithm knows whether it has just created the entry in -// |traversal.visited|, so it passes it along for convenience. -// -// The visitor function may call |traversal.abandonReferent()| if it -// doesn't want to traverse the outgoing edges of |edge.referent|. You can -// use this to limit the traversal to a given portion of the graph: it will -// never visit nodes reachable only through nodes that you have abandoned. -// Note that |abandonReferent| must be called the first time the given node -// is reached; that is, |first| must be true. -// -// The visitor function may call |traversal.stop()| if it doesn't want -// to visit any more nodes at all. -// -// The visitor function may consult |traversal.visited| for information -// about other nodes, but it should not add or remove entries. -// -// The visitor function should return true on success, or false if an -// error occurs. A false return value terminates the traversal -// immediately, and causes BreadthFirst::traverse to return -// false. -template -struct BreadthFirst { - - // Construct a breadth-first traversal object that reports the nodes it - // reaches to |handler|. The traversal asserts that no GC happens in its - // runtime during its lifetime. - // - // We do nothing with noGC, other than require it to exist, with a lifetime - // that encloses our own. - BreadthFirst(JSContext* cx, Handler& handler, const JS::AutoCheckCannotGC& noGC) - : wantNames(true), cx(cx), visited(), handler(handler), pending(), - traversalBegun(false), stopRequested(false), abandonRequested(false) - { } - - // Initialize this traversal object. Return false on OOM. - bool init() { return visited.init(); } - - // Add |node| as a starting point for the traversal. You may add - // as many starting points as you like. Return false on OOM. - bool addStart(Node node) { return pending.append(node); } - - // Add |node| as a starting point for the traversal (see addStart) and also - // add it to the |visited| set. Return false on OOM. - bool addStartVisited(Node node) { - typename NodeMap::AddPtr ptr = visited.lookupForAdd(node); - if (!ptr && !visited.add(ptr, node, typename Handler::NodeData())) - return false; - return addStart(node); - } - - // True if the handler wants us to compute edge names; doing so can be - // expensive in time and memory. True by default. - bool wantNames; - - // Traverse the graph in breadth-first order, starting at the given - // start nodes, applying |handler::operator()| for each edge traversed - // as described above. - // - // This should be called only once per instance of this class. - // - // Return false on OOM or error return from |handler::operator()|. - bool traverse() - { - MOZ_ASSERT(!traversalBegun); - traversalBegun = true; - - // While there are pending nodes, visit them. - while (!pending.empty()) { - Node origin = pending.front(); - pending.popFront(); - - // Get a range containing all origin's outgoing edges. - auto range = origin.edges(cx, wantNames); - if (!range) - return false; - - // Traverse each edge. - for (; !range->empty(); range->popFront()) { - MOZ_ASSERT(!stopRequested); - - Edge& edge = range->front(); - typename NodeMap::AddPtr a = visited.lookupForAdd(edge.referent); - bool first = !a; - - if (first) { - // This is the first time we've reached |edge.referent|. - // Mark it as visited. - if (!visited.add(a, edge.referent, typename Handler::NodeData())) - return false; - } - - MOZ_ASSERT(a); - - // Report this edge to the visitor function. - if (!handler(*this, origin, edge, &a->value(), first)) - return false; - - if (stopRequested) - return true; - - // Arrange to traverse this edge's referent's outgoing edges - // later --- unless |handler| asked us not to. - if (abandonRequested) { - // Skip the enqueue; reset flag for future iterations. - abandonRequested = false; - } else if (first) { - if (!pending.append(edge.referent)) - return false; - } - } - } - - return true; - } - - // Stop traversal, and return true from |traverse| without visiting any - // more nodes. Only |handler::operator()| should call this function; it - // may do so to stop the traversal early, without returning false and - // then making |traverse|'s caller disambiguate that result from a real - // error. - void stop() { stopRequested = true; } - - // Request that the current edge's referent's outgoing edges not be - // traversed. This must be called the first time that referent is reached. - // Other edges *to* that referent will still be traversed. - void abandonReferent() { abandonRequested = true; } - - // The context with which we were constructed. - JSContext* cx; - - // A map associating each node N that we have reached with a - // Handler::NodeData, for |handler|'s use. This is public, so that - // |handler| can access it to see the traversal thus far. - using NodeMap = js::HashMap, - js::SystemAllocPolicy>; - NodeMap visited; - - private: - // Our handler object. - Handler& handler; - - // A queue template. Appending and popping the front are constant time. - // Wasted space is never more than some recent actual population plus the - // current population. - template - class Queue { - js::Vector head, tail; - size_t frontIndex; - public: - Queue() : head(), tail(), frontIndex(0) { } - bool empty() { return frontIndex >= head.length(); } - T& front() { - MOZ_ASSERT(!empty()); - return head[frontIndex]; - } - void popFront() { - MOZ_ASSERT(!empty()); - frontIndex++; - if (frontIndex >= head.length()) { - head.clearAndFree(); - head.swap(tail); - frontIndex = 0; - } - } - bool append(const T& elt) { - return frontIndex == 0 ? head.append(elt) : tail.append(elt); - } - }; - - // A queue of nodes that we have reached, but whose outgoing edges we - // have not yet traversed. Nodes reachable in fewer edges are enqueued - // earlier. - Queue pending; - - // True if our traverse function has been called. - bool traversalBegun; - - // True if we've been asked to stop the traversal. - bool stopRequested; - - // True if we've been asked to abandon the current edge's referent. - bool abandonRequested; -}; - -} // namespace ubi -} // namespace JS - -#endif // js_UbiNodeBreadthFirst_h diff --git a/android/armeabi-v7a/include/spidermonkey/js/UbiNodeCensus.h b/android/armeabi-v7a/include/spidermonkey/js/UbiNodeCensus.h deleted file mode 100644 index c0859ec5..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/UbiNodeCensus.h +++ /dev/null @@ -1,251 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNodeCensus_h -#define js_UbiNodeCensus_h - -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" - -#include - -#include "jsapi.h" - -#include "js/UbiNode.h" -#include "js/UbiNodeBreadthFirst.h" - -// A census is a ubi::Node traversal that assigns each node to one or more -// buckets, and returns a report with the size of each bucket. -// -// We summarize the results of a census with counts broken down according to -// criteria selected by the API consumer code that is requesting the census. For -// example, the following breakdown might give an interesting overview of the -// heap: -// -// - all nodes -// - objects -// - objects with a specific [[Class]] * -// - strings -// - scripts -// - all other Node types -// - nodes with a specific ubi::Node::typeName * -// -// Obviously, the parts of this tree marked with * represent many separate -// counts, depending on how many distinct [[Class]] values and ubi::Node type -// names we encounter. -// -// The supported types of breakdowns are documented in -// js/src/doc/Debugger/Debugger.Memory.md. -// -// When we parse the 'breakdown' argument to takeCensus, we build a tree of -// CountType nodes. For example, for the breakdown shown in the -// Debugger.Memory.prototype.takeCensus, documentation: -// -// { -// by: "coarseType", -// objects: { by: "objectClass" }, -// other: { by: "internalType" } -// } -// -// we would build the following tree of CountType subclasses: -// -// ByCoarseType -// objects: ByObjectClass -// each class: SimpleCount -// scripts: SimpleCount -// strings: SimpleCount -// other: ByUbinodeType -// each type: SimpleCount -// -// The interior nodes are all breakdown types that categorize nodes according to -// one characteristic or another; and the leaf nodes are all SimpleType. -// -// Each CountType has its own concrete C++ type that holds the counts it -// produces. SimpleCount::Count just holds totals. ByObjectClass::Count has a -// hash table whose keys are object class names and whose values are counts of -// some other type (in the example above, SimpleCount). -// -// To keep actual count nodes small, they have no vtable. Instead, each count -// points to its CountType, which knows how to carry out all the operations we -// need on a Count. A CountType can produce new count nodes; process nodes as we -// visit them; build a JS object reporting the results; and destruct count -// nodes. - - -namespace JS { -namespace ubi { - -struct Census; - -class CountBase; - -struct CountDeleter { - void operator()(CountBase*); -}; - -using CountBasePtr = js::UniquePtr; - -// Abstract base class for CountType nodes. -struct CountType { - explicit CountType() { } - virtual ~CountType() { } - - // Destruct a count tree node that this type instance constructed. - virtual void destructCount(CountBase& count) = 0; - - // Return a fresh node for the count tree that categorizes nodes according - // to this type. Return a nullptr on OOM. - virtual CountBasePtr makeCount() = 0; - - // Trace |count| and all its children, for garbage collection. - virtual void traceCount(CountBase& count, JSTracer* trc) = 0; - - // Implement the 'count' method for counts returned by this CountType - // instance's 'newCount' method. - virtual MOZ_MUST_USE bool count(CountBase& count, - mozilla::MallocSizeOf mallocSizeOf, - const Node& node) = 0; - - // Implement the 'report' method for counts returned by this CountType - // instance's 'newCount' method. - virtual MOZ_MUST_USE bool report(JSContext* cx, CountBase& count, - MutableHandleValue report) = 0; -}; - -using CountTypePtr = js::UniquePtr; - -// An abstract base class for count tree nodes. -class CountBase { - // In lieu of a vtable, each CountBase points to its type, which - // carries not only the implementations of the CountBase methods, but also - // additional parameters for the type's behavior, as specified in the - // breakdown argument passed to takeCensus. - CountType& type; - - protected: - ~CountBase() { } - - public: - explicit CountBase(CountType& type) - : type(type) - , total_(0) - , smallestNodeIdCounted_(SIZE_MAX) - { } - - // Categorize and count |node| as appropriate for this count's type. - MOZ_MUST_USE bool count(mozilla::MallocSizeOf mallocSizeOf, const Node& node) { - total_++; - - auto id = node.identifier(); - if (id < smallestNodeIdCounted_) { - smallestNodeIdCounted_ = id; - } - -#ifdef DEBUG - size_t oldTotal = total_; -#endif - - bool ret = type.count(*this, mallocSizeOf, node); - - MOZ_ASSERT(total_ == oldTotal, - "CountType::count should not increment total_, CountBase::count handles that"); - - return ret; - } - - // Construct a JavaScript object reporting the counts recorded in this - // count, and store it in |report|. Return true on success, or false on - // failure. - MOZ_MUST_USE bool report(JSContext* cx, MutableHandleValue report) { - return type.report(cx, *this, report); - } - - // Down-cast this CountBase to its true type, based on its 'type' member, - // and run its destructor. - void destruct() { return type.destructCount(*this); } - - // Trace this count for garbage collection. - void trace(JSTracer* trc) { type.traceCount(*this, trc); } - - size_t total_; - - // The smallest JS::ubi::Node::identifier() passed to this instance's - // count() method. This provides a stable way to sort sets. - Node::Id smallestNodeIdCounted_; -}; - -class RootedCount : JS::CustomAutoRooter { - CountBasePtr count; - - void trace(JSTracer* trc) override { count->trace(trc); } - - public: - RootedCount(JSContext* cx, CountBasePtr&& count) - : CustomAutoRooter(cx), - count(Move(count)) - { } - CountBase* operator->() const { return count.get(); } - explicit operator bool() const { return count.get(); } - operator CountBasePtr&() { return count; } -}; - -// Common data for a census traversal, shared across all CountType nodes. -struct Census { - JSContext* const cx; - // If the targetZones set is non-empty, then only consider nodes whose zone - // is an element of the set. If the targetZones set is empty, then nodes in - // all zones are considered. - JS::ZoneSet targetZones; - Zone* atomsZone; - - explicit Census(JSContext* cx) : cx(cx), atomsZone(nullptr) { } - - MOZ_MUST_USE bool init(); -}; - -// A BreadthFirst handler type that conducts a census, using a CountBase to -// categorize and count each node. -class CensusHandler { - Census& census; - CountBasePtr& rootCount; - mozilla::MallocSizeOf mallocSizeOf; - - public: - CensusHandler(Census& census, CountBasePtr& rootCount, mozilla::MallocSizeOf mallocSizeOf) - : census(census), - rootCount(rootCount), - mallocSizeOf(mallocSizeOf) - { } - - MOZ_MUST_USE bool report(JSContext* cx, MutableHandleValue report) { - return rootCount->report(cx, report); - } - - // This class needs to retain no per-node data. - class NodeData { }; - - MOZ_MUST_USE bool operator() (BreadthFirst& traversal, - Node origin, const Edge& edge, - NodeData* referentData, bool first); -}; - -using CensusTraversal = BreadthFirst; - -// Examine the census options supplied by the API consumer, and (among other -// things) use that to build a CountType tree. -MOZ_MUST_USE bool ParseCensusOptions(JSContext* cx, Census& census, HandleObject options, - CountTypePtr& outResult); - -// Parse the breakdown language (as described in -// js/src/doc/Debugger/Debugger.Memory.md) into a CountTypePtr. A null pointer -// is returned on error and is reported to the cx. -CountTypePtr ParseBreakdown(JSContext* cx, HandleValue breakdownValue); - - -} // namespace ubi -} // namespace JS - -#endif // js_UbiNodeCensus_h diff --git a/android/armeabi-v7a/include/spidermonkey/js/UbiNodeDominatorTree.h b/android/armeabi-v7a/include/spidermonkey/js/UbiNodeDominatorTree.h deleted file mode 100644 index 3422b76b..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/UbiNodeDominatorTree.h +++ /dev/null @@ -1,677 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNodeDominatorTree_h -#define js_UbiNodeDominatorTree_h - -#include "mozilla/Attributes.h" -#include "mozilla/DebugOnly.h" -#include "mozilla/Maybe.h" -#include "mozilla/Move.h" -#include "mozilla/UniquePtr.h" - -#include "jsalloc.h" - -#include "js/UbiNode.h" -#include "js/UbiNodePostOrder.h" -#include "js/Utility.h" -#include "js/Vector.h" - -namespace JS { -namespace ubi { - -/** - * In a directed graph with a root node `R`, a node `A` is said to "dominate" a - * node `B` iff every path from `R` to `B` contains `A`. A node `A` is said to - * be the "immediate dominator" of a node `B` iff it dominates `B`, is not `B` - * itself, and does not dominate any other nodes which also dominate `B` in - * turn. - * - * If we take every node from a graph `G` and create a new graph `T` with edges - * to each node from its immediate dominator, then `T` is a tree (each node has - * only one immediate dominator, or none if it is the root). This tree is called - * a "dominator tree". - * - * This class represents a dominator tree constructed from a `JS::ubi::Node` - * heap graph. The domination relationship and dominator trees are useful tools - * for analyzing heap graphs because they tell you: - * - * - Exactly what could be reclaimed by the GC if some node `A` became - * unreachable: those nodes which are dominated by `A`, - * - * - The "retained size" of a node in the heap graph, in contrast to its - * "shallow size". The "shallow size" is the space taken by a node itself, - * not counting anything it references. The "retained size" of a node is its - * shallow size plus the size of all the things that would be collected if - * the original node wasn't (directly or indirectly) referencing them. In - * other words, the retained size is the shallow size of a node plus the - * shallow sizes of every other node it dominates. For example, the root - * node in a binary tree might have a small shallow size that does not take - * up much space itself, but it dominates the rest of the binary tree and - * its retained size is therefore significant (assuming no external - * references into the tree). - * - * The simple, engineered algorithm presented in "A Simple, Fast Dominance - * Algorithm" by Cooper el al[0] is used to find dominators and construct the - * dominator tree. This algorithm runs in O(n^2) time, but is faster in practice - * than alternative algorithms with better theoretical running times, such as - * Lengauer-Tarjan which runs in O(e * log(n)). The big caveat to that statement - * is that Cooper et al found it is faster in practice *on control flow graphs* - * and I'm not convinced that this property also holds on *heap* graphs. That - * said, the implementation of this algorithm is *much* simpler than - * Lengauer-Tarjan and has been found to be fast enough at least for the time - * being. - * - * [0]: http://www.cs.rice.edu/~keith/EMBED/dom.pdf - */ -class JS_PUBLIC_API(DominatorTree) -{ - private: - // Types. - - using PredecessorSets = js::HashMap, - js::SystemAllocPolicy>; - using NodeToIndexMap = js::HashMap, - js::SystemAllocPolicy>; - class DominatedSets; - - public: - class DominatedSetRange; - - /** - * A pointer to an immediately dominated node. - * - * Don't use this type directly; it is no safer than regular pointers. This - * is only for use indirectly with range-based for loops and - * `DominatedSetRange`. - * - * @see JS::ubi::DominatorTree::getDominatedSet - */ - class DominatedNodePtr - { - friend class DominatedSetRange; - - const JS::ubi::Vector& postOrder; - const uint32_t* ptr; - - DominatedNodePtr(const JS::ubi::Vector& postOrder, const uint32_t* ptr) - : postOrder(postOrder) - , ptr(ptr) - { } - - public: - bool operator!=(const DominatedNodePtr& rhs) const { return ptr != rhs.ptr; } - void operator++() { ptr++; } - const Node& operator*() const { return postOrder[*ptr]; } - }; - - /** - * A range of immediately dominated `JS::ubi::Node`s for use with - * range-based for loops. - * - * @see JS::ubi::DominatorTree::getDominatedSet - */ - class DominatedSetRange - { - friend class DominatedSets; - - const JS::ubi::Vector& postOrder; - const uint32_t* beginPtr; - const uint32_t* endPtr; - - DominatedSetRange(JS::ubi::Vector& postOrder, const uint32_t* begin, const uint32_t* end) - : postOrder(postOrder) - , beginPtr(begin) - , endPtr(end) - { - MOZ_ASSERT(begin <= end); - } - - public: - DominatedNodePtr begin() const { - MOZ_ASSERT(beginPtr <= endPtr); - return DominatedNodePtr(postOrder, beginPtr); - } - - DominatedNodePtr end() const { - return DominatedNodePtr(postOrder, endPtr); - } - - size_t length() const { - MOZ_ASSERT(beginPtr <= endPtr); - return endPtr - beginPtr; - } - - /** - * Safely skip ahead `n` dominators in the range, in O(1) time. - * - * Example usage: - * - * mozilla::Maybe range = myDominatorTree.getDominatedSet(myNode); - * if (range.isNothing()) { - * // Handle unknown nodes however you see fit... - * return false; - * } - * - * // Don't care about the first ten, for whatever reason. - * range->skip(10); - * for (const JS::ubi::Node& dominatedNode : *range) { - * // ... - * } - */ - void skip(size_t n) { - beginPtr += n; - if (beginPtr > endPtr) - beginPtr = endPtr; - } - }; - - private: - /** - * The set of all dominated sets in a dominator tree. - * - * Internally stores the sets in a contiguous array, with a side table of - * indices into that contiguous array to denote the start index of each - * individual set. - */ - class DominatedSets - { - JS::ubi::Vector dominated; - JS::ubi::Vector indices; - - DominatedSets(JS::ubi::Vector&& dominated, JS::ubi::Vector&& indices) - : dominated(mozilla::Move(dominated)) - , indices(mozilla::Move(indices)) - { } - - public: - // DominatedSets is not copy-able. - DominatedSets(const DominatedSets& rhs) = delete; - DominatedSets& operator=(const DominatedSets& rhs) = delete; - - // DominatedSets is move-able. - DominatedSets(DominatedSets&& rhs) - : dominated(mozilla::Move(rhs.dominated)) - , indices(mozilla::Move(rhs.indices)) - { - MOZ_ASSERT(this != &rhs, "self-move not allowed"); - } - DominatedSets& operator=(DominatedSets&& rhs) { - this->~DominatedSets(); - new (this) DominatedSets(mozilla::Move(rhs)); - return *this; - } - - /** - * Create the DominatedSets given the mapping of a node index to its - * immediate dominator. Returns `Some` on success, `Nothing` on OOM - * failure. - */ - static mozilla::Maybe Create(const JS::ubi::Vector& doms) { - auto length = doms.length(); - MOZ_ASSERT(length < UINT32_MAX); - - // Create a vector `dominated` holding a flattened set of buckets of - // immediately dominated children nodes, with a lookup table - // `indices` mapping from each node to the beginning of its bucket. - // - // This has three phases: - // - // 1. Iterate over the full set of nodes and count up the size of - // each bucket. These bucket sizes are temporarily stored in the - // `indices` vector. - // - // 2. Convert the `indices` vector to store the cumulative sum of - // the sizes of all buckets before each index, resulting in a - // mapping from node index to one past the end of that node's - // bucket. - // - // 3. Iterate over the full set of nodes again, filling in bucket - // entries from the end of the bucket's range to its - // beginning. This decrements each index as a bucket entry is - // filled in. After having filled in all of a bucket's entries, - // the index points to the start of the bucket. - - JS::ubi::Vector dominated; - JS::ubi::Vector indices; - if (!dominated.growBy(length) || !indices.growBy(length)) - return mozilla::Nothing(); - - // 1 - memset(indices.begin(), 0, length * sizeof(uint32_t)); - for (uint32_t i = 0; i < length; i++) - indices[doms[i]]++; - - // 2 - uint32_t sumOfSizes = 0; - for (uint32_t i = 0; i < length; i++) { - sumOfSizes += indices[i]; - MOZ_ASSERT(sumOfSizes <= length); - indices[i] = sumOfSizes; - } - - // 3 - for (uint32_t i = 0; i < length; i++) { - auto idxOfDom = doms[i]; - indices[idxOfDom]--; - dominated[indices[idxOfDom]] = i; - } - -#ifdef DEBUG - // Assert that our buckets are non-overlapping and don't run off the - // end of the vector. - uint32_t lastIndex = 0; - for (uint32_t i = 0; i < length; i++) { - MOZ_ASSERT(indices[i] >= lastIndex); - MOZ_ASSERT(indices[i] < length); - lastIndex = indices[i]; - } -#endif - - return mozilla::Some(DominatedSets(mozilla::Move(dominated), mozilla::Move(indices))); - } - - /** - * Get the set of nodes immediately dominated by the node at - * `postOrder[nodeIndex]`. - */ - DominatedSetRange dominatedSet(JS::ubi::Vector& postOrder, uint32_t nodeIndex) const { - MOZ_ASSERT(postOrder.length() == indices.length()); - MOZ_ASSERT(nodeIndex < indices.length()); - auto end = nodeIndex == indices.length() - 1 - ? dominated.end() - : &dominated[indices[nodeIndex + 1]]; - return DominatedSetRange(postOrder, &dominated[indices[nodeIndex]], end); - } - }; - - private: - // Data members. - JS::ubi::Vector postOrder; - NodeToIndexMap nodeToPostOrderIndex; - JS::ubi::Vector doms; - DominatedSets dominatedSets; - mozilla::Maybe> retainedSizes; - - private: - // We use `UNDEFINED` as a sentinel value in the `doms` vector to signal - // that we haven't found any dominators for the node at the corresponding - // index in `postOrder` yet. - static const uint32_t UNDEFINED = UINT32_MAX; - - DominatorTree(JS::ubi::Vector&& postOrder, NodeToIndexMap&& nodeToPostOrderIndex, - JS::ubi::Vector&& doms, DominatedSets&& dominatedSets) - : postOrder(mozilla::Move(postOrder)) - , nodeToPostOrderIndex(mozilla::Move(nodeToPostOrderIndex)) - , doms(mozilla::Move(doms)) - , dominatedSets(mozilla::Move(dominatedSets)) - , retainedSizes(mozilla::Nothing()) - { } - - static uint32_t intersect(JS::ubi::Vector& doms, uint32_t finger1, uint32_t finger2) { - while (finger1 != finger2) { - if (finger1 < finger2) - finger1 = doms[finger1]; - else if (finger2 < finger1) - finger2 = doms[finger2]; - } - return finger1; - } - - // Do the post order traversal of the heap graph and populate our - // predecessor sets. - static MOZ_MUST_USE bool doTraversal(JSContext* cx, AutoCheckCannotGC& noGC, const Node& root, - JS::ubi::Vector& postOrder, - PredecessorSets& predecessorSets) { - uint32_t nodeCount = 0; - auto onNode = [&](const Node& node) { - nodeCount++; - if (MOZ_UNLIKELY(nodeCount == UINT32_MAX)) - return false; - return postOrder.append(node); - }; - - auto onEdge = [&](const Node& origin, const Edge& edge) { - auto p = predecessorSets.lookupForAdd(edge.referent); - if (!p) { - mozilla::UniquePtr> set(js_new()); - if (!set || - !set->init() || - !predecessorSets.add(p, edge.referent, mozilla::Move(set))) - { - return false; - } - } - MOZ_ASSERT(p && p->value()); - return p->value()->put(origin); - }; - - PostOrder traversal(cx, noGC); - return traversal.init() && - traversal.addStart(root) && - traversal.traverse(onNode, onEdge); - } - - // Populates the given `map` with an entry for each node to its index in - // `postOrder`. - static MOZ_MUST_USE bool mapNodesToTheirIndices(JS::ubi::Vector& postOrder, - NodeToIndexMap& map) { - MOZ_ASSERT(!map.initialized()); - MOZ_ASSERT(postOrder.length() < UINT32_MAX); - uint32_t length = postOrder.length(); - if (!map.init(length)) - return false; - for (uint32_t i = 0; i < length; i++) - map.putNewInfallible(postOrder[i], i); - return true; - } - - // Convert the Node -> NodeSet predecessorSets to a index -> Vector - // form. - static MOZ_MUST_USE bool convertPredecessorSetsToVectors( - const Node& root, - JS::ubi::Vector& postOrder, - PredecessorSets& predecessorSets, - NodeToIndexMap& nodeToPostOrderIndex, - JS::ubi::Vector>& predecessorVectors) - { - MOZ_ASSERT(postOrder.length() < UINT32_MAX); - uint32_t length = postOrder.length(); - - MOZ_ASSERT(predecessorVectors.length() == 0); - if (!predecessorVectors.growBy(length)) - return false; - - for (uint32_t i = 0; i < length - 1; i++) { - auto& node = postOrder[i]; - MOZ_ASSERT(node != root, - "Only the last node should be root, since this was a post order traversal."); - - auto ptr = predecessorSets.lookup(node); - MOZ_ASSERT(ptr, - "Because this isn't the root, it had better have predecessors, or else how " - "did we even find it."); - - auto& predecessors = ptr->value(); - if (!predecessorVectors[i].reserve(predecessors->count())) - return false; - for (auto range = predecessors->all(); !range.empty(); range.popFront()) { - auto ptr = nodeToPostOrderIndex.lookup(range.front()); - MOZ_ASSERT(ptr); - predecessorVectors[i].infallibleAppend(ptr->value()); - } - } - predecessorSets.finish(); - return true; - } - - // Initialize `doms` such that the immediate dominator of the `root` is the - // `root` itself and all others are `UNDEFINED`. - static MOZ_MUST_USE bool initializeDominators(JS::ubi::Vector& doms, - uint32_t length) { - MOZ_ASSERT(doms.length() == 0); - if (!doms.growByUninitialized(length)) - return false; - doms[length - 1] = length - 1; - for (uint32_t i = 0; i < length - 1; i++) - doms[i] = UNDEFINED; - return true; - } - - void assertSanity() const { - MOZ_ASSERT(postOrder.length() == doms.length()); - MOZ_ASSERT(postOrder.length() == nodeToPostOrderIndex.count()); - MOZ_ASSERT_IF(retainedSizes.isSome(), postOrder.length() == retainedSizes->length()); - } - - MOZ_MUST_USE bool computeRetainedSizes(mozilla::MallocSizeOf mallocSizeOf) { - MOZ_ASSERT(retainedSizes.isNothing()); - auto length = postOrder.length(); - - retainedSizes.emplace(); - if (!retainedSizes->growBy(length)) { - retainedSizes = mozilla::Nothing(); - return false; - } - - // Iterate in forward order so that we know all of a node's children in - // the dominator tree have already had their retained size - // computed. Then we can simply say that the retained size of a node is - // its shallow size (JS::ubi::Node::size) plus the retained sizes of its - // immediate children in the tree. - - for (uint32_t i = 0; i < length; i++) { - auto size = postOrder[i].size(mallocSizeOf); - - for (const auto& dominated : dominatedSets.dominatedSet(postOrder, i)) { - // The root node dominates itself, but shouldn't contribute to - // its own retained size. - if (dominated == postOrder[length - 1]) { - MOZ_ASSERT(i == length - 1); - continue; - } - - auto ptr = nodeToPostOrderIndex.lookup(dominated); - MOZ_ASSERT(ptr); - auto idxOfDominated = ptr->value(); - MOZ_ASSERT(idxOfDominated < i); - size += retainedSizes.ref()[idxOfDominated]; - } - - retainedSizes.ref()[i] = size; - } - - return true; - } - - public: - // DominatorTree is not copy-able. - DominatorTree(const DominatorTree&) = delete; - DominatorTree& operator=(const DominatorTree&) = delete; - - // DominatorTree is move-able. - DominatorTree(DominatorTree&& rhs) - : postOrder(mozilla::Move(rhs.postOrder)) - , nodeToPostOrderIndex(mozilla::Move(rhs.nodeToPostOrderIndex)) - , doms(mozilla::Move(rhs.doms)) - , dominatedSets(mozilla::Move(rhs.dominatedSets)) - , retainedSizes(mozilla::Move(rhs.retainedSizes)) - { - MOZ_ASSERT(this != &rhs, "self-move is not allowed"); - } - DominatorTree& operator=(DominatorTree&& rhs) { - this->~DominatorTree(); - new (this) DominatorTree(mozilla::Move(rhs)); - return *this; - } - - /** - * Construct a `DominatorTree` of the heap graph visible from `root`. The - * `root` is also used as the root of the resulting dominator tree. - * - * The resulting `DominatorTree` instance must not outlive the - * `JS::ubi::Node` graph it was constructed from. - * - * - For `JS::ubi::Node` graphs backed by the live heap graph, this means - * that the `DominatorTree`'s lifetime _must_ be contained within the - * scope of the provided `AutoCheckCannotGC` reference because a GC will - * invalidate the nodes. - * - * - For `JS::ubi::Node` graphs backed by some other offline structure - * provided by the embedder, the resulting `DominatorTree`'s lifetime is - * bounded by that offline structure's lifetime. - * - * In practice, this means that within SpiderMonkey we must treat - * `DominatorTree` as if it were backed by the live heap graph and trust - * that embedders with knowledge of the graph's implementation will do the - * Right Thing. - * - * Returns `mozilla::Nothing()` on OOM failure. It is the caller's - * responsibility to handle and report the OOM. - */ - static mozilla::Maybe - Create(JSContext* cx, AutoCheckCannotGC& noGC, const Node& root) { - JS::ubi::Vector postOrder; - PredecessorSets predecessorSets; - if (!predecessorSets.init() || !doTraversal(cx, noGC, root, postOrder, predecessorSets)) - return mozilla::Nothing(); - - MOZ_ASSERT(postOrder.length() < UINT32_MAX); - uint32_t length = postOrder.length(); - MOZ_ASSERT(postOrder[length - 1] == root); - - // From here on out we wish to avoid hash table lookups, and we use - // indices into `postOrder` instead of actual nodes wherever - // possible. This greatly improves the performance of this - // implementation, but we have to pay a little bit of upfront cost to - // convert our data structures to play along first. - - NodeToIndexMap nodeToPostOrderIndex; - if (!mapNodesToTheirIndices(postOrder, nodeToPostOrderIndex)) - return mozilla::Nothing(); - - JS::ubi::Vector> predecessorVectors; - if (!convertPredecessorSetsToVectors(root, postOrder, predecessorSets, nodeToPostOrderIndex, - predecessorVectors)) - return mozilla::Nothing(); - - JS::ubi::Vector doms; - if (!initializeDominators(doms, length)) - return mozilla::Nothing(); - - bool changed = true; - while (changed) { - changed = false; - - // Iterate over the non-root nodes in reverse post order. - for (uint32_t indexPlusOne = length - 1; indexPlusOne > 0; indexPlusOne--) { - MOZ_ASSERT(postOrder[indexPlusOne - 1] != root); - - // Take the intersection of every predecessor's dominator set; - // that is the current best guess at the immediate dominator for - // this node. - - uint32_t newIDomIdx = UNDEFINED; - - auto& predecessors = predecessorVectors[indexPlusOne - 1]; - auto range = predecessors.all(); - for ( ; !range.empty(); range.popFront()) { - auto idx = range.front(); - if (doms[idx] != UNDEFINED) { - newIDomIdx = idx; - break; - } - } - - MOZ_ASSERT(newIDomIdx != UNDEFINED, - "Because the root is initialized to dominate itself and is the first " - "node in every path, there must exist a predecessor to this node that " - "also has a dominator."); - - for ( ; !range.empty(); range.popFront()) { - auto idx = range.front(); - if (doms[idx] != UNDEFINED) - newIDomIdx = intersect(doms, newIDomIdx, idx); - } - - // If the immediate dominator changed, we will have to do - // another pass of the outer while loop to continue the forward - // dataflow. - if (newIDomIdx != doms[indexPlusOne - 1]) { - doms[indexPlusOne - 1] = newIDomIdx; - changed = true; - } - } - } - - auto maybeDominatedSets = DominatedSets::Create(doms); - if (maybeDominatedSets.isNothing()) - return mozilla::Nothing(); - - return mozilla::Some(DominatorTree(mozilla::Move(postOrder), - mozilla::Move(nodeToPostOrderIndex), - mozilla::Move(doms), - mozilla::Move(*maybeDominatedSets))); - } - - /** - * Get the root node for this dominator tree. - */ - const Node& root() const { - return postOrder[postOrder.length() - 1]; - } - - /** - * Return the immediate dominator of the given `node`. If `node` was not - * reachable from the `root` that this dominator tree was constructed from, - * then return the null `JS::ubi::Node`. - */ - Node getImmediateDominator(const Node& node) const { - assertSanity(); - auto ptr = nodeToPostOrderIndex.lookup(node); - if (!ptr) - return Node(); - - auto idx = ptr->value(); - MOZ_ASSERT(idx < postOrder.length()); - return postOrder[doms[idx]]; - } - - /** - * Get the set of nodes immediately dominated by the given `node`. If `node` - * is not a member of this dominator tree, return `Nothing`. - * - * Example usage: - * - * mozilla::Maybe range = myDominatorTree.getDominatedSet(myNode); - * if (range.isNothing()) { - * // Handle unknown node however you see fit... - * return false; - * } - * - * for (const JS::ubi::Node& dominatedNode : *range) { - * // Do something with each immediately dominated node... - * } - */ - mozilla::Maybe getDominatedSet(const Node& node) { - assertSanity(); - auto ptr = nodeToPostOrderIndex.lookup(node); - if (!ptr) - return mozilla::Nothing(); - - auto idx = ptr->value(); - MOZ_ASSERT(idx < postOrder.length()); - return mozilla::Some(dominatedSets.dominatedSet(postOrder, idx)); - } - - /** - * Get the retained size of the given `node`. The size is placed in - * `outSize`, or 0 if `node` is not a member of the dominator tree. Returns - * false on OOM failure, leaving `outSize` unchanged. - */ - MOZ_MUST_USE bool getRetainedSize(const Node& node, mozilla::MallocSizeOf mallocSizeOf, - Node::Size& outSize) { - assertSanity(); - auto ptr = nodeToPostOrderIndex.lookup(node); - if (!ptr) { - outSize = 0; - return true; - } - - if (retainedSizes.isNothing() && !computeRetainedSizes(mallocSizeOf)) - return false; - - auto idx = ptr->value(); - MOZ_ASSERT(idx < postOrder.length()); - outSize = retainedSizes.ref()[idx]; - return true; - } -}; - -} // namespace ubi -} // namespace JS - -#endif // js_UbiNodeDominatorTree_h diff --git a/android/armeabi-v7a/include/spidermonkey/js/UbiNodePostOrder.h b/android/armeabi-v7a/include/spidermonkey/js/UbiNodePostOrder.h deleted file mode 100644 index a5042677..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/UbiNodePostOrder.h +++ /dev/null @@ -1,191 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNodePostOrder_h -#define js_UbiNodePostOrder_h - -#include "mozilla/Attributes.h" -#include "mozilla/Maybe.h" -#include "mozilla/Move.h" - -#include "jsalloc.h" - -#include "js/UbiNode.h" -#include "js/Utility.h" -#include "js/Vector.h" - -namespace JS { -namespace ubi { - -/** - * A post-order depth-first traversal of `ubi::Node` graphs. - * - * No GC may occur while an instance of `PostOrder` is live. - * - * The `NodeVisitor` type provided to `PostOrder::traverse` must have the - * following member: - * - * bool operator()(Node& node) - * - * The node visitor method. This method is called once for each `node` - * reachable from the start set in post-order. - * - * This visitor function should return true on success, or false if an error - * occurs. A false return value terminates the traversal immediately, and - * causes `PostOrder::traverse` to return false. - * - * The `EdgeVisitor` type provided to `PostOrder::traverse` must have the - * following member: - * - * bool operator()(Node& origin, Edge& edge) - * - * The edge visitor method. This method is called once for each outgoing - * `edge` from `origin` that is reachable from the start set. - * - * NB: UNLIKE NODES, THERE IS NO GUARANTEED ORDER IN WHICH EDGES AND THEIR - * ORIGINS ARE VISITED! - * - * This visitor function should return true on success, or false if an error - * occurs. A false return value terminates the traversal immediately, and - * causes `PostOrder::traverse` to return false. - */ -struct PostOrder { - private: - struct OriginAndEdges { - Node origin; - EdgeVector edges; - - OriginAndEdges(const Node& node, EdgeVector&& edges) - : origin(node) - , edges(mozilla::Move(edges)) - { } - - OriginAndEdges(const OriginAndEdges& rhs) = delete; - OriginAndEdges& operator=(const OriginAndEdges& rhs) = delete; - - OriginAndEdges(OriginAndEdges&& rhs) - : origin(rhs.origin) - , edges(mozilla::Move(rhs.edges)) - { - MOZ_ASSERT(&rhs != this, "self-move disallowed"); - } - - OriginAndEdges& operator=(OriginAndEdges&& rhs) { - this->~OriginAndEdges(); - new (this) OriginAndEdges(mozilla::Move(rhs)); - return *this; - } - }; - - using Stack = js::Vector; - using Set = js::HashSet, js::SystemAllocPolicy>; - - JSContext* cx; - Set seen; - Stack stack; -#ifdef DEBUG - bool traversed; -#endif - - private: - MOZ_MUST_USE bool fillEdgesFromRange(EdgeVector& edges, js::UniquePtr& range) { - MOZ_ASSERT(range); - for ( ; !range->empty(); range->popFront()) { - if (!edges.append(mozilla::Move(range->front()))) - return false; - } - return true; - } - - MOZ_MUST_USE bool pushForTraversing(const Node& node) { - EdgeVector edges; - auto range = node.edges(cx, /* wantNames */ false); - return range && - fillEdgesFromRange(edges, range) && - stack.append(OriginAndEdges(node, mozilla::Move(edges))); - } - - - public: - // Construct a post-order traversal object. - // - // The traversal asserts that no GC happens in its runtime during its - // lifetime via the `AutoCheckCannotGC&` parameter. We do nothing with it, - // other than require it to exist with a lifetime that encloses our own. - PostOrder(JSContext* cx, AutoCheckCannotGC&) - : cx(cx) - , seen() - , stack() -#ifdef DEBUG - , traversed(false) -#endif - { } - - // Initialize this traversal object. Return false on OOM. - MOZ_MUST_USE bool init() { return seen.init(); } - - // Add `node` as a starting point for the traversal. You may add - // as many starting points as you like. Returns false on OOM. - MOZ_MUST_USE bool addStart(const Node& node) { - if (!seen.put(node)) - return false; - return pushForTraversing(node); - } - - // Traverse the graph in post-order, starting with the set of nodes passed - // to `addStart` and applying `onNode::operator()` for each node in the - // graph and `onEdge::operator()` for each edge in the graph, as described - // above. - // - // This should be called only once per instance of this class. - // - // Return false on OOM or error return from `onNode::operator()` or - // `onEdge::operator()`. - template - MOZ_MUST_USE bool traverse(NodeVisitor onNode, EdgeVisitor onEdge) { -#ifdef DEBUG - MOZ_ASSERT(!traversed, "Can only traverse() once!"); - traversed = true; -#endif - - while (!stack.empty()) { - auto& origin = stack.back().origin; - auto& edges = stack.back().edges; - - if (edges.empty()) { - if (!onNode(origin)) - return false; - stack.popBack(); - continue; - } - - Edge edge = mozilla::Move(edges.back()); - edges.popBack(); - - if (!onEdge(origin, edge)) - return false; - - auto ptr = seen.lookupForAdd(edge.referent); - // We've already seen this node, don't follow its edges. - if (ptr) - continue; - - // Mark the referent as seen and follow its edges. - if (!seen.add(ptr, edge.referent) || - !pushForTraversing(edge.referent)) - { - return false; - } - } - - return true; - } -}; - -} // namespace ubi -} // namespace JS - -#endif // js_UbiNodePostOrder_h diff --git a/android/armeabi-v7a/include/spidermonkey/js/UbiNodeShortestPaths.h b/android/armeabi-v7a/include/spidermonkey/js/UbiNodeShortestPaths.h deleted file mode 100644 index edd5aebb..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/UbiNodeShortestPaths.h +++ /dev/null @@ -1,350 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNodeShortestPaths_h -#define js_UbiNodeShortestPaths_h - -#include "mozilla/Attributes.h" -#include "mozilla/Maybe.h" -#include "mozilla/Move.h" - -#include "jsalloc.h" - -#include "js/UbiNodeBreadthFirst.h" -#include "js/Vector.h" - -namespace JS { -namespace ubi { - -/** - * A back edge along a path in the heap graph. - */ -struct JS_PUBLIC_API(BackEdge) -{ - private: - Node predecessor_; - EdgeName name_; - - public: - using Ptr = mozilla::UniquePtr>; - - BackEdge() : predecessor_(), name_(nullptr) { } - - MOZ_MUST_USE bool init(const Node& predecessor, Edge& edge) { - MOZ_ASSERT(!predecessor_); - MOZ_ASSERT(!name_); - - predecessor_ = predecessor; - name_ = mozilla::Move(edge.name); - return true; - } - - BackEdge(const BackEdge&) = delete; - BackEdge& operator=(const BackEdge&) = delete; - - BackEdge(BackEdge&& rhs) - : predecessor_(rhs.predecessor_) - , name_(mozilla::Move(rhs.name_)) - { - MOZ_ASSERT(&rhs != this); - } - - BackEdge& operator=(BackEdge&& rhs) { - this->~BackEdge(); - new(this) BackEdge(Move(rhs)); - return *this; - } - - Ptr clone() const; - - const EdgeName& name() const { return name_; } - EdgeName& name() { return name_; } - - const JS::ubi::Node& predecessor() const { return predecessor_; } -}; - -/** - * A path is a series of back edges from which we discovered a target node. - */ -using Path = JS::ubi::Vector; - -/** - * The `JS::ubi::ShortestPaths` type represents a collection of up to N shortest - * retaining paths for each of a target set of nodes, starting from the same - * root node. - */ -struct JS_PUBLIC_API(ShortestPaths) -{ - private: - // Types, type aliases, and data members. - - using BackEdgeVector = JS::ubi::Vector; - using NodeToBackEdgeVectorMap = js::HashMap, - js::SystemAllocPolicy>; - - struct Handler; - using Traversal = BreadthFirst; - - /** - * A `JS::ubi::BreadthFirst` traversal handler that records back edges for - * how we reached each node, allowing us to reconstruct the shortest - * retaining paths after the traversal. - */ - struct Handler - { - using NodeData = BackEdge; - - ShortestPaths& shortestPaths; - size_t totalMaxPathsToRecord; - size_t totalPathsRecorded; - - explicit Handler(ShortestPaths& shortestPaths) - : shortestPaths(shortestPaths) - , totalMaxPathsToRecord(shortestPaths.targets_.count() * shortestPaths.maxNumPaths_) - , totalPathsRecorded(0) - { - } - - bool - operator()(Traversal& traversal, JS::ubi::Node origin, JS::ubi::Edge& edge, - BackEdge* back, bool first) - { - MOZ_ASSERT(back); - MOZ_ASSERT(origin == shortestPaths.root_ || traversal.visited.has(origin)); - MOZ_ASSERT(totalPathsRecorded < totalMaxPathsToRecord); - - if (first && !back->init(origin, edge)) - return false; - - if (!shortestPaths.targets_.has(edge.referent)) - return true; - - // If `first` is true, then we moved the edge's name into `back` in - // the above call to `init`. So clone that back edge to get the - // correct edge name. If `first` is not true, then our edge name is - // still in `edge`. This accounts for the asymmetry between - // `back->clone()` in the first branch, and the `init` call in the - // second branch. - - if (first) { - BackEdgeVector paths; - if (!paths.reserve(shortestPaths.maxNumPaths_)) - return false; - auto cloned = back->clone(); - if (!cloned) - return false; - paths.infallibleAppend(mozilla::Move(cloned)); - if (!shortestPaths.paths_.putNew(edge.referent, mozilla::Move(paths))) - return false; - totalPathsRecorded++; - } else { - auto ptr = shortestPaths.paths_.lookup(edge.referent); - MOZ_ASSERT(ptr, - "This isn't the first time we have seen the target node `edge.referent`. " - "We should have inserted it into shortestPaths.paths_ the first time we " - "saw it."); - - if (ptr->value().length() < shortestPaths.maxNumPaths_) { - BackEdge::Ptr thisBackEdge(js_new()); - if (!thisBackEdge || !thisBackEdge->init(origin, edge)) - return false; - ptr->value().infallibleAppend(mozilla::Move(thisBackEdge)); - totalPathsRecorded++; - } - } - - MOZ_ASSERT(totalPathsRecorded <= totalMaxPathsToRecord); - if (totalPathsRecorded == totalMaxPathsToRecord) - traversal.stop(); - - return true; - } - - }; - - // The maximum number of paths to record for each node. - uint32_t maxNumPaths_; - - // The root node we are starting the search from. - Node root_; - - // The set of nodes we are searching for paths to. - NodeSet targets_; - - // The resulting paths. - NodeToBackEdgeVectorMap paths_; - - // Need to keep alive the traversal's back edges so we can walk them later - // when the traversal is over when recreating the shortest paths. - Traversal::NodeMap backEdges_; - - private: - // Private methods. - - ShortestPaths(uint32_t maxNumPaths, const Node& root, NodeSet&& targets) - : maxNumPaths_(maxNumPaths) - , root_(root) - , targets_(mozilla::Move(targets)) - , paths_() - , backEdges_() - { - MOZ_ASSERT(maxNumPaths_ > 0); - MOZ_ASSERT(root_); - MOZ_ASSERT(targets_.initialized()); - } - - bool initialized() const { - return targets_.initialized() && - paths_.initialized() && - backEdges_.initialized(); - } - - public: - // Public methods. - - ShortestPaths(ShortestPaths&& rhs) - : maxNumPaths_(rhs.maxNumPaths_) - , root_(rhs.root_) - , targets_(mozilla::Move(rhs.targets_)) - , paths_(mozilla::Move(rhs.paths_)) - , backEdges_(mozilla::Move(rhs.backEdges_)) - { - MOZ_ASSERT(this != &rhs, "self-move is not allowed"); - } - - ShortestPaths& operator=(ShortestPaths&& rhs) { - this->~ShortestPaths(); - new (this) ShortestPaths(mozilla::Move(rhs)); - return *this; - } - - ShortestPaths(const ShortestPaths&) = delete; - ShortestPaths& operator=(const ShortestPaths&) = delete; - - /** - * Construct a new `JS::ubi::ShortestPaths`, finding up to `maxNumPaths` - * shortest retaining paths for each target node in `targets` starting from - * `root`. - * - * The resulting `ShortestPaths` instance must not outlive the - * `JS::ubi::Node` graph it was constructed from. - * - * - For `JS::ubi::Node` graphs backed by the live heap graph, this means - * that the `ShortestPaths`'s lifetime _must_ be contained within the - * scope of the provided `AutoCheckCannotGC` reference because a GC will - * invalidate the nodes. - * - * - For `JS::ubi::Node` graphs backed by some other offline structure - * provided by the embedder, the resulting `ShortestPaths`'s lifetime is - * bounded by that offline structure's lifetime. - * - * Returns `mozilla::Nothing()` on OOM failure. It is the caller's - * responsibility to handle and report the OOM. - */ - static mozilla::Maybe - Create(JSContext* cx, AutoCheckCannotGC& noGC, uint32_t maxNumPaths, const Node& root, NodeSet&& targets) { - MOZ_ASSERT(targets.count() > 0); - MOZ_ASSERT(maxNumPaths > 0); - - size_t count = targets.count(); - ShortestPaths paths(maxNumPaths, root, mozilla::Move(targets)); - if (!paths.paths_.init(count)) - return mozilla::Nothing(); - - Handler handler(paths); - Traversal traversal(cx, handler, noGC); - traversal.wantNames = true; - if (!traversal.init() || !traversal.addStart(root) || !traversal.traverse()) - return mozilla::Nothing(); - - // Take ownership of the back edges we created while traversing the - // graph so that we can follow them from `paths_` and don't - // use-after-free. - paths.backEdges_ = mozilla::Move(traversal.visited); - - MOZ_ASSERT(paths.initialized()); - return mozilla::Some(mozilla::Move(paths)); - } - - /** - * Get a range that iterates over each target node we searched for retaining - * paths for. The returned range must not outlive the `ShortestPaths` - * instance. - */ - NodeSet::Range eachTarget() const { - MOZ_ASSERT(initialized()); - return targets_.all(); - } - - /** - * Invoke the provided functor/lambda/callable once for each retaining path - * discovered for `target`. The `func` is passed a single `JS::ubi::Path&` - * argument, which contains each edge along the path ordered starting from - * the root and ending at the target, and must not outlive the scope of the - * call. - * - * Note that it is possible that we did not find any paths from the root to - * the given target, in which case `func` will not be invoked. - */ - template - MOZ_MUST_USE bool forEachPath(const Node& target, Func func) { - MOZ_ASSERT(initialized()); - MOZ_ASSERT(targets_.has(target)); - - auto ptr = paths_.lookup(target); - - // We didn't find any paths to this target, so nothing to do here. - if (!ptr) - return true; - - MOZ_ASSERT(ptr->value().length() <= maxNumPaths_); - - Path path; - for (const auto& backEdge : ptr->value()) { - path.clear(); - - if (!path.append(backEdge.get())) - return false; - - Node here = backEdge->predecessor(); - MOZ_ASSERT(here); - - while (here != root_) { - auto p = backEdges_.lookup(here); - MOZ_ASSERT(p); - if (!path.append(&p->value())) - return false; - here = p->value().predecessor(); - MOZ_ASSERT(here); - } - - path.reverse(); - - if (!func(path)) - return false; - } - - return true; - } -}; - -#ifdef DEBUG -// A helper function to dump the first `maxNumPaths` shortest retaining paths to -// `node` from the GC roots. Useful when GC things you expect to have been -// reclaimed by the collector haven't been! -// -// Usage: -// -// JSObject* foo = ...; -// JS::ubi::dumpPaths(rt, JS::ubi::Node(foo)); -JS_PUBLIC_API(void) -dumpPaths(JSRuntime* rt, Node node, uint32_t maxNumPaths = 10); -#endif - -} // namespace ubi -} // namespace JS - -#endif // js_UbiNodeShortestPaths_h diff --git a/android/armeabi-v7a/include/spidermonkey/js/UniquePtr.h b/android/armeabi-v7a/include/spidermonkey/js/UniquePtr.h deleted file mode 100644 index 0236bab4..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/UniquePtr.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UniquePtr_h -#define js_UniquePtr_h - -#include "mozilla/UniquePtr.h" - -#include "js/Utility.h" - -namespace js { - -// Replacement for mozilla::UniquePtr that defaults to js::DefaultDelete. -template > -using UniquePtr = mozilla::UniquePtr; - -namespace detail { - -template -struct UniqueSelector -{ - typedef UniquePtr SingleObject; -}; - -template -struct UniqueSelector -{ - typedef UniquePtr UnknownBound; -}; - -template -struct UniqueSelector -{ - typedef UniquePtr KnownBound; -}; - -} // namespace detail - -// Replacement for mozilla::MakeUnique that correctly calls js_new and produces -// a js::UniquePtr. -template -typename detail::UniqueSelector::SingleObject -MakeUnique(Args&&... aArgs) -{ - return UniquePtr(js_new(mozilla::Forward(aArgs)...)); -} - -template -typename detail::UniqueSelector::UnknownBound -MakeUnique(decltype(sizeof(int)) aN) = delete; - -template -typename detail::UniqueSelector::KnownBound -MakeUnique(Args&&... aArgs) = delete; - -} // namespace js - -#endif /* js_UniquePtr_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/Utility.h b/android/armeabi-v7a/include/spidermonkey/js/Utility.h deleted file mode 100644 index 75214c32..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/Utility.h +++ /dev/null @@ -1,577 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_Utility_h -#define js_Utility_h - -#include "mozilla/Assertions.h" -#include "mozilla/Atomics.h" -#include "mozilla/Attributes.h" -#include "mozilla/Compiler.h" -#include "mozilla/Move.h" -#include "mozilla/Scoped.h" -#include "mozilla/TemplateLib.h" -#include "mozilla/UniquePtr.h" - -#include -#include - -#ifdef JS_OOM_DO_BACKTRACES -#include -#include -#endif - -#include "jstypes.h" - -/* The public JS engine namespace. */ -namespace JS {} - -/* The mozilla-shared reusable template/utility namespace. */ -namespace mozilla {} - -/* The private JS engine namespace. */ -namespace js {} - -#define JS_STATIC_ASSERT(cond) static_assert(cond, "JS_STATIC_ASSERT") -#define JS_STATIC_ASSERT_IF(cond, expr) MOZ_STATIC_ASSERT_IF(cond, expr, "JS_STATIC_ASSERT_IF") - -extern MOZ_NORETURN MOZ_COLD JS_PUBLIC_API(void) -JS_Assert(const char* s, const char* file, int ln); - -/* - * Custom allocator support for SpiderMonkey - */ -#if defined JS_USE_CUSTOM_ALLOCATOR -# include "jscustomallocator.h" -#else - -namespace js { -namespace oom { - -/* - * To make testing OOM in certain helper threads more effective, - * allow restricting the OOM testing to a certain helper thread - * type. This allows us to fail e.g. in off-thread script parsing - * without causing an OOM in the main thread first. - */ -enum ThreadType { - THREAD_TYPE_NONE = 0, // 0 - THREAD_TYPE_MAIN, // 1 - THREAD_TYPE_ASMJS, // 2 - THREAD_TYPE_ION, // 3 - THREAD_TYPE_PARSE, // 4 - THREAD_TYPE_COMPRESS, // 5 - THREAD_TYPE_GCHELPER, // 6 - THREAD_TYPE_GCPARALLEL, // 7 - THREAD_TYPE_PROMISE_TASK, // 8 - THREAD_TYPE_MAX // Used to check shell function arguments -}; - -/* - * Getter/Setter functions to encapsulate mozilla::ThreadLocal, - * implementation is in jsutil.cpp. - */ -# if defined(DEBUG) || defined(JS_OOM_BREAKPOINT) -extern bool InitThreadType(void); -extern void SetThreadType(ThreadType); -extern uint32_t GetThreadType(void); -# else -inline bool InitThreadType(void) { return true; } -inline void SetThreadType(ThreadType t) {}; -inline uint32_t GetThreadType(void) { return 0; } -# endif - -} /* namespace oom */ -} /* namespace js */ - -# if defined(DEBUG) || defined(JS_OOM_BREAKPOINT) - -#ifdef JS_OOM_BREAKPOINT -static MOZ_NEVER_INLINE void js_failedAllocBreakpoint() { asm(""); } -#define JS_OOM_CALL_BP_FUNC() js_failedAllocBreakpoint() -#else -#define JS_OOM_CALL_BP_FUNC() do {} while(0) -#endif - -namespace js { -namespace oom { - -/* - * Out of memory testing support. We provide various testing functions to - * simulate OOM conditions and so we can test that they are handled correctly. - */ - -extern JS_PUBLIC_DATA(uint32_t) targetThread; -extern JS_PUBLIC_DATA(uint64_t) maxAllocations; -extern JS_PUBLIC_DATA(uint64_t) counter; -extern JS_PUBLIC_DATA(bool) failAlways; - -extern void -SimulateOOMAfter(uint64_t allocations, uint32_t thread, bool always); - -extern void -ResetSimulatedOOM(); - -inline bool -IsThreadSimulatingOOM() -{ - return js::oom::targetThread && js::oom::targetThread == js::oom::GetThreadType(); -} - -inline bool -IsSimulatedOOMAllocation() -{ - return IsThreadSimulatingOOM() && - (counter == maxAllocations || (counter > maxAllocations && failAlways)); -} - -inline bool -ShouldFailWithOOM() -{ - if (!IsThreadSimulatingOOM()) - return false; - - counter++; - if (IsSimulatedOOMAllocation()) { - JS_OOM_CALL_BP_FUNC(); - return true; - } - return false; -} - -inline bool -HadSimulatedOOM() { - return counter >= maxAllocations; -} - -} /* namespace oom */ -} /* namespace js */ - -# define JS_OOM_POSSIBLY_FAIL() \ - do { \ - if (js::oom::ShouldFailWithOOM()) \ - return nullptr; \ - } while (0) - -# define JS_OOM_POSSIBLY_FAIL_BOOL() \ - do { \ - if (js::oom::ShouldFailWithOOM()) \ - return false; \ - } while (0) - -# else - -# define JS_OOM_POSSIBLY_FAIL() do {} while(0) -# define JS_OOM_POSSIBLY_FAIL_BOOL() do {} while(0) -namespace js { -namespace oom { -static inline bool IsSimulatedOOMAllocation() { return false; } -static inline bool ShouldFailWithOOM() { return false; } -} /* namespace oom */ -} /* namespace js */ - -# endif /* DEBUG || JS_OOM_BREAKPOINT */ - -namespace js { - -/* Disable OOM testing in sections which are not OOM safe. */ -struct MOZ_RAII AutoEnterOOMUnsafeRegion -{ - MOZ_NORETURN MOZ_COLD void crash(const char* reason); - MOZ_NORETURN MOZ_COLD void crash(size_t size, const char* reason); - - using AnnotateOOMAllocationSizeCallback = void(*)(size_t); - static AnnotateOOMAllocationSizeCallback annotateOOMSizeCallback; - static void setAnnotateOOMAllocationSizeCallback(AnnotateOOMAllocationSizeCallback callback) { - annotateOOMSizeCallback = callback; - } - -#if defined(DEBUG) || defined(JS_OOM_BREAKPOINT) - AutoEnterOOMUnsafeRegion() - : oomEnabled_(oom::IsThreadSimulatingOOM() && oom::maxAllocations != UINT64_MAX), - oomAfter_(0) - { - if (oomEnabled_) { - MOZ_ALWAYS_TRUE(owner_.compareExchange(nullptr, this)); - oomAfter_ = int64_t(oom::maxAllocations) - int64_t(oom::counter); - oom::maxAllocations = UINT64_MAX; - } - } - - ~AutoEnterOOMUnsafeRegion() { - if (oomEnabled_) { - MOZ_ASSERT(oom::maxAllocations == UINT64_MAX); - int64_t maxAllocations = int64_t(oom::counter) + oomAfter_; - MOZ_ASSERT(maxAllocations >= 0, - "alloc count + oom limit exceeds range, your oom limit is probably too large"); - oom::maxAllocations = uint64_t(maxAllocations); - MOZ_ALWAYS_TRUE(owner_.compareExchange(this, nullptr)); - } - } - - private: - // Used to catch concurrent use from other threads. - static mozilla::Atomic owner_; - - bool oomEnabled_; - int64_t oomAfter_; -#endif -}; - -} /* namespace js */ - -static inline void* js_malloc(size_t bytes) -{ - JS_OOM_POSSIBLY_FAIL(); - return malloc(bytes); -} - -static inline void* js_calloc(size_t bytes) -{ - JS_OOM_POSSIBLY_FAIL(); - return calloc(bytes, 1); -} - -static inline void* js_calloc(size_t nmemb, size_t size) -{ - JS_OOM_POSSIBLY_FAIL(); - return calloc(nmemb, size); -} - -static inline void* js_realloc(void* p, size_t bytes) -{ - // realloc() with zero size is not portable, as some implementations may - // return nullptr on success and free |p| for this. We assume nullptr - // indicates failure and that |p| is still valid. - MOZ_ASSERT(bytes != 0); - - JS_OOM_POSSIBLY_FAIL(); - return realloc(p, bytes); -} - -static inline void js_free(void* p) -{ - free(p); -} - -static inline char* js_strdup(const char* s) -{ - JS_OOM_POSSIBLY_FAIL(); - return strdup(s); -} -#endif/* JS_USE_CUSTOM_ALLOCATOR */ - -#include - -/* - * Low-level memory management in SpiderMonkey: - * - * ** Do not use the standard malloc/free/realloc: SpiderMonkey allows these - * to be redefined (via JS_USE_CUSTOM_ALLOCATOR) and Gecko even #define's - * these symbols. - * - * ** Do not use the builtin C++ operator new and delete: these throw on - * error and we cannot override them not to. - * - * Allocation: - * - * - If the lifetime of the allocation is tied to the lifetime of a GC-thing - * (that is, finalizing the GC-thing will free the allocation), call one of - * the following functions: - * - * JSContext::{malloc_,realloc_,calloc_,new_} - * JSRuntime::{malloc_,realloc_,calloc_,new_} - * - * These functions accumulate the number of bytes allocated which is used as - * part of the GC-triggering heuristic. - * - * The difference between the JSContext and JSRuntime versions is that the - * cx version reports an out-of-memory error on OOM. (This follows from the - * general SpiderMonkey idiom that a JSContext-taking function reports its - * own errors.) - * - * - Otherwise, use js_malloc/js_realloc/js_calloc/js_new - * - * Deallocation: - * - * - Ordinarily, use js_free/js_delete. - * - * - For deallocations during GC finalization, use one of the following - * operations on the FreeOp provided to the finalizer: - * - * FreeOp::{free_,delete_} - * - * The advantage of these operations is that the memory is batched and freed - * on another thread. - */ - -/* - * Given a class which should provide a 'new' method, add - * JS_DECLARE_NEW_METHODS (see js::MallocProvider for an example). - * - * Note: Do not add a ; at the end of a use of JS_DECLARE_NEW_METHODS, - * or the build will break. - */ -#define JS_DECLARE_NEW_METHODS(NEWNAME, ALLOCATOR, QUALIFIERS) \ - template \ - QUALIFIERS T * \ - NEWNAME(Args&&... args) MOZ_HEAP_ALLOCATOR { \ - void* memory = ALLOCATOR(sizeof(T)); \ - return MOZ_LIKELY(memory) \ - ? new(memory) T(mozilla::Forward(args)...) \ - : nullptr; \ - } - -/* - * Given a class which should provide 'make' methods, add - * JS_DECLARE_MAKE_METHODS (see js::MallocProvider for an example). This - * method is functionally the same as JS_DECLARE_NEW_METHODS: it just declares - * methods that return mozilla::UniquePtr instances that will singly-manage - * ownership of the created object. - * - * Note: Do not add a ; at the end of a use of JS_DECLARE_MAKE_METHODS, - * or the build will break. - */ -#define JS_DECLARE_MAKE_METHODS(MAKENAME, NEWNAME, QUALIFIERS)\ - template \ - QUALIFIERS mozilla::UniquePtr> \ - MAKENAME(Args&&... args) MOZ_HEAP_ALLOCATOR { \ - T* ptr = NEWNAME(mozilla::Forward(args)...); \ - return mozilla::UniquePtr>(ptr); \ - } - -JS_DECLARE_NEW_METHODS(js_new, js_malloc, static MOZ_ALWAYS_INLINE) - -namespace js { - -/* - * Calculate the number of bytes needed to allocate |numElems| contiguous - * instances of type |T|. Return false if the calculation overflowed. - */ -template -MOZ_MUST_USE inline bool -CalculateAllocSize(size_t numElems, size_t* bytesOut) -{ - *bytesOut = numElems * sizeof(T); - return (numElems & mozilla::tl::MulOverflowMask::value) == 0; -} - -/* - * Calculate the number of bytes needed to allocate a single instance of type - * |T| followed by |numExtra| contiguous instances of type |Extra|. Return - * false if the calculation overflowed. - */ -template -MOZ_MUST_USE inline bool -CalculateAllocSizeWithExtra(size_t numExtra, size_t* bytesOut) -{ - *bytesOut = sizeof(T) + numExtra * sizeof(Extra); - return (numExtra & mozilla::tl::MulOverflowMask::value) == 0 && - *bytesOut >= sizeof(T); -} - -} /* namespace js */ - -template -static MOZ_ALWAYS_INLINE void -js_delete(const T* p) -{ - if (p) { - p->~T(); - js_free(const_cast(p)); - } -} - -template -static MOZ_ALWAYS_INLINE void -js_delete_poison(const T* p) -{ - if (p) { - p->~T(); - memset(const_cast(p), 0x3B, sizeof(T)); - js_free(const_cast(p)); - } -} - -template -static MOZ_ALWAYS_INLINE T* -js_pod_malloc() -{ - return static_cast(js_malloc(sizeof(T))); -} - -template -static MOZ_ALWAYS_INLINE T* -js_pod_calloc() -{ - return static_cast(js_calloc(sizeof(T))); -} - -template -static MOZ_ALWAYS_INLINE T* -js_pod_malloc(size_t numElems) -{ - size_t bytes; - if (MOZ_UNLIKELY(!js::CalculateAllocSize(numElems, &bytes))) - return nullptr; - return static_cast(js_malloc(bytes)); -} - -template -static MOZ_ALWAYS_INLINE T* -js_pod_calloc(size_t numElems) -{ - size_t bytes; - if (MOZ_UNLIKELY(!js::CalculateAllocSize(numElems, &bytes))) - return nullptr; - return static_cast(js_calloc(bytes)); -} - -template -static MOZ_ALWAYS_INLINE T* -js_pod_realloc(T* prior, size_t oldSize, size_t newSize) -{ - MOZ_ASSERT(!(oldSize & mozilla::tl::MulOverflowMask::value)); - size_t bytes; - if (MOZ_UNLIKELY(!js::CalculateAllocSize(newSize, &bytes))) - return nullptr; - return static_cast(js_realloc(prior, bytes)); -} - -namespace js { - -template -struct ScopedFreePtrTraits -{ - typedef T* type; - static T* empty() { return nullptr; } - static void release(T* ptr) { js_free(ptr); } -}; -SCOPED_TEMPLATE(ScopedJSFreePtr, ScopedFreePtrTraits) - -template -struct ScopedDeletePtrTraits : public ScopedFreePtrTraits -{ - static void release(T* ptr) { js_delete(ptr); } -}; -SCOPED_TEMPLATE(ScopedJSDeletePtr, ScopedDeletePtrTraits) - -template -struct ScopedReleasePtrTraits : public ScopedFreePtrTraits -{ - static void release(T* ptr) { if (ptr) ptr->release(); } -}; -SCOPED_TEMPLATE(ScopedReleasePtr, ScopedReleasePtrTraits) - -} /* namespace js */ - -namespace JS { - -template -struct DeletePolicy -{ - constexpr DeletePolicy() {} - - template - MOZ_IMPLICIT DeletePolicy(DeletePolicy other, - typename mozilla::EnableIf::value, - int>::Type dummy = 0) - {} - - void operator()(const T* ptr) { - js_delete(const_cast(ptr)); - } -}; - -struct FreePolicy -{ - void operator()(const void* ptr) { - js_free(const_cast(ptr)); - } -}; - -typedef mozilla::UniquePtr UniqueChars; -typedef mozilla::UniquePtr UniqueTwoByteChars; - -} // namespace JS - -namespace js { - -/* Integral types for all hash functions. */ -typedef uint32_t HashNumber; -const unsigned HashNumberSizeBits = 32; - -namespace detail { - -/* - * Given a raw hash code, h, return a number that can be used to select a hash - * bucket. - * - * This function aims to produce as uniform an output distribution as possible, - * especially in the most significant (leftmost) bits, even though the input - * distribution may be highly nonrandom, given the constraints that this must - * be deterministic and quick to compute. - * - * Since the leftmost bits of the result are best, the hash bucket index is - * computed by doing ScrambleHashCode(h) / (2^32/N) or the equivalent - * right-shift, not ScrambleHashCode(h) % N or the equivalent bit-mask. - * - * FIXME: OrderedHashTable uses a bit-mask; see bug 775896. - */ -inline HashNumber -ScrambleHashCode(HashNumber h) -{ - /* - * Simply returning h would not cause any hash tables to produce wrong - * answers. But it can produce pathologically bad performance: The caller - * right-shifts the result, keeping only the highest bits. The high bits of - * hash codes are very often completely entropy-free. (So are the lowest - * bits.) - * - * So we use Fibonacci hashing, as described in Knuth, The Art of Computer - * Programming, 6.4. This mixes all the bits of the input hash code h. - * - * The value of goldenRatio is taken from the hex - * expansion of the golden ratio, which starts 1.9E3779B9.... - * This value is especially good if values with consecutive hash codes - * are stored in a hash table; see Knuth for details. - */ - static const HashNumber goldenRatio = 0x9E3779B9U; - return h * goldenRatio; -} - -} /* namespace detail */ - -} /* namespace js */ - -/* sixgill annotation defines */ -#ifndef HAVE_STATIC_ANNOTATIONS -# define HAVE_STATIC_ANNOTATIONS -# ifdef XGILL_PLUGIN -# define STATIC_PRECONDITION(COND) __attribute__((precondition(#COND))) -# define STATIC_PRECONDITION_ASSUME(COND) __attribute__((precondition_assume(#COND))) -# define STATIC_POSTCONDITION(COND) __attribute__((postcondition(#COND))) -# define STATIC_POSTCONDITION_ASSUME(COND) __attribute__((postcondition_assume(#COND))) -# define STATIC_INVARIANT(COND) __attribute__((invariant(#COND))) -# define STATIC_INVARIANT_ASSUME(COND) __attribute__((invariant_assume(#COND))) -# define STATIC_ASSUME(COND) \ - JS_BEGIN_MACRO \ - __attribute__((assume_static(#COND), unused)) \ - int STATIC_PASTE1(assume_static_, __COUNTER__); \ - JS_END_MACRO -# else /* XGILL_PLUGIN */ -# define STATIC_PRECONDITION(COND) /* nothing */ -# define STATIC_PRECONDITION_ASSUME(COND) /* nothing */ -# define STATIC_POSTCONDITION(COND) /* nothing */ -# define STATIC_POSTCONDITION_ASSUME(COND) /* nothing */ -# define STATIC_INVARIANT(COND) /* nothing */ -# define STATIC_INVARIANT_ASSUME(COND) /* nothing */ -# define STATIC_ASSUME(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO -# endif /* XGILL_PLUGIN */ -# define STATIC_SKIP_INFERENCE STATIC_INVARIANT(skip_inference()) -#endif /* HAVE_STATIC_ANNOTATIONS */ - -#endif /* js_Utility_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/Value.h b/android/armeabi-v7a/include/spidermonkey/js/Value.h deleted file mode 100644 index 00fdad58..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/Value.h +++ /dev/null @@ -1,1509 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* JS::Value implementation. */ - -#ifndef js_Value_h -#define js_Value_h - -#include "mozilla/Attributes.h" -#include "mozilla/Casting.h" -#include "mozilla/FloatingPoint.h" -#include "mozilla/Likely.h" - -#include /* for std::numeric_limits */ - -#include "js-config.h" -#include "jstypes.h" - -#include "js/GCAPI.h" -#include "js/RootingAPI.h" -#include "js/Utility.h" - -namespace JS { class Value; } - -/* JS::Value can store a full int32_t. */ -#define JSVAL_INT_BITS 32 -#define JSVAL_INT_MIN ((int32_t)0x80000000) -#define JSVAL_INT_MAX ((int32_t)0x7fffffff) - -#if defined(JS_PUNBOX64) -# define JSVAL_TAG_SHIFT 47 -#endif - -// Use enums so that printing a JS::Value in the debugger shows nice -// symbolic type tags. - -#if defined(_MSC_VER) -# define JS_ENUM_HEADER(id, type) enum id : type -# define JS_ENUM_FOOTER(id) -#else -# define JS_ENUM_HEADER(id, type) enum id -# define JS_ENUM_FOOTER(id) __attribute__((packed)) -#endif - -/* Remember to propagate changes to the C defines below. */ -JS_ENUM_HEADER(JSValueType, uint8_t) -{ - JSVAL_TYPE_DOUBLE = 0x00, - JSVAL_TYPE_INT32 = 0x01, - JSVAL_TYPE_UNDEFINED = 0x02, - JSVAL_TYPE_BOOLEAN = 0x03, - JSVAL_TYPE_MAGIC = 0x04, - JSVAL_TYPE_STRING = 0x05, - JSVAL_TYPE_SYMBOL = 0x06, - JSVAL_TYPE_PRIVATE_GCTHING = 0x07, - JSVAL_TYPE_NULL = 0x08, - JSVAL_TYPE_OBJECT = 0x0c, - - /* These never appear in a jsval; they are only provided as an out-of-band value. */ - JSVAL_TYPE_UNKNOWN = 0x20, - JSVAL_TYPE_MISSING = 0x21 -} JS_ENUM_FOOTER(JSValueType); - -static_assert(sizeof(JSValueType) == 1, - "compiler typed enum support is apparently buggy"); - -#if defined(JS_NUNBOX32) - -/* Remember to propagate changes to the C defines below. */ -JS_ENUM_HEADER(JSValueTag, uint32_t) -{ - JSVAL_TAG_CLEAR = 0xFFFFFF80, - JSVAL_TAG_INT32 = JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32, - JSVAL_TAG_UNDEFINED = JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED, - JSVAL_TAG_STRING = JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING, - JSVAL_TAG_SYMBOL = JSVAL_TAG_CLEAR | JSVAL_TYPE_SYMBOL, - JSVAL_TAG_BOOLEAN = JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN, - JSVAL_TAG_MAGIC = JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC, - JSVAL_TAG_NULL = JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL, - JSVAL_TAG_OBJECT = JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT, - JSVAL_TAG_PRIVATE_GCTHING = JSVAL_TAG_CLEAR | JSVAL_TYPE_PRIVATE_GCTHING -} JS_ENUM_FOOTER(JSValueTag); - -static_assert(sizeof(JSValueTag) == sizeof(uint32_t), - "compiler typed enum support is apparently buggy"); - -#elif defined(JS_PUNBOX64) - -/* Remember to propagate changes to the C defines below. */ -JS_ENUM_HEADER(JSValueTag, uint32_t) -{ - JSVAL_TAG_MAX_DOUBLE = 0x1FFF0, - JSVAL_TAG_INT32 = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_INT32, - JSVAL_TAG_UNDEFINED = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_UNDEFINED, - JSVAL_TAG_STRING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_STRING, - JSVAL_TAG_SYMBOL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_SYMBOL, - JSVAL_TAG_BOOLEAN = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN, - JSVAL_TAG_MAGIC = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC, - JSVAL_TAG_NULL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL, - JSVAL_TAG_OBJECT = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT, - JSVAL_TAG_PRIVATE_GCTHING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_PRIVATE_GCTHING -} JS_ENUM_FOOTER(JSValueTag); - -static_assert(sizeof(JSValueTag) == sizeof(uint32_t), - "compiler typed enum support is apparently buggy"); - -JS_ENUM_HEADER(JSValueShiftedTag, uint64_t) -{ - JSVAL_SHIFTED_TAG_MAX_DOUBLE = ((((uint64_t)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF), - JSVAL_SHIFTED_TAG_INT32 = (((uint64_t)JSVAL_TAG_INT32) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_UNDEFINED = (((uint64_t)JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_STRING = (((uint64_t)JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_SYMBOL = (((uint64_t)JSVAL_TAG_SYMBOL) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_BOOLEAN = (((uint64_t)JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_MAGIC = (((uint64_t)JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_NULL = (((uint64_t)JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_OBJECT = (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_PRIVATE_GCTHING = (((uint64_t)JSVAL_TAG_PRIVATE_GCTHING) << JSVAL_TAG_SHIFT) -} JS_ENUM_FOOTER(JSValueShiftedTag); - -static_assert(sizeof(JSValueShiftedTag) == sizeof(uint64_t), - "compiler typed enum support is apparently buggy"); - -#endif - -/* - * All our supported compilers implement C++11 |enum Foo : T| syntax, so don't - * expose these macros. (This macro exists *only* because gcc bug 51242 - * makes bit-fields of - * typed enums trigger a warning that can't be turned off. Don't expose it - * beyond this file!) - */ -#undef JS_ENUM_HEADER -#undef JS_ENUM_FOOTER - -#if defined(JS_NUNBOX32) - -#define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_CLEAR | (type))) - -#define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET JSVAL_TAG_NULL -#define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET JSVAL_TAG_OBJECT -#define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32 -#define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET JSVAL_TAG_STRING - -#elif defined(JS_PUNBOX64) - -#define JSVAL_PAYLOAD_MASK 0x00007FFFFFFFFFFFLL -#define JSVAL_TAG_MASK 0xFFFF800000000000LL -#define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_MAX_DOUBLE | (type))) -#define JSVAL_TYPE_TO_SHIFTED_TAG(type) (((uint64_t)JSVAL_TYPE_TO_TAG(type)) << JSVAL_TAG_SHIFT) - -#define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET JSVAL_TAG_NULL -#define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET JSVAL_TAG_OBJECT -#define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32 -#define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET JSVAL_TAG_STRING - -#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET JSVAL_SHIFTED_TAG_NULL -#define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET JSVAL_SHIFTED_TAG_OBJECT -#define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET JSVAL_SHIFTED_TAG_UNDEFINED -#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET JSVAL_SHIFTED_TAG_STRING - -#endif /* JS_PUNBOX64 */ - -typedef enum JSWhyMagic -{ - /** a hole in a native object's elements */ - JS_ELEMENTS_HOLE, - - /** there is not a pending iterator value */ - JS_NO_ITER_VALUE, - - /** exception value thrown when closing a generator */ - JS_GENERATOR_CLOSING, - - /** compiler sentinel value */ - JS_NO_CONSTANT, - - /** used in debug builds to catch tracing errors */ - JS_THIS_POISON, - - /** used in debug builds to catch tracing errors */ - JS_ARG_POISON, - - /** an empty subnode in the AST serializer */ - JS_SERIALIZE_NO_NODE, - - /** lazy arguments value on the stack */ - JS_LAZY_ARGUMENTS, - - /** optimized-away 'arguments' value */ - JS_OPTIMIZED_ARGUMENTS, - - /** magic value passed to natives to indicate construction */ - JS_IS_CONSTRUCTING, - - /** value of static block object slot */ - JS_BLOCK_NEEDS_CLONE, - - /** see class js::HashableValue */ - JS_HASH_KEY_EMPTY, - - /** error while running Ion code */ - JS_ION_ERROR, - - /** missing recover instruction result */ - JS_ION_BAILOUT, - - /** optimized out slot */ - JS_OPTIMIZED_OUT, - - /** uninitialized lexical bindings that produce ReferenceError on touch. */ - JS_UNINITIALIZED_LEXICAL, - - /** for local use */ - JS_GENERIC_MAGIC, - - JS_WHY_MAGIC_COUNT -} JSWhyMagic; - -namespace JS { - -static inline constexpr JS::Value UndefinedValue(); -static inline JS::Value PoisonedObjectValue(JSObject* obj); - -namespace detail { - -constexpr int CanonicalizedNaNSignBit = 0; -constexpr uint64_t CanonicalizedNaNSignificand = 0x8000000000000ULL; - -constexpr uint64_t CanonicalizedNaNBits = - mozilla::SpecificNaNBits::value; - -} // namespace detail - -/** - * Returns a generic quiet NaN value, with all payload bits set to zero. - * - * Among other properties, this NaN's bit pattern conforms to JS::Value's - * bit pattern restrictions. - */ -static MOZ_ALWAYS_INLINE double -GenericNaN() -{ - return mozilla::SpecificNaN(detail::CanonicalizedNaNSignBit, - detail::CanonicalizedNaNSignificand); -} - -/* MSVC with PGO miscompiles this function. */ -#if defined(_MSC_VER) -# pragma optimize("g", off) -#endif -static inline double -CanonicalizeNaN(double d) -{ - if (MOZ_UNLIKELY(mozilla::IsNaN(d))) - return GenericNaN(); - return d; -} -#if defined(_MSC_VER) -# pragma optimize("", on) -#endif - -/** - * JS::Value is the interface for a single JavaScript Engine value. A few - * general notes on JS::Value: - * - * - JS::Value has setX() and isX() members for X in - * - * { Int32, Double, String, Symbol, Boolean, Undefined, Null, Object, Magic } - * - * JS::Value also contains toX() for each of the non-singleton types. - * - * - Magic is a singleton type whose payload contains either a JSWhyMagic "reason" for - * the magic value or a uint32_t value. By providing JSWhyMagic values when - * creating and checking for magic values, it is possible to assert, at - * runtime, that only magic values with the expected reason flow through a - * particular value. For example, if cx->exception has a magic value, the - * reason must be JS_GENERATOR_CLOSING. - * - * - The JS::Value operations are preferred. The JSVAL_* operations remain for - * compatibility; they may be removed at some point. These operations mostly - * provide similar functionality. But there are a few key differences. One - * is that JS::Value gives null a separate type. - * Also, to help prevent mistakenly boxing a nullable JSObject* as an object, - * Value::setObject takes a JSObject&. (Conversely, Value::toObject returns a - * JSObject&.) A convenience member Value::setObjectOrNull is provided. - * - * - JSVAL_VOID is the same as the singleton value of the Undefined type. - * - * - Note that JS::Value is 8 bytes on 32 and 64-bit architectures. Thus, on - * 32-bit user code should avoid copying jsval/JS::Value as much as possible, - * preferring to pass by const Value&. - */ -class MOZ_NON_PARAM alignas(8) Value -{ - public: -#if defined(JS_NUNBOX32) - using PayloadType = uint32_t; -#elif defined(JS_PUNBOX64) - using PayloadType = uint64_t; -#endif - - /* - * N.B. the default constructor leaves Value unitialized. Adding a default - * constructor prevents Value from being stored in a union. - */ - Value() = default; - Value(const Value& v) = default; - - /** - * Returns false if creating a NumberValue containing the given type would - * be lossy, true otherwise. - */ - template - static bool isNumberRepresentable(const T t) { - return T(double(t)) == t; - } - - /*** Mutators ***/ - - void setNull() { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_NULL, 0); - } - - void setUndefined() { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_UNDEFINED, 0); - } - - void setInt32(int32_t i) { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_INT32, uint32_t(i)); - } - - int32_t& getInt32Ref() { - MOZ_ASSERT(isInt32()); - return data.s.payload.i32; - } - - void setDouble(double d) { - // Don't assign to data.asDouble to fix a miscompilation with - // GCC 5.2.1 and 5.3.1. See bug 1312488. - data = layout(d); - MOZ_ASSERT(isDouble()); - } - - void setNaN() { - setDouble(GenericNaN()); - } - - double& getDoubleRef() { - MOZ_ASSERT(isDouble()); - return data.asDouble; - } - - void setString(JSString* str) { - MOZ_ASSERT(uintptr_t(str) > 0x1000); - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_STRING, PayloadType(str)); - } - - void setSymbol(JS::Symbol* sym) { - MOZ_ASSERT(uintptr_t(sym) > 0x1000); - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_SYMBOL, PayloadType(sym)); - } - - void setObject(JSObject& obj) { - MOZ_ASSERT(uintptr_t(&obj) > 0x1000 || uintptr_t(&obj) == 0x48); -#if defined(JS_PUNBOX64) - // VisualStudio cannot contain parenthesized C++ style cast and shift - // inside decltype in template parameter: - // AssertionConditionType> 1))> - // It throws syntax error. - MOZ_ASSERT((((uintptr_t)&obj) >> JSVAL_TAG_SHIFT) == 0); -#endif - setObjectNoCheck(&obj); - } - - private: - void setObjectNoCheck(JSObject* obj) { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_OBJECT, PayloadType(obj)); - } - - friend inline Value PoisonedObjectValue(JSObject* obj); - - public: - void setBoolean(bool b) { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_BOOLEAN, uint32_t(b)); - } - - void setMagic(JSWhyMagic why) { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_MAGIC, uint32_t(why)); - } - - void setMagicUint32(uint32_t payload) { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_MAGIC, payload); - } - - bool setNumber(uint32_t ui) { - if (ui > JSVAL_INT_MAX) { - setDouble((double)ui); - return false; - } else { - setInt32((int32_t)ui); - return true; - } - } - - bool setNumber(double d) { - int32_t i; - if (mozilla::NumberIsInt32(d, &i)) { - setInt32(i); - return true; - } - - setDouble(d); - return false; - } - - void setObjectOrNull(JSObject* arg) { - if (arg) - setObject(*arg); - else - setNull(); - } - - void swap(Value& rhs) { - uint64_t tmp = rhs.data.asBits; - rhs.data.asBits = data.asBits; - data.asBits = tmp; - } - - private: - JSValueTag toTag() const { -#if defined(JS_NUNBOX32) - return data.s.tag; -#elif defined(JS_PUNBOX64) - return JSValueTag(data.asBits >> JSVAL_TAG_SHIFT); -#endif - } - - public: - /*** JIT-only interfaces to interact with and create raw Values ***/ -#if defined(JS_NUNBOX32) - PayloadType toNunboxPayload() const { - return data.s.payload.i32; - } - - JSValueTag toNunboxTag() const { - return data.s.tag; - } -#elif defined(JS_PUNBOX64) - const void* bitsAsPunboxPointer() const { - return reinterpret_cast(data.asBits); - } -#endif - - /*** Value type queries ***/ - - /* - * N.B. GCC, in some but not all cases, chooses to emit signed comparison - * of JSValueTag even though its underlying type has been forced to be - * uint32_t. Thus, all comparisons should explicitly cast operands to - * uint32_t. - */ - - bool isUndefined() const { -#if defined(JS_NUNBOX32) - return toTag() == JSVAL_TAG_UNDEFINED; -#elif defined(JS_PUNBOX64) - return data.asBits == JSVAL_SHIFTED_TAG_UNDEFINED; -#endif - } - - bool isNull() const { -#if defined(JS_NUNBOX32) - return toTag() == JSVAL_TAG_NULL; -#elif defined(JS_PUNBOX64) - return data.asBits == JSVAL_SHIFTED_TAG_NULL; -#endif - } - - bool isNullOrUndefined() const { - return isNull() || isUndefined(); - } - - bool isInt32() const { - return toTag() == JSVAL_TAG_INT32; - } - - bool isInt32(int32_t i32) const { - return data.asBits == bitsFromTagAndPayload(JSVAL_TAG_INT32, uint32_t(i32)); - } - - bool isDouble() const { -#if defined(JS_NUNBOX32) - return uint32_t(toTag()) <= uint32_t(JSVAL_TAG_CLEAR); -#elif defined(JS_PUNBOX64) - return (data.asBits | mozilla::DoubleTypeTraits::kSignBit) <= JSVAL_SHIFTED_TAG_MAX_DOUBLE; -#endif - } - - bool isNumber() const { -#if defined(JS_NUNBOX32) - MOZ_ASSERT(toTag() != JSVAL_TAG_CLEAR); - return uint32_t(toTag()) <= uint32_t(JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET); -#elif defined(JS_PUNBOX64) - return data.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET; -#endif - } - - bool isString() const { - return toTag() == JSVAL_TAG_STRING; - } - - bool isSymbol() const { - return toTag() == JSVAL_TAG_SYMBOL; - } - - bool isObject() const { -#if defined(JS_NUNBOX32) - return toTag() == JSVAL_TAG_OBJECT; -#elif defined(JS_PUNBOX64) - MOZ_ASSERT((data.asBits >> JSVAL_TAG_SHIFT) <= JSVAL_TAG_OBJECT); - return data.asBits >= JSVAL_SHIFTED_TAG_OBJECT; -#endif - } - - bool isPrimitive() const { -#if defined(JS_NUNBOX32) - return uint32_t(toTag()) < uint32_t(JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET); -#elif defined(JS_PUNBOX64) - return data.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET; -#endif - } - - bool isObjectOrNull() const { - MOZ_ASSERT(uint32_t(toTag()) <= uint32_t(JSVAL_TAG_OBJECT)); -#if defined(JS_NUNBOX32) - return uint32_t(toTag()) >= uint32_t(JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET); -#elif defined(JS_PUNBOX64) - return data.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET; -#endif - } - - bool isGCThing() const { -#if defined(JS_NUNBOX32) - /* gcc sometimes generates signed < without explicit casts. */ - return uint32_t(toTag()) >= uint32_t(JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET); -#elif defined(JS_PUNBOX64) - return data.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET; -#endif - } - - bool isBoolean() const { - return toTag() == JSVAL_TAG_BOOLEAN; - } - - bool isTrue() const { - return data.asBits == bitsFromTagAndPayload(JSVAL_TAG_BOOLEAN, uint32_t(true)); - } - - bool isFalse() const { - return data.asBits == bitsFromTagAndPayload(JSVAL_TAG_BOOLEAN, uint32_t(false)); - } - - bool isMagic() const { - return toTag() == JSVAL_TAG_MAGIC; - } - - bool isMagic(JSWhyMagic why) const { - MOZ_ASSERT_IF(isMagic(), data.s.payload.why == why); - return isMagic(); - } - - bool isMarkable() const { - return isGCThing() && !isNull(); - } - - JS::TraceKind traceKind() const { - MOZ_ASSERT(isMarkable()); - static_assert((JSVAL_TAG_STRING & 0x03) == size_t(JS::TraceKind::String), - "Value type tags must correspond with JS::TraceKinds."); - static_assert((JSVAL_TAG_SYMBOL & 0x03) == size_t(JS::TraceKind::Symbol), - "Value type tags must correspond with JS::TraceKinds."); - static_assert((JSVAL_TAG_OBJECT & 0x03) == size_t(JS::TraceKind::Object), - "Value type tags must correspond with JS::TraceKinds."); - if (MOZ_UNLIKELY(isPrivateGCThing())) - return JS::GCThingTraceKind(toGCThing()); - return JS::TraceKind(toTag() & 0x03); - } - - JSWhyMagic whyMagic() const { - MOZ_ASSERT(isMagic()); - return data.s.payload.why; - } - - uint32_t magicUint32() const { - MOZ_ASSERT(isMagic()); - return data.s.payload.u32; - } - - /*** Comparison ***/ - - bool operator==(const Value& rhs) const { - return data.asBits == rhs.data.asBits; - } - - bool operator!=(const Value& rhs) const { - return data.asBits != rhs.data.asBits; - } - - friend inline bool SameType(const Value& lhs, const Value& rhs); - - /*** Extract the value's typed payload ***/ - - int32_t toInt32() const { - MOZ_ASSERT(isInt32()); -#if defined(JS_NUNBOX32) - return data.s.payload.i32; -#elif defined(JS_PUNBOX64) - return int32_t(data.asBits); -#endif - } - - double toDouble() const { - MOZ_ASSERT(isDouble()); - return data.asDouble; - } - - double toNumber() const { - MOZ_ASSERT(isNumber()); - return isDouble() ? toDouble() : double(toInt32()); - } - - JSString* toString() const { - MOZ_ASSERT(isString()); -#if defined(JS_NUNBOX32) - return data.s.payload.str; -#elif defined(JS_PUNBOX64) - return reinterpret_cast(data.asBits & JSVAL_PAYLOAD_MASK); -#endif - } - - JS::Symbol* toSymbol() const { - MOZ_ASSERT(isSymbol()); -#if defined(JS_NUNBOX32) - return data.s.payload.sym; -#elif defined(JS_PUNBOX64) - return reinterpret_cast(data.asBits & JSVAL_PAYLOAD_MASK); -#endif - } - - JSObject& toObject() const { - MOZ_ASSERT(isObject()); -#if defined(JS_NUNBOX32) - return *data.s.payload.obj; -#elif defined(JS_PUNBOX64) - return *toObjectOrNull(); -#endif - } - - JSObject* toObjectOrNull() const { - MOZ_ASSERT(isObjectOrNull()); -#if defined(JS_NUNBOX32) - return data.s.payload.obj; -#elif defined(JS_PUNBOX64) - uint64_t ptrBits = data.asBits & JSVAL_PAYLOAD_MASK; - MOZ_ASSERT((ptrBits & 0x7) == 0); - return reinterpret_cast(ptrBits); -#endif - } - - js::gc::Cell* toGCThing() const { - MOZ_ASSERT(isGCThing()); -#if defined(JS_NUNBOX32) - return data.s.payload.cell; -#elif defined(JS_PUNBOX64) - uint64_t ptrBits = data.asBits & JSVAL_PAYLOAD_MASK; - MOZ_ASSERT((ptrBits & 0x7) == 0); - return reinterpret_cast(ptrBits); -#endif - } - - js::gc::Cell* toMarkablePointer() const { - MOZ_ASSERT(isMarkable()); - return toGCThing(); - } - - GCCellPtr toGCCellPtr() const { - return GCCellPtr(toGCThing(), traceKind()); - } - - bool toBoolean() const { - MOZ_ASSERT(isBoolean()); -#if defined(JS_NUNBOX32) - return bool(data.s.payload.boo); -#elif defined(JS_PUNBOX64) - return bool(data.asBits & JSVAL_PAYLOAD_MASK); -#endif - } - - uint32_t payloadAsRawUint32() const { - MOZ_ASSERT(!isDouble()); - return data.s.payload.u32; - } - - uint64_t asRawBits() const { - return data.asBits; - } - - JSValueType extractNonDoubleType() const { - uint32_t type = toTag() & 0xF; - MOZ_ASSERT(type > JSVAL_TYPE_DOUBLE); - return JSValueType(type); - } - - /* - * Private API - * - * Private setters/getters allow the caller to read/write arbitrary types - * that fit in the 64-bit payload. It is the caller's responsibility, after - * storing to a value with setPrivateX to read only using getPrivateX. - * Privates values are given a type which ensures they are not marked. - */ - - void setPrivate(void* ptr) { - MOZ_ASSERT((uintptr_t(ptr) & 1) == 0); -#if defined(JS_NUNBOX32) - data.s.tag = JSValueTag(0); - data.s.payload.ptr = ptr; -#elif defined(JS_PUNBOX64) - data.asBits = uintptr_t(ptr) >> 1; -#endif - MOZ_ASSERT(isDouble()); - } - - void* toPrivate() const { - MOZ_ASSERT(isDouble()); -#if defined(JS_NUNBOX32) - return data.s.payload.ptr; -#elif defined(JS_PUNBOX64) - MOZ_ASSERT((data.asBits & 0x8000000000000000ULL) == 0); - return reinterpret_cast(data.asBits << 1); -#endif - } - - void setPrivateUint32(uint32_t ui) { - MOZ_ASSERT(uint32_t(int32_t(ui)) == ui); - setInt32(int32_t(ui)); - } - - uint32_t toPrivateUint32() const { - return uint32_t(toInt32()); - } - - /* - * Private GC Thing API - * - * Non-JSObject, JSString, and JS::Symbol cells may be put into the 64-bit - * payload as private GC things. Such Values are considered isMarkable() - * and isGCThing(), and as such, automatically marked. Their traceKind() - * is gotten via their cells. - */ - - void setPrivateGCThing(js::gc::Cell* cell) { - MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::String, - "Private GC thing Values must not be strings. Make a StringValue instead."); - MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::Symbol, - "Private GC thing Values must not be symbols. Make a SymbolValue instead."); - MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::Object, - "Private GC thing Values must not be objects. Make an ObjectValue instead."); - - MOZ_ASSERT(uintptr_t(cell) > 0x1000); -#if defined(JS_PUNBOX64) - // VisualStudio cannot contain parenthesized C++ style cast and shift - // inside decltype in template parameter: - // AssertionConditionType> 1))> - // It throws syntax error. - MOZ_ASSERT((((uintptr_t)cell) >> JSVAL_TAG_SHIFT) == 0); -#endif - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_PRIVATE_GCTHING, PayloadType(cell)); - } - - bool isPrivateGCThing() const { - return toTag() == JSVAL_TAG_PRIVATE_GCTHING; - } - - const size_t* payloadWord() const { -#if defined(JS_NUNBOX32) - return &data.s.payload.word; -#elif defined(JS_PUNBOX64) - return &data.asWord; -#endif - } - - const uintptr_t* payloadUIntPtr() const { -#if defined(JS_NUNBOX32) - return &data.s.payload.uintptr; -#elif defined(JS_PUNBOX64) - return &data.asUIntPtr; -#endif - } - -#if !defined(_MSC_VER) && !defined(__sparc) - // Value must be POD so that MSVC will pass it by value and not in memory - // (bug 689101); the same is true for SPARC as well (bug 737344). More - // precisely, we don't want Value return values compiled as out params. - private: -#endif - -#if MOZ_LITTLE_ENDIAN -# if defined(JS_NUNBOX32) - union layout { - uint64_t asBits; - struct { - union { - int32_t i32; - uint32_t u32; - uint32_t boo; // Don't use |bool| -- it must be four bytes. - JSString* str; - JS::Symbol* sym; - JSObject* obj; - js::gc::Cell* cell; - void* ptr; - JSWhyMagic why; - size_t word; - uintptr_t uintptr; - } payload; - JSValueTag tag; - } s; - double asDouble; - void* asPtr; - - layout() = default; - explicit constexpr layout(uint64_t bits) : asBits(bits) {} - explicit constexpr layout(double d) : asDouble(d) {} - } data; -# elif defined(JS_PUNBOX64) - union layout { - uint64_t asBits; -#if !defined(_WIN64) - /* MSVC does not pack these correctly :-( */ - struct { - uint64_t payload47 : 47; - JSValueTag tag : 17; - } debugView; -#endif - struct { - union { - int32_t i32; - uint32_t u32; - JSWhyMagic why; - } payload; - } s; - double asDouble; - void* asPtr; - size_t asWord; - uintptr_t asUIntPtr; - - layout() = default; - explicit constexpr layout(uint64_t bits) : asBits(bits) {} - explicit constexpr layout(double d) : asDouble(d) {} - } data; -# endif /* JS_PUNBOX64 */ -#else /* MOZ_LITTLE_ENDIAN */ -# if defined(JS_NUNBOX32) - union layout { - uint64_t asBits; - struct { - JSValueTag tag; - union { - int32_t i32; - uint32_t u32; - uint32_t boo; // Don't use |bool| -- it must be four bytes. - JSString* str; - JS::Symbol* sym; - JSObject* obj; - js::gc::Cell* cell; - void* ptr; - JSWhyMagic why; - size_t word; - uintptr_t uintptr; - } payload; - } s; - double asDouble; - void* asPtr; - - layout() = default; - explicit constexpr layout(uint64_t bits) : asBits(bits) {} - explicit constexpr layout(double d) : asDouble(d) {} - } data; -# elif defined(JS_PUNBOX64) - union layout { - uint64_t asBits; - struct { - JSValueTag tag : 17; - uint64_t payload47 : 47; - } debugView; - struct { - uint32_t padding; - union { - int32_t i32; - uint32_t u32; - JSWhyMagic why; - } payload; - } s; - double asDouble; - void* asPtr; - size_t asWord; - uintptr_t asUIntPtr; - - layout() = default; - explicit constexpr layout(uint64_t bits) : asBits(bits) {} - explicit constexpr layout(double d) : asDouble(d) {} - } data; -# endif /* JS_PUNBOX64 */ -#endif /* MOZ_LITTLE_ENDIAN */ - - private: - explicit constexpr Value(uint64_t asBits) : data(asBits) {} - explicit constexpr Value(double d) : data(d) {} - - void staticAssertions() { - JS_STATIC_ASSERT(sizeof(JSValueType) == 1); - JS_STATIC_ASSERT(sizeof(JSValueTag) == 4); - JS_STATIC_ASSERT(sizeof(JSWhyMagic) <= 4); - JS_STATIC_ASSERT(sizeof(Value) == 8); - } - - friend constexpr Value JS::UndefinedValue(); - - public: - static constexpr uint64_t - bitsFromTagAndPayload(JSValueTag tag, PayloadType payload) - { -#if defined(JS_NUNBOX32) - return (uint64_t(uint32_t(tag)) << 32) | payload; -#elif defined(JS_PUNBOX64) - return (uint64_t(uint32_t(tag)) << JSVAL_TAG_SHIFT) | payload; -#endif - } - - static constexpr Value - fromTagAndPayload(JSValueTag tag, PayloadType payload) - { - return fromRawBits(bitsFromTagAndPayload(tag, payload)); - } - - static constexpr Value - fromRawBits(uint64_t asBits) { - return Value(asBits); - } - - static constexpr Value - fromInt32(int32_t i) { - return fromTagAndPayload(JSVAL_TAG_INT32, uint32_t(i)); - } - - static constexpr Value - fromDouble(double d) { - return Value(d); - } -} JS_HAZ_GC_POINTER; - -static_assert(sizeof(Value) == 8, "Value size must leave three tag bits, be a binary power, and is ubiquitously depended upon everywhere"); - -inline bool -IsOptimizedPlaceholderMagicValue(const Value& v) -{ - if (v.isMagic()) { - MOZ_ASSERT(v.whyMagic() == JS_OPTIMIZED_ARGUMENTS || v.whyMagic() == JS_OPTIMIZED_OUT); - return true; - } - return false; -} - -static MOZ_ALWAYS_INLINE void -ExposeValueToActiveJS(const Value& v) -{ - if (v.isMarkable()) - js::gc::ExposeGCThingToActiveJS(GCCellPtr(v)); -} - -/************************************************************************/ - -static inline Value -NullValue() -{ - Value v; - v.setNull(); - return v; -} - -static inline constexpr Value -UndefinedValue() -{ - return Value::fromTagAndPayload(JSVAL_TAG_UNDEFINED, 0); -} - -static inline constexpr Value -Int32Value(int32_t i32) -{ - return Value::fromInt32(i32); -} - -static inline Value -DoubleValue(double dbl) -{ - Value v; - v.setDouble(dbl); - return v; -} - -static inline Value -CanonicalizedDoubleValue(double d) -{ - return MOZ_UNLIKELY(mozilla::IsNaN(d)) - ? Value::fromRawBits(detail::CanonicalizedNaNBits) - : Value::fromDouble(d); -} - -static inline bool -IsCanonicalized(double d) -{ - if (mozilla::IsInfinite(d) || mozilla::IsFinite(d)) - return true; - - uint64_t bits; - mozilla::BitwiseCast(d, &bits); - return (bits & ~mozilla::DoubleTypeTraits::kSignBit) == detail::CanonicalizedNaNBits; -} - -static inline Value -DoubleNaNValue() -{ - Value v; - v.setNaN(); - return v; -} - -static inline Value -Float32Value(float f) -{ - Value v; - v.setDouble(f); - return v; -} - -static inline Value -StringValue(JSString* str) -{ - Value v; - v.setString(str); - return v; -} - -static inline Value -SymbolValue(JS::Symbol* sym) -{ - Value v; - v.setSymbol(sym); - return v; -} - -static inline Value -BooleanValue(bool boo) -{ - Value v; - v.setBoolean(boo); - return v; -} - -static inline Value -TrueValue() -{ - Value v; - v.setBoolean(true); - return v; -} - -static inline Value -FalseValue() -{ - Value v; - v.setBoolean(false); - return v; -} - -static inline Value -ObjectValue(JSObject& obj) -{ - Value v; - v.setObject(obj); - return v; -} - -static inline Value -ObjectValueCrashOnTouch() -{ - Value v; - v.setObject(*reinterpret_cast(0x48)); - return v; -} - -static inline Value -MagicValue(JSWhyMagic why) -{ - Value v; - v.setMagic(why); - return v; -} - -static inline Value -MagicValueUint32(uint32_t payload) -{ - Value v; - v.setMagicUint32(payload); - return v; -} - -static inline Value -NumberValue(float f) -{ - Value v; - v.setNumber(f); - return v; -} - -static inline Value -NumberValue(double dbl) -{ - Value v; - v.setNumber(dbl); - return v; -} - -static inline Value -NumberValue(int8_t i) -{ - return Int32Value(i); -} - -static inline Value -NumberValue(uint8_t i) -{ - return Int32Value(i); -} - -static inline Value -NumberValue(int16_t i) -{ - return Int32Value(i); -} - -static inline Value -NumberValue(uint16_t i) -{ - return Int32Value(i); -} - -static inline Value -NumberValue(int32_t i) -{ - return Int32Value(i); -} - -static inline constexpr Value -NumberValue(uint32_t i) -{ - return i <= JSVAL_INT_MAX - ? Int32Value(int32_t(i)) - : Value::fromDouble(double(i)); -} - -namespace detail { - -template -class MakeNumberValue -{ - public: - template - static inline Value create(const T t) - { - Value v; - if (JSVAL_INT_MIN <= t && t <= JSVAL_INT_MAX) - v.setInt32(int32_t(t)); - else - v.setDouble(double(t)); - return v; - } -}; - -template <> -class MakeNumberValue -{ - public: - template - static inline Value create(const T t) - { - Value v; - if (t <= JSVAL_INT_MAX) - v.setInt32(int32_t(t)); - else - v.setDouble(double(t)); - return v; - } -}; - -} // namespace detail - -template -static inline Value -NumberValue(const T t) -{ - MOZ_ASSERT(Value::isNumberRepresentable(t), "value creation would be lossy"); - return detail::MakeNumberValue::is_signed>::create(t); -} - -static inline Value -ObjectOrNullValue(JSObject* obj) -{ - Value v; - v.setObjectOrNull(obj); - return v; -} - -static inline Value -PrivateValue(void* ptr) -{ - Value v; - v.setPrivate(ptr); - return v; -} - -static inline Value -PrivateUint32Value(uint32_t ui) -{ - Value v; - v.setPrivateUint32(ui); - return v; -} - -static inline Value -PrivateGCThingValue(js::gc::Cell* cell) -{ - Value v; - v.setPrivateGCThing(cell); - return v; -} - -static inline Value -PoisonedObjectValue(JSObject* obj) -{ - Value v; - v.setObjectNoCheck(obj); - return v; -} - -inline bool -SameType(const Value& lhs, const Value& rhs) -{ -#if defined(JS_NUNBOX32) - JSValueTag ltag = lhs.toTag(), rtag = rhs.toTag(); - return ltag == rtag || (ltag < JSVAL_TAG_CLEAR && rtag < JSVAL_TAG_CLEAR); -#elif defined(JS_PUNBOX64) - return (lhs.isDouble() && rhs.isDouble()) || - (((lhs.data.asBits ^ rhs.data.asBits) & 0xFFFF800000000000ULL) == 0); -#endif -} - -} // namespace JS - -/************************************************************************/ - -namespace JS { -JS_PUBLIC_API(void) HeapValuePostBarrier(Value* valuep, const Value& prev, const Value& next); - -template <> -struct GCPolicy -{ - static Value initial() { return UndefinedValue(); } - static void trace(JSTracer* trc, Value* v, const char* name) { - js::UnsafeTraceManuallyBarrieredEdge(trc, v, name); - } - static bool isTenured(const Value& thing) { - return !thing.isGCThing() || !IsInsideNursery(thing.toGCThing()); - } -}; - -} // namespace JS - -namespace js { - -template <> -struct BarrierMethods -{ - static gc::Cell* asGCThingOrNull(const JS::Value& v) { - return v.isMarkable() ? v.toGCThing() : nullptr; - } - static void postBarrier(JS::Value* v, const JS::Value& prev, const JS::Value& next) { - JS::HeapValuePostBarrier(v, prev, next); - } - static void exposeToJS(const JS::Value& v) { - JS::ExposeValueToActiveJS(v); - } -}; - -template class MutableValueOperations; - -/** - * A class designed for CRTP use in implementing the non-mutating parts of the - * Value interface in Value-like classes. Outer must be a class inheriting - * ValueOperations with a visible get() method returning a const - * reference to the Value abstracted by Outer. - */ -template -class ValueOperations -{ - friend class MutableValueOperations; - - const JS::Value& value() const { return static_cast(this)->get(); } - - public: - bool isUndefined() const { return value().isUndefined(); } - bool isNull() const { return value().isNull(); } - bool isBoolean() const { return value().isBoolean(); } - bool isTrue() const { return value().isTrue(); } - bool isFalse() const { return value().isFalse(); } - bool isNumber() const { return value().isNumber(); } - bool isInt32() const { return value().isInt32(); } - bool isInt32(int32_t i32) const { return value().isInt32(i32); } - bool isDouble() const { return value().isDouble(); } - bool isString() const { return value().isString(); } - bool isSymbol() const { return value().isSymbol(); } - bool isObject() const { return value().isObject(); } - bool isMagic() const { return value().isMagic(); } - bool isMagic(JSWhyMagic why) const { return value().isMagic(why); } - bool isMarkable() const { return value().isMarkable(); } - bool isPrimitive() const { return value().isPrimitive(); } - bool isGCThing() const { return value().isGCThing(); } - - bool isNullOrUndefined() const { return value().isNullOrUndefined(); } - bool isObjectOrNull() const { return value().isObjectOrNull(); } - - bool toBoolean() const { return value().toBoolean(); } - double toNumber() const { return value().toNumber(); } - int32_t toInt32() const { return value().toInt32(); } - double toDouble() const { return value().toDouble(); } - JSString* toString() const { return value().toString(); } - JS::Symbol* toSymbol() const { return value().toSymbol(); } - JSObject& toObject() const { return value().toObject(); } - JSObject* toObjectOrNull() const { return value().toObjectOrNull(); } - gc::Cell* toGCThing() const { return value().toGCThing(); } - JS::TraceKind traceKind() const { return value().traceKind(); } - void* toPrivate() const { return value().toPrivate(); } - uint32_t toPrivateUint32() const { return value().toPrivateUint32(); } - - uint64_t asRawBits() const { return value().asRawBits(); } - JSValueType extractNonDoubleType() const { return value().extractNonDoubleType(); } - - JSWhyMagic whyMagic() const { return value().whyMagic(); } - uint32_t magicUint32() const { return value().magicUint32(); } -}; - -/** - * A class designed for CRTP use in implementing all the mutating parts of the - * Value interface in Value-like classes. Outer must be a class inheriting - * MutableValueOperations with visible get() methods returning const and - * non-const references to the Value abstracted by Outer. - */ -template -class MutableValueOperations : public ValueOperations -{ - JS::Value& value() { return static_cast(this)->get(); } - - public: - void setNull() { value().setNull(); } - void setUndefined() { value().setUndefined(); } - void setInt32(int32_t i) { value().setInt32(i); } - void setDouble(double d) { value().setDouble(d); } - void setNaN() { setDouble(JS::GenericNaN()); } - void setBoolean(bool b) { value().setBoolean(b); } - void setMagic(JSWhyMagic why) { value().setMagic(why); } - bool setNumber(uint32_t ui) { return value().setNumber(ui); } - bool setNumber(double d) { return value().setNumber(d); } - void setString(JSString* str) { this->value().setString(str); } - void setSymbol(JS::Symbol* sym) { this->value().setSymbol(sym); } - void setObject(JSObject& obj) { this->value().setObject(obj); } - void setObjectOrNull(JSObject* arg) { this->value().setObjectOrNull(arg); } - void setPrivate(void* ptr) { this->value().setPrivate(ptr); } - void setPrivateUint32(uint32_t ui) { this->value().setPrivateUint32(ui); } - void setPrivateGCThing(js::gc::Cell* cell) { this->value().setPrivateGCThing(cell); } -}; - -/* - * Augment the generic Heap interface when T = Value with - * type-querying, value-extracting, and mutating operations. - */ -template <> -class HeapBase : public ValueOperations > -{ - typedef JS::Heap Outer; - - friend class ValueOperations; - - void setBarriered(const JS::Value& v) { - *static_cast*>(this) = v; - } - - public: - void setNull() { setBarriered(JS::NullValue()); } - void setUndefined() { setBarriered(JS::UndefinedValue()); } - void setInt32(int32_t i) { setBarriered(JS::Int32Value(i)); } - void setDouble(double d) { setBarriered(JS::DoubleValue(d)); } - void setNaN() { setDouble(JS::GenericNaN()); } - void setBoolean(bool b) { setBarriered(JS::BooleanValue(b)); } - void setMagic(JSWhyMagic why) { setBarriered(JS::MagicValue(why)); } - void setString(JSString* str) { setBarriered(JS::StringValue(str)); } - void setSymbol(JS::Symbol* sym) { setBarriered(JS::SymbolValue(sym)); } - void setObject(JSObject& obj) { setBarriered(JS::ObjectValue(obj)); } - void setPrivateGCThing(js::gc::Cell* cell) { setBarriered(JS::PrivateGCThingValue(cell)); } - - bool setNumber(uint32_t ui) { - if (ui > JSVAL_INT_MAX) { - setDouble((double)ui); - return false; - } else { - setInt32((int32_t)ui); - return true; - } - } - - bool setNumber(double d) { - int32_t i; - if (mozilla::NumberIsInt32(d, &i)) { - setInt32(i); - return true; - } - - setDouble(d); - return false; - } - - void setObjectOrNull(JSObject* arg) { - if (arg) - setObject(*arg); - else - setNull(); - } -}; - -template <> -class HandleBase : public ValueOperations > -{}; - -template <> -class MutableHandleBase : public MutableValueOperations > -{}; - -template <> -class RootedBase : public MutableValueOperations > -{}; - -template <> -class PersistentRootedBase : public MutableValueOperations> -{}; - -/* - * If the Value is a GC pointer type, convert to that type and call |f| with - * the pointer. If the Value is not a GC type, calls F::defaultValue. - */ -template -auto -DispatchTyped(F f, const JS::Value& val, Args&&... args) - -> decltype(f(static_cast(nullptr), mozilla::Forward(args)...)) -{ - if (val.isString()) - return f(val.toString(), mozilla::Forward(args)...); - if (val.isObject()) - return f(&val.toObject(), mozilla::Forward(args)...); - if (val.isSymbol()) - return f(val.toSymbol(), mozilla::Forward(args)...); - if (MOZ_UNLIKELY(val.isPrivateGCThing())) - return DispatchTyped(f, val.toGCCellPtr(), mozilla::Forward(args)...); - MOZ_ASSERT(!val.isMarkable()); - return F::defaultValue(val); -} - -template struct VoidDefaultAdaptor { static void defaultValue(const S&) {} }; -template struct IdentityDefaultAdaptor { static S defaultValue(const S& v) {return v;} }; -template struct BoolDefaultAdaptor { static bool defaultValue(const S&) { return v; } }; - -} // namespace js - -/************************************************************************/ - -namespace JS { - -extern JS_PUBLIC_DATA(const HandleValue) NullHandleValue; -extern JS_PUBLIC_DATA(const HandleValue) UndefinedHandleValue; -extern JS_PUBLIC_DATA(const HandleValue) TrueHandleValue; -extern JS_PUBLIC_DATA(const HandleValue) FalseHandleValue; - -} // namespace JS - -#endif /* js_Value_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/Vector.h b/android/armeabi-v7a/include/spidermonkey/js/Vector.h deleted file mode 100644 index 6fa63e93..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/Vector.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_Vector_h -#define js_Vector_h - -#include "mozilla/Vector.h" - -/* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */ -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4345) -#endif - -namespace js { - -class TempAllocPolicy; - -namespace detail { - -template -struct TypeIsGCThing : mozilla::FalseType -{}; - -// Uncomment this once we actually can assert it: -//template <> -//struct TypeIsGCThing : mozilla::TrueType -//{}; - -} // namespace detail - -template ::value>::Type - > -using Vector = mozilla::Vector; - -} // namespace js - -#endif /* js_Vector_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/js/WeakMapPtr.h b/android/armeabi-v7a/include/spidermonkey/js/WeakMapPtr.h deleted file mode 100644 index 41860551..00000000 --- a/android/armeabi-v7a/include/spidermonkey/js/WeakMapPtr.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_WeakMapPtr_h -#define js_WeakMapPtr_h - -#include "jspubtd.h" - -#include "js/TypeDecls.h" - -namespace JS { - -// A wrapper around the internal C++ representation of SpiderMonkey WeakMaps, -// usable outside the engine. -// -// The supported template specializations are enumerated in WeakMapPtr.cpp. If -// you want to use this class for a different key/value combination, add it to -// the list and the compiler will generate the relevant machinery. -template -class JS_PUBLIC_API(WeakMapPtr) -{ - public: - WeakMapPtr() : ptr(nullptr) {} - bool init(JSContext* cx); - bool initialized() { return ptr != nullptr; } - void destroy(); - virtual ~WeakMapPtr() { MOZ_ASSERT(!initialized()); } - void trace(JSTracer* tracer); - - V lookup(const K& key); - bool put(JSContext* cx, const K& key, const V& value); - - private: - void* ptr; - - // WeakMapPtr is neither copyable nor assignable. - WeakMapPtr(const WeakMapPtr& wmp) = delete; - WeakMapPtr& operator=(const WeakMapPtr& wmp) = delete; -}; - -} /* namespace JS */ - -#endif /* js_WeakMapPtr_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/jsalloc.h b/android/armeabi-v7a/include/spidermonkey/jsalloc.h deleted file mode 100644 index b9ae5190..00000000 --- a/android/armeabi-v7a/include/spidermonkey/jsalloc.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* - * JS allocation policies. - * - * The allocators here are for system memory with lifetimes which are not - * managed by the GC. See the comment at the top of vm/MallocProvider.h. - */ - -#ifndef jsalloc_h -#define jsalloc_h - -#include "js/TypeDecls.h" -#include "js/Utility.h" - -namespace js { - -enum class AllocFunction { - Malloc, - Calloc, - Realloc -}; - -struct ContextFriendFields; - -/* Policy for using system memory functions and doing no error reporting. */ -class SystemAllocPolicy -{ - public: - template T* maybe_pod_malloc(size_t numElems) { return js_pod_malloc(numElems); } - template T* maybe_pod_calloc(size_t numElems) { return js_pod_calloc(numElems); } - template T* maybe_pod_realloc(T* p, size_t oldSize, size_t newSize) { - return js_pod_realloc(p, oldSize, newSize); - } - template T* pod_malloc(size_t numElems) { return maybe_pod_malloc(numElems); } - template T* pod_calloc(size_t numElems) { return maybe_pod_calloc(numElems); } - template T* pod_realloc(T* p, size_t oldSize, size_t newSize) { - return maybe_pod_realloc(p, oldSize, newSize); - } - void free_(void* p) { js_free(p); } - void reportAllocOverflow() const {} - bool checkSimulatedOOM() const { - return !js::oom::ShouldFailWithOOM(); - } -}; - -class ExclusiveContext; -void ReportOutOfMemory(ExclusiveContext* cxArg); - -/* - * Allocation policy that calls the system memory functions and reports errors - * to the context. Since the JSContext given on construction is stored for - * the lifetime of the container, this policy may only be used for containers - * whose lifetime is a shorter than the given JSContext. - * - * FIXME bug 647103 - rewrite this in terms of temporary allocation functions, - * not the system ones. - */ -class TempAllocPolicy -{ - ContextFriendFields* const cx_; - - /* - * Non-inline helper to call JSRuntime::onOutOfMemory with minimal - * code bloat. - */ - JS_FRIEND_API(void*) onOutOfMemory(AllocFunction allocFunc, size_t nbytes, - void* reallocPtr = nullptr); - - template - T* onOutOfMemoryTyped(AllocFunction allocFunc, size_t numElems, void* reallocPtr = nullptr) { - size_t bytes; - if (MOZ_UNLIKELY(!CalculateAllocSize(numElems, &bytes))) - return nullptr; - return static_cast(onOutOfMemory(allocFunc, bytes, reallocPtr)); - } - - public: - MOZ_IMPLICIT TempAllocPolicy(JSContext* cx) : cx_((ContextFriendFields*) cx) {} // :( - MOZ_IMPLICIT TempAllocPolicy(ContextFriendFields* cx) : cx_(cx) {} - - template - T* maybe_pod_malloc(size_t numElems) { - return js_pod_malloc(numElems); - } - - template - T* maybe_pod_calloc(size_t numElems) { - return js_pod_calloc(numElems); - } - - template - T* maybe_pod_realloc(T* prior, size_t oldSize, size_t newSize) { - return js_pod_realloc(prior, oldSize, newSize); - } - - template - T* pod_malloc(size_t numElems) { - T* p = maybe_pod_malloc(numElems); - if (MOZ_UNLIKELY(!p)) - p = onOutOfMemoryTyped(AllocFunction::Malloc, numElems); - return p; - } - - template - T* pod_calloc(size_t numElems) { - T* p = maybe_pod_calloc(numElems); - if (MOZ_UNLIKELY(!p)) - p = onOutOfMemoryTyped(AllocFunction::Calloc, numElems); - return p; - } - - template - T* pod_realloc(T* prior, size_t oldSize, size_t newSize) { - T* p2 = maybe_pod_realloc(prior, oldSize, newSize); - if (MOZ_UNLIKELY(!p2)) - p2 = onOutOfMemoryTyped(AllocFunction::Realloc, newSize, prior); - return p2; - } - - void free_(void* p) { - js_free(p); - } - - JS_FRIEND_API(void) reportAllocOverflow() const; - - bool checkSimulatedOOM() const { - if (js::oom::ShouldFailWithOOM()) { - js::ReportOutOfMemory(reinterpret_cast(cx_)); - return false; - } - - return true; - } -}; - -} /* namespace js */ - -#endif /* jsalloc_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/jsapi.h b/android/armeabi-v7a/include/spidermonkey/jsapi.h deleted file mode 100644 index 84d639a0..00000000 --- a/android/armeabi-v7a/include/spidermonkey/jsapi.h +++ /dev/null @@ -1,6630 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* JavaScript API. */ - -#ifndef jsapi_h -#define jsapi_h - -#include "mozilla/AlreadyAddRefed.h" -#include "mozilla/FloatingPoint.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Range.h" -#include "mozilla/RangedPtr.h" -#include "mozilla/RefCounted.h" -#include "mozilla/RefPtr.h" -#include "mozilla/Variant.h" - -#include -#include -#include -#include - -#include "jsalloc.h" -#include "jspubtd.h" - -#include "js/CallArgs.h" -#include "js/CharacterEncoding.h" -#include "js/Class.h" -#include "js/GCVector.h" -#include "js/HashTable.h" -#include "js/Id.h" -#include "js/Principals.h" -#include "js/Realm.h" -#include "js/RootingAPI.h" -#include "js/TracingAPI.h" -#include "js/Utility.h" -#include "js/Value.h" -#include "js/Vector.h" - -/************************************************************************/ - -namespace JS { - -class TwoByteChars; - -#ifdef JS_DEBUG - -class JS_PUBLIC_API(AutoCheckRequestDepth) -{ - JSContext* cx; - public: - explicit AutoCheckRequestDepth(JSContext* cx); - explicit AutoCheckRequestDepth(js::ContextFriendFields* cx); - ~AutoCheckRequestDepth(); -}; - -# define CHECK_REQUEST(cx) \ - JS::AutoCheckRequestDepth _autoCheckRequestDepth(cx) - -#else - -# define CHECK_REQUEST(cx) \ - ((void) 0) - -#endif /* JS_DEBUG */ - -/** AutoValueArray roots an internal fixed-size array of Values. */ -template -class MOZ_RAII AutoValueArray : public AutoGCRooter -{ - const size_t length_; - Value elements_[N]; - - public: - explicit AutoValueArray(JSContext* cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, VALARRAY), length_(N) - { - /* Always initialize in case we GC before assignment. */ - mozilla::PodArrayZero(elements_); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - unsigned length() const { return length_; } - const Value* begin() const { return elements_; } - Value* begin() { return elements_; } - - HandleValue operator[](unsigned i) const { - MOZ_ASSERT(i < N); - return HandleValue::fromMarkedLocation(&elements_[i]); - } - MutableHandleValue operator[](unsigned i) { - MOZ_ASSERT(i < N); - return MutableHandleValue::fromMarkedLocation(&elements_[i]); - } - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -template -class MOZ_RAII AutoVectorRooterBase : protected AutoGCRooter -{ - typedef js::Vector VectorImpl; - VectorImpl vector; - - public: - explicit AutoVectorRooterBase(JSContext* cx, ptrdiff_t tag - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, tag), vector(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - explicit AutoVectorRooterBase(js::ContextFriendFields* cx, ptrdiff_t tag - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, tag), vector(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - typedef T ElementType; - typedef typename VectorImpl::Range Range; - - size_t length() const { return vector.length(); } - bool empty() const { return vector.empty(); } - - MOZ_MUST_USE bool append(const T& v) { return vector.append(v); } - MOZ_MUST_USE bool appendN(const T& v, size_t len) { return vector.appendN(v, len); } - MOZ_MUST_USE bool append(const T* ptr, size_t len) { return vector.append(ptr, len); } - MOZ_MUST_USE bool appendAll(const AutoVectorRooterBase& other) { - return vector.appendAll(other.vector); - } - - MOZ_MUST_USE bool insert(T* p, const T& val) { return vector.insert(p, val); } - - /* For use when space has already been reserved. */ - void infallibleAppend(const T& v) { vector.infallibleAppend(v); } - - void popBack() { vector.popBack(); } - T popCopy() { return vector.popCopy(); } - - MOZ_MUST_USE bool growBy(size_t inc) { - size_t oldLength = vector.length(); - if (!vector.growByUninitialized(inc)) - return false; - makeRangeGCSafe(oldLength); - return true; - } - - MOZ_MUST_USE bool resize(size_t newLength) { - size_t oldLength = vector.length(); - if (newLength <= oldLength) { - vector.shrinkBy(oldLength - newLength); - return true; - } - if (!vector.growByUninitialized(newLength - oldLength)) - return false; - makeRangeGCSafe(oldLength); - return true; - } - - void clear() { vector.clear(); } - - MOZ_MUST_USE bool reserve(size_t newLength) { - return vector.reserve(newLength); - } - - JS::MutableHandle operator[](size_t i) { - return JS::MutableHandle::fromMarkedLocation(&vector[i]); - } - JS::Handle operator[](size_t i) const { - return JS::Handle::fromMarkedLocation(&vector[i]); - } - - const T* begin() const { return vector.begin(); } - T* begin() { return vector.begin(); } - - const T* end() const { return vector.end(); } - T* end() { return vector.end(); } - - Range all() { return vector.all(); } - - const T& back() const { return vector.back(); } - - friend void AutoGCRooter::trace(JSTracer* trc); - - private: - void makeRangeGCSafe(size_t oldLength) { - T* t = vector.begin() + oldLength; - for (size_t i = oldLength; i < vector.length(); ++i, ++t) - memset(t, 0, sizeof(T)); - } - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -template -class MOZ_RAII AutoVectorRooter : public AutoVectorRooterBase -{ - public: - explicit AutoVectorRooter(JSContext* cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoVectorRooterBase(cx, this->GetTag(T())) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - explicit AutoVectorRooter(js::ContextFriendFields* cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoVectorRooterBase(cx, this->GetTag(T())) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class AutoValueVector : public Rooted> { - using Vec = GCVector; - using Base = Rooted; - public: - explicit AutoValueVector(JSContext* cx) : Base(cx, Vec(cx)) {} - explicit AutoValueVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {} -}; - -class AutoIdVector : public Rooted> { - using Vec = GCVector; - using Base = Rooted; - public: - explicit AutoIdVector(JSContext* cx) : Base(cx, Vec(cx)) {} - explicit AutoIdVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {} - - bool appendAll(const AutoIdVector& other) { return this->Base::appendAll(other.get()); } -}; - -class AutoObjectVector : public Rooted> { - using Vec = GCVector; - using Base = Rooted; - public: - explicit AutoObjectVector(JSContext* cx) : Base(cx, Vec(cx)) {} - explicit AutoObjectVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {} -}; - -using ValueVector = JS::GCVector; -using IdVector = JS::GCVector; -using ScriptVector = JS::GCVector; -using StringVector = JS::GCVector; - -template -class MOZ_RAII AutoHashMapRooter : protected AutoGCRooter -{ - private: - typedef js::HashMap HashMapImpl; - - public: - explicit AutoHashMapRooter(JSContext* cx, ptrdiff_t tag - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, tag), map(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - typedef Key KeyType; - typedef Value ValueType; - typedef typename HashMapImpl::Entry Entry; - typedef typename HashMapImpl::Lookup Lookup; - typedef typename HashMapImpl::Ptr Ptr; - typedef typename HashMapImpl::AddPtr AddPtr; - - bool init(uint32_t len = 16) { - return map.init(len); - } - bool initialized() const { - return map.initialized(); - } - Ptr lookup(const Lookup& l) const { - return map.lookup(l); - } - void remove(Ptr p) { - map.remove(p); - } - AddPtr lookupForAdd(const Lookup& l) const { - return map.lookupForAdd(l); - } - - template - bool add(AddPtr& p, const KeyInput& k, const ValueInput& v) { - return map.add(p, k, v); - } - - bool add(AddPtr& p, const Key& k) { - return map.add(p, k); - } - - template - bool relookupOrAdd(AddPtr& p, const KeyInput& k, const ValueInput& v) { - return map.relookupOrAdd(p, k, v); - } - - typedef typename HashMapImpl::Range Range; - Range all() const { - return map.all(); - } - - typedef typename HashMapImpl::Enum Enum; - - void clear() { - map.clear(); - } - - void finish() { - map.finish(); - } - - bool empty() const { - return map.empty(); - } - - uint32_t count() const { - return map.count(); - } - - size_t capacity() const { - return map.capacity(); - } - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return map.sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return map.sizeOfIncludingThis(mallocSizeOf); - } - - /************************************************** Shorthand operations */ - - bool has(const Lookup& l) const { - return map.has(l); - } - - template - bool put(const KeyInput& k, const ValueInput& v) { - return map.put(k, v); - } - - template - bool putNew(const KeyInput& k, const ValueInput& v) { - return map.putNew(k, v); - } - - Ptr lookupWithDefault(const Key& k, const Value& defaultValue) { - return map.lookupWithDefault(k, defaultValue); - } - - void remove(const Lookup& l) { - map.remove(l); - } - - friend void AutoGCRooter::trace(JSTracer* trc); - - private: - AutoHashMapRooter(const AutoHashMapRooter& hmr) = delete; - AutoHashMapRooter& operator=(const AutoHashMapRooter& hmr) = delete; - - HashMapImpl map; - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -template -class MOZ_RAII AutoHashSetRooter : protected AutoGCRooter -{ - private: - typedef js::HashSet HashSetImpl; - - public: - explicit AutoHashSetRooter(JSContext* cx, ptrdiff_t tag - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, tag), set(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - typedef typename HashSetImpl::Lookup Lookup; - typedef typename HashSetImpl::Ptr Ptr; - typedef typename HashSetImpl::AddPtr AddPtr; - - bool init(uint32_t len = 16) { - return set.init(len); - } - bool initialized() const { - return set.initialized(); - } - Ptr lookup(const Lookup& l) const { - return set.lookup(l); - } - void remove(Ptr p) { - set.remove(p); - } - AddPtr lookupForAdd(const Lookup& l) const { - return set.lookupForAdd(l); - } - - bool add(AddPtr& p, const T& t) { - return set.add(p, t); - } - - bool relookupOrAdd(AddPtr& p, const Lookup& l, const T& t) { - return set.relookupOrAdd(p, l, t); - } - - typedef typename HashSetImpl::Range Range; - Range all() const { - return set.all(); - } - - typedef typename HashSetImpl::Enum Enum; - - void clear() { - set.clear(); - } - - void finish() { - set.finish(); - } - - bool empty() const { - return set.empty(); - } - - uint32_t count() const { - return set.count(); - } - - size_t capacity() const { - return set.capacity(); - } - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return set.sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return set.sizeOfIncludingThis(mallocSizeOf); - } - - /************************************************** Shorthand operations */ - - bool has(const Lookup& l) const { - return set.has(l); - } - - bool put(const T& t) { - return set.put(t); - } - - bool putNew(const T& t) { - return set.putNew(t); - } - - void remove(const Lookup& l) { - set.remove(l); - } - - friend void AutoGCRooter::trace(JSTracer* trc); - - private: - AutoHashSetRooter(const AutoHashSetRooter& hmr) = delete; - AutoHashSetRooter& operator=(const AutoHashSetRooter& hmr) = delete; - - HashSetImpl set; - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -/** - * Custom rooting behavior for internal and external clients. - */ -class MOZ_RAII JS_PUBLIC_API(CustomAutoRooter) : private AutoGCRooter -{ - public: - template - explicit CustomAutoRooter(const CX& cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, CUSTOM) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - friend void AutoGCRooter::trace(JSTracer* trc); - - protected: - virtual ~CustomAutoRooter() {} - - /** Supplied by derived class to trace roots. */ - virtual void trace(JSTracer* trc) = 0; - - private: - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -/** A handle to an array of rooted values. */ -class HandleValueArray -{ - const size_t length_; - const Value * const elements_; - - HandleValueArray(size_t len, const Value* elements) : length_(len), elements_(elements) {} - - public: - explicit HandleValueArray(const RootedValue& value) : length_(1), elements_(value.address()) {} - - MOZ_IMPLICIT HandleValueArray(const AutoValueVector& values) - : length_(values.length()), elements_(values.begin()) {} - - template - MOZ_IMPLICIT HandleValueArray(const AutoValueArray& values) : length_(N), elements_(values.begin()) {} - - /** CallArgs must already be rooted somewhere up the stack. */ - MOZ_IMPLICIT HandleValueArray(const JS::CallArgs& args) : length_(args.length()), elements_(args.array()) {} - - /** Use with care! Only call this if the data is guaranteed to be marked. */ - static HandleValueArray fromMarkedLocation(size_t len, const Value* elements) { - return HandleValueArray(len, elements); - } - - static HandleValueArray subarray(const HandleValueArray& values, size_t startIndex, size_t len) { - MOZ_ASSERT(startIndex + len <= values.length()); - return HandleValueArray(len, values.begin() + startIndex); - } - - static HandleValueArray empty() { - return HandleValueArray(0, nullptr); - } - - size_t length() const { return length_; } - const Value* begin() const { return elements_; } - - HandleValue operator[](size_t i) const { - MOZ_ASSERT(i < length_); - return HandleValue::fromMarkedLocation(&elements_[i]); - } -}; - -} /* namespace JS */ - -/************************************************************************/ - -struct JSFreeOp { - protected: - JSRuntime* runtime_; - - explicit JSFreeOp(JSRuntime* rt) - : runtime_(rt) { } - - public: - JSRuntime* runtime() const { - MOZ_ASSERT(runtime_); - return runtime_; - } -}; - -/* Callbacks and their arguments. */ - -/************************************************************************/ - -typedef enum JSGCStatus { - JSGC_BEGIN, - JSGC_END -} JSGCStatus; - -typedef void -(* JSGCCallback)(JSContext* cx, JSGCStatus status, void* data); - -typedef void -(* JSObjectsTenuredCallback)(JSContext* cx, void* data); - -typedef enum JSFinalizeStatus { - /** - * Called when preparing to sweep a group of zones, before anything has been - * swept. The collector will not yield to the mutator before calling the - * callback with JSFINALIZE_GROUP_END status. - */ - JSFINALIZE_GROUP_START, - - /** - * Called when preparing to sweep a group of zones. Weak references to - * unmarked things have been removed and things that are not swept - * incrementally have been finalized at this point. The collector may yield - * to the mutator after this point. - */ - JSFINALIZE_GROUP_END, - - /** - * Called at the end of collection when everything has been swept. - */ - JSFINALIZE_COLLECTION_END -} JSFinalizeStatus; - -typedef void -(* JSFinalizeCallback)(JSFreeOp* fop, JSFinalizeStatus status, bool isZoneGC, void* data); - -typedef void -(* JSWeakPointerZoneGroupCallback)(JSContext* cx, void* data); - -typedef void -(* JSWeakPointerCompartmentCallback)(JSContext* cx, JSCompartment* comp, void* data); - -typedef bool -(* JSInterruptCallback)(JSContext* cx); - -typedef JSObject* -(* JSGetIncumbentGlobalCallback)(JSContext* cx); - -typedef bool -(* JSEnqueuePromiseJobCallback)(JSContext* cx, JS::HandleObject job, - JS::HandleObject allocationSite, JS::HandleObject incumbentGlobal, - void* data); - -enum class PromiseRejectionHandlingState { - Unhandled, - Handled -}; - -typedef void -(* JSPromiseRejectionTrackerCallback)(JSContext* cx, JS::HandleObject promise, - PromiseRejectionHandlingState state, void* data); - -typedef void -(* JSProcessPromiseCallback)(JSContext* cx, JS::HandleObject promise); - -/** - * Possible exception types. These types are part of a JSErrorFormatString - * structure. They define which error to throw in case of a runtime error. - * - * JSEXN_WARN is used for warnings in js.msg files (for instance because we - * don't want to prepend 'Error:' to warning messages). This value can go away - * if we ever decide to use an entirely separate mechanism for warnings. - */ -typedef enum JSExnType { - JSEXN_ERR, - JSEXN_FIRST = JSEXN_ERR, - JSEXN_INTERNALERR, - JSEXN_EVALERR, - JSEXN_RANGEERR, - JSEXN_REFERENCEERR, - JSEXN_SYNTAXERR, - JSEXN_TYPEERR, - JSEXN_URIERR, - JSEXN_DEBUGGEEWOULDRUN, - JSEXN_WASMCOMPILEERROR, - JSEXN_WASMRUNTIMEERROR, - JSEXN_WARN, - JSEXN_LIMIT -} JSExnType; - -typedef struct JSErrorFormatString { - /** The error message name in ASCII. */ - const char* name; - - /** The error format string in ASCII. */ - const char* format; - - /** The number of arguments to expand in the formatted error message. */ - uint16_t argCount; - - /** One of the JSExnType constants above. */ - int16_t exnType; -} JSErrorFormatString; - -typedef const JSErrorFormatString* -(* JSErrorCallback)(void* userRef, const unsigned errorNumber); - -typedef bool -(* JSLocaleToUpperCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval); - -typedef bool -(* JSLocaleToLowerCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval); - -typedef bool -(* JSLocaleCompare)(JSContext* cx, JS::HandleString src1, JS::HandleString src2, - JS::MutableHandleValue rval); - -typedef bool -(* JSLocaleToUnicode)(JSContext* cx, const char* src, JS::MutableHandleValue rval); - -/** - * Callback used to ask the embedding for the cross compartment wrapper handler - * that implements the desired prolicy for this kind of object in the - * destination compartment. |obj| is the object to be wrapped. If |existing| is - * non-nullptr, it will point to an existing wrapper object that should be - * re-used if possible. |existing| is guaranteed to be a cross-compartment - * wrapper with a lazily-defined prototype and the correct global. It is - * guaranteed not to wrap a function. - */ -typedef JSObject* -(* JSWrapObjectCallback)(JSContext* cx, JS::HandleObject existing, JS::HandleObject obj); - -/** - * Callback used by the wrap hook to ask the embedding to prepare an object - * for wrapping in a context. This might include unwrapping other wrappers - * or even finding a more suitable object for the new compartment. - */ -typedef void -(* JSPreWrapCallback)(JSContext* cx, JS::HandleObject scope, JS::HandleObject obj, - JS::HandleObject objectPassedToWrap, - JS::MutableHandleObject retObj); - -struct JSWrapObjectCallbacks -{ - JSWrapObjectCallback wrap; - JSPreWrapCallback preWrap; -}; - -typedef void -(* JSDestroyCompartmentCallback)(JSFreeOp* fop, JSCompartment* compartment); - -typedef size_t -(* JSSizeOfIncludingThisCompartmentCallback)(mozilla::MallocSizeOf mallocSizeOf, - JSCompartment* compartment); - -typedef void -(* JSZoneCallback)(JS::Zone* zone); - -typedef void -(* JSCompartmentNameCallback)(JSContext* cx, JSCompartment* compartment, - char* buf, size_t bufsize); - -/************************************************************************/ - -static MOZ_ALWAYS_INLINE JS::Value -JS_NumberValue(double d) -{ - int32_t i; - d = JS::CanonicalizeNaN(d); - if (mozilla::NumberIsInt32(d, &i)) - return JS::Int32Value(i); - return JS::DoubleValue(d); -} - -/************************************************************************/ - -JS_PUBLIC_API(bool) -JS_StringHasBeenPinned(JSContext* cx, JSString* str); - -namespace JS { - -/** - * Container class for passing in script source buffers to the JS engine. This - * not only groups the buffer and length values, it also provides a way to - * optionally pass ownership of the buffer to the JS engine without copying. - * Rules for use: - * - * 1) The data array must be allocated with js_malloc() or js_realloc() if - * ownership is being granted to the SourceBufferHolder. - * 2) If ownership is not given to the SourceBufferHolder, then the memory - * must be kept alive until the JS compilation is complete. - * 3) Any code calling SourceBufferHolder::take() must guarantee to keep the - * memory alive until JS compilation completes. Normally only the JS - * engine should be calling take(). - * - * Example use: - * - * size_t length = 512; - * char16_t* chars = static_cast(js_malloc(sizeof(char16_t) * length)); - * JS::SourceBufferHolder srcBuf(chars, length, JS::SourceBufferHolder::GiveOwnership); - * JS::Compile(cx, options, srcBuf); - */ -class MOZ_STACK_CLASS SourceBufferHolder final -{ - public: - enum Ownership { - NoOwnership, - GiveOwnership - }; - - SourceBufferHolder(const char16_t* data, size_t dataLength, Ownership ownership) - : data_(data), - length_(dataLength), - ownsChars_(ownership == GiveOwnership) - { - // Ensure that null buffers properly return an unowned, empty, - // null-terminated string. - static const char16_t NullChar_ = 0; - if (!get()) { - data_ = &NullChar_; - length_ = 0; - ownsChars_ = false; - } - } - - SourceBufferHolder(SourceBufferHolder&& other) - : data_(other.data_), - length_(other.length_), - ownsChars_(other.ownsChars_) - { - other.data_ = nullptr; - other.length_ = 0; - other.ownsChars_ = false; - } - - ~SourceBufferHolder() { - if (ownsChars_) - js_free(const_cast(data_)); - } - - // Access the underlying source buffer without affecting ownership. - const char16_t* get() const { return data_; } - - // Length of the source buffer in char16_t code units (not bytes) - size_t length() const { return length_; } - - // Returns true if the SourceBufferHolder owns the buffer and will free - // it upon destruction. If true, it is legal to call take(). - bool ownsChars() const { return ownsChars_; } - - // Retrieve and take ownership of the underlying data buffer. The caller - // is now responsible for calling js_free() on the returned value, *but only - // after JS script compilation has completed*. - // - // After the buffer has been taken the SourceBufferHolder functions as if - // it had been constructed on an unowned buffer; get() and length() still - // work. In order for this to be safe the taken buffer must be kept alive - // until after JS script compilation completes as noted above. - // - // Note, it's the caller's responsibility to check ownsChars() before taking - // the buffer. Taking and then free'ing an unowned buffer will have dire - // consequences. - char16_t* take() { - MOZ_ASSERT(ownsChars_); - ownsChars_ = false; - return const_cast(data_); - } - - private: - SourceBufferHolder(SourceBufferHolder&) = delete; - SourceBufferHolder& operator=(SourceBufferHolder&) = delete; - - const char16_t* data_; - size_t length_; - bool ownsChars_; -}; - -} /* namespace JS */ - -/************************************************************************/ - -/* Property attributes, set in JSPropertySpec and passed to API functions. - * - * NB: The data structure in which some of these values are stored only uses - * a uint8_t to store the relevant information. Proceed with caution if - * trying to reorder or change the the first byte worth of flags. - */ -#define JSPROP_ENUMERATE 0x01 /* property is visible to for/in loop */ -#define JSPROP_READONLY 0x02 /* not settable: assignment is no-op. - This flag is only valid when neither - JSPROP_GETTER nor JSPROP_SETTER is - set. */ -#define JSPROP_PERMANENT 0x04 /* property cannot be deleted */ -#define JSPROP_PROPOP_ACCESSORS 0x08 /* Passed to JS_Define(UC)Property* and - JS_DefineElement if getters/setters - are JSGetterOp/JSSetterOp */ -#define JSPROP_GETTER 0x10 /* property holds getter function */ -#define JSPROP_SETTER 0x20 /* property holds setter function */ -#define JSPROP_SHARED 0x40 /* don't allocate a value slot for this - property; don't copy the property on - set of the same-named property in an - object that delegates to a prototype - containing this property */ -#define JSPROP_INTERNAL_USE_BIT 0x80 /* internal JS engine use only */ -#define JSFUN_STUB_GSOPS 0x200 /* use JS_PropertyStub getter/setter - instead of defaulting to class gsops - for property holding function */ - -#define JSFUN_CONSTRUCTOR 0x400 /* native that can be called as a ctor */ - -// 0x800 /* Unused */ - -#define JSFUN_HAS_REST 0x1000 /* function has ...rest parameter. */ - -#define JSFUN_FLAGS_MASK 0x1e00 /* | of all the JSFUN_* flags */ - -/* - * If set, will allow redefining a non-configurable property, but only on a - * non-DOM global. This is a temporary hack that will need to go away in bug - * 1105518. - */ -#define JSPROP_REDEFINE_NONCONFIGURABLE 0x1000 - -/* - * Resolve hooks and enumerate hooks must pass this flag when calling - * JS_Define* APIs to reify lazily-defined properties. - * - * JSPROP_RESOLVING is used only with property-defining APIs. It tells the - * engine to skip the resolve hook when performing the lookup at the beginning - * of property definition. This keeps the resolve hook from accidentally - * triggering itself: unchecked recursion. - * - * For enumerate hooks, triggering the resolve hook would be merely silly, not - * fatal, except in some cases involving non-configurable properties. - */ -#define JSPROP_RESOLVING 0x2000 - -#define JSPROP_IGNORE_ENUMERATE 0x4000 /* ignore the value in JSPROP_ENUMERATE. - This flag only valid when defining over - an existing property. */ -#define JSPROP_IGNORE_READONLY 0x8000 /* ignore the value in JSPROP_READONLY. - This flag only valid when defining over - an existing property. */ -#define JSPROP_IGNORE_PERMANENT 0x10000 /* ignore the value in JSPROP_PERMANENT. - This flag only valid when defining over - an existing property. */ -#define JSPROP_IGNORE_VALUE 0x20000 /* ignore the Value in the descriptor. Nothing was - specified when passed to Object.defineProperty - from script. */ - -/** Microseconds since the epoch, midnight, January 1, 1970 UTC. */ -extern JS_PUBLIC_API(int64_t) -JS_Now(void); - -/** Don't want to export data, so provide accessors for non-inline Values. */ -extern JS_PUBLIC_API(JS::Value) -JS_GetNaNValue(JSContext* cx); - -extern JS_PUBLIC_API(JS::Value) -JS_GetNegativeInfinityValue(JSContext* cx); - -extern JS_PUBLIC_API(JS::Value) -JS_GetPositiveInfinityValue(JSContext* cx); - -extern JS_PUBLIC_API(JS::Value) -JS_GetEmptyStringValue(JSContext* cx); - -extern JS_PUBLIC_API(JSString*) -JS_GetEmptyString(JSContext* cx); - -extern JS_PUBLIC_API(bool) -JS_ValueToObject(JSContext* cx, JS::HandleValue v, JS::MutableHandleObject objp); - -extern JS_PUBLIC_API(JSFunction*) -JS_ValueToFunction(JSContext* cx, JS::HandleValue v); - -extern JS_PUBLIC_API(JSFunction*) -JS_ValueToConstructor(JSContext* cx, JS::HandleValue v); - -extern JS_PUBLIC_API(JSString*) -JS_ValueToSource(JSContext* cx, JS::Handle v); - -extern JS_PUBLIC_API(bool) -JS_DoubleIsInt32(double d, int32_t* ip); - -extern JS_PUBLIC_API(JSType) -JS_TypeOfValue(JSContext* cx, JS::Handle v); - -namespace JS { - -extern JS_PUBLIC_API(const char*) -InformalValueTypeName(const JS::Value& v); - -} /* namespace JS */ - -extern JS_PUBLIC_API(bool) -JS_StrictlyEqual(JSContext* cx, JS::Handle v1, JS::Handle v2, bool* equal); - -extern JS_PUBLIC_API(bool) -JS_LooselyEqual(JSContext* cx, JS::Handle v1, JS::Handle v2, bool* equal); - -extern JS_PUBLIC_API(bool) -JS_SameValue(JSContext* cx, JS::Handle v1, JS::Handle v2, bool* same); - -/** True iff fun is the global eval function. */ -extern JS_PUBLIC_API(bool) -JS_IsBuiltinEvalFunction(JSFunction* fun); - -/** True iff fun is the Function constructor. */ -extern JS_PUBLIC_API(bool) -JS_IsBuiltinFunctionConstructor(JSFunction* fun); - -/************************************************************************/ - -/* - * Locking, contexts, and memory allocation. - * - * It is important that SpiderMonkey be initialized, and the first context - * be created, in a single-threaded fashion. Otherwise the behavior of the - * library is undefined. - * See: http://developer.mozilla.org/en/docs/Category:JSAPI_Reference - */ - -extern JS_PUBLIC_API(JSContext*) -JS_NewContext(uint32_t maxbytes, - uint32_t maxNurseryBytes = JS::DefaultNurseryBytes, - JSContext* parentContext = nullptr); - -extern JS_PUBLIC_API(void) -JS_DestroyContext(JSContext* cx); - -typedef double (*JS_CurrentEmbedderTimeFunction)(); - -/** - * The embedding can specify a time function that will be used in some - * situations. The function can return the time however it likes; but - * the norm is to return times in units of milliseconds since an - * arbitrary, but consistent, epoch. If the time function is not set, - * a built-in default will be used. - */ -JS_PUBLIC_API(void) -JS_SetCurrentEmbedderTimeFunction(JS_CurrentEmbedderTimeFunction timeFn); - -/** - * Return the time as computed using the current time function, or a - * suitable default if one has not been set. - */ -JS_PUBLIC_API(double) -JS_GetCurrentEmbedderTime(); - -JS_PUBLIC_API(void*) -JS_GetContextPrivate(JSContext* cx); - -JS_PUBLIC_API(void) -JS_SetContextPrivate(JSContext* cx, void* data); - -extern JS_PUBLIC_API(JSContext*) -JS_GetParentContext(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_BeginRequest(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_EndRequest(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_SetFutexCanWait(JSContext* cx); - -namespace js { - -void -AssertHeapIsIdle(JSRuntime* rt); - -} /* namespace js */ - -class MOZ_RAII JSAutoRequest -{ - public: - explicit JSAutoRequest(JSContext* cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mContext(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - JS_BeginRequest(mContext); - } - ~JSAutoRequest() { - JS_EndRequest(mContext); - } - - protected: - JSContext* mContext; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - -#if 0 - private: - static void* operator new(size_t) CPP_THROW_NEW { return 0; } - static void operator delete(void*, size_t) { } -#endif -}; - -extern JS_PUBLIC_API(JSVersion) -JS_GetVersion(JSContext* cx); - -/** - * Mutate the version on the compartment. This is generally discouraged, but - * necessary to support the version mutation in the js and xpc shell command - * set. - * - * It would be nice to put this in jsfriendapi, but the linkage requirements - * of the shells make that impossible. - */ -JS_PUBLIC_API(void) -JS_SetVersionForCompartment(JSCompartment* compartment, JSVersion version); - -extern JS_PUBLIC_API(const char*) -JS_VersionToString(JSVersion version); - -extern JS_PUBLIC_API(JSVersion) -JS_StringToVersion(const char* string); - -namespace JS { - -class JS_PUBLIC_API(ContextOptions) { - public: - ContextOptions() - : baseline_(true), - ion_(true), - asmJS_(true), - wasm_(false), - wasmAlwaysBaseline_(false), - throwOnAsmJSValidationFailure_(false), - nativeRegExp_(true), - unboxedArrays_(false), - asyncStack_(true), - throwOnDebuggeeWouldRun_(true), - dumpStackOnDebuggeeWouldRun_(false), - werror_(false), - strictMode_(false), - extraWarnings_(false) - { - } - - bool baseline() const { return baseline_; } - ContextOptions& setBaseline(bool flag) { - baseline_ = flag; - return *this; - } - ContextOptions& toggleBaseline() { - baseline_ = !baseline_; - return *this; - } - - bool ion() const { return ion_; } - ContextOptions& setIon(bool flag) { - ion_ = flag; - return *this; - } - ContextOptions& toggleIon() { - ion_ = !ion_; - return *this; - } - - bool asmJS() const { return asmJS_; } - ContextOptions& setAsmJS(bool flag) { - asmJS_ = flag; - return *this; - } - ContextOptions& toggleAsmJS() { - asmJS_ = !asmJS_; - return *this; - } - - bool wasm() const { return wasm_; } - ContextOptions& setWasm(bool flag) { - wasm_ = flag; - return *this; - } - ContextOptions& toggleWasm() { - wasm_ = !wasm_; - return *this; - } - - bool wasmAlwaysBaseline() const { return wasmAlwaysBaseline_; } - ContextOptions& setWasmAlwaysBaseline(bool flag) { - wasmAlwaysBaseline_ = flag; - return *this; - } - ContextOptions& toggleWasmAlwaysBaseline() { - wasmAlwaysBaseline_ = !wasmAlwaysBaseline_; - return *this; - } - - bool throwOnAsmJSValidationFailure() const { return throwOnAsmJSValidationFailure_; } - ContextOptions& setThrowOnAsmJSValidationFailure(bool flag) { - throwOnAsmJSValidationFailure_ = flag; - return *this; - } - ContextOptions& toggleThrowOnAsmJSValidationFailure() { - throwOnAsmJSValidationFailure_ = !throwOnAsmJSValidationFailure_; - return *this; - } - - bool nativeRegExp() const { return nativeRegExp_; } - ContextOptions& setNativeRegExp(bool flag) { - nativeRegExp_ = flag; - return *this; - } - - bool unboxedArrays() const { return unboxedArrays_; } - ContextOptions& setUnboxedArrays(bool flag) { - unboxedArrays_ = flag; - return *this; - } - - bool asyncStack() const { return asyncStack_; } - ContextOptions& setAsyncStack(bool flag) { - asyncStack_ = flag; - return *this; - } - - bool throwOnDebuggeeWouldRun() const { return throwOnDebuggeeWouldRun_; } - ContextOptions& setThrowOnDebuggeeWouldRun(bool flag) { - throwOnDebuggeeWouldRun_ = flag; - return *this; - } - - bool dumpStackOnDebuggeeWouldRun() const { return dumpStackOnDebuggeeWouldRun_; } - ContextOptions& setDumpStackOnDebuggeeWouldRun(bool flag) { - dumpStackOnDebuggeeWouldRun_ = flag; - return *this; - } - - bool werror() const { return werror_; } - ContextOptions& setWerror(bool flag) { - werror_ = flag; - return *this; - } - ContextOptions& toggleWerror() { - werror_ = !werror_; - return *this; - } - - bool strictMode() const { return strictMode_; } - ContextOptions& setStrictMode(bool flag) { - strictMode_ = flag; - return *this; - } - ContextOptions& toggleStrictMode() { - strictMode_ = !strictMode_; - return *this; - } - - bool extraWarnings() const { return extraWarnings_; } - ContextOptions& setExtraWarnings(bool flag) { - extraWarnings_ = flag; - return *this; - } - ContextOptions& toggleExtraWarnings() { - extraWarnings_ = !extraWarnings_; - return *this; - } - - private: - bool baseline_ : 1; - bool ion_ : 1; - bool asmJS_ : 1; - bool wasm_ : 1; - bool wasmAlwaysBaseline_ : 1; - bool throwOnAsmJSValidationFailure_ : 1; - bool nativeRegExp_ : 1; - bool unboxedArrays_ : 1; - bool asyncStack_ : 1; - bool throwOnDebuggeeWouldRun_ : 1; - bool dumpStackOnDebuggeeWouldRun_ : 1; - bool werror_ : 1; - bool strictMode_ : 1; - bool extraWarnings_ : 1; -}; - -JS_PUBLIC_API(ContextOptions&) -ContextOptionsRef(JSContext* cx); - -/** - * Initialize the runtime's self-hosted code. Embeddings should call this - * exactly once per runtime/context, before the first JS_NewGlobalObject - * call. - */ -JS_PUBLIC_API(bool) -InitSelfHostedCode(JSContext* cx); - -/** - * Asserts (in debug and release builds) that `obj` belongs to the current - * thread's context. - */ -JS_PUBLIC_API(void) -AssertObjectBelongsToCurrentThread(JSObject* obj); - -} /* namespace JS */ - -extern JS_PUBLIC_API(const char*) -JS_GetImplementationVersion(void); - -extern JS_PUBLIC_API(void) -JS_SetDestroyCompartmentCallback(JSContext* cx, JSDestroyCompartmentCallback callback); - -extern JS_PUBLIC_API(void) -JS_SetSizeOfIncludingThisCompartmentCallback(JSContext* cx, - JSSizeOfIncludingThisCompartmentCallback callback); - -extern JS_PUBLIC_API(void) -JS_SetDestroyZoneCallback(JSContext* cx, JSZoneCallback callback); - -extern JS_PUBLIC_API(void) -JS_SetSweepZoneCallback(JSContext* cx, JSZoneCallback callback); - -extern JS_PUBLIC_API(void) -JS_SetCompartmentNameCallback(JSContext* cx, JSCompartmentNameCallback callback); - -extern JS_PUBLIC_API(void) -JS_SetWrapObjectCallbacks(JSContext* cx, const JSWrapObjectCallbacks* callbacks); - -extern JS_PUBLIC_API(void) -JS_SetCompartmentPrivate(JSCompartment* compartment, void* data); - -extern JS_PUBLIC_API(void*) -JS_GetCompartmentPrivate(JSCompartment* compartment); - -extern JS_PUBLIC_API(void) -JS_SetZoneUserData(JS::Zone* zone, void* data); - -extern JS_PUBLIC_API(void*) -JS_GetZoneUserData(JS::Zone* zone); - -extern JS_PUBLIC_API(bool) -JS_WrapObject(JSContext* cx, JS::MutableHandleObject objp); - -extern JS_PUBLIC_API(bool) -JS_WrapValue(JSContext* cx, JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(JSObject*) -JS_TransplantObject(JSContext* cx, JS::HandleObject origobj, JS::HandleObject target); - -extern JS_PUBLIC_API(bool) -JS_RefreshCrossCompartmentWrappers(JSContext* cx, JS::Handle obj); - -/* - * At any time, a JSContext has a current (possibly-nullptr) compartment. - * Compartments are described in: - * - * developer.mozilla.org/en-US/docs/SpiderMonkey/SpiderMonkey_compartments - * - * The current compartment of a context may be changed. The preferred way to do - * this is with JSAutoCompartment: - * - * void foo(JSContext* cx, JSObject* obj) { - * // in some compartment 'c' - * { - * JSAutoCompartment ac(cx, obj); // constructor enters - * // in the compartment of 'obj' - * } // destructor leaves - * // back in compartment 'c' - * } - * - * For more complicated uses that don't neatly fit in a C++ stack frame, the - * compartment can entered and left using separate function calls: - * - * void foo(JSContext* cx, JSObject* obj) { - * // in 'oldCompartment' - * JSCompartment* oldCompartment = JS_EnterCompartment(cx, obj); - * // in the compartment of 'obj' - * JS_LeaveCompartment(cx, oldCompartment); - * // back in 'oldCompartment' - * } - * - * Note: these calls must still execute in a LIFO manner w.r.t all other - * enter/leave calls on the context. Furthermore, only the return value of a - * JS_EnterCompartment call may be passed as the 'oldCompartment' argument of - * the corresponding JS_LeaveCompartment call. - */ - -class MOZ_RAII JS_PUBLIC_API(JSAutoCompartment) -{ - JSContext* cx_; - JSCompartment* oldCompartment_; - public: - JSAutoCompartment(JSContext* cx, JSObject* target - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - JSAutoCompartment(JSContext* cx, JSScript* target - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - ~JSAutoCompartment(); - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class MOZ_RAII JS_PUBLIC_API(JSAutoNullableCompartment) -{ - JSContext* cx_; - JSCompartment* oldCompartment_; - public: - explicit JSAutoNullableCompartment(JSContext* cx, JSObject* targetOrNull - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - ~JSAutoNullableCompartment(); - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -/** NB: This API is infallible; a nullptr return value does not indicate error. */ -extern JS_PUBLIC_API(JSCompartment*) -JS_EnterCompartment(JSContext* cx, JSObject* target); - -extern JS_PUBLIC_API(void) -JS_LeaveCompartment(JSContext* cx, JSCompartment* oldCompartment); - -typedef void (*JSIterateCompartmentCallback)(JSContext* cx, void* data, JSCompartment* compartment); - -/** - * This function calls |compartmentCallback| on every compartment. Beware that - * there is no guarantee that the compartment will survive after the callback - * returns. Also, barriers are disabled via the TraceSession. - */ -extern JS_PUBLIC_API(void) -JS_IterateCompartments(JSContext* cx, void* data, - JSIterateCompartmentCallback compartmentCallback); - -/** - * Initialize standard JS class constructors, prototypes, and any top-level - * functions and constants associated with the standard classes (e.g. isNaN - * for Number). - * - * NB: This sets cx's global object to obj if it was null. - */ -extern JS_PUBLIC_API(bool) -JS_InitStandardClasses(JSContext* cx, JS::Handle obj); - -/** - * Resolve id, which must contain either a string or an int, to a standard - * class name in obj if possible, defining the class's constructor and/or - * prototype and storing true in *resolved. If id does not name a standard - * class or a top-level property induced by initializing a standard class, - * store false in *resolved and just return true. Return false on error, - * as usual for bool result-typed API entry points. - * - * This API can be called directly from a global object class's resolve op, - * to define standard classes lazily. The class's enumerate op should call - * JS_EnumerateStandardClasses(cx, obj), to define eagerly during for..in - * loops any classes not yet resolved lazily. - */ -extern JS_PUBLIC_API(bool) -JS_ResolveStandardClass(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolved); - -extern JS_PUBLIC_API(bool) -JS_MayResolveStandardClass(const JSAtomState& names, jsid id, JSObject* maybeObj); - -extern JS_PUBLIC_API(bool) -JS_EnumerateStandardClasses(JSContext* cx, JS::HandleObject obj); - -extern JS_PUBLIC_API(bool) -JS_GetClassObject(JSContext* cx, JSProtoKey key, JS::MutableHandle objp); - -extern JS_PUBLIC_API(bool) -JS_GetClassPrototype(JSContext* cx, JSProtoKey key, JS::MutableHandle objp); - -namespace JS { - -/* - * Determine if the given object is an instance/prototype/constructor for a standard - * class. If so, return the associated JSProtoKey. If not, return JSProto_Null. - */ - -extern JS_PUBLIC_API(JSProtoKey) -IdentifyStandardInstance(JSObject* obj); - -extern JS_PUBLIC_API(JSProtoKey) -IdentifyStandardPrototype(JSObject* obj); - -extern JS_PUBLIC_API(JSProtoKey) -IdentifyStandardInstanceOrPrototype(JSObject* obj); - -extern JS_PUBLIC_API(JSProtoKey) -IdentifyStandardConstructor(JSObject* obj); - -extern JS_PUBLIC_API(void) -ProtoKeyToId(JSContext* cx, JSProtoKey key, JS::MutableHandleId idp); - -} /* namespace JS */ - -extern JS_PUBLIC_API(JSProtoKey) -JS_IdToProtoKey(JSContext* cx, JS::HandleId id); - -/** - * Returns the original value of |Function.prototype| from the global object in - * which |forObj| was created. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetFunctionPrototype(JSContext* cx, JS::HandleObject forObj); - -/** - * Returns the original value of |Object.prototype| from the global object in - * which |forObj| was created. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetObjectPrototype(JSContext* cx, JS::HandleObject forObj); - -/** - * Returns the original value of |Array.prototype| from the global object in - * which |forObj| was created. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetArrayPrototype(JSContext* cx, JS::HandleObject forObj); - -/** - * Returns the original value of |Error.prototype| from the global - * object of the current compartment of cx. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetErrorPrototype(JSContext* cx); - -/** - * Returns the %IteratorPrototype% object that all built-in iterator prototype - * chains go through for the global object of the current compartment of cx. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetIteratorPrototype(JSContext* cx); - -extern JS_PUBLIC_API(JSObject*) -JS_GetGlobalForObject(JSContext* cx, JSObject* obj); - -extern JS_PUBLIC_API(bool) -JS_IsGlobalObject(JSObject* obj); - -extern JS_PUBLIC_API(JSObject*) -JS_GlobalLexicalEnvironment(JSObject* obj); - -extern JS_PUBLIC_API(bool) -JS_HasExtensibleLexicalEnvironment(JSObject* obj); - -extern JS_PUBLIC_API(JSObject*) -JS_ExtensibleLexicalEnvironment(JSObject* obj); - -/** - * May return nullptr, if |c| never had a global (e.g. the atoms compartment), - * or if |c|'s global has been collected. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetGlobalForCompartmentOrNull(JSContext* cx, JSCompartment* c); - -namespace JS { - -extern JS_PUBLIC_API(JSObject*) -CurrentGlobalOrNull(JSContext* cx); - -} // namespace JS - -/** - * Add 'Reflect.parse', a SpiderMonkey extension, to the Reflect object on the - * given global. - */ -extern JS_PUBLIC_API(bool) -JS_InitReflectParse(JSContext* cx, JS::HandleObject global); - -/** - * Add various profiling-related functions as properties of the given object. - * Defined in builtin/Profilers.cpp. - */ -extern JS_PUBLIC_API(bool) -JS_DefineProfilingFunctions(JSContext* cx, JS::HandleObject obj); - -/* Defined in vm/Debugger.cpp. */ -extern JS_PUBLIC_API(bool) -JS_DefineDebuggerObject(JSContext* cx, JS::HandleObject obj); - -#ifdef JS_HAS_CTYPES -/** - * Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes' - * object will be sealed. - */ -extern JS_PUBLIC_API(bool) -JS_InitCTypesClass(JSContext* cx, JS::HandleObject global); - -/** - * Convert a unicode string 'source' of length 'slen' to the platform native - * charset, returning a null-terminated string allocated with JS_malloc. On - * failure, this function should report an error. - */ -typedef char* -(* JSCTypesUnicodeToNativeFun)(JSContext* cx, const char16_t* source, size_t slen); - -/** - * Set of function pointers that ctypes can use for various internal functions. - * See JS_SetCTypesCallbacks below. Providing nullptr for a function is safe, - * and will result in the applicable ctypes functionality not being available. - */ -struct JSCTypesCallbacks { - JSCTypesUnicodeToNativeFun unicodeToNative; -}; - -typedef struct JSCTypesCallbacks JSCTypesCallbacks; - -/** - * Set the callbacks on the provided 'ctypesObj' object. 'callbacks' should be a - * pointer to static data that exists for the lifetime of 'ctypesObj', but it - * may safely be altered after calling this function and without having - * to call this function again. - */ -extern JS_PUBLIC_API(void) -JS_SetCTypesCallbacks(JSObject* ctypesObj, const JSCTypesCallbacks* callbacks); -#endif - -extern JS_PUBLIC_API(void*) -JS_malloc(JSContext* cx, size_t nbytes); - -extern JS_PUBLIC_API(void*) -JS_realloc(JSContext* cx, void* p, size_t oldBytes, size_t newBytes); - -/** - * A wrapper for js_free(p) that may delay js_free(p) invocation as a - * performance optimization. - * cx may be nullptr. - */ -extern JS_PUBLIC_API(void) -JS_free(JSContext* cx, void* p); - -/** - * A wrapper for js_free(p) that may delay js_free(p) invocation as a - * performance optimization as specified by the given JSFreeOp instance. - */ -extern JS_PUBLIC_API(void) -JS_freeop(JSFreeOp* fop, void* p); - -extern JS_PUBLIC_API(void) -JS_updateMallocCounter(JSContext* cx, size_t nbytes); - -extern JS_PUBLIC_API(char*) -JS_strdup(JSContext* cx, const char* s); - -/** - * Register externally maintained GC roots. - * - * traceOp: the trace operation. For each root the implementation should call - * JS::TraceEdge whenever the root contains a traceable thing. - * data: the data argument to pass to each invocation of traceOp. - */ -extern JS_PUBLIC_API(bool) -JS_AddExtraGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data); - -/** Undo a call to JS_AddExtraGCRootsTracer. */ -extern JS_PUBLIC_API(void) -JS_RemoveExtraGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data); - -/* - * Garbage collector API. - */ -extern JS_PUBLIC_API(void) -JS_GC(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_MaybeGC(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_SetGCCallback(JSContext* cx, JSGCCallback cb, void* data); - -extern JS_PUBLIC_API(void) -JS_SetObjectsTenuredCallback(JSContext* cx, JSObjectsTenuredCallback cb, - void* data); - -extern JS_PUBLIC_API(bool) -JS_AddFinalizeCallback(JSContext* cx, JSFinalizeCallback cb, void* data); - -extern JS_PUBLIC_API(void) -JS_RemoveFinalizeCallback(JSContext* cx, JSFinalizeCallback cb); - -/* - * Weak pointers and garbage collection - * - * Weak pointers are by their nature not marked as part of garbage collection, - * but they may need to be updated in two cases after a GC: - * - * 1) Their referent was found not to be live and is about to be finalized - * 2) Their referent has been moved by a compacting GC - * - * To handle this, any part of the system that maintain weak pointers to - * JavaScript GC things must register a callback with - * JS_(Add,Remove)WeakPointer{ZoneGroup,Compartment}Callback(). This callback - * must then call JS_UpdateWeakPointerAfterGC() on all weak pointers it knows - * about. - * - * Since sweeping is incremental, we have several callbacks to avoid repeatedly - * having to visit all embedder structures. The WeakPointerZoneGroupCallback is - * called once for each strongly connected group of zones, whereas the - * WeakPointerCompartmentCallback is called once for each compartment that is - * visited while sweeping. Structures that cannot contain references in more - * than one compartment should sweep the relevant per-compartment structures - * using the latter callback to minimizer per-slice overhead. - * - * The argument to JS_UpdateWeakPointerAfterGC() is an in-out param. If the - * referent is about to be finalized the pointer will be set to null. If the - * referent has been moved then the pointer will be updated to point to the new - * location. - * - * Callers of this method are responsible for updating any state that is - * dependent on the object's address. For example, if the object's address is - * used as a key in a hashtable, then the object must be removed and - * re-inserted with the correct hash. - */ - -extern JS_PUBLIC_API(bool) -JS_AddWeakPointerZoneGroupCallback(JSContext* cx, JSWeakPointerZoneGroupCallback cb, void* data); - -extern JS_PUBLIC_API(void) -JS_RemoveWeakPointerZoneGroupCallback(JSContext* cx, JSWeakPointerZoneGroupCallback cb); - -extern JS_PUBLIC_API(bool) -JS_AddWeakPointerCompartmentCallback(JSContext* cx, JSWeakPointerCompartmentCallback cb, - void* data); - -extern JS_PUBLIC_API(void) -JS_RemoveWeakPointerCompartmentCallback(JSContext* cx, JSWeakPointerCompartmentCallback cb); - -extern JS_PUBLIC_API(void) -JS_UpdateWeakPointerAfterGC(JS::Heap* objp); - -extern JS_PUBLIC_API(void) -JS_UpdateWeakPointerAfterGCUnbarriered(JSObject** objp); - -typedef enum JSGCParamKey { - /** Maximum nominal heap before last ditch GC. */ - JSGC_MAX_BYTES = 0, - - /** Number of JS_malloc bytes before last ditch GC. */ - JSGC_MAX_MALLOC_BYTES = 1, - - /** Amount of bytes allocated by the GC. */ - JSGC_BYTES = 3, - - /** Number of times GC has been invoked. Includes both major and minor GC. */ - JSGC_NUMBER = 4, - - /** Select GC mode. */ - JSGC_MODE = 6, - - /** Number of cached empty GC chunks. */ - JSGC_UNUSED_CHUNKS = 7, - - /** Total number of allocated GC chunks. */ - JSGC_TOTAL_CHUNKS = 8, - - /** Max milliseconds to spend in an incremental GC slice. */ - JSGC_SLICE_TIME_BUDGET = 9, - - /** Maximum size the GC mark stack can grow to. */ - JSGC_MARK_STACK_LIMIT = 10, - - /** - * GCs less than this far apart in time will be considered 'high-frequency GCs'. - * See setGCLastBytes in jsgc.cpp. - */ - JSGC_HIGH_FREQUENCY_TIME_LIMIT = 11, - - /** Start of dynamic heap growth. */ - JSGC_HIGH_FREQUENCY_LOW_LIMIT = 12, - - /** End of dynamic heap growth. */ - JSGC_HIGH_FREQUENCY_HIGH_LIMIT = 13, - - /** Upper bound of heap growth. */ - JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX = 14, - - /** Lower bound of heap growth. */ - JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN = 15, - - /** Heap growth for low frequency GCs. */ - JSGC_LOW_FREQUENCY_HEAP_GROWTH = 16, - - /** - * If false, the heap growth factor is fixed at 3. If true, it is determined - * based on whether GCs are high- or low- frequency. - */ - JSGC_DYNAMIC_HEAP_GROWTH = 17, - - /** If true, high-frequency GCs will use a longer mark slice. */ - JSGC_DYNAMIC_MARK_SLICE = 18, - - /** Lower limit after which we limit the heap growth. */ - JSGC_ALLOCATION_THRESHOLD = 19, - - /** - * We try to keep at least this many unused chunks in the free chunk pool at - * all times, even after a shrinking GC. - */ - JSGC_MIN_EMPTY_CHUNK_COUNT = 21, - - /** We never keep more than this many unused chunks in the free chunk pool. */ - JSGC_MAX_EMPTY_CHUNK_COUNT = 22, - - /** Whether compacting GC is enabled. */ - JSGC_COMPACTING_ENABLED = 23, - - /** If true, painting can trigger IGC slices. */ - JSGC_REFRESH_FRAME_SLICES_ENABLED = 24, -} JSGCParamKey; - -extern JS_PUBLIC_API(void) -JS_SetGCParameter(JSContext* cx, JSGCParamKey key, uint32_t value); - -extern JS_PUBLIC_API(uint32_t) -JS_GetGCParameter(JSContext* cx, JSGCParamKey key); - -extern JS_PUBLIC_API(void) -JS_SetGCParametersBasedOnAvailableMemory(JSContext* cx, uint32_t availMem); - -/** - * Create a new JSString whose chars member refers to external memory, i.e., - * memory requiring application-specific finalization. - */ -extern JS_PUBLIC_API(JSString*) -JS_NewExternalString(JSContext* cx, const char16_t* chars, size_t length, - const JSStringFinalizer* fin); - -/** - * Return whether 'str' was created with JS_NewExternalString or - * JS_NewExternalStringWithClosure. - */ -extern JS_PUBLIC_API(bool) -JS_IsExternalString(JSString* str); - -/** - * Return the 'fin' arg passed to JS_NewExternalString. - */ -extern JS_PUBLIC_API(const JSStringFinalizer*) -JS_GetExternalStringFinalizer(JSString* str); - -/** - * Set the size of the native stack that should not be exceed. To disable - * stack size checking pass 0. - * - * SpiderMonkey allows for a distinction between system code (such as GCs, which - * may incidentally be triggered by script but are not strictly performed on - * behalf of such script), trusted script (as determined by JS_SetTrustedPrincipals), - * and untrusted script. Each kind of code may have a different stack quota, - * allowing embedders to keep higher-priority machinery running in the face of - * scripted stack exhaustion by something else. - * - * The stack quotas for each kind of code should be monotonically descending, - * and may be specified with this function. If 0 is passed for a given kind - * of code, it defaults to the value of the next-highest-priority kind. - * - * This function may only be called immediately after the runtime is initialized - * and before any code is executed and/or interrupts requested. - */ -extern JS_PUBLIC_API(void) -JS_SetNativeStackQuota(JSContext* cx, size_t systemCodeStackSize, - size_t trustedScriptStackSize = 0, - size_t untrustedScriptStackSize = 0); - -/************************************************************************/ - -extern JS_PUBLIC_API(bool) -JS_ValueToId(JSContext* cx, JS::HandleValue v, JS::MutableHandleId idp); - -extern JS_PUBLIC_API(bool) -JS_StringToId(JSContext* cx, JS::HandleString s, JS::MutableHandleId idp); - -extern JS_PUBLIC_API(bool) -JS_IdToValue(JSContext* cx, jsid id, JS::MutableHandle vp); - -namespace JS { - -/** - * Convert obj to a primitive value. On success, store the result in vp and - * return true. - * - * The hint argument must be JSTYPE_STRING, JSTYPE_NUMBER, or JSTYPE_VOID (no - * hint). - * - * Implements: ES6 7.1.1 ToPrimitive(input, [PreferredType]). - */ -extern JS_PUBLIC_API(bool) -ToPrimitive(JSContext* cx, JS::HandleObject obj, JSType hint, JS::MutableHandleValue vp); - -/** - * If args.get(0) is one of the strings "string", "number", or "default", set - * *result to JSTYPE_STRING, JSTYPE_NUMBER, or JSTYPE_VOID accordingly and - * return true. Otherwise, return false with a TypeError pending. - * - * This can be useful in implementing a @@toPrimitive method. - */ -extern JS_PUBLIC_API(bool) -GetFirstArgumentAsTypeHint(JSContext* cx, CallArgs args, JSType *result); - -} /* namespace JS */ - -extern JS_PUBLIC_API(bool) -JS_PropertyStub(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(bool) -JS_StrictPropertyStub(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp, JS::ObjectOpResult& result); - -template -struct JSConstScalarSpec { - const char* name; - T val; -}; - -typedef JSConstScalarSpec JSConstDoubleSpec; -typedef JSConstScalarSpec JSConstIntegerSpec; - -struct JSJitInfo; - -/** - * Wrapper to relace JSNative for JSPropertySpecs and JSFunctionSpecs. This will - * allow us to pass one JSJitInfo per function with the property/function spec, - * without additional field overhead. - */ -typedef struct JSNativeWrapper { - JSNative op; - const JSJitInfo* info; -} JSNativeWrapper; - -/* - * Macro static initializers which make it easy to pass no JSJitInfo as part of a - * JSPropertySpec or JSFunctionSpec. - */ -#define JSNATIVE_WRAPPER(native) { {native, nullptr} } - -/** - * Description of a property. JS_DefineProperties and JS_InitClass take arrays - * of these and define many properties at once. JS_PSG, JS_PSGS and JS_PS_END - * are helper macros for defining such arrays. - */ -struct JSPropertySpec { - struct SelfHostedWrapper { - void* unused; - const char* funname; - }; - - struct ValueWrapper { - uintptr_t type; - union { - const char* string; - int32_t int32; - }; - }; - - const char* name; - uint8_t flags; - union { - struct { - union { - JSNativeWrapper native; - SelfHostedWrapper selfHosted; - } getter; - union { - JSNativeWrapper native; - SelfHostedWrapper selfHosted; - } setter; - } accessors; - ValueWrapper value; - }; - - bool isAccessor() const { - return !(flags & JSPROP_INTERNAL_USE_BIT); - } - bool getValue(JSContext* cx, JS::MutableHandleValue value) const; - - bool isSelfHosted() const { - MOZ_ASSERT(isAccessor()); - -#ifdef DEBUG - // Verify that our accessors match our JSPROP_GETTER flag. - if (flags & JSPROP_GETTER) - checkAccessorsAreSelfHosted(); - else - checkAccessorsAreNative(); -#endif - return (flags & JSPROP_GETTER); - } - - static_assert(sizeof(SelfHostedWrapper) == sizeof(JSNativeWrapper), - "JSPropertySpec::getter/setter must be compact"); - static_assert(offsetof(SelfHostedWrapper, funname) == offsetof(JSNativeWrapper, info), - "JS_SELF_HOSTED* macros below require that " - "SelfHostedWrapper::funname overlay " - "JSNativeWrapper::info"); -private: - void checkAccessorsAreNative() const { - MOZ_ASSERT(accessors.getter.native.op); - // We may not have a setter at all. So all we can assert here, for the - // native case is that if we have a jitinfo for the setter then we have - // a setter op too. This is good enough to make sure we don't have a - // SelfHostedWrapper for the setter. - MOZ_ASSERT_IF(accessors.setter.native.info, accessors.setter.native.op); - } - - void checkAccessorsAreSelfHosted() const { - MOZ_ASSERT(!accessors.getter.selfHosted.unused); - MOZ_ASSERT(!accessors.setter.selfHosted.unused); - } -}; - -namespace JS { -namespace detail { - -/* NEVER DEFINED, DON'T USE. For use by JS_CAST_NATIVE_TO only. */ -inline int CheckIsNative(JSNative native); - -/* NEVER DEFINED, DON'T USE. For use by JS_CAST_STRING_TO only. */ -template -inline int -CheckIsCharacterLiteral(const char (&arr)[N]); - -/* NEVER DEFINED, DON'T USE. For use by JS_CAST_INT32_TO only. */ -inline int CheckIsInt32(int32_t value); - -/* NEVER DEFINED, DON'T USE. For use by JS_PROPERTYOP_GETTER only. */ -inline int CheckIsGetterOp(JSGetterOp op); - -/* NEVER DEFINED, DON'T USE. For use by JS_PROPERTYOP_SETTER only. */ -inline int CheckIsSetterOp(JSSetterOp op); - -} // namespace detail -} // namespace JS - -#define JS_CAST_NATIVE_TO(v, To) \ - (static_cast(sizeof(JS::detail::CheckIsNative(v))), \ - reinterpret_cast(v)) - -#define JS_CAST_STRING_TO(s, To) \ - (static_cast(sizeof(JS::detail::CheckIsCharacterLiteral(s))), \ - reinterpret_cast(s)) - -#define JS_CAST_INT32_TO(s, To) \ - (static_cast(sizeof(JS::detail::CheckIsInt32(s))), \ - reinterpret_cast(s)) - -#define JS_CHECK_ACCESSOR_FLAGS(flags) \ - (static_cast::Type>(0), \ - (flags)) - -#define JS_PROPERTYOP_GETTER(v) \ - (static_cast(sizeof(JS::detail::CheckIsGetterOp(v))), \ - reinterpret_cast(v)) - -#define JS_PROPERTYOP_SETTER(v) \ - (static_cast(sizeof(JS::detail::CheckIsSetterOp(v))), \ - reinterpret_cast(v)) - -#define JS_STUBGETTER JS_PROPERTYOP_GETTER(JS_PropertyStub) - -#define JS_STUBSETTER JS_PROPERTYOP_SETTER(JS_StrictPropertyStub) - -#define JS_PS_ACCESSOR_SPEC(name, getter, setter, flags, extraFlags) \ - { name, uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | extraFlags), \ - { { getter, setter } } } -#define JS_PS_VALUE_SPEC(name, value, flags) \ - { name, uint8_t(flags | JSPROP_INTERNAL_USE_BIT), \ - { { value, JSNATIVE_WRAPPER(nullptr) } } } - -#define SELFHOSTED_WRAPPER(name) \ - { { nullptr, JS_CAST_STRING_TO(name, const JSJitInfo*) } } -#define STRINGVALUE_WRAPPER(value) \ - { { reinterpret_cast(JSVAL_TYPE_STRING), JS_CAST_STRING_TO(value, const JSJitInfo*) } } -#define INT32VALUE_WRAPPER(value) \ - { { reinterpret_cast(JSVAL_TYPE_INT32), JS_CAST_INT32_TO(value, const JSJitInfo*) } } - -/* - * JSPropertySpec uses JSNativeWrapper. These macros encapsulate the definition - * of JSNative-backed JSPropertySpecs, by defining the JSNativeWrappers for - * them. - */ -#define JS_PSG(name, getter, flags) \ - JS_PS_ACCESSOR_SPEC(name, JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(nullptr), flags, \ - JSPROP_SHARED) -#define JS_PSGS(name, getter, setter, flags) \ - JS_PS_ACCESSOR_SPEC(name, JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(setter), flags, \ - JSPROP_SHARED) -#define JS_SELF_HOSTED_GET(name, getterName, flags) \ - JS_PS_ACCESSOR_SPEC(name, SELFHOSTED_WRAPPER(getterName), JSNATIVE_WRAPPER(nullptr), flags, \ - JSPROP_SHARED | JSPROP_GETTER) -#define JS_SELF_HOSTED_GETSET(name, getterName, setterName, flags) \ - JS_PS_ACCESSOR_SPEC(name, SELFHOSTED_WRAPPER(getterName), SELFHOSTED_WRAPPER(setterName), \ - flags, JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER) -#define JS_SELF_HOSTED_SYM_GET(symbol, getterName, flags) \ - JS_PS_ACCESSOR_SPEC(reinterpret_cast(uint32_t(::JS::SymbolCode::symbol) + 1), \ - SELFHOSTED_WRAPPER(getterName), JSNATIVE_WRAPPER(nullptr), flags, \ - JSPROP_SHARED | JSPROP_GETTER) -#define JS_STRING_PS(name, string, flags) \ - JS_PS_VALUE_SPEC(name, STRINGVALUE_WRAPPER(string), flags) -#define JS_STRING_SYM_PS(symbol, string, flags) \ - JS_PS_VALUE_SPEC(reinterpret_cast(uint32_t(::JS::SymbolCode::symbol) + 1), \ - STRINGVALUE_WRAPPER(string), flags) -#define JS_INT32_PS(name, value, flags) \ - JS_PS_VALUE_SPEC(name, INT32VALUE_WRAPPER(value), flags) -#define JS_PS_END \ - JS_PS_ACCESSOR_SPEC(nullptr, JSNATIVE_WRAPPER(nullptr), JSNATIVE_WRAPPER(nullptr), 0, 0) - -/** - * To define a native function, set call to a JSNativeWrapper. To define a - * self-hosted function, set selfHostedName to the name of a function - * compiled during JSRuntime::initSelfHosting. - */ -struct JSFunctionSpec { - const char* name; - JSNativeWrapper call; - uint16_t nargs; - uint16_t flags; - const char* selfHostedName; -}; - -/* - * Terminating sentinel initializer to put at the end of a JSFunctionSpec array - * that's passed to JS_DefineFunctions or JS_InitClass. - */ -#define JS_FS_END JS_FS(nullptr,nullptr,0,0) - -/* - * Initializer macros for a JSFunctionSpec array element. JS_FN (whose name pays - * homage to the old JSNative/JSFastNative split) simply adds the flag - * JSFUN_STUB_GSOPS. JS_FNINFO allows the simple adding of - * JSJitInfos. JS_SELF_HOSTED_FN declares a self-hosted function. - * JS_INLINABLE_FN allows specifying an InlinableNative enum value for natives - * inlined or specialized by the JIT. Finally JS_FNSPEC has slots for all the - * fields. - * - * The _SYM variants allow defining a function with a symbol key rather than a - * string key. For example, use JS_SYM_FN(iterator, ...) to define an - * @@iterator method. - */ -#define JS_FS(name,call,nargs,flags) \ - JS_FNSPEC(name, call, nullptr, nargs, flags, nullptr) -#define JS_FN(name,call,nargs,flags) \ - JS_FNSPEC(name, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr) -#define JS_INLINABLE_FN(name,call,nargs,flags,native) \ - JS_FNSPEC(name, call, &js::jit::JitInfo_##native, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr) -#define JS_SYM_FN(symbol,call,nargs,flags) \ - JS_SYM_FNSPEC(symbol, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr) -#define JS_FNINFO(name,call,info,nargs,flags) \ - JS_FNSPEC(name, call, info, nargs, flags, nullptr) -#define JS_SELF_HOSTED_FN(name,selfHostedName,nargs,flags) \ - JS_FNSPEC(name, nullptr, nullptr, nargs, flags, selfHostedName) -#define JS_SELF_HOSTED_SYM_FN(symbol, selfHostedName, nargs, flags) \ - JS_SYM_FNSPEC(symbol, nullptr, nullptr, nargs, flags, selfHostedName) -#define JS_SYM_FNSPEC(symbol, call, info, nargs, flags, selfHostedName) \ - JS_FNSPEC(reinterpret_cast( \ - uint32_t(::JS::SymbolCode::symbol) + 1), \ - call, info, nargs, flags, selfHostedName) -#define JS_FNSPEC(name,call,info,nargs,flags,selfHostedName) \ - {name, {call, info}, nargs, flags, selfHostedName} - -extern JS_PUBLIC_API(JSObject*) -JS_InitClass(JSContext* cx, JS::HandleObject obj, JS::HandleObject parent_proto, - const JSClass* clasp, JSNative constructor, unsigned nargs, - const JSPropertySpec* ps, const JSFunctionSpec* fs, - const JSPropertySpec* static_ps, const JSFunctionSpec* static_fs); - -/** - * Set up ctor.prototype = proto and proto.constructor = ctor with the - * right property flags. - */ -extern JS_PUBLIC_API(bool) -JS_LinkConstructorAndPrototype(JSContext* cx, JS::Handle ctor, - JS::Handle proto); - -extern JS_PUBLIC_API(const JSClass*) -JS_GetClass(JSObject* obj); - -extern JS_PUBLIC_API(bool) -JS_InstanceOf(JSContext* cx, JS::Handle obj, const JSClass* clasp, JS::CallArgs* args); - -extern JS_PUBLIC_API(bool) -JS_HasInstance(JSContext* cx, JS::Handle obj, JS::Handle v, bool* bp); - -namespace JS { - -// Implementation of -// http://www.ecma-international.org/ecma-262/6.0/#sec-ordinaryhasinstance. If -// you're looking for the equivalent of "instanceof", you want JS_HasInstance, -// not this function. -extern JS_PUBLIC_API(bool) -OrdinaryHasInstance(JSContext* cx, HandleObject objArg, HandleValue v, bool* bp); - -} // namespace JS - -extern JS_PUBLIC_API(void*) -JS_GetPrivate(JSObject* obj); - -extern JS_PUBLIC_API(void) -JS_SetPrivate(JSObject* obj, void* data); - -extern JS_PUBLIC_API(void*) -JS_GetInstancePrivate(JSContext* cx, JS::Handle obj, const JSClass* clasp, - JS::CallArgs* args); - -extern JS_PUBLIC_API(JSObject*) -JS_GetConstructor(JSContext* cx, JS::Handle proto); - -namespace JS { - -enum ZoneSpecifier { - FreshZone = 0, - SystemZone = 1 -}; - -/** - * CompartmentCreationOptions specifies options relevant to creating a new - * compartment, that are either immutable characteristics of that compartment - * or that are discarded after the compartment has been created. - * - * Access to these options on an existing compartment is read-only: if you - * need particular selections, make them before you create the compartment. - */ -class JS_PUBLIC_API(CompartmentCreationOptions) -{ - public: - CompartmentCreationOptions() - : addonId_(nullptr), - traceGlobal_(nullptr), - invisibleToDebugger_(false), - mergeable_(false), - preserveJitCode_(false), - cloneSingletons_(false), - sharedMemoryAndAtomics_(false), - secureContext_(false) - { - zone_.spec = JS::FreshZone; - } - - // A null add-on ID means that the compartment is not associated with an - // add-on. - JSAddonId* addonIdOrNull() const { return addonId_; } - CompartmentCreationOptions& setAddonId(JSAddonId* id) { - addonId_ = id; - return *this; - } - - JSTraceOp getTrace() const { - return traceGlobal_; - } - CompartmentCreationOptions& setTrace(JSTraceOp op) { - traceGlobal_ = op; - return *this; - } - - void* zonePointer() const { - MOZ_ASSERT(uintptr_t(zone_.pointer) > uintptr_t(JS::SystemZone)); - return zone_.pointer; - } - ZoneSpecifier zoneSpecifier() const { return zone_.spec; } - CompartmentCreationOptions& setZone(ZoneSpecifier spec); - CompartmentCreationOptions& setSameZoneAs(JSObject* obj); - - // Certain scopes (i.e. XBL compilation scopes) are implementation details - // of the embedding, and references to them should never leak out to script. - // This flag causes the this compartment to skip firing onNewGlobalObject - // and makes addDebuggee a no-op for this global. - bool invisibleToDebugger() const { return invisibleToDebugger_; } - CompartmentCreationOptions& setInvisibleToDebugger(bool flag) { - invisibleToDebugger_ = flag; - return *this; - } - - // Compartments used for off-thread compilation have their contents merged - // into a target compartment when the compilation is finished. This is only - // allowed if this flag is set. The invisibleToDebugger flag must also be - // set for such compartments. - bool mergeable() const { return mergeable_; } - CompartmentCreationOptions& setMergeable(bool flag) { - mergeable_ = flag; - return *this; - } - - // Determines whether this compartment should preserve JIT code on - // non-shrinking GCs. - bool preserveJitCode() const { return preserveJitCode_; } - CompartmentCreationOptions& setPreserveJitCode(bool flag) { - preserveJitCode_ = flag; - return *this; - } - - bool cloneSingletons() const { return cloneSingletons_; } - CompartmentCreationOptions& setCloneSingletons(bool flag) { - cloneSingletons_ = flag; - return *this; - } - - bool getSharedMemoryAndAtomicsEnabled() const; - CompartmentCreationOptions& setSharedMemoryAndAtomicsEnabled(bool flag); - - // This flag doesn't affect JS engine behavior. It is used by Gecko to - // mark whether content windows and workers are "Secure Context"s. See - // https://w3c.github.io/webappsec-secure-contexts/ - // https://bugzilla.mozilla.org/show_bug.cgi?id=1162772#c34 - bool secureContext() const { return secureContext_; } - CompartmentCreationOptions& setSecureContext(bool flag) { - secureContext_ = flag; - return *this; - } - - private: - JSAddonId* addonId_; - JSTraceOp traceGlobal_; - union { - ZoneSpecifier spec; - void* pointer; // js::Zone* is not exposed in the API. - } zone_; - bool invisibleToDebugger_; - bool mergeable_; - bool preserveJitCode_; - bool cloneSingletons_; - bool sharedMemoryAndAtomics_; - bool secureContext_; -}; - -/** - * CompartmentBehaviors specifies behaviors of a compartment that can be - * changed after the compartment's been created. - */ -class JS_PUBLIC_API(CompartmentBehaviors) -{ - public: - class Override { - public: - Override() : mode_(Default) {} - - bool get(bool defaultValue) const { - if (mode_ == Default) - return defaultValue; - return mode_ == ForceTrue; - } - - void set(bool overrideValue) { - mode_ = overrideValue ? ForceTrue : ForceFalse; - } - - void reset() { - mode_ = Default; - } - - private: - enum Mode { - Default, - ForceTrue, - ForceFalse - }; - - Mode mode_; - }; - - CompartmentBehaviors() - : version_(JSVERSION_UNKNOWN) - , discardSource_(false) - , disableLazyParsing_(false) - , singletonsAsTemplates_(true) - { - } - - JSVersion version() const { return version_; } - CompartmentBehaviors& setVersion(JSVersion aVersion) { - MOZ_ASSERT(aVersion != JSVERSION_UNKNOWN); - version_ = aVersion; - return *this; - } - - // For certain globals, we know enough about the code that will run in them - // that we can discard script source entirely. - bool discardSource() const { return discardSource_; } - CompartmentBehaviors& setDiscardSource(bool flag) { - discardSource_ = flag; - return *this; - } - - bool disableLazyParsing() const { return disableLazyParsing_; } - CompartmentBehaviors& setDisableLazyParsing(bool flag) { - disableLazyParsing_ = flag; - return *this; - } - - bool extraWarnings(JSContext* cx) const; - Override& extraWarningsOverride() { return extraWarningsOverride_; } - - bool getSingletonsAsTemplates() const { - return singletonsAsTemplates_; - } - CompartmentBehaviors& setSingletonsAsValues() { - singletonsAsTemplates_ = false; - return *this; - } - - private: - JSVersion version_; - bool discardSource_; - bool disableLazyParsing_; - Override extraWarningsOverride_; - - // To XDR singletons, we need to ensure that all singletons are all used as - // templates, by making JSOP_OBJECT return a clone of the JSScript - // singleton, instead of returning the value which is baked in the JSScript. - bool singletonsAsTemplates_; -}; - -/** - * CompartmentOptions specifies compartment characteristics: both those that - * can't be changed on a compartment once it's been created - * (CompartmentCreationOptions), and those that can be changed on an existing - * compartment (CompartmentBehaviors). - */ -class JS_PUBLIC_API(CompartmentOptions) -{ - public: - explicit CompartmentOptions() - : creationOptions_(), - behaviors_() - {} - - CompartmentOptions(const CompartmentCreationOptions& compartmentCreation, - const CompartmentBehaviors& compartmentBehaviors) - : creationOptions_(compartmentCreation), - behaviors_(compartmentBehaviors) - {} - - // CompartmentCreationOptions specify fundamental compartment - // characteristics that must be specified when the compartment is created, - // that can't be changed after the compartment is created. - CompartmentCreationOptions& creationOptions() { - return creationOptions_; - } - const CompartmentCreationOptions& creationOptions() const { - return creationOptions_; - } - - // CompartmentBehaviors specify compartment characteristics that can be - // changed after the compartment is created. - CompartmentBehaviors& behaviors() { - return behaviors_; - } - const CompartmentBehaviors& behaviors() const { - return behaviors_; - } - - private: - CompartmentCreationOptions creationOptions_; - CompartmentBehaviors behaviors_; -}; - -JS_PUBLIC_API(const CompartmentCreationOptions&) -CompartmentCreationOptionsRef(JSCompartment* compartment); - -JS_PUBLIC_API(const CompartmentCreationOptions&) -CompartmentCreationOptionsRef(JSObject* obj); - -JS_PUBLIC_API(const CompartmentCreationOptions&) -CompartmentCreationOptionsRef(JSContext* cx); - -JS_PUBLIC_API(CompartmentBehaviors&) -CompartmentBehaviorsRef(JSCompartment* compartment); - -JS_PUBLIC_API(CompartmentBehaviors&) -CompartmentBehaviorsRef(JSObject* obj); - -JS_PUBLIC_API(CompartmentBehaviors&) -CompartmentBehaviorsRef(JSContext* cx); - -/** - * During global creation, we fire notifications to callbacks registered - * via the Debugger API. These callbacks are arbitrary script, and can touch - * the global in arbitrary ways. When that happens, the global should not be - * in a half-baked state. But this creates a problem for consumers that need - * to set slots on the global to put it in a consistent state. - * - * This API provides a way for consumers to set slots atomically (immediately - * after the global is created), before any debugger hooks are fired. It's - * unfortunately on the clunky side, but that's the way the cookie crumbles. - * - * If callers have no additional state on the global to set up, they may pass - * |FireOnNewGlobalHook| to JS_NewGlobalObject, which causes that function to - * fire the hook as its final act before returning. Otherwise, callers should - * pass |DontFireOnNewGlobalHook|, which means that they are responsible for - * invoking JS_FireOnNewGlobalObject upon successfully creating the global. If - * an error occurs and the operation aborts, callers should skip firing the - * hook. But otherwise, callers must take care to fire the hook exactly once - * before compiling any script in the global's scope (we have assertions in - * place to enforce this). This lets us be sure that debugger clients never miss - * breakpoints. - */ -enum OnNewGlobalHookOption { - FireOnNewGlobalHook, - DontFireOnNewGlobalHook -}; - -} /* namespace JS */ - -extern JS_PUBLIC_API(JSObject*) -JS_NewGlobalObject(JSContext* cx, const JSClass* clasp, JSPrincipals* principals, - JS::OnNewGlobalHookOption hookOption, - const JS::CompartmentOptions& options); -/** - * Spidermonkey does not have a good way of keeping track of what compartments should be marked on - * their own. We can mark the roots unconditionally, but marking GC things only relevant in live - * compartments is hard. To mitigate this, we create a static trace hook, installed on each global - * object, from which we can be sure the compartment is relevant, and mark it. - * - * It is still possible to specify custom trace hooks for global object classes. They can be - * provided via the CompartmentOptions passed to JS_NewGlobalObject. - */ -extern JS_PUBLIC_API(void) -JS_GlobalObjectTraceHook(JSTracer* trc, JSObject* global); - -extern JS_PUBLIC_API(void) -JS_FireOnNewGlobalObject(JSContext* cx, JS::HandleObject global); - -extern JS_PUBLIC_API(JSObject*) -JS_NewObject(JSContext* cx, const JSClass* clasp); - -extern JS_PUBLIC_API(bool) -JS_IsNative(JSObject* obj); - -/** - * Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default - * proto. If proto is nullptr, the JS object will have `null` as [[Prototype]]. - */ -extern JS_PUBLIC_API(JSObject*) -JS_NewObjectWithGivenProto(JSContext* cx, const JSClass* clasp, JS::Handle proto); - -/** Creates a new plain object, like `new Object()`, with Object.prototype as [[Prototype]]. */ -extern JS_PUBLIC_API(JSObject*) -JS_NewPlainObject(JSContext* cx); - -/** - * Freeze obj, and all objects it refers to, recursively. This will not recurse - * through non-extensible objects, on the assumption that those are already - * deep-frozen. - */ -extern JS_PUBLIC_API(bool) -JS_DeepFreezeObject(JSContext* cx, JS::Handle obj); - -/** - * Freezes an object; see ES5's Object.freeze(obj) method. - */ -extern JS_PUBLIC_API(bool) -JS_FreezeObject(JSContext* cx, JS::Handle obj); - - -/*** Property descriptors ************************************************************************/ - -namespace JS { - -struct JS_PUBLIC_API(PropertyDescriptor) { - JSObject* obj; - unsigned attrs; - JSGetterOp getter; - JSSetterOp setter; - JS::Value value; - - PropertyDescriptor() - : obj(nullptr), attrs(0), getter(nullptr), setter(nullptr), value(JS::UndefinedValue()) - {} - - static void trace(PropertyDescriptor* self, JSTracer* trc) { self->trace(trc); } - void trace(JSTracer* trc); -}; - -template -class PropertyDescriptorOperations -{ - const PropertyDescriptor& desc() const { return static_cast(this)->get(); } - - bool has(unsigned bit) const { - MOZ_ASSERT(bit != 0); - MOZ_ASSERT((bit & (bit - 1)) == 0); // only a single bit - return (desc().attrs & bit) != 0; - } - - bool hasAny(unsigned bits) const { - return (desc().attrs & bits) != 0; - } - - bool hasAll(unsigned bits) const { - return (desc().attrs & bits) == bits; - } - - // Non-API attributes bit used internally for arguments objects. - enum { SHADOWABLE = JSPROP_INTERNAL_USE_BIT }; - - public: - // Descriptors with JSGetterOp/JSSetterOp are considered data - // descriptors. It's complicated. - bool isAccessorDescriptor() const { return hasAny(JSPROP_GETTER | JSPROP_SETTER); } - bool isGenericDescriptor() const { - return (desc().attrs& - (JSPROP_GETTER | JSPROP_SETTER | JSPROP_IGNORE_READONLY | JSPROP_IGNORE_VALUE)) == - (JSPROP_IGNORE_READONLY | JSPROP_IGNORE_VALUE); - } - bool isDataDescriptor() const { return !isAccessorDescriptor() && !isGenericDescriptor(); } - - bool hasConfigurable() const { return !has(JSPROP_IGNORE_PERMANENT); } - bool configurable() const { MOZ_ASSERT(hasConfigurable()); return !has(JSPROP_PERMANENT); } - - bool hasEnumerable() const { return !has(JSPROP_IGNORE_ENUMERATE); } - bool enumerable() const { MOZ_ASSERT(hasEnumerable()); return has(JSPROP_ENUMERATE); } - - bool hasValue() const { return !isAccessorDescriptor() && !has(JSPROP_IGNORE_VALUE); } - JS::HandleValue value() const { - return JS::HandleValue::fromMarkedLocation(&desc().value); - } - - bool hasWritable() const { return !isAccessorDescriptor() && !has(JSPROP_IGNORE_READONLY); } - bool writable() const { MOZ_ASSERT(hasWritable()); return !has(JSPROP_READONLY); } - - bool hasGetterObject() const { return has(JSPROP_GETTER); } - JS::HandleObject getterObject() const { - MOZ_ASSERT(hasGetterObject()); - return JS::HandleObject::fromMarkedLocation( - reinterpret_cast(&desc().getter)); - } - bool hasSetterObject() const { return has(JSPROP_SETTER); } - JS::HandleObject setterObject() const { - MOZ_ASSERT(hasSetterObject()); - return JS::HandleObject::fromMarkedLocation( - reinterpret_cast(&desc().setter)); - } - - bool hasGetterOrSetter() const { return desc().getter || desc().setter; } - bool isShared() const { return has(JSPROP_SHARED); } - - JS::HandleObject object() const { - return JS::HandleObject::fromMarkedLocation(&desc().obj); - } - unsigned attributes() const { return desc().attrs; } - JSGetterOp getter() const { return desc().getter; } - JSSetterOp setter() const { return desc().setter; } - - void assertValid() const { -#ifdef DEBUG - MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE | JSPROP_IGNORE_ENUMERATE | - JSPROP_PERMANENT | JSPROP_IGNORE_PERMANENT | - JSPROP_READONLY | JSPROP_IGNORE_READONLY | - JSPROP_IGNORE_VALUE | - JSPROP_GETTER | - JSPROP_SETTER | - JSPROP_SHARED | - JSPROP_REDEFINE_NONCONFIGURABLE | - JSPROP_RESOLVING | - SHADOWABLE)) == 0); - MOZ_ASSERT(!hasAll(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE)); - MOZ_ASSERT(!hasAll(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT)); - if (isAccessorDescriptor()) { - MOZ_ASSERT(has(JSPROP_SHARED)); - MOZ_ASSERT(!has(JSPROP_READONLY)); - MOZ_ASSERT(!has(JSPROP_IGNORE_READONLY)); - MOZ_ASSERT(!has(JSPROP_IGNORE_VALUE)); - MOZ_ASSERT(!has(SHADOWABLE)); - MOZ_ASSERT(value().isUndefined()); - MOZ_ASSERT_IF(!has(JSPROP_GETTER), !getter()); - MOZ_ASSERT_IF(!has(JSPROP_SETTER), !setter()); - } else { - MOZ_ASSERT(!hasAll(JSPROP_IGNORE_READONLY | JSPROP_READONLY)); - MOZ_ASSERT_IF(has(JSPROP_IGNORE_VALUE), value().isUndefined()); - } - MOZ_ASSERT(getter() != JS_PropertyStub); - MOZ_ASSERT(setter() != JS_StrictPropertyStub); - - MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_ENUMERATE)); - MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_PERMANENT)); - MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_READONLY)); - MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_VALUE)); - MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_REDEFINE_NONCONFIGURABLE)); -#endif - } - - void assertComplete() const { -#ifdef DEBUG - assertValid(); - MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE | - JSPROP_PERMANENT | - JSPROP_READONLY | - JSPROP_GETTER | - JSPROP_SETTER | - JSPROP_SHARED | - JSPROP_REDEFINE_NONCONFIGURABLE | - JSPROP_RESOLVING | - SHADOWABLE)) == 0); - MOZ_ASSERT_IF(isAccessorDescriptor(), has(JSPROP_GETTER) && has(JSPROP_SETTER)); -#endif - } - - void assertCompleteIfFound() const { -#ifdef DEBUG - if (object()) - assertComplete(); -#endif - } -}; - -template -class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations -{ - PropertyDescriptor& desc() { return static_cast(this)->get(); } - - public: - void clear() { - object().set(nullptr); - setAttributes(0); - setGetter(nullptr); - setSetter(nullptr); - value().setUndefined(); - } - - void initFields(HandleObject obj, HandleValue v, unsigned attrs, - JSGetterOp getterOp, JSSetterOp setterOp) { - MOZ_ASSERT(getterOp != JS_PropertyStub); - MOZ_ASSERT(setterOp != JS_StrictPropertyStub); - - object().set(obj); - value().set(v); - setAttributes(attrs); - setGetter(getterOp); - setSetter(setterOp); - } - - void assign(PropertyDescriptor& other) { - object().set(other.obj); - setAttributes(other.attrs); - setGetter(other.getter); - setSetter(other.setter); - value().set(other.value); - } - - void setDataDescriptor(HandleValue v, unsigned attrs) { - MOZ_ASSERT((attrs & ~(JSPROP_ENUMERATE | - JSPROP_PERMANENT | - JSPROP_READONLY | - JSPROP_IGNORE_ENUMERATE | - JSPROP_IGNORE_PERMANENT | - JSPROP_IGNORE_READONLY)) == 0); - object().set(nullptr); - setAttributes(attrs); - setGetter(nullptr); - setSetter(nullptr); - value().set(v); - } - - JS::MutableHandleObject object() { - return JS::MutableHandleObject::fromMarkedLocation(&desc().obj); - } - unsigned& attributesRef() { return desc().attrs; } - JSGetterOp& getter() { return desc().getter; } - JSSetterOp& setter() { return desc().setter; } - JS::MutableHandleValue value() { - return JS::MutableHandleValue::fromMarkedLocation(&desc().value); - } - void setValue(JS::HandleValue v) { - MOZ_ASSERT(!(desc().attrs & (JSPROP_GETTER | JSPROP_SETTER))); - attributesRef() &= ~JSPROP_IGNORE_VALUE; - value().set(v); - } - - void setConfigurable(bool configurable) { - setAttributes((desc().attrs & ~(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT)) | - (configurable ? 0 : JSPROP_PERMANENT)); - } - void setEnumerable(bool enumerable) { - setAttributes((desc().attrs & ~(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE)) | - (enumerable ? JSPROP_ENUMERATE : 0)); - } - void setWritable(bool writable) { - MOZ_ASSERT(!(desc().attrs & (JSPROP_GETTER | JSPROP_SETTER))); - setAttributes((desc().attrs & ~(JSPROP_IGNORE_READONLY | JSPROP_READONLY)) | - (writable ? 0 : JSPROP_READONLY)); - } - void setAttributes(unsigned attrs) { desc().attrs = attrs; } - - void setGetter(JSGetterOp op) { - MOZ_ASSERT(op != JS_PropertyStub); - desc().getter = op; - } - void setSetter(JSSetterOp op) { - MOZ_ASSERT(op != JS_StrictPropertyStub); - desc().setter = op; - } - void setGetterObject(JSObject* obj) { - desc().getter = reinterpret_cast(obj); - desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY); - desc().attrs |= JSPROP_GETTER | JSPROP_SHARED; - } - void setSetterObject(JSObject* obj) { - desc().setter = reinterpret_cast(obj); - desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY); - desc().attrs |= JSPROP_SETTER | JSPROP_SHARED; - } - - JS::MutableHandleObject getterObject() { - MOZ_ASSERT(this->hasGetterObject()); - return JS::MutableHandleObject::fromMarkedLocation( - reinterpret_cast(&desc().getter)); - } - JS::MutableHandleObject setterObject() { - MOZ_ASSERT(this->hasSetterObject()); - return JS::MutableHandleObject::fromMarkedLocation( - reinterpret_cast(&desc().setter)); - } -}; - -} /* namespace JS */ - -namespace js { - -template <> -class RootedBase - : public JS::MutablePropertyDescriptorOperations> -{}; - -template <> -class HandleBase - : public JS::PropertyDescriptorOperations> -{}; - -template <> -class MutableHandleBase - : public JS::MutablePropertyDescriptorOperations> -{}; - -} /* namespace js */ - -namespace JS { - -extern JS_PUBLIC_API(bool) -ObjectToCompletePropertyDescriptor(JSContext* cx, - JS::HandleObject obj, - JS::HandleValue descriptor, - JS::MutableHandle desc); - -/* - * ES6 draft rev 32 (2015 Feb 2) 6.2.4.4 FromPropertyDescriptor(Desc). - * - * If desc.object() is null, then vp is set to undefined. - */ -extern JS_PUBLIC_API(bool) -FromPropertyDescriptor(JSContext* cx, - JS::Handle desc, - JS::MutableHandleValue vp); - -} // namespace JS - - -/*** Standard internal methods ******************************************************************** - * - * The functions below are the fundamental operations on objects. - * - * ES6 specifies 14 internal methods that define how objects behave. The - * standard is actually quite good on this topic, though you may have to read - * it a few times. See ES6 sections 6.1.7.2 and 6.1.7.3. - * - * When 'obj' is an ordinary object, these functions have boring standard - * behavior as specified by ES6 section 9.1; see the section about internal - * methods in js/src/vm/NativeObject.h. - * - * Proxies override the behavior of internal methods. So when 'obj' is a proxy, - * any one of the functions below could do just about anything. See - * js/public/Proxy.h. - */ - -/** - * Get the prototype of obj, storing it in result. - * - * Implements: ES6 [[GetPrototypeOf]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_GetPrototype(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject result); - -/** - * If |obj| (underneath any functionally-transparent wrapper proxies) has as - * its [[GetPrototypeOf]] trap the ordinary [[GetPrototypeOf]] behavior defined - * for ordinary objects, set |*isOrdinary = true| and store |obj|'s prototype - * in |result|. Otherwise set |*isOrdinary = false|. In case of error, both - * outparams have unspecified value. - */ -extern JS_PUBLIC_API(bool) -JS_GetPrototypeIfOrdinary(JSContext* cx, JS::HandleObject obj, bool* isOrdinary, - JS::MutableHandleObject result); - -/** - * Change the prototype of obj. - * - * Implements: ES6 [[SetPrototypeOf]] internal method. - * - * In cases where ES6 [[SetPrototypeOf]] returns false without an exception, - * JS_SetPrototype throws a TypeError and returns false. - * - * Performance warning: JS_SetPrototype is very bad for performance. It may - * cause compiled jit-code to be invalidated. It also causes not only obj but - * all other objects in the same "group" as obj to be permanently deoptimized. - * It's better to create the object with the right prototype from the start. - */ -extern JS_PUBLIC_API(bool) -JS_SetPrototype(JSContext* cx, JS::HandleObject obj, JS::HandleObject proto); - -/** - * Determine whether obj is extensible. Extensible objects can have new - * properties defined on them. Inextensible objects can't, and their - * [[Prototype]] slot is fixed as well. - * - * Implements: ES6 [[IsExtensible]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_IsExtensible(JSContext* cx, JS::HandleObject obj, bool* extensible); - -/** - * Attempt to make |obj| non-extensible. - * - * Not all failures are treated as errors. See the comment on - * JS::ObjectOpResult in js/public/Class.h. - * - * Implements: ES6 [[PreventExtensions]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_PreventExtensions(JSContext* cx, JS::HandleObject obj, JS::ObjectOpResult& result); - -/** - * Attempt to make the [[Prototype]] of |obj| immutable, such that any attempt - * to modify it will fail. If an error occurs during the attempt, return false - * (with a pending exception set, depending upon the nature of the error). If - * no error occurs, return true with |*succeeded| set to indicate whether the - * attempt successfully made the [[Prototype]] immutable. - * - * This is a nonstandard internal method. - */ -extern JS_PUBLIC_API(bool) -JS_SetImmutablePrototype(JSContext* cx, JS::HandleObject obj, bool* succeeded); - -/** - * Get a description of one of obj's own properties. If no such property exists - * on obj, return true with desc.object() set to null. - * - * Implements: ES6 [[GetOwnProperty]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_GetOwnPropertyDescriptorById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandle desc); - -extern JS_PUBLIC_API(bool) -JS_GetOwnPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* name, - JS::MutableHandle desc); - -extern JS_PUBLIC_API(bool) -JS_GetOwnUCPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char16_t* name, - JS::MutableHandle desc); - -/** - * Like JS_GetOwnPropertyDescriptorById, but also searches the prototype chain - * if no own property is found directly on obj. The object on which the - * property is found is returned in desc.object(). If the property is not found - * on the prototype chain, this returns true with desc.object() set to null. - */ -extern JS_PUBLIC_API(bool) -JS_GetPropertyDescriptorById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandle desc); - -extern JS_PUBLIC_API(bool) -JS_GetPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* name, - JS::MutableHandle desc); - -/** - * Define a property on obj. - * - * This function uses JS::ObjectOpResult to indicate conditions that ES6 - * specifies as non-error failures. This is inconvenient at best, so use this - * function only if you are implementing a proxy handler's defineProperty() - * method. For all other purposes, use one of the many DefineProperty functions - * below that throw an exception in all failure cases. - * - * Implements: ES6 [[DefineOwnProperty]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::Handle desc, - JS::ObjectOpResult& result); - -/** - * Define a property on obj, throwing a TypeError if the attempt fails. - * This is the C++ equivalent of `Object.defineProperty(obj, id, desc)`. - */ -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::Handle desc); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleString value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, int32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, uint32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, double value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleValue value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleObject value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleString value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, int32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, uint32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, double value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::Handle desc, - JS::ObjectOpResult& result); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::Handle desc); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::HandleValue value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::HandleObject value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::HandleString value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - int32_t value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - uint32_t value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - double value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleObject value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleString value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, int32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, uint32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, double value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -/** - * Compute the expression `id in obj`. - * - * If obj has an own or inherited property obj[id], set *foundp = true and - * return true. If not, set *foundp = false and return true. On error, return - * false with an exception pending. - * - * Implements: ES6 [[Has]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_HasPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_HasProperty(JSContext* cx, JS::HandleObject obj, const char* name, bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_HasUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - bool* vp); - -extern JS_PUBLIC_API(bool) -JS_HasElement(JSContext* cx, JS::HandleObject obj, uint32_t index, bool* foundp); - -/** - * Determine whether obj has an own property with the key `id`. - * - * Implements: ES6 7.3.11 HasOwnProperty(O, P). - */ -extern JS_PUBLIC_API(bool) -JS_HasOwnPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_HasOwnProperty(JSContext* cx, JS::HandleObject obj, const char* name, bool* foundp); - -/** - * Get the value of the property `obj[id]`, or undefined if no such property - * exists. This is the C++ equivalent of `vp = Reflect.get(obj, id, receiver)`. - * - * Most callers don't need the `receiver` argument. Consider using - * JS_GetProperty instead. (But if you're implementing a proxy handler's set() - * method, it's often correct to call this function and pass the receiver - * through.) - * - * Implements: ES6 [[Get]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_ForwardGetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::HandleValue receiver, JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(bool) -JS_ForwardGetElementTo(JSContext* cx, JS::HandleObject obj, uint32_t index, - JS::HandleObject receiver, JS::MutableHandleValue vp); - -/** - * Get the value of the property `obj[id]`, or undefined if no such property - * exists. The result is stored in vp. - * - * Implements: ES6 7.3.1 Get(O, P). - */ -extern JS_PUBLIC_API(bool) -JS_GetPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(bool) -JS_GetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(bool) -JS_GetUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(bool) -JS_GetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp); - -/** - * Perform the same property assignment as `Reflect.set(obj, id, v, receiver)`. - * - * This function has a `receiver` argument that most callers don't need. - * Consider using JS_SetProperty instead. - * - * Implements: ES6 [[Set]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_ForwardSetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v, - JS::HandleValue receiver, JS::ObjectOpResult& result); - -/** - * Perform the assignment `obj[id] = v`. - * - * This function performs non-strict assignment, so if the property is - * read-only, nothing happens and no error is thrown. - */ -extern JS_PUBLIC_API(bool) -JS_SetPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v); - -extern JS_PUBLIC_API(bool) -JS_SetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleValue v); - -extern JS_PUBLIC_API(bool) -JS_SetUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::HandleValue v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleValue v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleObject v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleString v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, int32_t v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, uint32_t v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, double v); - -/** - * Delete a property. This is the C++ equivalent of - * `result = Reflect.deleteProperty(obj, id)`. - * - * This function has a `result` out parameter that most callers don't need. - * Unless you can pass through an ObjectOpResult provided by your caller, it's - * probably best to use the JS_DeletePropertyById signature with just 3 - * arguments. - * - * Implements: ES6 [[Delete]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_DeletePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::ObjectOpResult& result); - -extern JS_PUBLIC_API(bool) -JS_DeleteProperty(JSContext* cx, JS::HandleObject obj, const char* name, - JS::ObjectOpResult& result); - -extern JS_PUBLIC_API(bool) -JS_DeleteUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::ObjectOpResult& result); - -extern JS_PUBLIC_API(bool) -JS_DeleteElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::ObjectOpResult& result); - -/** - * Delete a property, ignoring strict failures. This is the C++ equivalent of - * the JS `delete obj[id]` in non-strict mode code. - */ -extern JS_PUBLIC_API(bool) -JS_DeletePropertyById(JSContext* cx, JS::HandleObject obj, jsid id); - -extern JS_PUBLIC_API(bool) -JS_DeleteProperty(JSContext* cx, JS::HandleObject obj, const char* name); - -extern JS_PUBLIC_API(bool) -JS_DeleteElement(JSContext* cx, JS::HandleObject obj, uint32_t index); - -/** - * Get an array of the non-symbol enumerable properties of obj. - * This function is roughly equivalent to: - * - * var result = []; - * for (key in obj) - * result.push(key); - * return result; - * - * This is the closest thing we currently have to the ES6 [[Enumerate]] - * internal method. - * - * The array of ids returned by JS_Enumerate must be rooted to protect its - * contents from garbage collection. Use JS::Rooted. - */ -extern JS_PUBLIC_API(bool) -JS_Enumerate(JSContext* cx, JS::HandleObject obj, JS::MutableHandle props); - -/* - * API for determining callability and constructability. [[Call]] and - * [[Construct]] are internal methods that aren't present on all objects, so it - * is useful to ask if they are there or not. The standard itself asks these - * questions routinely. - */ -namespace JS { - -/** - * Return true if the given object is callable. In ES6 terms, an object is - * callable if it has a [[Call]] internal method. - * - * Implements: ES6 7.2.3 IsCallable(argument). - * - * Functions are callable. A scripted proxy or wrapper is callable if its - * target is callable. Most other objects aren't callable. - */ -extern JS_PUBLIC_API(bool) -IsCallable(JSObject* obj); - -/** - * Return true if the given object is a constructor. In ES6 terms, an object is - * a constructor if it has a [[Construct]] internal method. The expression - * `new obj()` throws a TypeError if obj is not a constructor. - * - * Implements: ES6 7.2.4 IsConstructor(argument). - * - * JS functions and classes are constructors. Arrow functions and most builtin - * functions are not. A scripted proxy or wrapper is a constructor if its - * target is a constructor. - */ -extern JS_PUBLIC_API(bool) -IsConstructor(JSObject* obj); - -} /* namespace JS */ - -/** - * Call a function, passing a this-value and arguments. This is the C++ - * equivalent of `rval = Reflect.apply(fun, obj, args)`. - * - * Implements: ES6 7.3.12 Call(F, V, [argumentsList]). - * Use this function to invoke the [[Call]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_CallFunctionValue(JSContext* cx, JS::HandleObject obj, JS::HandleValue fval, - const JS::HandleValueArray& args, JS::MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -JS_CallFunction(JSContext* cx, JS::HandleObject obj, JS::HandleFunction fun, - const JS::HandleValueArray& args, JS::MutableHandleValue rval); - -/** - * Perform the method call `rval = obj[name](args)`. - */ -extern JS_PUBLIC_API(bool) -JS_CallFunctionName(JSContext* cx, JS::HandleObject obj, const char* name, - const JS::HandleValueArray& args, JS::MutableHandleValue rval); - -namespace JS { - -static inline bool -Call(JSContext* cx, JS::HandleObject thisObj, JS::HandleFunction fun, - const JS::HandleValueArray& args, MutableHandleValue rval) -{ - return !!JS_CallFunction(cx, thisObj, fun, args, rval); -} - -static inline bool -Call(JSContext* cx, JS::HandleObject thisObj, JS::HandleValue fun, const JS::HandleValueArray& args, - MutableHandleValue rval) -{ - return !!JS_CallFunctionValue(cx, thisObj, fun, args, rval); -} - -static inline bool -Call(JSContext* cx, JS::HandleObject thisObj, const char* name, const JS::HandleValueArray& args, - MutableHandleValue rval) -{ - return !!JS_CallFunctionName(cx, thisObj, name, args, rval); -} - -extern JS_PUBLIC_API(bool) -Call(JSContext* cx, JS::HandleValue thisv, JS::HandleValue fun, const JS::HandleValueArray& args, - MutableHandleValue rval); - -static inline bool -Call(JSContext* cx, JS::HandleValue thisv, JS::HandleObject funObj, const JS::HandleValueArray& args, - MutableHandleValue rval) -{ - MOZ_ASSERT(funObj); - JS::RootedValue fun(cx, JS::ObjectValue(*funObj)); - return Call(cx, thisv, fun, args, rval); -} - -/** - * Invoke a constructor. This is the C++ equivalent of - * `rval = Reflect.construct(fun, args, newTarget)`. - * - * JS::Construct() takes a `newTarget` argument that most callers don't need. - * Consider using the four-argument Construct signature instead. (But if you're - * implementing a subclass or a proxy handler's construct() method, this is the - * right function to call.) - * - * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]). - * Use this function to invoke the [[Construct]] internal method. - */ -extern JS_PUBLIC_API(bool) -Construct(JSContext* cx, JS::HandleValue fun, HandleObject newTarget, - const JS::HandleValueArray &args, MutableHandleObject objp); - -/** - * Invoke a constructor. This is the C++ equivalent of - * `rval = new fun(...args)`. - * - * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]), when - * newTarget is omitted. - */ -extern JS_PUBLIC_API(bool) -Construct(JSContext* cx, JS::HandleValue fun, const JS::HandleValueArray& args, - MutableHandleObject objp); - -} /* namespace JS */ - -/** - * Invoke a constructor, like the JS expression `new ctor(...args)`. Returns - * the new object, or null on error. - */ -extern JS_PUBLIC_API(JSObject*) -JS_New(JSContext* cx, JS::HandleObject ctor, const JS::HandleValueArray& args); - - -/*** Other property-defining functions ***********************************************************/ - -extern JS_PUBLIC_API(JSObject*) -JS_DefineObject(JSContext* cx, JS::HandleObject obj, const char* name, - const JSClass* clasp = nullptr, unsigned attrs = 0); - -extern JS_PUBLIC_API(bool) -JS_DefineConstDoubles(JSContext* cx, JS::HandleObject obj, const JSConstDoubleSpec* cds); - -extern JS_PUBLIC_API(bool) -JS_DefineConstIntegers(JSContext* cx, JS::HandleObject obj, const JSConstIntegerSpec* cis); - -extern JS_PUBLIC_API(bool) -JS_DefineProperties(JSContext* cx, JS::HandleObject obj, const JSPropertySpec* ps); - - -/* * */ - -extern JS_PUBLIC_API(bool) -JS_AlreadyHasOwnPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_AlreadyHasOwnProperty(JSContext* cx, JS::HandleObject obj, const char* name, - bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_AlreadyHasOwnUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, - size_t namelen, bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_AlreadyHasOwnElement(JSContext* cx, JS::HandleObject obj, uint32_t index, bool* foundp); - -extern JS_PUBLIC_API(JSObject*) -JS_NewArrayObject(JSContext* cx, const JS::HandleValueArray& contents); - -extern JS_PUBLIC_API(JSObject*) -JS_NewArrayObject(JSContext* cx, size_t length); - -/** - * Returns true and sets |*isArray| indicating whether |value| is an Array - * object or a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isArray == false| when passed a proxy whose - * target is an Array, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -JS_IsArrayObject(JSContext* cx, JS::HandleValue value, bool* isArray); - -/** - * Returns true and sets |*isArray| indicating whether |obj| is an Array object - * or a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isArray == false| when passed a proxy whose - * target is an Array, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -JS_IsArrayObject(JSContext* cx, JS::HandleObject obj, bool* isArray); - -extern JS_PUBLIC_API(bool) -JS_GetArrayLength(JSContext* cx, JS::Handle obj, uint32_t* lengthp); - -extern JS_PUBLIC_API(bool) -JS_SetArrayLength(JSContext* cx, JS::Handle obj, uint32_t length); - -namespace JS { - -/** - * Returns true and sets |*isMap| indicating whether |obj| is an Map object - * or a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isMap == false| when passed a proxy whose - * target is an Map, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -IsMapObject(JSContext* cx, JS::HandleObject obj, bool* isMap); - -/** - * Returns true and sets |*isSet| indicating whether |obj| is an Set object - * or a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isSet == false| when passed a proxy whose - * target is an Set, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -IsSetObject(JSContext* cx, JS::HandleObject obj, bool* isSet); - -} /* namespace JS */ - -/** - * Assign 'undefined' to all of the object's non-reserved slots. Note: this is - * done for all slots, regardless of the associated property descriptor. - */ -JS_PUBLIC_API(void) -JS_SetAllNonReservedSlotsToUndefined(JSContext* cx, JSObject* objArg); - -/** - * Create a new array buffer with the given contents. It must be legal to pass - * these contents to free(). On success, the ownership is transferred to the - * new array buffer. - */ -extern JS_PUBLIC_API(JSObject*) -JS_NewArrayBufferWithContents(JSContext* cx, size_t nbytes, void* contents); - -/** - * Create a new array buffer with the given contents. The array buffer does not take ownership of - * contents, and JS_DetachArrayBuffer must be called before the contents are disposed of. - */ -extern JS_PUBLIC_API(JSObject*) -JS_NewArrayBufferWithExternalContents(JSContext* cx, size_t nbytes, void* contents); - -/** - * Steal the contents of the given array buffer. The array buffer has its - * length set to 0 and its contents array cleared. The caller takes ownership - * of the return value and must free it or transfer ownership via - * JS_NewArrayBufferWithContents when done using it. - */ -extern JS_PUBLIC_API(void*) -JS_StealArrayBufferContents(JSContext* cx, JS::HandleObject obj); - -/** - * Returns a pointer to the ArrayBuffer |obj|'s data. |obj| and its views will store and expose - * the data in the returned pointer: assigning into the returned pointer will affect values exposed - * by views of |obj| and vice versa. - * - * The caller must ultimately deallocate the returned pointer to avoid leaking. The memory is - * *not* garbage-collected with |obj|. These steps must be followed to deallocate: - * - * 1. The ArrayBuffer |obj| must be detached using JS_DetachArrayBuffer. - * 2. The returned pointer must be freed using JS_free. - * - * To perform step 1, callers *must* hold a reference to |obj| until they finish using the returned - * pointer. They *must not* attempt to let |obj| be GC'd, then JS_free the pointer. - * - * If |obj| isn't an ArrayBuffer, this function returns null and reports an error. - */ -extern JS_PUBLIC_API(void*) -JS_ExternalizeArrayBufferContents(JSContext* cx, JS::HandleObject obj); - -/** - * Create a new mapped array buffer with the given memory mapped contents. It - * must be legal to free the contents pointer by unmapping it. On success, - * ownership is transferred to the new mapped array buffer. - */ -extern JS_PUBLIC_API(JSObject*) -JS_NewMappedArrayBufferWithContents(JSContext* cx, size_t nbytes, void* contents); - -/** - * Create memory mapped array buffer contents. - * Caller must take care of closing fd after calling this function. - */ -extern JS_PUBLIC_API(void*) -JS_CreateMappedArrayBufferContents(int fd, size_t offset, size_t length); - -/** - * Release the allocated resource of mapped array buffer contents before the - * object is created. - * If a new object has been created by JS_NewMappedArrayBufferWithContents() - * with this content, then JS_DetachArrayBuffer() should be used instead to - * release the resource used by the object. - */ -extern JS_PUBLIC_API(void) -JS_ReleaseMappedArrayBufferContents(void* contents, size_t length); - -extern JS_PUBLIC_API(JS::Value) -JS_GetReservedSlot(JSObject* obj, uint32_t index); - -extern JS_PUBLIC_API(void) -JS_SetReservedSlot(JSObject* obj, uint32_t index, const JS::Value& v); - - -/************************************************************************/ - -/* - * Functions and scripts. - */ -extern JS_PUBLIC_API(JSFunction*) -JS_NewFunction(JSContext* cx, JSNative call, unsigned nargs, unsigned flags, - const char* name); - -namespace JS { - -extern JS_PUBLIC_API(JSFunction*) -GetSelfHostedFunction(JSContext* cx, const char* selfHostedName, HandleId id, - unsigned nargs); - -/** - * Create a new function based on the given JSFunctionSpec, *fs. - * id is the result of a successful call to - * `PropertySpecNameToPermanentId(cx, fs->name, &id)`. - * - * Unlike JS_DefineFunctions, this does not treat fs as an array. - * *fs must not be JS_FS_END. - */ -extern JS_PUBLIC_API(JSFunction*) -NewFunctionFromSpec(JSContext* cx, const JSFunctionSpec* fs, HandleId id); - -} /* namespace JS */ - -extern JS_PUBLIC_API(JSObject*) -JS_GetFunctionObject(JSFunction* fun); - -/** - * Return the function's identifier as a JSString, or null if fun is unnamed. - * The returned string lives as long as fun, so you don't need to root a saved - * reference to it if fun is well-connected or rooted, and provided you bound - * the use of the saved reference by fun's lifetime. - */ -extern JS_PUBLIC_API(JSString*) -JS_GetFunctionId(JSFunction* fun); - -/** - * Return a function's display name. This is the defined name if one was given - * where the function was defined, or it could be an inferred name by the JS - * engine in the case that the function was defined to be anonymous. This can - * still return nullptr if a useful display name could not be inferred. The - * same restrictions on rooting as those in JS_GetFunctionId apply. - */ -extern JS_PUBLIC_API(JSString*) -JS_GetFunctionDisplayId(JSFunction* fun); - -/* - * Return the arity (length) of fun. - */ -extern JS_PUBLIC_API(uint16_t) -JS_GetFunctionArity(JSFunction* fun); - -/** - * Infallible predicate to test whether obj is a function object (faster than - * comparing obj's class name to "Function", but equivalent unless someone has - * overwritten the "Function" identifier with a different constructor and then - * created instances using that constructor that might be passed in as obj). - */ -extern JS_PUBLIC_API(bool) -JS_ObjectIsFunction(JSContext* cx, JSObject* obj); - -extern JS_PUBLIC_API(bool) -JS_IsNativeFunction(JSObject* funobj, JSNative call); - -/** Return whether the given function is a valid constructor. */ -extern JS_PUBLIC_API(bool) -JS_IsConstructor(JSFunction* fun); - -extern JS_PUBLIC_API(bool) -JS_DefineFunctions(JSContext* cx, JS::Handle obj, const JSFunctionSpec* fs); - -extern JS_PUBLIC_API(JSFunction*) -JS_DefineFunction(JSContext* cx, JS::Handle obj, const char* name, JSNative call, - unsigned nargs, unsigned attrs); - -extern JS_PUBLIC_API(JSFunction*) -JS_DefineUCFunction(JSContext* cx, JS::Handle obj, - const char16_t* name, size_t namelen, JSNative call, - unsigned nargs, unsigned attrs); - -extern JS_PUBLIC_API(JSFunction*) -JS_DefineFunctionById(JSContext* cx, JS::Handle obj, JS::Handle id, JSNative call, - unsigned nargs, unsigned attrs); - -extern JS_PUBLIC_API(bool) -JS_IsFunctionBound(JSFunction* fun); - -extern JS_PUBLIC_API(JSObject*) -JS_GetBoundFunctionTarget(JSFunction* fun); - -namespace JS { - -/** - * Clone a top-level function into cx's global. This function will dynamically - * fail if funobj was lexically nested inside some other function. - */ -extern JS_PUBLIC_API(JSObject*) -CloneFunctionObject(JSContext* cx, HandleObject funobj); - -/** - * As above, but providing an explicit scope chain. scopeChain must not include - * the global object on it; that's implicit. It needs to contain the other - * objects that should end up on the clone's scope chain. - */ -extern JS_PUBLIC_API(JSObject*) -CloneFunctionObject(JSContext* cx, HandleObject funobj, AutoObjectVector& scopeChain); - -} // namespace JS - -/** - * Given a buffer, return false if the buffer might become a valid - * javascript statement with the addition of more lines. Otherwise return - * true. The intent is to support interactive compilation - accumulate - * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to - * the compiler. - */ -extern JS_PUBLIC_API(bool) -JS_BufferIsCompilableUnit(JSContext* cx, JS::Handle obj, const char* utf8, - size_t length); - -/** - * |script| will always be set. On failure, it will be set to nullptr. - */ -extern JS_PUBLIC_API(bool) -JS_CompileScript(JSContext* cx, const char* ascii, size_t length, - const JS::CompileOptions& options, - JS::MutableHandleScript script); - -/** - * |script| will always be set. On failure, it will be set to nullptr. - */ -extern JS_PUBLIC_API(bool) -JS_CompileUCScript(JSContext* cx, const char16_t* chars, size_t length, - const JS::CompileOptions& options, - JS::MutableHandleScript script); - -extern JS_PUBLIC_API(JSObject*) -JS_GetGlobalFromScript(JSScript* script); - -extern JS_PUBLIC_API(const char*) -JS_GetScriptFilename(JSScript* script); - -extern JS_PUBLIC_API(unsigned) -JS_GetScriptBaseLineNumber(JSContext* cx, JSScript* script); - -extern JS_PUBLIC_API(JSScript*) -JS_GetFunctionScript(JSContext* cx, JS::HandleFunction fun); - -namespace JS { - -/* Options for JavaScript compilation. */ - -/* - * In the most common use case, a CompileOptions instance is allocated on the - * stack, and holds non-owning references to non-POD option values: strings; - * principals; objects; and so on. The code declaring the instance guarantees - * that such option values will outlive the CompileOptions itself: objects are - * otherwise rooted; principals have had their reference counts bumped; strings - * will not be freed until the CompileOptions goes out of scope. In this - * situation, CompileOptions only refers to things others own, so it can be - * lightweight. - * - * In some cases, however, we need to hold compilation options with a - * non-stack-like lifetime. For example, JS::CompileOffThread needs to save - * compilation options where a worker thread can find them, and then return - * immediately. The worker thread will come along at some later point, and use - * the options. - * - * The compiler itself just needs to be able to access a collection of options; - * it doesn't care who owns them, or what's keeping them alive. It does its own - * addrefs/copies/tracing/etc. - * - * Furthermore, in some cases compile options are propagated from one entity to - * another (e.g. from a scriipt to a function defined in that script). This - * involves copying over some, but not all, of the options. - * - * So, we have a class hierarchy that reflects these four use cases: - * - * - TransitiveCompileOptions is the common base class, representing options - * that should get propagated from a script to functions defined in that - * script. This is never instantiated directly. - * - * - ReadOnlyCompileOptions is the only subclass of TransitiveCompileOptions, - * representing a full set of compile options. It can be used by code that - * simply needs to access options set elsewhere, like the compiler. This, - * again, is never instantiated directly. - * - * - The usual CompileOptions class must be stack-allocated, and holds - * non-owning references to the filename, element, and so on. It's derived - * from ReadOnlyCompileOptions, so the compiler can use it. - * - * - OwningCompileOptions roots / copies / reference counts of all its values, - * and unroots / frees / releases them when it is destructed. It too is - * derived from ReadOnlyCompileOptions, so the compiler accepts it. - */ - -enum class AsmJSOption : uint8_t { Enabled, Disabled, DisabledByDebugger }; - -/** - * The common base class for the CompileOptions hierarchy. - * - * Use this in code that needs to propagate compile options from one compilation - * unit to another. - */ -class JS_FRIEND_API(TransitiveCompileOptions) -{ - protected: - // The Web Platform allows scripts to be loaded from arbitrary cross-origin - // sources. This allows an attack by which a malicious website loads a - // sensitive file (say, a bank statement) cross-origin (using the user's - // cookies), and sniffs the generated syntax errors (via a window.onerror - // handler) for juicy morsels of its contents. - // - // To counter this attack, HTML5 specifies that script errors should be - // sanitized ("muted") when the script is not same-origin with the global - // for which it is loaded. Callers should set this flag for cross-origin - // scripts, and it will be propagated appropriately to child scripts and - // passed back in JSErrorReports. - bool mutedErrors_; - const char* filename_; - const char* introducerFilename_; - const char16_t* sourceMapURL_; - - // This constructor leaves 'version' set to JSVERSION_UNKNOWN. The structure - // is unusable until that's set to something more specific; the derived - // classes' constructors take care of that, in ways appropriate to their - // purpose. - TransitiveCompileOptions() - : mutedErrors_(false), - filename_(nullptr), - introducerFilename_(nullptr), - sourceMapURL_(nullptr), - version(JSVERSION_UNKNOWN), - versionSet(false), - utf8(false), - selfHostingMode(false), - canLazilyParse(true), - strictOption(false), - extraWarningsOption(false), - werrorOption(false), - asmJSOption(AsmJSOption::Disabled), - throwOnAsmJSValidationFailureOption(false), - forceAsync(false), - installedFile(false), - sourceIsLazy(false), - introductionType(nullptr), - introductionLineno(0), - introductionOffset(0), - hasIntroductionInfo(false) - { } - - // Set all POD options (those not requiring reference counts, copies, - // rooting, or other hand-holding) to their values in |rhs|. - void copyPODTransitiveOptions(const TransitiveCompileOptions& rhs); - - public: - // Read-only accessors for non-POD options. The proper way to set these - // depends on the derived type. - bool mutedErrors() const { return mutedErrors_; } - const char* filename() const { return filename_; } - const char* introducerFilename() const { return introducerFilename_; } - const char16_t* sourceMapURL() const { return sourceMapURL_; } - virtual JSObject* element() const = 0; - virtual JSString* elementAttributeName() const = 0; - virtual JSScript* introductionScript() const = 0; - - // POD options. - JSVersion version; - bool versionSet; - bool utf8; - bool selfHostingMode; - bool canLazilyParse; - bool strictOption; - bool extraWarningsOption; - bool werrorOption; - AsmJSOption asmJSOption; - bool throwOnAsmJSValidationFailureOption; - bool forceAsync; - bool installedFile; // 'true' iff pre-compiling js file in packaged app - bool sourceIsLazy; - - // |introductionType| is a statically allocated C string: - // one of "eval", "Function", or "GeneratorFunction". - const char* introductionType; - unsigned introductionLineno; - uint32_t introductionOffset; - bool hasIntroductionInfo; - - private: - void operator=(const TransitiveCompileOptions&) = delete; -}; - -/** - * The class representing a full set of compile options. - * - * Use this in code that only needs to access compilation options created - * elsewhere, like the compiler. Don't instantiate this class (the constructor - * is protected anyway); instead, create instances only of the derived classes: - * CompileOptions and OwningCompileOptions. - */ -class JS_FRIEND_API(ReadOnlyCompileOptions) : public TransitiveCompileOptions -{ - friend class CompileOptions; - - protected: - ReadOnlyCompileOptions() - : TransitiveCompileOptions(), - lineno(1), - column(0), - isRunOnce(false), - noScriptRval(false) - { } - - // Set all POD options (those not requiring reference counts, copies, - // rooting, or other hand-holding) to their values in |rhs|. - void copyPODOptions(const ReadOnlyCompileOptions& rhs); - - public: - // Read-only accessors for non-POD options. The proper way to set these - // depends on the derived type. - bool mutedErrors() const { return mutedErrors_; } - const char* filename() const { return filename_; } - const char* introducerFilename() const { return introducerFilename_; } - const char16_t* sourceMapURL() const { return sourceMapURL_; } - virtual JSObject* element() const = 0; - virtual JSString* elementAttributeName() const = 0; - virtual JSScript* introductionScript() const = 0; - - // POD options. - unsigned lineno; - unsigned column; - // isRunOnce only applies to non-function scripts. - bool isRunOnce; - bool noScriptRval; - - private: - void operator=(const ReadOnlyCompileOptions&) = delete; -}; - -/** - * Compilation options, with dynamic lifetime. An instance of this type - * makes a copy of / holds / roots all dynamically allocated resources - * (principals; elements; strings) that it refers to. Its destructor frees - * / drops / unroots them. This is heavier than CompileOptions, below, but - * unlike CompileOptions, it can outlive any given stack frame. - * - * Note that this *roots* any JS values it refers to - they're live - * unconditionally. Thus, instances of this type can't be owned, directly - * or indirectly, by a JavaScript object: if any value that this roots ever - * comes to refer to the object that owns this, then the whole cycle, and - * anything else it entrains, will never be freed. - */ -class JS_FRIEND_API(OwningCompileOptions) : public ReadOnlyCompileOptions -{ - PersistentRootedObject elementRoot; - PersistentRootedString elementAttributeNameRoot; - PersistentRootedScript introductionScriptRoot; - - public: - // A minimal constructor, for use with OwningCompileOptions::copy. This - // leaves |this.version| set to JSVERSION_UNKNOWN; the instance - // shouldn't be used until we've set that to something real (as |copy| - // will). - explicit OwningCompileOptions(JSContext* cx); - ~OwningCompileOptions(); - - JSObject* element() const override { return elementRoot; } - JSString* elementAttributeName() const override { return elementAttributeNameRoot; } - JSScript* introductionScript() const override { return introductionScriptRoot; } - - // Set this to a copy of |rhs|. Return false on OOM. - bool copy(JSContext* cx, const ReadOnlyCompileOptions& rhs); - - /* These setters make copies of their string arguments, and are fallible. */ - bool setFile(JSContext* cx, const char* f); - bool setFileAndLine(JSContext* cx, const char* f, unsigned l); - bool setSourceMapURL(JSContext* cx, const char16_t* s); - bool setIntroducerFilename(JSContext* cx, const char* s); - - /* These setters are infallible, and can be chained. */ - OwningCompileOptions& setLine(unsigned l) { lineno = l; return *this; } - OwningCompileOptions& setElement(JSObject* e) { - elementRoot = e; - return *this; - } - OwningCompileOptions& setElementAttributeName(JSString* p) { - elementAttributeNameRoot = p; - return *this; - } - OwningCompileOptions& setIntroductionScript(JSScript* s) { - introductionScriptRoot = s; - return *this; - } - OwningCompileOptions& setMutedErrors(bool mute) { - mutedErrors_ = mute; - return *this; - } - OwningCompileOptions& setVersion(JSVersion v) { - version = v; - versionSet = true; - return *this; - } - OwningCompileOptions& setUTF8(bool u) { utf8 = u; return *this; } - OwningCompileOptions& setColumn(unsigned c) { column = c; return *this; } - OwningCompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; } - OwningCompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; } - OwningCompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; } - OwningCompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; } - OwningCompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; } - OwningCompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; } - bool setIntroductionInfo(JSContext* cx, const char* introducerFn, const char* intro, - unsigned line, JSScript* script, uint32_t offset) - { - if (!setIntroducerFilename(cx, introducerFn)) - return false; - introductionType = intro; - introductionLineno = line; - introductionScriptRoot = script; - introductionOffset = offset; - hasIntroductionInfo = true; - return true; - } - - private: - void operator=(const CompileOptions& rhs) = delete; -}; - -/** - * Compilation options stored on the stack. An instance of this type - * simply holds references to dynamically allocated resources (element; - * filename; source map URL) that are owned by something else. If you - * create an instance of this type, it's up to you to guarantee that - * everything you store in it will outlive it. - */ -class MOZ_STACK_CLASS JS_FRIEND_API(CompileOptions) final : public ReadOnlyCompileOptions -{ - RootedObject elementRoot; - RootedString elementAttributeNameRoot; - RootedScript introductionScriptRoot; - - public: - explicit CompileOptions(JSContext* cx, JSVersion version = JSVERSION_UNKNOWN); - CompileOptions(js::ContextFriendFields* cx, const ReadOnlyCompileOptions& rhs) - : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx), - introductionScriptRoot(cx) - { - copyPODOptions(rhs); - - filename_ = rhs.filename(); - introducerFilename_ = rhs.introducerFilename(); - sourceMapURL_ = rhs.sourceMapURL(); - elementRoot = rhs.element(); - elementAttributeNameRoot = rhs.elementAttributeName(); - introductionScriptRoot = rhs.introductionScript(); - } - - CompileOptions(js::ContextFriendFields* cx, const TransitiveCompileOptions& rhs) - : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx), - introductionScriptRoot(cx) - { - copyPODTransitiveOptions(rhs); - - filename_ = rhs.filename(); - introducerFilename_ = rhs.introducerFilename(); - sourceMapURL_ = rhs.sourceMapURL(); - elementRoot = rhs.element(); - elementAttributeNameRoot = rhs.elementAttributeName(); - introductionScriptRoot = rhs.introductionScript(); - } - - JSObject* element() const override { return elementRoot; } - JSString* elementAttributeName() const override { return elementAttributeNameRoot; } - JSScript* introductionScript() const override { return introductionScriptRoot; } - - CompileOptions& setFile(const char* f) { filename_ = f; return *this; } - CompileOptions& setLine(unsigned l) { lineno = l; return *this; } - CompileOptions& setFileAndLine(const char* f, unsigned l) { - filename_ = f; lineno = l; return *this; - } - CompileOptions& setSourceMapURL(const char16_t* s) { sourceMapURL_ = s; return *this; } - CompileOptions& setElement(JSObject* e) { elementRoot = e; return *this; } - CompileOptions& setElementAttributeName(JSString* p) { - elementAttributeNameRoot = p; - return *this; - } - CompileOptions& setIntroductionScript(JSScript* s) { - introductionScriptRoot = s; - return *this; - } - CompileOptions& setMutedErrors(bool mute) { - mutedErrors_ = mute; - return *this; - } - CompileOptions& setVersion(JSVersion v) { - version = v; - versionSet = true; - return *this; - } - CompileOptions& setUTF8(bool u) { utf8 = u; return *this; } - CompileOptions& setColumn(unsigned c) { column = c; return *this; } - CompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; } - CompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; } - CompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; } - CompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; } - CompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; } - CompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; } - CompileOptions& setIntroductionInfo(const char* introducerFn, const char* intro, - unsigned line, JSScript* script, uint32_t offset) - { - introducerFilename_ = introducerFn; - introductionType = intro; - introductionLineno = line; - introductionScriptRoot = script; - introductionOffset = offset; - hasIntroductionInfo = true; - return *this; - } - CompileOptions& maybeMakeStrictMode(bool strict) { - strictOption = strictOption || strict; - return *this; - } - - private: - void operator=(const CompileOptions& rhs) = delete; -}; - -/** - * |script| will always be set. On failure, it will be set to nullptr. - */ -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* bytes, size_t length, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - FILE* file, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* filename, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* bytes, size_t length, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - FILE* file, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* filename, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CanCompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options, size_t length); - -/* - * Off thread compilation control flow. - * - * After successfully triggering an off thread compile of a script, the - * callback will eventually be invoked with the specified data and a token - * for the compilation. The callback will be invoked while off the main thread, - * so must ensure that its operations are thread safe. Afterwards, one of the - * following functions must be invoked on the main thread: - * - * - FinishOffThreadScript, to get the result script (or nullptr on failure). - * - CancelOffThreadScript, to free the resources without creating a script. - * - * The characters passed in to CompileOffThread must remain live until the - * callback is invoked, and the resulting script will be rooted until the call - * to FinishOffThreadScript. - */ - -extern JS_PUBLIC_API(bool) -CompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, - OffThreadCompileCallback callback, void* callbackData); - -extern JS_PUBLIC_API(JSScript*) -FinishOffThreadScript(JSContext* cx, void* token); - -extern JS_PUBLIC_API(void) -CancelOffThreadScript(JSContext* cx, void* token); - -extern JS_PUBLIC_API(bool) -CompileOffThreadModule(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, - OffThreadCompileCallback callback, void* callbackData); - -extern JS_PUBLIC_API(JSObject*) -FinishOffThreadModule(JSContext* cx, void* token); - -extern JS_PUBLIC_API(void) -CancelOffThreadModule(JSContext* cx, void* token); - -/** - * Compile a function with envChain plus the global as its scope chain. - * envChain must contain objects in the current compartment of cx. The actual - * scope chain used for the function will consist of With wrappers for those - * objects, followed by the current global of the compartment cx is in. This - * global must not be explicitly included in the scope chain. - */ -extern JS_PUBLIC_API(bool) -CompileFunction(JSContext* cx, AutoObjectVector& envChain, - const ReadOnlyCompileOptions& options, - const char* name, unsigned nargs, const char* const* argnames, - const char16_t* chars, size_t length, JS::MutableHandleFunction fun); - -/** - * Same as above, but taking a SourceBufferHolder for the function body. - */ -extern JS_PUBLIC_API(bool) -CompileFunction(JSContext* cx, AutoObjectVector& envChain, - const ReadOnlyCompileOptions& options, - const char* name, unsigned nargs, const char* const* argnames, - SourceBufferHolder& srcBuf, JS::MutableHandleFunction fun); - -/** - * Same as above, but taking a const char * for the function body. - */ -extern JS_PUBLIC_API(bool) -CompileFunction(JSContext* cx, AutoObjectVector& envChain, - const ReadOnlyCompileOptions& options, - const char* name, unsigned nargs, const char* const* argnames, - const char* bytes, size_t length, JS::MutableHandleFunction fun); - -} /* namespace JS */ - -extern JS_PUBLIC_API(JSString*) -JS_DecompileScript(JSContext* cx, JS::Handle script, const char* name, unsigned indent); - -/* - * API extension: OR this into indent to avoid pretty-printing the decompiled - * source resulting from JS_DecompileFunction. - */ -#define JS_DONT_PRETTY_PRINT ((unsigned)0x8000) - -extern JS_PUBLIC_API(JSString*) -JS_DecompileFunction(JSContext* cx, JS::Handle fun, unsigned indent); - - -/* - * NB: JS_ExecuteScript and the JS::Evaluate APIs come in two flavors: either - * they use the global as the scope, or they take an AutoObjectVector of objects - * to use as the scope chain. In the former case, the global is also used as - * the "this" keyword value and the variables object (ECMA parlance for where - * 'var' and 'function' bind names) of the execution context for script. In the - * latter case, the first object in the provided list is used, unless the list - * is empty, in which case the global is used. - * - * Why a runtime option? The alternative is to add APIs duplicating those - * for the other value of flags, and that doesn't seem worth the code bloat - * cost. Such new entry points would probably have less obvious names, too, so - * would not tend to be used. The ContextOptionsRef adjustment, OTOH, can be - * more easily hacked into existing code that does not depend on the bug; such - * code can continue to use the familiar JS::Evaluate, etc., entry points. - */ - -/** - * Evaluate a script in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -JS_ExecuteScript(JSContext* cx, JS::HandleScript script, JS::MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -JS_ExecuteScript(JSContext* cx, JS::HandleScript script); - -/** - * As above, but providing an explicit scope chain. envChain must not include - * the global object on it; that's implicit. It needs to contain the other - * objects that should end up on the script's scope chain. - */ -extern JS_PUBLIC_API(bool) -JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain, - JS::HandleScript script, JS::MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain, JS::HandleScript script); - -namespace JS { - -/** - * Like the above, but handles a cross-compartment script. If the script is - * cross-compartment, it is cloned into the current compartment before executing. - */ -extern JS_PUBLIC_API(bool) -CloneAndExecuteScript(JSContext* cx, JS::Handle script, - JS::MutableHandleValue rval); - -} /* namespace JS */ - -namespace JS { - -/** - * Evaluate the given source buffer in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleValue rval); - -/** - * As above, but providing an explicit scope chain. envChain must not include - * the global object on it; that's implicit. It needs to contain the other - * objects that should end up on the script's scope chain. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, AutoObjectVector& envChain, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleValue rval); - -/** - * Evaluate the given character buffer in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, JS::MutableHandleValue rval); - -/** - * As above, but providing an explicit scope chain. envChain must not include - * the global object on it; that's implicit. It needs to contain the other - * objects that should end up on the script's scope chain. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, AutoObjectVector& envChain, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, JS::MutableHandleValue rval); - -/** - * Evaluate the given byte buffer in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* bytes, size_t length, JS::MutableHandleValue rval); - -/** - * Evaluate the given file in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* filename, JS::MutableHandleValue rval); - -/** - * Get the HostResolveImportedModule hook for a global. - */ -extern JS_PUBLIC_API(JSFunction*) -GetModuleResolveHook(JSContext* cx); - -/** - * Set the HostResolveImportedModule hook for a global to the given function. - */ -extern JS_PUBLIC_API(void) -SetModuleResolveHook(JSContext* cx, JS::HandleFunction func); - -/** - * Parse the given source buffer as a module in the scope of the current global - * of cx and return a source text module record. - */ -extern JS_PUBLIC_API(bool) -CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleObject moduleRecord); - -/** - * Set the [[HostDefined]] field of a source text module record to the given - * value. - */ -extern JS_PUBLIC_API(void) -SetModuleHostDefinedField(JSObject* module, const JS::Value& value); - -/** - * Get the [[HostDefined]] field of a source text module record. - */ -extern JS_PUBLIC_API(JS::Value) -GetModuleHostDefinedField(JSObject* module); - -/* - * Perform the ModuleDeclarationInstantiation operation on on the give source - * text module record. - * - * This transitively resolves all module dependencies (calling the - * HostResolveImportedModule hook) and initializes the environment record for - * the module. - */ -extern JS_PUBLIC_API(bool) -ModuleDeclarationInstantiation(JSContext* cx, JS::HandleObject moduleRecord); - -/* - * Perform the ModuleEvaluation operation on on the give source text module - * record. - * - * This does nothing if this module has already been evaluated. Otherwise, it - * transitively evaluates all dependences of this module and then evaluates this - * module. - * - * ModuleDeclarationInstantiation must have completed prior to calling this. - */ -extern JS_PUBLIC_API(bool) -ModuleEvaluation(JSContext* cx, JS::HandleObject moduleRecord); - -/* - * Get a list of the module specifiers used by a source text module - * record to request importation of modules. - * - * The result is a JavaScript array of string values. To extract the individual - * values use only JS_GetArrayLength and JS_GetElement with indices 0 to - * length - 1. - */ -extern JS_PUBLIC_API(JSObject*) -GetRequestedModules(JSContext* cx, JS::HandleObject moduleRecord); - -/* - * Get the script associated with a module. - */ -extern JS_PUBLIC_API(JSScript*) -GetModuleScript(JSContext* cx, JS::HandleObject moduleRecord); - -} /* namespace JS */ - -extern JS_PUBLIC_API(bool) -JS_CheckForInterrupt(JSContext* cx); - -/* - * These functions allow setting an interrupt callback that will be called - * from the JS thread some time after any thread triggered the callback using - * JS_RequestInterruptCallback(cx). - * - * To schedule the GC and for other activities the engine internally triggers - * interrupt callbacks. The embedding should thus not rely on callbacks being - * triggered through the external API only. - * - * Important note: Additional callbacks can occur inside the callback handler - * if it re-enters the JS engine. The embedding must ensure that the callback - * is disconnected before attempting such re-entry. - */ -extern JS_PUBLIC_API(bool) -JS_AddInterruptCallback(JSContext* cx, JSInterruptCallback callback); - -extern JS_PUBLIC_API(bool) -JS_DisableInterruptCallback(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_ResetInterruptCallback(JSContext* cx, bool enable); - -extern JS_PUBLIC_API(void) -JS_RequestInterruptCallback(JSContext* cx); - -namespace JS { - -/** - * Sets the callback that's invoked whenever an incumbent global is required. - * - * SpiderMonkey doesn't itself have a notion of incumbent globals as defined - * by the html spec, so we need the embedding to provide this. - * See dom/base/ScriptSettings.h for details. - */ -extern JS_PUBLIC_API(void) -SetGetIncumbentGlobalCallback(JSContext* cx, JSGetIncumbentGlobalCallback callback); - -/** - * Sets the callback that's invoked whenever a Promise job should be enqeued. - * - * SpiderMonkey doesn't schedule Promise resolution jobs itself; instead, - * using this function the embedding can provide a callback to do that - * scheduling. The provided `callback` is invoked with the promise job, - * the corresponding Promise's allocation stack, and the `data` pointer - * passed here as arguments. - */ -extern JS_PUBLIC_API(void) -SetEnqueuePromiseJobCallback(JSContext* cx, JSEnqueuePromiseJobCallback callback, - void* data = nullptr); - -/** - * Sets the callback that's invoked whenever a Promise is rejected without - * a rejection handler, and when a Promise that was previously rejected - * without a handler gets a handler attached. - */ -extern JS_PUBLIC_API(void) -SetPromiseRejectionTrackerCallback(JSContext* cx, JSPromiseRejectionTrackerCallback callback, - void* data = nullptr); - -/** - * Returns a new instance of the Promise builtin class in the current - * compartment, with the right slot layout. If a `proto` is passed, that gets - * set as the instance's [[Prototype]] instead of the original value of - * `Promise.prototype`. - */ -extern JS_PUBLIC_API(JSObject*) -NewPromiseObject(JSContext* cx, JS::HandleObject executor, JS::HandleObject proto = nullptr); - -/** - * Returns true if the given object is an unwrapped PromiseObject, false - * otherwise. - */ -extern JS_PUBLIC_API(bool) -IsPromiseObject(JS::HandleObject obj); - -/** - * Returns the current compartment's original Promise constructor. - */ -extern JS_PUBLIC_API(JSObject*) -GetPromiseConstructor(JSContext* cx); - -/** - * Returns the current compartment's original Promise.prototype. - */ -extern JS_PUBLIC_API(JSObject*) -GetPromisePrototype(JSContext* cx); - -// Keep this in sync with the PROMISE_STATE defines in SelfHostingDefines.h. -enum class PromiseState { - Pending, - Fulfilled, - Rejected -}; - -/** - * Returns the given Promise's state as a JS::PromiseState enum value. - */ -extern JS_PUBLIC_API(PromiseState) -GetPromiseState(JS::HandleObject promise); - -/** - * Returns the given Promise's process-unique ID. - */ -JS_PUBLIC_API(uint64_t) -GetPromiseID(JS::HandleObject promise); - -/** - * Returns the given Promise's result: either the resolution value for - * fulfilled promises, or the rejection reason for rejected ones. - */ -extern JS_PUBLIC_API(JS::Value) -GetPromiseResult(JS::HandleObject promise); - -/** - * Returns a js::SavedFrame linked list of the stack that lead to the given - * Promise's allocation. - */ -extern JS_PUBLIC_API(JSObject*) -GetPromiseAllocationSite(JS::HandleObject promise); - -extern JS_PUBLIC_API(JSObject*) -GetPromiseResolutionSite(JS::HandleObject promise); - -#ifdef DEBUG -extern JS_PUBLIC_API(void) -DumpPromiseAllocationSite(JSContext* cx, JS::HandleObject promise); - -extern JS_PUBLIC_API(void) -DumpPromiseResolutionSite(JSContext* cx, JS::HandleObject promise); -#endif - -/** - * Calls the current compartment's original Promise.resolve on the original - * Promise constructor, with `resolutionValue` passed as an argument. - */ -extern JS_PUBLIC_API(JSObject*) -CallOriginalPromiseResolve(JSContext* cx, JS::HandleValue resolutionValue); - -/** - * Calls the current compartment's original Promise.reject on the original - * Promise constructor, with `resolutionValue` passed as an argument. - */ -extern JS_PUBLIC_API(JSObject*) -CallOriginalPromiseReject(JSContext* cx, JS::HandleValue rejectionValue); - -/** - * Resolves the given Promise with the given `resolutionValue`. - * - * Calls the `resolve` function that was passed to the executor function when - * the Promise was created. - */ -extern JS_PUBLIC_API(bool) -ResolvePromise(JSContext* cx, JS::HandleObject promise, JS::HandleValue resolutionValue); - -/** - * Rejects the given `promise` with the given `rejectionValue`. - * - * Calls the `reject` function that was passed to the executor function when - * the Promise was created. - */ -extern JS_PUBLIC_API(bool) -RejectPromise(JSContext* cx, JS::HandleObject promise, JS::HandleValue rejectionValue); - -/** - * Calls the current compartment's original Promise.prototype.then on the - * given `promise`, with `onResolve` and `onReject` passed as arguments. - * - * Asserts if the passed-in `promise` object isn't an unwrapped instance of - * `Promise` or a subclass or `onResolve` and `onReject` aren't both either - * `nullptr` or callable objects. - */ -extern JS_PUBLIC_API(JSObject*) -CallOriginalPromiseThen(JSContext* cx, JS::HandleObject promise, - JS::HandleObject onResolve, JS::HandleObject onReject); - -/** - * Unforgeable, optimized version of the JS builtin Promise.prototype.then. - * - * Takes a Promise instance and `onResolve`, `onReject` callables to enqueue - * as reactions for that promise. In difference to Promise.prototype.then, - * this doesn't create and return a new Promise instance. - * - * Asserts if the passed-in `promise` object isn't an unwrapped instance of - * `Promise` or a subclass or `onResolve` and `onReject` aren't both callable - * objects. - */ -extern JS_PUBLIC_API(bool) -AddPromiseReactions(JSContext* cx, JS::HandleObject promise, - JS::HandleObject onResolve, JS::HandleObject onReject); - -/** - * Unforgeable version of the JS builtin Promise.all. - * - * Takes an AutoObjectVector of Promise objects and returns a promise that's - * resolved with an array of resolution values when all those promises ahve - * been resolved, or rejected with the rejection value of the first rejected - * promise. - * - * Asserts if the array isn't dense or one of the entries isn't an unwrapped - * instance of Promise or a subclass. - */ -extern JS_PUBLIC_API(JSObject*) -GetWaitForAllPromise(JSContext* cx, const JS::AutoObjectVector& promises); - -/** - * An AsyncTask represents a SpiderMonkey-internal operation that starts on a - * JSContext's owner thread, possibly executes on other threads, completes, and - * then needs to be scheduled to run again on the JSContext's owner thread. The - * embedding provides for this final dispatch back to the JSContext's owner - * thread by calling methods on this interface when requested. - */ -struct JS_PUBLIC_API(AsyncTask) -{ - AsyncTask() : user(nullptr) {} - virtual ~AsyncTask() {} - - /** - * After the FinishAsyncTaskCallback is called and succeeds, one of these - * two functions will be called on the original JSContext's owner thread. - */ - virtual void finish(JSContext* cx) = 0; - virtual void cancel(JSContext* cx) = 0; - - /* The embedding may use this field to attach arbitrary data to a task. */ - void* user; -}; - -/** - * A new AsyncTask object, created inside SpiderMonkey on the JSContext's owner - * thread, will be passed to the StartAsyncTaskCallback before it is dispatched - * to another thread. The embedding may use the AsyncTask::user field to attach - * additional task state. - * - * If this function succeeds, SpiderMonkey will call the FinishAsyncTaskCallback - * at some point in the future. Otherwise, FinishAsyncTaskCallback will *not* - * be called. SpiderMonkey assumes that, if StartAsyncTaskCallback fails, it is - * because the JSContext is being shut down. - */ -typedef bool -(*StartAsyncTaskCallback)(JSContext* cx, AsyncTask* task); - -/** - * The FinishAsyncTaskCallback may be called from any thread and will only be - * passed AsyncTasks that have already been started via StartAsyncTaskCallback. - * If the embedding returns 'true', indicating success, the embedding must call - * either task->finish() or task->cancel() on the JSContext's owner thread at - * some point in the future. - */ -typedef bool -(*FinishAsyncTaskCallback)(AsyncTask* task); - -/** - * Set the above callbacks for the given context. - */ -extern JS_PUBLIC_API(void) -SetAsyncTaskCallbacks(JSContext* cx, StartAsyncTaskCallback start, FinishAsyncTaskCallback finish); - -} // namespace JS - -extern JS_PUBLIC_API(bool) -JS_IsRunning(JSContext* cx); - -namespace JS { - -/** - * This class can be used to store a pointer to the youngest frame of a saved - * stack in the specified JSContext. This reference will be picked up by any new - * calls performed until the class is destroyed, with the specified asyncCause, - * that must not be empty. - * - * Any stack capture initiated during these new calls will go through the async - * stack instead of the current stack. - * - * Capturing the stack before a new call is performed will not be affected. - * - * The provided chain of SavedFrame objects can live in any compartment, - * although it will be copied to the compartment where the stack is captured. - * - * See also `js/src/doc/SavedFrame/SavedFrame.md` for documentation on async - * stack frames. - */ -class MOZ_STACK_CLASS JS_PUBLIC_API(AutoSetAsyncStackForNewCalls) -{ - JSContext* cx; - RootedObject oldAsyncStack; - const char* oldAsyncCause; - bool oldAsyncCallIsExplicit; - - public: - enum class AsyncCallKind { - // The ordinary kind of call, where we may apply an async - // parent if there is no ordinary parent. - IMPLICIT, - // An explicit async parent, e.g., callFunctionWithAsyncStack, - // where we always want to override any ordinary parent. - EXPLICIT - }; - - // The stack parameter cannot be null by design, because it would be - // ambiguous whether that would clear any scheduled async stack and make the - // normal stack reappear in the new call, or just keep the async stack - // already scheduled for the new call, if any. - // - // asyncCause is owned by the caller and its lifetime must outlive the - // lifetime of the AutoSetAsyncStackForNewCalls object. It is strongly - // encouraged that asyncCause be a string constant or similar statically - // allocated string. - AutoSetAsyncStackForNewCalls(JSContext* cx, HandleObject stack, - const char* asyncCause, - AsyncCallKind kind = AsyncCallKind::IMPLICIT); - ~AutoSetAsyncStackForNewCalls(); -}; - -} // namespace JS - -/************************************************************************/ - -/* - * Strings. - * - * NB: JS_NewUCString takes ownership of bytes on success, avoiding a copy; - * but on error (signified by null return), it leaves chars owned by the - * caller. So the caller must free bytes in the error case, if it has no use - * for them. In contrast, all the JS_New*StringCopy* functions do not take - * ownership of the character memory passed to them -- they copy it. - */ -extern JS_PUBLIC_API(JSString*) -JS_NewStringCopyN(JSContext* cx, const char* s, size_t n); - -extern JS_PUBLIC_API(JSString*) -JS_NewStringCopyZ(JSContext* cx, const char* s); - -extern JS_PUBLIC_API(JSString*) -JS_NewStringCopyUTF8Z(JSContext* cx, const JS::ConstUTF8CharsZ s); - -extern JS_PUBLIC_API(JSString*) -JS_NewStringCopyUTF8N(JSContext* cx, const JS::UTF8Chars s); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeAndPinJSString(JSContext* cx, JS::HandleString str); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeStringN(JSContext* cx, const char* s, size_t length); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeString(JSContext* cx, const char* s); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeAndPinStringN(JSContext* cx, const char* s, size_t length); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeAndPinString(JSContext* cx, const char* s); - -extern JS_PUBLIC_API(JSString*) -JS_NewUCString(JSContext* cx, char16_t* chars, size_t length); - -extern JS_PUBLIC_API(JSString*) -JS_NewUCStringCopyN(JSContext* cx, const char16_t* s, size_t n); - -extern JS_PUBLIC_API(JSString*) -JS_NewUCStringCopyZ(JSContext* cx, const char16_t* s); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeUCStringN(JSContext* cx, const char16_t* s, size_t length); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeUCString(JSContext* cx, const char16_t* s); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeAndPinUCStringN(JSContext* cx, const char16_t* s, size_t length); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeAndPinUCString(JSContext* cx, const char16_t* s); - -extern JS_PUBLIC_API(bool) -JS_CompareStrings(JSContext* cx, JSString* str1, JSString* str2, int32_t* result); - -extern JS_PUBLIC_API(bool) -JS_StringEqualsAscii(JSContext* cx, JSString* str, const char* asciiBytes, bool* match); - -extern JS_PUBLIC_API(size_t) -JS_PutEscapedString(JSContext* cx, char* buffer, size_t size, JSString* str, char quote); - -extern JS_PUBLIC_API(bool) -JS_FileEscapedString(FILE* fp, JSString* str, char quote); - -/* - * Extracting string characters and length. - * - * While getting the length of a string is infallible, getting the chars can - * fail. As indicated by the lack of a JSContext parameter, there are two - * special cases where getting the chars is infallible: - * - * The first case is for strings that have been atomized, e.g. directly by - * JS_AtomizeAndPinString or implicitly because it is stored in a jsid. - * - * The second case is "flat" strings that have been explicitly prepared in a - * fallible context by JS_FlattenString. To catch errors, a separate opaque - * JSFlatString type is returned by JS_FlattenString and expected by - * JS_GetFlatStringChars. Note, though, that this is purely a syntactic - * distinction: the input and output of JS_FlattenString are the same actual - * GC-thing. If a JSString is known to be flat, JS_ASSERT_STRING_IS_FLAT can be - * used to make a debug-checked cast. Example: - * - * // in a fallible context - * JSFlatString* fstr = JS_FlattenString(cx, str); - * if (!fstr) - * return false; - * MOZ_ASSERT(fstr == JS_ASSERT_STRING_IS_FLAT(str)); - * - * // in an infallible context, for the same 'str' - * AutoCheckCannotGC nogc; - * const char16_t* chars = JS_GetTwoByteFlatStringChars(nogc, fstr) - * MOZ_ASSERT(chars); - * - * Flat strings and interned strings are always null-terminated, so - * JS_FlattenString can be used to get a null-terminated string. - * - * Additionally, string characters are stored as either Latin1Char (8-bit) - * or char16_t (16-bit). Clients can use JS_StringHasLatin1Chars and can then - * call either the Latin1* or TwoByte* functions. Some functions like - * JS_CopyStringChars and JS_GetStringCharAt accept both Latin1 and TwoByte - * strings. - */ - -extern JS_PUBLIC_API(size_t) -JS_GetStringLength(JSString* str); - -extern JS_PUBLIC_API(bool) -JS_StringIsFlat(JSString* str); - -/** Returns true iff the string's characters are stored as Latin1. */ -extern JS_PUBLIC_API(bool) -JS_StringHasLatin1Chars(JSString* str); - -extern JS_PUBLIC_API(const JS::Latin1Char*) -JS_GetLatin1StringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str, - size_t* length); - -extern JS_PUBLIC_API(const char16_t*) -JS_GetTwoByteStringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str, - size_t* length); - -extern JS_PUBLIC_API(bool) -JS_GetStringCharAt(JSContext* cx, JSString* str, size_t index, char16_t* res); - -extern JS_PUBLIC_API(char16_t) -JS_GetFlatStringCharAt(JSFlatString* str, size_t index); - -extern JS_PUBLIC_API(const char16_t*) -JS_GetTwoByteExternalStringChars(JSString* str); - -extern JS_PUBLIC_API(bool) -JS_CopyStringChars(JSContext* cx, mozilla::Range dest, JSString* str); - -extern JS_PUBLIC_API(JSFlatString*) -JS_FlattenString(JSContext* cx, JSString* str); - -extern JS_PUBLIC_API(const JS::Latin1Char*) -JS_GetLatin1FlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str); - -extern JS_PUBLIC_API(const char16_t*) -JS_GetTwoByteFlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str); - -static MOZ_ALWAYS_INLINE JSFlatString* -JSID_TO_FLAT_STRING(jsid id) -{ - MOZ_ASSERT(JSID_IS_STRING(id)); - return (JSFlatString*)(JSID_BITS(id)); -} - -static MOZ_ALWAYS_INLINE JSFlatString* -JS_ASSERT_STRING_IS_FLAT(JSString* str) -{ - MOZ_ASSERT(JS_StringIsFlat(str)); - return (JSFlatString*)str; -} - -static MOZ_ALWAYS_INLINE JSString* -JS_FORGET_STRING_FLATNESS(JSFlatString* fstr) -{ - return (JSString*)fstr; -} - -/* - * Additional APIs that avoid fallibility when given a flat string. - */ - -extern JS_PUBLIC_API(bool) -JS_FlatStringEqualsAscii(JSFlatString* str, const char* asciiBytes); - -extern JS_PUBLIC_API(size_t) -JS_PutEscapedFlatString(char* buffer, size_t size, JSFlatString* str, char quote); - -/** - * Create a dependent string, i.e., a string that owns no character storage, - * but that refers to a slice of another string's chars. Dependent strings - * are mutable by definition, so the thread safety comments above apply. - */ -extern JS_PUBLIC_API(JSString*) -JS_NewDependentString(JSContext* cx, JS::HandleString str, size_t start, - size_t length); - -/** - * Concatenate two strings, possibly resulting in a rope. - * See above for thread safety comments. - */ -extern JS_PUBLIC_API(JSString*) -JS_ConcatStrings(JSContext* cx, JS::HandleString left, JS::HandleString right); - -/** - * For JS_DecodeBytes, set *dstlenp to the size of the destination buffer before - * the call; on return, *dstlenp contains the number of characters actually - * stored. To determine the necessary destination buffer size, make a sizing - * call that passes nullptr for dst. - * - * On errors, the functions report the error. In that case, *dstlenp contains - * the number of characters or bytes transferred so far. If cx is nullptr, no - * error is reported on failure, and the functions simply return false. - * - * NB: This function does not store an additional zero byte or char16_t after the - * transcoded string. - */ -JS_PUBLIC_API(bool) -JS_DecodeBytes(JSContext* cx, const char* src, size_t srclen, char16_t* dst, - size_t* dstlenp); - -/** - * A variation on JS_EncodeCharacters where a null terminated string is - * returned that you are expected to call JS_free on when done. - */ -JS_PUBLIC_API(char*) -JS_EncodeString(JSContext* cx, JSString* str); - -/** - * Same behavior as JS_EncodeString(), but encode into UTF-8 string - */ -JS_PUBLIC_API(char*) -JS_EncodeStringToUTF8(JSContext* cx, JS::HandleString str); - -/** - * Get number of bytes in the string encoding (without accounting for a - * terminating zero bytes. The function returns (size_t) -1 if the string - * can not be encoded into bytes and reports an error using cx accordingly. - */ -JS_PUBLIC_API(size_t) -JS_GetStringEncodingLength(JSContext* cx, JSString* str); - -/** - * Encode string into a buffer. The function does not stores an additional - * zero byte. The function returns (size_t) -1 if the string can not be - * encoded into bytes with no error reported. Otherwise it returns the number - * of bytes that are necessary to encode the string. If that exceeds the - * length parameter, the string will be cut and only length bytes will be - * written into the buffer. - */ -JS_PUBLIC_API(size_t) -JS_EncodeStringToBuffer(JSContext* cx, JSString* str, char* buffer, size_t length); - -class MOZ_RAII JSAutoByteString -{ - public: - JSAutoByteString(JSContext* cx, JSString* str - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mBytes(JS_EncodeString(cx, str)) - { - MOZ_ASSERT(cx); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - explicit JSAutoByteString(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) - : mBytes(nullptr) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - ~JSAutoByteString() { - JS_free(nullptr, mBytes); - } - - /* Take ownership of the given byte array. */ - void initBytes(char* bytes) { - MOZ_ASSERT(!mBytes); - mBytes = bytes; - } - - char* encodeLatin1(JSContext* cx, JSString* str) { - MOZ_ASSERT(!mBytes); - MOZ_ASSERT(cx); - mBytes = JS_EncodeString(cx, str); - return mBytes; - } - - char* encodeLatin1(js::ExclusiveContext* cx, JSString* str); - - char* encodeUtf8(JSContext* cx, JS::HandleString str) { - MOZ_ASSERT(!mBytes); - MOZ_ASSERT(cx); - mBytes = JS_EncodeStringToUTF8(cx, str); - return mBytes; - } - - void clear() { - js_free(mBytes); - mBytes = nullptr; - } - - char* ptr() const { - return mBytes; - } - - bool operator!() const { - return !mBytes; - } - - size_t length() const { - if (!mBytes) - return 0; - return strlen(mBytes); - } - - private: - char* mBytes; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - - /* Copy and assignment are not supported. */ - JSAutoByteString(const JSAutoByteString& another); - JSAutoByteString& operator=(const JSAutoByteString& another); -}; - -namespace JS { - -extern JS_PUBLIC_API(JSAddonId*) -NewAddonId(JSContext* cx, JS::HandleString str); - -extern JS_PUBLIC_API(JSString*) -StringOfAddonId(JSAddonId* id); - -extern JS_PUBLIC_API(JSAddonId*) -AddonIdOfObject(JSObject* obj); - -} // namespace JS - -/************************************************************************/ -/* - * Symbols - */ - -namespace JS { - -/** - * Create a new Symbol with the given description. This function never returns - * a Symbol that is in the Runtime-wide symbol registry. - * - * If description is null, the new Symbol's [[Description]] attribute is - * undefined. - */ -JS_PUBLIC_API(Symbol*) -NewSymbol(JSContext* cx, HandleString description); - -/** - * Symbol.for as specified in ES6. - * - * Get a Symbol with the description 'key' from the Runtime-wide symbol registry. - * If there is not already a Symbol with that description in the registry, a new - * Symbol is created and registered. 'key' must not be null. - */ -JS_PUBLIC_API(Symbol*) -GetSymbolFor(JSContext* cx, HandleString key); - -/** - * Get the [[Description]] attribute of the given symbol. - * - * This function is infallible. If it returns null, that means the symbol's - * [[Description]] is undefined. - */ -JS_PUBLIC_API(JSString*) -GetSymbolDescription(HandleSymbol symbol); - -/* Well-known symbols. */ -#define JS_FOR_EACH_WELL_KNOWN_SYMBOL(macro) \ - macro(isConcatSpreadable) \ - macro(iterator) \ - macro(match) \ - macro(replace) \ - macro(search) \ - macro(species) \ - macro(hasInstance) \ - macro(split) \ - macro(toPrimitive) \ - macro(toStringTag) \ - macro(unscopables) - -enum class SymbolCode : uint32_t { - // There is one SymbolCode for each well-known symbol. -#define JS_DEFINE_SYMBOL_ENUM(name) name, - JS_FOR_EACH_WELL_KNOWN_SYMBOL(JS_DEFINE_SYMBOL_ENUM) // SymbolCode::iterator, etc. -#undef JS_DEFINE_SYMBOL_ENUM - Limit, - InSymbolRegistry = 0xfffffffe, // created by Symbol.for() or JS::GetSymbolFor() - UniqueSymbol = 0xffffffff // created by Symbol() or JS::NewSymbol() -}; - -/* For use in loops that iterate over the well-known symbols. */ -const size_t WellKnownSymbolLimit = size_t(SymbolCode::Limit); - -/** - * Return the SymbolCode telling what sort of symbol `symbol` is. - * - * A symbol's SymbolCode never changes once it is created. - */ -JS_PUBLIC_API(SymbolCode) -GetSymbolCode(Handle symbol); - -/** - * Get one of the well-known symbols defined by ES6. A single set of well-known - * symbols is shared by all compartments in a JSRuntime. - * - * `which` must be in the range [0, WellKnownSymbolLimit). - */ -JS_PUBLIC_API(Symbol*) -GetWellKnownSymbol(JSContext* cx, SymbolCode which); - -/** - * Return true if the given JSPropertySpec::name or JSFunctionSpec::name value - * is actually a symbol code and not a string. See JS_SYM_FN. - */ -inline bool -PropertySpecNameIsSymbol(const char* name) -{ - uintptr_t u = reinterpret_cast(name); - return u != 0 && u - 1 < WellKnownSymbolLimit; -} - -JS_PUBLIC_API(bool) -PropertySpecNameEqualsId(const char* name, HandleId id); - -/** - * Create a jsid that does not need to be marked for GC. - * - * 'name' is a JSPropertySpec::name or JSFunctionSpec::name value. The - * resulting jsid, on success, is either an interned string or a well-known - * symbol; either way it is immune to GC so there is no need to visit *idp - * during GC marking. - */ -JS_PUBLIC_API(bool) -PropertySpecNameToPermanentId(JSContext* cx, const char* name, jsid* idp); - -} /* namespace JS */ - -/************************************************************************/ -/* - * JSON functions - */ -typedef bool (* JSONWriteCallback)(const char16_t* buf, uint32_t len, void* data); - -/** - * JSON.stringify as specified by ES5. - */ -JS_PUBLIC_API(bool) -JS_Stringify(JSContext* cx, JS::MutableHandleValue value, JS::HandleObject replacer, - JS::HandleValue space, JSONWriteCallback callback, void* data); - -namespace JS { - -/** - * An API akin to JS_Stringify but with the goal of not having observable - * side-effects when the stringification is performed. This means it does not - * allow a replacer or a custom space, and has the following constraints on its - * input: - * - * 1) The input must be a plain object or array, not an abitrary value. - * 2) Every value in the graph reached by the algorithm starting with this - * object must be one of the following: null, undefined, a string (NOT a - * string object!), a boolean, a finite number (i.e. no NaN or Infinity or - * -Infinity), a plain object with no accessor properties, or an Array with - * no holes. - * - * The actual behavior differs from JS_Stringify only in asserting the above and - * NOT attempting to get the "toJSON" property from things, since that could - * clearly have side-effects. - */ -JS_PUBLIC_API(bool) -ToJSONMaybeSafely(JSContext* cx, JS::HandleObject input, - JSONWriteCallback callback, void* data); - -} /* namespace JS */ - -/** - * JSON.parse as specified by ES5. - */ -JS_PUBLIC_API(bool) -JS_ParseJSON(JSContext* cx, const char16_t* chars, uint32_t len, JS::MutableHandleValue vp); - -JS_PUBLIC_API(bool) -JS_ParseJSON(JSContext* cx, JS::HandleString str, JS::MutableHandleValue vp); - -JS_PUBLIC_API(bool) -JS_ParseJSONWithReviver(JSContext* cx, const char16_t* chars, uint32_t len, JS::HandleValue reviver, - JS::MutableHandleValue vp); - -JS_PUBLIC_API(bool) -JS_ParseJSONWithReviver(JSContext* cx, JS::HandleString str, JS::HandleValue reviver, - JS::MutableHandleValue vp); - -/************************************************************************/ - -/** - * The default locale for the ECMAScript Internationalization API - * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat). - * Note that the Internationalization API encourages clients to - * specify their own locales. - * The locale string remains owned by the caller. - */ -extern JS_PUBLIC_API(bool) -JS_SetDefaultLocale(JSContext* cx, const char* locale); - -/** - * Look up the default locale for the ECMAScript Internationalization API. - */ -extern JS_PUBLIC_API(JS::UniqueChars) -JS_GetDefaultLocale(JSContext* cx); - -/** - * Reset the default locale to OS defaults. - */ -extern JS_PUBLIC_API(void) -JS_ResetDefaultLocale(JSContext* cx); - -/** - * Locale specific string conversion and error message callbacks. - */ -struct JSLocaleCallbacks { - JSLocaleToUpperCase localeToUpperCase; - JSLocaleToLowerCase localeToLowerCase; - JSLocaleCompare localeCompare; // not used #if EXPOSE_INTL_API - JSLocaleToUnicode localeToUnicode; -}; - -/** - * Establish locale callbacks. The pointer must persist as long as the - * JSContext. Passing nullptr restores the default behaviour. - */ -extern JS_PUBLIC_API(void) -JS_SetLocaleCallbacks(JSContext* cx, const JSLocaleCallbacks* callbacks); - -/** - * Return the address of the current locale callbacks struct, which may - * be nullptr. - */ -extern JS_PUBLIC_API(const JSLocaleCallbacks*) -JS_GetLocaleCallbacks(JSContext* cx); - -/************************************************************************/ - -/* - * Error reporting. - */ - -namespace JS { -const uint16_t MaxNumErrorArguments = 10; -}; - -/** - * Report an exception represented by the sprintf-like conversion of format - * and its arguments. - */ -extern JS_PUBLIC_API(void) -JS_ReportErrorASCII(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -extern JS_PUBLIC_API(void) -JS_ReportErrorLatin1(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -extern JS_PUBLIC_API(void) -JS_ReportErrorUTF8(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -/* - * Use an errorNumber to retrieve the format string, args are char* - */ -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberASCII(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, ...); - -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberASCIIVA(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, va_list ap); - -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberLatin1(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, ...); - -#ifdef va_start -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberLatin1VA(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, va_list ap); -#endif - -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberUTF8(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, ...); - -#ifdef va_start -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberUTF8VA(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, va_list ap); -#endif - -/* - * Use an errorNumber to retrieve the format string, args are char16_t* - */ -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberUC(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, ...); - -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberUCArray(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, - const char16_t** args); - -/** - * As above, but report a warning instead (JSREPORT_IS_WARNING(report.flags)). - * Return true if there was no error trying to issue the warning, and if the - * warning was not converted into an error due to the JSOPTION_WERROR option - * being set, false otherwise. - */ -extern JS_PUBLIC_API(bool) -JS_ReportWarningASCII(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -extern JS_PUBLIC_API(bool) -JS_ReportWarningLatin1(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -extern JS_PUBLIC_API(bool) -JS_ReportWarningUTF8(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -extern JS_PUBLIC_API(bool) -JS_ReportErrorFlagsAndNumberASCII(JSContext* cx, unsigned flags, - JSErrorCallback errorCallback, void* userRef, - const unsigned errorNumber, ...); - -extern JS_PUBLIC_API(bool) -JS_ReportErrorFlagsAndNumberLatin1(JSContext* cx, unsigned flags, - JSErrorCallback errorCallback, void* userRef, - const unsigned errorNumber, ...); - -extern JS_PUBLIC_API(bool) -JS_ReportErrorFlagsAndNumberUTF8(JSContext* cx, unsigned flags, - JSErrorCallback errorCallback, void* userRef, - const unsigned errorNumber, ...); - -extern JS_PUBLIC_API(bool) -JS_ReportErrorFlagsAndNumberUC(JSContext* cx, unsigned flags, - JSErrorCallback errorCallback, void* userRef, - const unsigned errorNumber, ...); - -/** - * Complain when out of memory. - */ -extern JS_PUBLIC_API(void) -JS_ReportOutOfMemory(JSContext* cx); - -/** - * Complain when an allocation size overflows the maximum supported limit. - */ -extern JS_PUBLIC_API(void) -JS_ReportAllocationOverflow(JSContext* cx); - -class JSErrorReport -{ - // The (default) error message. - // If ownsMessage_ is true, the it is freed in destructor. - JS::ConstUTF8CharsZ message_; - - // Offending source line without final '\n'. - // If ownsLinebuf__ is true, the buffer is freed in destructor. - const char16_t* linebuf_; - - // Number of chars in linebuf_. Does not include trailing '\0'. - size_t linebufLength_; - - // The 0-based offset of error token in linebuf_. - size_t tokenOffset_; - - public: - JSErrorReport() - : linebuf_(nullptr), linebufLength_(0), tokenOffset_(0), - filename(nullptr), lineno(0), column(0), - flags(0), errorNumber(0), - exnType(0), isMuted(false), - ownsLinebuf_(false), ownsMessage_(false) - {} - - ~JSErrorReport() { - freeLinebuf(); - freeMessage(); - } - - const char* filename; /* source file name, URL, etc., or null */ - unsigned lineno; /* source line number */ - unsigned column; /* zero-based column index in line */ - unsigned flags; /* error/warning, etc. */ - unsigned errorNumber; /* the error number, e.g. see js.msg */ - int16_t exnType; /* One of the JSExnType constants */ - bool isMuted : 1; /* See the comment in ReadOnlyCompileOptions. */ - - private: - bool ownsLinebuf_ : 1; - bool ownsMessage_ : 1; - - public: - const char16_t* linebuf() const { - return linebuf_; - } - size_t linebufLength() const { - return linebufLength_; - } - size_t tokenOffset() const { - return tokenOffset_; - } - void initOwnedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg, size_t tokenOffsetArg) { - initBorrowedLinebuf(linebufArg, linebufLengthArg, tokenOffsetArg); - ownsLinebuf_ = true; - } - void initBorrowedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg, size_t tokenOffsetArg); - void freeLinebuf(); - - const JS::ConstUTF8CharsZ message() const { - return message_; - } - - void initOwnedMessage(const char* messageArg) { - initBorrowedMessage(messageArg); - ownsMessage_ = true; - } - void initBorrowedMessage(const char* messageArg) { - MOZ_ASSERT(!message_); - message_ = JS::ConstUTF8CharsZ(messageArg, strlen(messageArg)); - } - - JSString* newMessageString(JSContext* cx); - - void freeMessage(); -}; - -/* - * JSErrorReport flag values. These may be freely composed. - */ -#define JSREPORT_ERROR 0x0 /* pseudo-flag for default case */ -#define JSREPORT_WARNING 0x1 /* reported via JS_ReportWarning */ -#define JSREPORT_EXCEPTION 0x2 /* exception was thrown */ -#define JSREPORT_STRICT 0x4 /* error or warning due to strict option */ - -#define JSREPORT_USER_1 0x8 /* user-defined flag */ - -/* - * If JSREPORT_EXCEPTION is set, then a JavaScript-catchable exception - * has been thrown for this runtime error, and the host should ignore it. - * Exception-aware hosts should also check for JS_IsExceptionPending if - * JS_ExecuteScript returns failure, and signal or propagate the exception, as - * appropriate. - */ -#define JSREPORT_IS_WARNING(flags) (((flags) & JSREPORT_WARNING) != 0) -#define JSREPORT_IS_EXCEPTION(flags) (((flags) & JSREPORT_EXCEPTION) != 0) -#define JSREPORT_IS_STRICT(flags) (((flags) & JSREPORT_STRICT) != 0) - -namespace JS { - -using WarningReporter = void (*)(JSContext* cx, JSErrorReport* report); - -extern JS_PUBLIC_API(WarningReporter) -SetWarningReporter(JSContext* cx, WarningReporter reporter); - -extern JS_PUBLIC_API(WarningReporter) -GetWarningReporter(JSContext* cx); - -extern JS_PUBLIC_API(bool) -CreateError(JSContext* cx, JSExnType type, HandleObject stack, - HandleString fileName, uint32_t lineNumber, uint32_t columnNumber, - JSErrorReport* report, HandleString message, MutableHandleValue rval); - -/************************************************************************/ - -/* - * Weak Maps. - */ - -extern JS_PUBLIC_API(JSObject*) -NewWeakMapObject(JSContext* cx); - -extern JS_PUBLIC_API(bool) -IsWeakMapObject(JSObject* obj); - -extern JS_PUBLIC_API(bool) -GetWeakMapEntry(JSContext* cx, JS::HandleObject mapObj, JS::HandleObject key, - JS::MutableHandleValue val); - -extern JS_PUBLIC_API(bool) -SetWeakMapEntry(JSContext* cx, JS::HandleObject mapObj, JS::HandleObject key, - JS::HandleValue val); - -/* - * Map - */ -extern JS_PUBLIC_API(JSObject*) -NewMapObject(JSContext* cx); - -extern JS_PUBLIC_API(uint32_t) -MapSize(JSContext* cx, HandleObject obj); - -extern JS_PUBLIC_API(bool) -MapGet(JSContext* cx, HandleObject obj, - HandleValue key, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -MapHas(JSContext* cx, HandleObject obj, HandleValue key, bool* rval); - -extern JS_PUBLIC_API(bool) -MapSet(JSContext* cx, HandleObject obj, HandleValue key, HandleValue val); - -extern JS_PUBLIC_API(bool) -MapDelete(JSContext *cx, HandleObject obj, HandleValue key, bool *rval); - -extern JS_PUBLIC_API(bool) -MapClear(JSContext* cx, HandleObject obj); - -extern JS_PUBLIC_API(bool) -MapKeys(JSContext* cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -MapValues(JSContext* cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -MapEntries(JSContext* cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -MapForEach(JSContext *cx, HandleObject obj, HandleValue callbackFn, HandleValue thisVal); - -/* - * Set - */ -extern JS_PUBLIC_API(JSObject *) -NewSetObject(JSContext *cx); - -extern JS_PUBLIC_API(uint32_t) -SetSize(JSContext *cx, HandleObject obj); - -extern JS_PUBLIC_API(bool) -SetHas(JSContext *cx, HandleObject obj, HandleValue key, bool *rval); - -extern JS_PUBLIC_API(bool) -SetDelete(JSContext *cx, HandleObject obj, HandleValue key, bool *rval); - -extern JS_PUBLIC_API(bool) -SetAdd(JSContext *cx, HandleObject obj, HandleValue key); - -extern JS_PUBLIC_API(bool) -SetClear(JSContext *cx, HandleObject obj); - -extern JS_PUBLIC_API(bool) -SetKeys(JSContext *cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -SetValues(JSContext *cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -SetEntries(JSContext *cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -SetForEach(JSContext *cx, HandleObject obj, HandleValue callbackFn, HandleValue thisVal); - -} /* namespace JS */ - -/* - * Dates. - */ - -extern JS_PUBLIC_API(JSObject*) -JS_NewDateObject(JSContext* cx, int year, int mon, int mday, int hour, int min, int sec); - -/** - * Returns true and sets |*isDate| indicating whether |obj| is a Date object or - * a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isDate == false| when passed a proxy whose - * target is a Date, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -JS_ObjectIsDate(JSContext* cx, JS::HandleObject obj, bool* isDate); - -/************************************************************************/ - -/* - * Regular Expressions. - */ -#define JSREG_FOLD 0x01u /* fold uppercase to lowercase */ -#define JSREG_GLOB 0x02u /* global exec, creates array of matches */ -#define JSREG_MULTILINE 0x04u /* treat ^ and $ as begin and end of line */ -#define JSREG_STICKY 0x08u /* only match starting at lastIndex */ -#define JSREG_UNICODE 0x10u /* unicode */ - -extern JS_PUBLIC_API(JSObject*) -JS_NewRegExpObject(JSContext* cx, const char* bytes, size_t length, unsigned flags); - -extern JS_PUBLIC_API(JSObject*) -JS_NewUCRegExpObject(JSContext* cx, const char16_t* chars, size_t length, unsigned flags); - -extern JS_PUBLIC_API(bool) -JS_SetRegExpInput(JSContext* cx, JS::HandleObject obj, JS::HandleString input); - -extern JS_PUBLIC_API(bool) -JS_ClearRegExpStatics(JSContext* cx, JS::HandleObject obj); - -extern JS_PUBLIC_API(bool) -JS_ExecuteRegExp(JSContext* cx, JS::HandleObject obj, JS::HandleObject reobj, - char16_t* chars, size_t length, size_t* indexp, bool test, - JS::MutableHandleValue rval); - -/* RegExp interface for clients without a global object. */ - -extern JS_PUBLIC_API(bool) -JS_ExecuteRegExpNoStatics(JSContext* cx, JS::HandleObject reobj, char16_t* chars, size_t length, - size_t* indexp, bool test, JS::MutableHandleValue rval); - -/** - * Returns true and sets |*isRegExp| indicating whether |obj| is a RegExp - * object or a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isRegExp == false| when passed a proxy whose - * target is a RegExp, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -JS_ObjectIsRegExp(JSContext* cx, JS::HandleObject obj, bool* isRegExp); - -extern JS_PUBLIC_API(unsigned) -JS_GetRegExpFlags(JSContext* cx, JS::HandleObject obj); - -extern JS_PUBLIC_API(JSString*) -JS_GetRegExpSource(JSContext* cx, JS::HandleObject obj); - -/************************************************************************/ - -extern JS_PUBLIC_API(bool) -JS_IsExceptionPending(JSContext* cx); - -extern JS_PUBLIC_API(bool) -JS_GetPendingException(JSContext* cx, JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(void) -JS_SetPendingException(JSContext* cx, JS::HandleValue v); - -extern JS_PUBLIC_API(void) -JS_ClearPendingException(JSContext* cx); - -namespace JS { - -/** - * Save and later restore the current exception state of a given JSContext. - * This is useful for implementing behavior in C++ that's like try/catch - * or try/finally in JS. - * - * Typical usage: - * - * bool ok = JS::Evaluate(cx, ...); - * AutoSaveExceptionState savedExc(cx); - * ... cleanup that might re-enter JS ... - * return ok; - */ -class JS_PUBLIC_API(AutoSaveExceptionState) -{ - private: - JSContext* context; - bool wasPropagatingForcedReturn; - bool wasOverRecursed; - bool wasThrowing; - RootedValue exceptionValue; - - public: - /* - * Take a snapshot of cx's current exception state. Then clear any current - * pending exception in cx. - */ - explicit AutoSaveExceptionState(JSContext* cx); - - /* - * If neither drop() nor restore() was called, restore the exception - * state only if no exception is currently pending on cx. - */ - ~AutoSaveExceptionState(); - - /* - * Discard any stored exception state. - * If this is called, the destructor is a no-op. - */ - void drop() { - wasPropagatingForcedReturn = false; - wasOverRecursed = false; - wasThrowing = false; - exceptionValue.setUndefined(); - } - - /* - * Replace cx's exception state with the stored exception state. Then - * discard the stored exception state. If this is called, the - * destructor is a no-op. - */ - void restore(); -}; - -} /* namespace JS */ - -/* Deprecated API. Use AutoSaveExceptionState instead. */ -extern JS_PUBLIC_API(JSExceptionState*) -JS_SaveExceptionState(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_RestoreExceptionState(JSContext* cx, JSExceptionState* state); - -extern JS_PUBLIC_API(void) -JS_DropExceptionState(JSContext* cx, JSExceptionState* state); - -/** - * If the given object is an exception object, the exception will have (or be - * able to lazily create) an error report struct, and this function will return - * the address of that struct. Otherwise, it returns nullptr. The lifetime - * of the error report struct that might be returned is the same as the - * lifetime of the exception object. - */ -extern JS_PUBLIC_API(JSErrorReport*) -JS_ErrorFromException(JSContext* cx, JS::HandleObject obj); - -/** - * If the given object is an exception object (or an unwrappable - * cross-compartment wrapper for one), return the stack for that exception, if - * any. Will return null if the given object is not an exception object - * (including if it's null or a security wrapper that can't be unwrapped) or if - * the exception has no stack. - */ -extern JS_PUBLIC_API(JSObject*) -ExceptionStackOrNull(JS::HandleObject obj); - -/* - * Throws a StopIteration exception on cx. - */ -extern JS_PUBLIC_API(bool) -JS_ThrowStopIteration(JSContext* cx); - -extern JS_PUBLIC_API(bool) -JS_IsStopIteration(const JS::Value& v); - -/** - * A JS context always has an "owner thread". The owner thread is set when the - * context is created (to the current thread) and practically all entry points - * into the JS engine check that a context (or anything contained in the - * context: runtime, compartment, object, etc) is only touched by its owner - * thread. Embeddings may check this invariant outside the JS engine by calling - * JS_AbortIfWrongThread (which will abort if not on the owner thread, even for - * non-debug builds). - */ - -extern JS_PUBLIC_API(void) -JS_AbortIfWrongThread(JSContext* cx); - -/************************************************************************/ - -/** - * A constructor can request that the JS engine create a default new 'this' - * object of the given class, using the callee to determine parentage and - * [[Prototype]]. - */ -extern JS_PUBLIC_API(JSObject*) -JS_NewObjectForConstructor(JSContext* cx, const JSClass* clasp, const JS::CallArgs& args); - -/************************************************************************/ - -#ifdef JS_GC_ZEAL -#define JS_DEFAULT_ZEAL_FREQ 100 - -extern JS_PUBLIC_API(void) -JS_GetGCZealBits(JSContext* cx, uint32_t* zealBits, uint32_t* frequency, uint32_t* nextScheduled); - -extern JS_PUBLIC_API(void) -JS_SetGCZeal(JSContext* cx, uint8_t zeal, uint32_t frequency); - -extern JS_PUBLIC_API(void) -JS_ScheduleGC(JSContext* cx, uint32_t count); -#endif - -extern JS_PUBLIC_API(void) -JS_SetParallelParsingEnabled(JSContext* cx, bool enabled); - -extern JS_PUBLIC_API(void) -JS_SetOffthreadIonCompilationEnabled(JSContext* cx, bool enabled); - -#define JIT_COMPILER_OPTIONS(Register) \ - Register(BASELINE_WARMUP_TRIGGER, "baseline.warmup.trigger") \ - Register(ION_WARMUP_TRIGGER, "ion.warmup.trigger") \ - Register(ION_GVN_ENABLE, "ion.gvn.enable") \ - Register(ION_FORCE_IC, "ion.forceinlineCaches") \ - Register(ION_ENABLE, "ion.enable") \ - Register(ION_INTERRUPT_WITHOUT_SIGNAL, "ion.interrupt-without-signals") \ - Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis") \ - Register(BASELINE_ENABLE, "baseline.enable") \ - Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \ - Register(JUMP_THRESHOLD, "jump-threshold") \ - Register(ASMJS_ATOMICS_ENABLE, "asmjs.atomics.enable") \ - Register(WASM_TEST_MODE, "wasm.test-mode") \ - Register(WASM_FOLD_OFFSETS, "wasm.fold-offsets") - -typedef enum JSJitCompilerOption { -#define JIT_COMPILER_DECLARE(key, str) \ - JSJITCOMPILER_ ## key, - - JIT_COMPILER_OPTIONS(JIT_COMPILER_DECLARE) -#undef JIT_COMPILER_DECLARE - - JSJITCOMPILER_NOT_AN_OPTION -} JSJitCompilerOption; - -extern JS_PUBLIC_API(void) -JS_SetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t value); -extern JS_PUBLIC_API(bool) -JS_GetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t* valueOut); - -/** - * Convert a uint32_t index into a jsid. - */ -extern JS_PUBLIC_API(bool) -JS_IndexToId(JSContext* cx, uint32_t index, JS::MutableHandleId); - -/** - * Convert chars into a jsid. - * - * |chars| may not be an index. - */ -extern JS_PUBLIC_API(bool) -JS_CharsToId(JSContext* cx, JS::TwoByteChars chars, JS::MutableHandleId); - -/** - * Test if the given string is a valid ECMAScript identifier - */ -extern JS_PUBLIC_API(bool) -JS_IsIdentifier(JSContext* cx, JS::HandleString str, bool* isIdentifier); - -/** - * Test whether the given chars + length are a valid ECMAScript identifier. - * This version is infallible, so just returns whether the chars are an - * identifier. - */ -extern JS_PUBLIC_API(bool) -JS_IsIdentifier(const char16_t* chars, size_t length); - -namespace js { -class ScriptSource; -} // namespace js - -namespace JS { - -class MOZ_RAII JS_PUBLIC_API(AutoFilename) -{ - private: - js::ScriptSource* ss_; - mozilla::Variant filename_; - - AutoFilename(const AutoFilename&) = delete; - AutoFilename& operator=(const AutoFilename&) = delete; - - public: - AutoFilename() - : ss_(nullptr), - filename_(mozilla::AsVariant(nullptr)) - {} - - ~AutoFilename() { - reset(); - } - - void reset(); - - void setOwned(UniqueChars&& filename); - void setUnowned(const char* filename); - void setScriptSource(js::ScriptSource* ss); - - const char* get() const; -}; - -/** - * Return the current filename, line number and column number of the most - * currently running frame. Returns true if a scripted frame was found, false - * otherwise. - * - * If a the embedding has hidden the scripted caller for the topmost activation - * record, this will also return false. - */ -extern JS_PUBLIC_API(bool) -DescribeScriptedCaller(JSContext* cx, AutoFilename* filename = nullptr, - unsigned* lineno = nullptr, unsigned* column = nullptr); - -extern JS_PUBLIC_API(JSObject*) -GetScriptedCallerGlobal(JSContext* cx); - -/** - * Informs the JS engine that the scripted caller should be hidden. This can be - * used by the embedding to maintain an override of the scripted caller in its - * calculations, by hiding the scripted caller in the JS engine and pushing data - * onto a separate stack, which it inspects when DescribeScriptedCaller returns - * null. - * - * We maintain a counter on each activation record. Add() increments the counter - * of the topmost activation, and Remove() decrements it. The count may never - * drop below zero, and must always be exactly zero when the activation is - * popped from the stack. - */ -extern JS_PUBLIC_API(void) -HideScriptedCaller(JSContext* cx); - -extern JS_PUBLIC_API(void) -UnhideScriptedCaller(JSContext* cx); - -class MOZ_RAII AutoHideScriptedCaller -{ - public: - explicit AutoHideScriptedCaller(JSContext* cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mContext(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - HideScriptedCaller(mContext); - } - ~AutoHideScriptedCaller() { - UnhideScriptedCaller(mContext); - } - - protected: - JSContext* mContext; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -/* - * Encode/Decode interpreted scripts and functions to/from memory. - */ - -typedef mozilla::Vector TranscodeBuffer; - -enum TranscodeResult -{ - // Successful encoding / decoding. - TranscodeResult_Ok = 0, - - // A warning message, is set to the message out-param. - TranscodeResult_Failure = 0x100, - TranscodeResult_Failure_BadBuildId = TranscodeResult_Failure | 0x1, - TranscodeResult_Failure_RunOnceNotSupported = TranscodeResult_Failure | 0x2, - TranscodeResult_Failure_AsmJSNotSupported = TranscodeResult_Failure | 0x3, - TranscodeResult_Failure_UnknownClassKind = TranscodeResult_Failure | 0x4, - - // A error, the JSContext has a pending exception. - TranscodeResult_Throw = 0x200 -}; - -extern JS_PUBLIC_API(TranscodeResult) -EncodeScript(JSContext* cx, TranscodeBuffer& buffer, JS::HandleScript script); - -extern JS_PUBLIC_API(TranscodeResult) -EncodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::HandleObject funobj); - -extern JS_PUBLIC_API(TranscodeResult) -DecodeScript(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleScript scriptp, - size_t cursorIndex = 0); - -extern JS_PUBLIC_API(TranscodeResult) -DecodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleFunction funp, - size_t cursorIndex = 0); - -} /* namespace JS */ - -namespace js { - -enum class StackFormat { SpiderMonkey, V8, Default }; - -/* - * Sets the format used for stringifying Error stacks. - * - * The default format is StackFormat::SpiderMonkey. Use StackFormat::V8 - * in order to emulate V8's stack formatting. StackFormat::Default can't be - * used here. - */ -extern JS_PUBLIC_API(void) -SetStackFormat(JSContext* cx, StackFormat format); - -extern JS_PUBLIC_API(StackFormat) -GetStackFormat(JSContext* cx); - -} - -namespace JS { - -/* - * This callback represents a request by the JS engine to open for reading the - * existing cache entry for the given global and char range that may contain a - * module. If a cache entry exists, the callback shall return 'true' and return - * the size, base address and an opaque file handle as outparams. If the - * callback returns 'true', the JS engine guarantees a call to - * CloseAsmJSCacheEntryForReadOp, passing the same base address, size and - * handle. - */ -typedef bool -(* OpenAsmJSCacheEntryForReadOp)(HandleObject global, const char16_t* begin, const char16_t* limit, - size_t* size, const uint8_t** memory, intptr_t* handle); -typedef void -(* CloseAsmJSCacheEntryForReadOp)(size_t size, const uint8_t* memory, intptr_t handle); - -/** The list of reasons why an asm.js module may not be stored in the cache. */ -enum AsmJSCacheResult -{ - AsmJSCache_Success, - AsmJSCache_MIN = AsmJSCache_Success, - AsmJSCache_ModuleTooSmall, - AsmJSCache_SynchronousScript, - AsmJSCache_QuotaExceeded, - AsmJSCache_StorageInitFailure, - AsmJSCache_Disabled_Internal, - AsmJSCache_Disabled_ShellFlags, - AsmJSCache_Disabled_JitInspector, - AsmJSCache_InternalError, - AsmJSCache_Disabled_PrivateBrowsing, - AsmJSCache_LIMIT -}; - -/* - * This callback represents a request by the JS engine to open for writing a - * cache entry of the given size for the given global and char range containing - * the just-compiled module. If cache entry space is available, the callback - * shall return 'true' and return the base address and an opaque file handle as - * outparams. If the callback returns 'true', the JS engine guarantees a call - * to CloseAsmJSCacheEntryForWriteOp passing the same base address, size and - * handle. - * - * If 'installed' is true, then the cache entry is associated with a permanently - * installed JS file (e.g., in a packaged webapp). This information allows the - * embedding to store the cache entry in a installed location associated with - * the principal of 'global' where it will not be evicted until the associated - * installed JS file is removed. - */ -typedef AsmJSCacheResult -(* OpenAsmJSCacheEntryForWriteOp)(HandleObject global, bool installed, - const char16_t* begin, const char16_t* end, - size_t size, uint8_t** memory, intptr_t* handle); -typedef void -(* CloseAsmJSCacheEntryForWriteOp)(size_t size, uint8_t* memory, intptr_t handle); - -struct AsmJSCacheOps -{ - OpenAsmJSCacheEntryForReadOp openEntryForRead; - CloseAsmJSCacheEntryForReadOp closeEntryForRead; - OpenAsmJSCacheEntryForWriteOp openEntryForWrite; - CloseAsmJSCacheEntryForWriteOp closeEntryForWrite; -}; - -extern JS_PUBLIC_API(void) -SetAsmJSCacheOps(JSContext* cx, const AsmJSCacheOps* callbacks); - -/** - * Return the buildId (represented as a sequence of characters) associated with - * the currently-executing build. If the JS engine is embedded such that a - * single cache entry can be observed by different compiled versions of the JS - * engine, it is critical that the buildId shall change for each new build of - * the JS engine. - */ -typedef js::Vector BuildIdCharVector; - -typedef bool -(* BuildIdOp)(BuildIdCharVector* buildId); - -extern JS_PUBLIC_API(void) -SetBuildIdOp(JSContext* cx, BuildIdOp buildIdOp); - -/** - * The WasmModule interface allows the embedding to hold a reference to the - * underying C++ implementation of a JS WebAssembly.Module object for purposes - * of (de)serialization off the object's JSRuntime's thread. - * - * - Serialization starts when WebAssembly.Module is passed to the - * structured-clone algorithm. JS::GetWasmModule is called on the JSRuntime - * thread that initiated the structured clone to get the JS::WasmModule. - * This interface is then taken to a background thread where serializedSize() - * and serialize() are called to write the object to two files: a bytecode file - * that always allows successful deserialization and a compiled-code file keyed - * on cpu- and build-id that may become invalid if either of these change between - * serialization and deserialization. After serialization, the reference is - * dropped from the background thread. - * - * - Deserialization starts when the structured clone algorithm encounters a - * serialized WebAssembly.Module. On a background thread, the compiled-code file - * is opened and CompiledWasmModuleAssumptionsMatch is called to see if it is - * still valid (as described above). DeserializeWasmModule is then called to - * construct a JS::WasmModule (also on the background thread), passing the - * bytecode file descriptor and, if valid, the compiled-code file descriptor. - * The JS::WasmObject is then transported to the JSRuntime thread (which - * originated the request) and the wrapping WebAssembly.Module object is created - * by calling createObject(). - */ - -struct WasmModule : mozilla::external::AtomicRefCounted -{ - MOZ_DECLARE_REFCOUNTED_TYPENAME(WasmModule) - virtual ~WasmModule() {} - - virtual void serializedSize(size_t* maybeBytecodeSize, size_t* maybeCompiledSize) const = 0; - virtual void serialize(uint8_t* maybeBytecodeBegin, size_t maybeBytecodeSize, - uint8_t* maybeCompiledBegin, size_t maybeCompiledSize) const = 0; - - virtual JSObject* createObject(JSContext* cx) = 0; -}; - -extern JS_PUBLIC_API(bool) -IsWasmModuleObject(HandleObject obj); - -extern JS_PUBLIC_API(RefPtr) -GetWasmModule(HandleObject obj); - -extern JS_PUBLIC_API(bool) -CompiledWasmModuleAssumptionsMatch(PRFileDesc* compiled, BuildIdCharVector&& buildId); - -extern JS_PUBLIC_API(RefPtr) -DeserializeWasmModule(PRFileDesc* bytecode, PRFileDesc* maybeCompiled, BuildIdCharVector&& buildId, - JS::UniqueChars filename, unsigned line, unsigned column); - -/** - * Convenience class for imitating a JS level for-of loop. Typical usage: - * - * ForOfIterator it(cx); - * if (!it.init(iterable)) - * return false; - * RootedValue val(cx); - * while (true) { - * bool done; - * if (!it.next(&val, &done)) - * return false; - * if (done) - * break; - * if (!DoStuff(cx, val)) - * return false; - * } - */ -class MOZ_STACK_CLASS JS_PUBLIC_API(ForOfIterator) { - protected: - JSContext* cx_; - /* - * Use the ForOfPIC on the global object (see vm/GlobalObject.h) to try - * to optimize iteration across arrays. - * - * Case 1: Regular Iteration - * iterator - pointer to the iterator object. - * index - fixed to NOT_ARRAY (== UINT32_MAX) - * - * Case 2: Optimized Array Iteration - * iterator - pointer to the array object. - * index - current position in array. - * - * The cases are distinguished by whether or not |index| is equal to NOT_ARRAY. - */ - JS::RootedObject iterator; - uint32_t index; - - static const uint32_t NOT_ARRAY = UINT32_MAX; - - ForOfIterator(const ForOfIterator&) = delete; - ForOfIterator& operator=(const ForOfIterator&) = delete; - - public: - explicit ForOfIterator(JSContext* cx) : cx_(cx), iterator(cx_), index(NOT_ARRAY) { } - - enum NonIterableBehavior { - ThrowOnNonIterable, - AllowNonIterable - }; - - /** - * Initialize the iterator. If AllowNonIterable is passed then if getting - * the @@iterator property from iterable returns undefined init() will just - * return true instead of throwing. Callers must then check - * valueIsIterable() before continuing with the iteration. - */ - bool init(JS::HandleValue iterable, - NonIterableBehavior nonIterableBehavior = ThrowOnNonIterable); - - /** - * Get the next value from the iterator. If false *done is true - * after this call, do not examine val. - */ - bool next(JS::MutableHandleValue val, bool* done); - - /** - * If initialized with throwOnNonCallable = false, check whether - * the value is iterable. - */ - bool valueIsIterable() const { - return iterator; - } - - private: - inline bool nextFromOptimizedArray(MutableHandleValue val, bool* done); - bool materializeArrayIterator(); -}; - - -/** - * If a large allocation fails when calling pod_{calloc,realloc}CanGC, the JS - * engine may call the large-allocation- failure callback, if set, to allow the - * embedding to flush caches, possibly perform shrinking GCs, etc. to make some - * room. The allocation will then be retried (and may still fail.) - */ - -typedef void -(* LargeAllocationFailureCallback)(void* data); - -extern JS_PUBLIC_API(void) -SetLargeAllocationFailureCallback(JSContext* cx, LargeAllocationFailureCallback afc, void* data); - -/** - * Unlike the error reporter, which is only called if the exception for an OOM - * bubbles up and is not caught, the OutOfMemoryCallback is called immediately - * at the OOM site to allow the embedding to capture the current state of heap - * allocation before anything is freed. If the large-allocation-failure callback - * is called at all (not all allocation sites call the large-allocation-failure - * callback on failure), it is called before the out-of-memory callback; the - * out-of-memory callback is only called if the allocation still fails after the - * large-allocation-failure callback has returned. - */ - -typedef void -(* OutOfMemoryCallback)(JSContext* cx, void* data); - -extern JS_PUBLIC_API(void) -SetOutOfMemoryCallback(JSContext* cx, OutOfMemoryCallback cb, void* data); - -/** - * Capture all frames. - */ -struct AllFrames { }; - -/** - * Capture at most this many frames. - */ -struct MaxFrames -{ - uint32_t maxFrames; - - explicit MaxFrames(uint32_t max) - : maxFrames(max) - { - MOZ_ASSERT(max > 0); - } -}; - -/** - * Capture the first frame with the given principals. By default, do not - * consider self-hosted frames with the given principals as satisfying the stack - * capture. - */ -struct FirstSubsumedFrame -{ - JSContext* cx; - JSPrincipals* principals; - bool ignoreSelfHosted; - - /** - * Use the cx's current compartment's principals. - */ - explicit FirstSubsumedFrame(JSContext* cx, bool ignoreSelfHostedFrames = true); - - explicit FirstSubsumedFrame(JSContext* ctx, JSPrincipals* p, bool ignoreSelfHostedFrames = true) - : cx(ctx) - , principals(p) - , ignoreSelfHosted(ignoreSelfHostedFrames) - { - if (principals) - JS_HoldPrincipals(principals); - } - - // No copying because we want to avoid holding and dropping principals - // unnecessarily. - FirstSubsumedFrame(const FirstSubsumedFrame&) = delete; - FirstSubsumedFrame& operator=(const FirstSubsumedFrame&) = delete; - - FirstSubsumedFrame(FirstSubsumedFrame&& rhs) - : principals(rhs.principals) - , ignoreSelfHosted(rhs.ignoreSelfHosted) - { - MOZ_ASSERT(this != &rhs, "self move disallowed"); - rhs.principals = nullptr; - } - - FirstSubsumedFrame& operator=(FirstSubsumedFrame&& rhs) { - new (this) FirstSubsumedFrame(mozilla::Move(rhs)); - return *this; - } - - ~FirstSubsumedFrame() { - if (principals) - JS_DropPrincipals(cx, principals); - } -}; - -using StackCapture = mozilla::Variant; - -/** - * Capture the current call stack as a chain of SavedFrame JSObjects, and set - * |stackp| to the SavedFrame for the youngest stack frame, or nullptr if there - * are no JS frames on the stack. - * - * The |capture| parameter describes the portion of the JS stack to capture: - * - * * |JS::AllFrames|: Capture all frames on the stack. - * - * * |JS::MaxFrames|: Capture no more than |JS::MaxFrames::maxFrames| from the - * stack. - * - * * |JS::FirstSubsumedFrame|: Capture the first frame whose principals are - * subsumed by |JS::FirstSubsumedFrame::principals|. By default, do not - * consider self-hosted frames; this can be controlled via the - * |JS::FirstSubsumedFrame::ignoreSelfHosted| flag. Do not capture any async - * stack. - */ -extern JS_PUBLIC_API(bool) -CaptureCurrentStack(JSContext* cx, MutableHandleObject stackp, - StackCapture&& capture = StackCapture(AllFrames())); - -/* - * This is a utility function for preparing an async stack to be used - * by some other object. This may be used when you need to treat a - * given stack trace as an async parent. If you just need to capture - * the current stack, async parents and all, use CaptureCurrentStack - * instead. - * - * Here |asyncStack| is the async stack to prepare. It is copied into - * |cx|'s current compartment, and the newest frame is given - * |asyncCause| as its asynchronous cause. If |maxFrameCount| is - * non-zero, capture at most the youngest |maxFrameCount| frames. The - * new stack object is written to |stackp|. Returns true on success, - * or sets an exception and returns |false| on error. - */ -extern JS_PUBLIC_API(bool) -CopyAsyncStack(JSContext* cx, HandleObject asyncStack, - HandleString asyncCause, MutableHandleObject stackp, - unsigned maxFrameCount); - -/* - * Accessors for working with SavedFrame JSObjects - * - * Each of these functions assert that if their `HandleObject savedFrame` - * argument is non-null, its JSClass is the SavedFrame class (or it is a - * cross-compartment or Xray wrapper around an object with the SavedFrame class) - * and the object is not the SavedFrame.prototype object. - * - * Each of these functions will find the first SavedFrame object in the chain - * whose underlying stack frame principals are subsumed by the cx's current - * compartment's principals, and operate on that SavedFrame object. This - * prevents leaking information about privileged frames to un-privileged - * callers. As a result, the SavedFrame in parameters do _NOT_ need to be in the - * same compartment as the cx, and the various out parameters are _NOT_ - * guaranteed to be in the same compartment as cx. - * - * You may consider or skip over self-hosted frames by passing - * `SavedFrameSelfHosted::Include` or `SavedFrameSelfHosted::Exclude` - * respectively. - * - * Additionally, it may be the case that there is no such SavedFrame object - * whose captured frame's principals are subsumed by the caller's compartment's - * principals! If the `HandleObject savedFrame` argument is null, or the - * caller's principals do not subsume any of the chained SavedFrame object's - * principals, `SavedFrameResult::AccessDenied` is returned and a (hopefully) - * sane default value is chosen for the out param. - * - * See also `js/src/doc/SavedFrame/SavedFrame.md`. - */ - -enum class SavedFrameResult { - Ok, - AccessDenied -}; - -enum class SavedFrameSelfHosted { - Include, - Exclude -}; - -/** - * Given a SavedFrame JSObject, get its source property. Defaults to the empty - * string. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameSource(JSContext* cx, HandleObject savedFrame, MutableHandleString sourcep, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its line property. Defaults to 0. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameLine(JSContext* cx, HandleObject savedFrame, uint32_t* linep, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its column property. Defaults to 0. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameColumn(JSContext* cx, HandleObject savedFrame, uint32_t* columnp, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its functionDisplayName string, or nullptr - * if SpiderMonkey was unable to infer a name for the captured frame's - * function. Defaults to nullptr. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameFunctionDisplayName(JSContext* cx, HandleObject savedFrame, MutableHandleString namep, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its asyncCause string. Defaults to nullptr. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameAsyncCause(JSContext* cx, HandleObject savedFrame, MutableHandleString asyncCausep, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its asyncParent SavedFrame object or nullptr - * if there is no asyncParent. The `asyncParentp` out parameter is _NOT_ - * guaranteed to be in the cx's compartment. Defaults to nullptr. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameAsyncParent(JSContext* cx, HandleObject savedFrame, MutableHandleObject asyncParentp, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its parent SavedFrame object or nullptr if - * it is the oldest frame in the stack. The `parentp` out parameter is _NOT_ - * guaranteed to be in the cx's compartment. Defaults to nullptr. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameParent(JSContext* cx, HandleObject savedFrame, MutableHandleObject parentp, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject stack, stringify it in the same format as - * Error.prototype.stack. The stringified stack out parameter is placed in the - * cx's compartment. Defaults to the empty string. - * - * The same notes above about SavedFrame accessors applies here as well: cx - * doesn't need to be in stack's compartment, and stack can be null, a - * SavedFrame object, or a wrapper (CCW or Xray) around a SavedFrame object. - * - * Optional indent parameter specifies the number of white spaces to indent - * each line. - */ -extern JS_PUBLIC_API(bool) -BuildStackString(JSContext* cx, HandleObject stack, MutableHandleString stringp, - size_t indent = 0, js::StackFormat stackFormat = js::StackFormat::Default); - -/** - * Return true iff the given object is either a SavedFrame object or wrapper - * around a SavedFrame object, and it is not the SavedFrame.prototype object. - */ -extern JS_PUBLIC_API(bool) -IsSavedFrame(JSObject* obj); - -} /* namespace JS */ - - -/* Stopwatch-based performance monitoring. */ - -namespace js { - -class AutoStopwatch; - -/** - * Abstract base class for a representation of the performance of a - * component. Embeddings interested in performance monitoring should - * provide a concrete implementation of this class, as well as the - * relevant callbacks (see below). - */ -struct PerformanceGroup { - PerformanceGroup(); - - // The current iteration of the event loop. - uint64_t iteration() const; - - // `true` if an instance of `AutoStopwatch` is already monitoring - // the performance of this performance group for this iteration - // of the event loop, `false` otherwise. - bool isAcquired(uint64_t it) const; - - // `true` if a specific instance of `AutoStopwatch` is already monitoring - // the performance of this performance group for this iteration - // of the event loop, `false` otherwise. - bool isAcquired(uint64_t it, const AutoStopwatch* owner) const; - - // Mark that an instance of `AutoStopwatch` is monitoring - // the performance of this group for a given iteration. - void acquire(uint64_t it, const AutoStopwatch* owner); - - // Mark that no `AutoStopwatch` is monitoring the - // performance of this group for the iteration. - void release(uint64_t it, const AutoStopwatch* owner); - - // The number of cycles spent in this group during this iteration - // of the event loop. Note that cycles are not a reliable measure, - // especially over short intervals. See Stopwatch.* for a more - // complete discussion on the imprecision of cycle measurement. - uint64_t recentCycles(uint64_t iteration) const; - void addRecentCycles(uint64_t iteration, uint64_t cycles); - - // The number of times this group has been activated during this - // iteration of the event loop. - uint64_t recentTicks(uint64_t iteration) const; - void addRecentTicks(uint64_t iteration, uint64_t ticks); - - // The number of microseconds spent doing CPOW during this - // iteration of the event loop. - uint64_t recentCPOW(uint64_t iteration) const; - void addRecentCPOW(uint64_t iteration, uint64_t CPOW); - - // Get rid of any data that pretends to be recent. - void resetRecentData(); - - // `true` if new measures should be added to this group, `false` - // otherwise. - bool isActive() const; - void setIsActive(bool); - - // `true` if this group has been used in the current iteration, - // `false` otherwise. - bool isUsedInThisIteration() const; - void setIsUsedInThisIteration(bool); - protected: - // An implementation of `delete` for this object. Must be provided - // by the embedding. - virtual void Delete() = 0; - - private: - // The number of cycles spent in this group during this iteration - // of the event loop. Note that cycles are not a reliable measure, - // especially over short intervals. See Runtime.cpp for a more - // complete discussion on the imprecision of cycle measurement. - uint64_t recentCycles_; - - // The number of times this group has been activated during this - // iteration of the event loop. - uint64_t recentTicks_; - - // The number of microseconds spent doing CPOW during this - // iteration of the event loop. - uint64_t recentCPOW_; - - // The current iteration of the event loop. If necessary, - // may safely overflow. - uint64_t iteration_; - - // `true` if new measures should be added to this group, `false` - // otherwise. - bool isActive_; - - // `true` if this group has been used in the current iteration, - // `false` otherwise. - bool isUsedInThisIteration_; - - // The stopwatch currently monitoring the group, - // or `nullptr` if none. Used ony for comparison. - const AutoStopwatch* owner_; - - public: - // Compatibility with RefPtr<> - void AddRef(); - void Release(); - uint64_t refCount_; -}; - -using PerformanceGroupVector = mozilla::Vector, 0, SystemAllocPolicy>; - -/** - * Commit any Performance Monitoring data. - * - * Until `FlushMonitoring` has been called, all PerformanceMonitoring data is invisible - * to the outside world and can cancelled with a call to `ResetMonitoring`. - */ -extern JS_PUBLIC_API(bool) -FlushPerformanceMonitoring(JSContext*); - -/** - * Cancel any measurement that hasn't been committed. - */ -extern JS_PUBLIC_API(void) -ResetPerformanceMonitoring(JSContext*); - -/** - * Cleanup any memory used by performance monitoring. - */ -extern JS_PUBLIC_API(void) -DisposePerformanceMonitoring(JSContext*); - -/** - * Turn on/off stopwatch-based CPU monitoring. - * - * `SetStopwatchIsMonitoringCPOW` or `SetStopwatchIsMonitoringJank` - * may return `false` if monitoring could not be activated, which may - * happen if we are out of memory. - */ -extern JS_PUBLIC_API(bool) -SetStopwatchIsMonitoringCPOW(JSContext*, bool); -extern JS_PUBLIC_API(bool) -GetStopwatchIsMonitoringCPOW(JSContext*); -extern JS_PUBLIC_API(bool) -SetStopwatchIsMonitoringJank(JSContext*, bool); -extern JS_PUBLIC_API(bool) -GetStopwatchIsMonitoringJank(JSContext*); - -// Extract the CPU rescheduling data. -extern JS_PUBLIC_API(void) -GetPerfMonitoringTestCpuRescheduling(JSContext*, uint64_t* stayed, uint64_t* moved); - - -/** - * Add a number of microseconds to the time spent waiting on CPOWs - * since process start. - */ -extern JS_PUBLIC_API(void) -AddCPOWPerformanceDelta(JSContext*, uint64_t delta); - -typedef bool -(*StopwatchStartCallback)(uint64_t, void*); -extern JS_PUBLIC_API(bool) -SetStopwatchStartCallback(JSContext*, StopwatchStartCallback, void*); - -typedef bool -(*StopwatchCommitCallback)(uint64_t, PerformanceGroupVector&, void*); -extern JS_PUBLIC_API(bool) -SetStopwatchCommitCallback(JSContext*, StopwatchCommitCallback, void*); - -typedef bool -(*GetGroupsCallback)(JSContext*, PerformanceGroupVector&, void*); -extern JS_PUBLIC_API(bool) -SetGetPerformanceGroupsCallback(JSContext*, GetGroupsCallback, void*); - -} /* namespace js */ - - -#endif /* jsapi_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/jsbytecode.h b/android/armeabi-v7a/include/spidermonkey/jsbytecode.h deleted file mode 100644 index 8e4f4cf9..00000000 --- a/android/armeabi-v7a/include/spidermonkey/jsbytecode.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsbytecode_h -#define jsbytecode_h - -#include - -typedef uint8_t jsbytecode; - -#endif /* jsbytecode_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/jsclist.h b/android/armeabi-v7a/include/spidermonkey/jsclist.h deleted file mode 100644 index b8455152..00000000 --- a/android/armeabi-v7a/include/spidermonkey/jsclist.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsclist_h -#define jsclist_h - -#include "jstypes.h" - -/* -** Circular linked list -*/ -typedef struct JSCListStr { - struct JSCListStr* next; - struct JSCListStr* prev; -} JSCList; - -/* -** Insert element "_e" into the list, before "_l". -*/ -#define JS_INSERT_BEFORE(_e,_l) \ - JS_BEGIN_MACRO \ - (_e)->next = (_l); \ - (_e)->prev = (_l)->prev; \ - (_l)->prev->next = (_e); \ - (_l)->prev = (_e); \ - JS_END_MACRO - -/* -** Insert element "_e" into the list, after "_l". -*/ -#define JS_INSERT_AFTER(_e,_l) \ - JS_BEGIN_MACRO \ - (_e)->next = (_l)->next; \ - (_e)->prev = (_l); \ - (_l)->next->prev = (_e); \ - (_l)->next = (_e); \ - JS_END_MACRO - -/* -** Return the element following element "_e" -*/ -#define JS_NEXT_LINK(_e) \ - ((_e)->next) -/* -** Return the element preceding element "_e" -*/ -#define JS_PREV_LINK(_e) \ - ((_e)->prev) - -/* -** Append an element "_e" to the end of the list "_l" -*/ -#define JS_APPEND_LINK(_e,_l) JS_INSERT_BEFORE(_e,_l) - -/* -** Insert an element "_e" at the head of the list "_l" -*/ -#define JS_INSERT_LINK(_e,_l) JS_INSERT_AFTER(_e,_l) - -/* Return the head/tail of the list */ -#define JS_LIST_HEAD(_l) (_l)->next -#define JS_LIST_TAIL(_l) (_l)->prev - -/* -** Remove the element "_e" from it's circular list. -*/ -#define JS_REMOVE_LINK(_e) \ - JS_BEGIN_MACRO \ - (_e)->prev->next = (_e)->next; \ - (_e)->next->prev = (_e)->prev; \ - JS_END_MACRO - -/* -** Remove the element "_e" from it's circular list. Also initializes the -** linkage. -*/ -#define JS_REMOVE_AND_INIT_LINK(_e) \ - JS_BEGIN_MACRO \ - (_e)->prev->next = (_e)->next; \ - (_e)->next->prev = (_e)->prev; \ - (_e)->next = (_e); \ - (_e)->prev = (_e); \ - JS_END_MACRO - -/* -** Return non-zero if the given circular list "_l" is empty, zero if the -** circular list is not empty -*/ -#define JS_CLIST_IS_EMPTY(_l) \ - bool((_l)->next == (_l)) - -/* -** Initialize a circular list -*/ -#define JS_INIT_CLIST(_l) \ - JS_BEGIN_MACRO \ - (_l)->next = (_l); \ - (_l)->prev = (_l); \ - JS_END_MACRO - -#define JS_INIT_STATIC_CLIST(_l) \ - {(_l), (_l)} - -#endif /* jsclist_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/jscpucfg.h b/android/armeabi-v7a/include/spidermonkey/jscpucfg.h deleted file mode 100644 index 80fdf6bb..00000000 --- a/android/armeabi-v7a/include/spidermonkey/jscpucfg.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jscpucfg_h -#define jscpucfg_h - -#include "mozilla/EndianUtils.h" - -#ifndef JS_STACK_GROWTH_DIRECTION -# ifdef __hppa -# define JS_STACK_GROWTH_DIRECTION (1) -# else -# define JS_STACK_GROWTH_DIRECTION (-1) -# endif -#endif - -#endif /* jscpucfg_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/jsfriendapi.h b/android/armeabi-v7a/include/spidermonkey/jsfriendapi.h deleted file mode 100644 index d6463d3d..00000000 --- a/android/armeabi-v7a/include/spidermonkey/jsfriendapi.h +++ /dev/null @@ -1,3067 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsfriendapi_h -#define jsfriendapi_h - -#include "mozilla/Atomics.h" -#include "mozilla/Casting.h" -#include "mozilla/Maybe.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/UniquePtr.h" - -#include "jsapi.h" // For JSAutoByteString. See bug 1033916. -#include "jsbytecode.h" -#include "jspubtd.h" - -#include "js/CallArgs.h" -#include "js/CallNonGenericMethod.h" -#include "js/Class.h" -#include "js/Utility.h" - -#if JS_STACK_GROWTH_DIRECTION > 0 -# define JS_CHECK_STACK_SIZE(limit, sp) (MOZ_LIKELY((uintptr_t)(sp) < (limit))) -#else -# define JS_CHECK_STACK_SIZE(limit, sp) (MOZ_LIKELY((uintptr_t)(sp) > (limit))) -#endif - -class JSAtom; -struct JSErrorFormatString; -class JSLinearString; -struct JSJitInfo; -class JSErrorReport; - -namespace JS { -template -class Heap; -} /* namespace JS */ - -namespace js { -class JS_FRIEND_API(BaseProxyHandler); -class InterpreterFrame; -} /* namespace js */ - -extern JS_FRIEND_API(void) -JS_SetGrayGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data); - -extern JS_FRIEND_API(JSObject*) -JS_FindCompilationScope(JSContext* cx, JS::HandleObject obj); - -extern JS_FRIEND_API(JSFunction*) -JS_GetObjectFunction(JSObject* obj); - -extern JS_FRIEND_API(bool) -JS_SplicePrototype(JSContext* cx, JS::HandleObject obj, JS::HandleObject proto); - -extern JS_FRIEND_API(JSObject*) -JS_NewObjectWithUniqueType(JSContext* cx, const JSClass* clasp, JS::HandleObject proto); - -/** - * Allocate an object in exactly the same way as JS_NewObjectWithGivenProto, but - * without invoking the metadata callback on it. This allows creation of - * internal bookkeeping objects that are guaranteed to not have metadata - * attached to them. - */ -extern JS_FRIEND_API(JSObject*) -JS_NewObjectWithoutMetadata(JSContext* cx, const JSClass* clasp, JS::Handle proto); - -extern JS_FRIEND_API(uint32_t) -JS_ObjectCountDynamicSlots(JS::HandleObject obj); - -extern JS_FRIEND_API(size_t) -JS_SetProtoCalled(JSContext* cx); - -extern JS_FRIEND_API(size_t) -JS_GetCustomIteratorCount(JSContext* cx); - -extern JS_FRIEND_API(bool) -JS_NondeterministicGetWeakMapKeys(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret); - -extern JS_FRIEND_API(bool) -JS_NondeterministicGetWeakSetKeys(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret); - -// Raw JSScript* because this needs to be callable from a signal handler. -extern JS_FRIEND_API(unsigned) -JS_PCToLineNumber(JSScript* script, jsbytecode* pc, unsigned* columnp = nullptr); - -/** - * Determine whether the given object is backed by a DeadObjectProxy. - * - * Such objects hold no other objects (they have no outgoing reference edges) - * and will throw if you touch them (e.g. by reading/writing a property). - */ -extern JS_FRIEND_API(bool) -JS_IsDeadWrapper(JSObject* obj); - -/* - * Used by the cycle collector to trace through a shape or object group and - * all cycle-participating data it reaches, using bounded stack space. - */ -extern JS_FRIEND_API(void) -JS_TraceShapeCycleCollectorChildren(JS::CallbackTracer* trc, JS::GCCellPtr shape); -extern JS_FRIEND_API(void) -JS_TraceObjectGroupCycleCollectorChildren(JS::CallbackTracer* trc, JS::GCCellPtr group); - -enum { - JS_TELEMETRY_GC_REASON, - JS_TELEMETRY_GC_IS_ZONE_GC, - JS_TELEMETRY_GC_MS, - JS_TELEMETRY_GC_BUDGET_MS, - JS_TELEMETRY_GC_ANIMATION_MS, - JS_TELEMETRY_GC_MAX_PAUSE_MS, - JS_TELEMETRY_GC_MARK_MS, - JS_TELEMETRY_GC_SWEEP_MS, - JS_TELEMETRY_GC_COMPACT_MS, - JS_TELEMETRY_GC_MARK_ROOTS_MS, - JS_TELEMETRY_GC_MARK_GRAY_MS, - JS_TELEMETRY_GC_SLICE_MS, - JS_TELEMETRY_GC_SLOW_PHASE, - JS_TELEMETRY_GC_MMU_50, - JS_TELEMETRY_GC_RESET, - JS_TELEMETRY_GC_RESET_REASON, - JS_TELEMETRY_GC_INCREMENTAL_DISABLED, - JS_TELEMETRY_GC_NON_INCREMENTAL, - JS_TELEMETRY_GC_NON_INCREMENTAL_REASON, - JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS, - JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS, - JS_TELEMETRY_GC_MINOR_REASON, - JS_TELEMETRY_GC_MINOR_REASON_LONG, - JS_TELEMETRY_GC_MINOR_US, - JS_TELEMETRY_GC_NURSERY_BYTES, - JS_TELEMETRY_GC_PRETENURE_COUNT, - JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, - JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_ADDONS, - JS_TELEMETRY_ADDON_EXCEPTIONS, - JS_TELEMETRY_AOT_USAGE, - JS_TELEMETRY_END -}; - -typedef void -(*JSAccumulateTelemetryDataCallback)(int id, uint32_t sample, const char* key); - -extern JS_FRIEND_API(void) -JS_SetAccumulateTelemetryCallback(JSContext* cx, JSAccumulateTelemetryDataCallback callback); - -extern JS_FRIEND_API(bool) -JS_GetIsSecureContext(JSCompartment* compartment); - -extern JS_FRIEND_API(JSPrincipals*) -JS_GetCompartmentPrincipals(JSCompartment* compartment); - -extern JS_FRIEND_API(void) -JS_SetCompartmentPrincipals(JSCompartment* compartment, JSPrincipals* principals); - -extern JS_FRIEND_API(JSPrincipals*) -JS_GetScriptPrincipals(JSScript* script); - -extern JS_FRIEND_API(bool) -JS_ScriptHasMutedErrors(JSScript* script); - -extern JS_FRIEND_API(JSObject*) -JS_CloneObject(JSContext* cx, JS::HandleObject obj, JS::HandleObject proto); - -/** - * Copy the own properties of src to dst in a fast way. src and dst must both - * be native and must be in the compartment of cx. They must have the same - * class, the same parent, and the same prototype. Class reserved slots will - * NOT be copied. - * - * dst must not have any properties on it before this function is called. - * - * src must have been allocated via JS_NewObjectWithoutMetadata so that we can - * be sure it has no metadata that needs copying to dst. This also means that - * dst needs to have the compartment global as its parent. This function will - * preserve the existing metadata on dst, if any. - */ -extern JS_FRIEND_API(bool) -JS_InitializePropertiesFromCompatibleNativeObject(JSContext* cx, - JS::HandleObject dst, - JS::HandleObject src); - -extern JS_FRIEND_API(JSString*) -JS_BasicObjectToString(JSContext* cx, JS::HandleObject obj); - -namespace js { - -JS_FRIEND_API(bool) -GetBuiltinClass(JSContext* cx, JS::HandleObject obj, ESClass* cls); - -JS_FRIEND_API(const char*) -ObjectClassName(JSContext* cx, JS::HandleObject obj); - -JS_FRIEND_API(void) -ReportOverRecursed(JSContext* maybecx); - -JS_FRIEND_API(bool) -AddRawValueRoot(JSContext* cx, JS::Value* vp, const char* name); - -JS_FRIEND_API(void) -RemoveRawValueRoot(JSContext* cx, JS::Value* vp); - -JS_FRIEND_API(JSAtom*) -GetPropertyNameFromPC(JSScript* script, jsbytecode* pc); - -#ifdef JS_DEBUG - -/* - * Routines to print out values during debugging. These are FRIEND_API to help - * the debugger find them and to support temporarily hacking js::Dump* calls - * into other code. Note that there are overloads that do not require the FILE* - * parameter, which will default to stderr. - */ - -extern JS_FRIEND_API(void) -DumpString(JSString* str, FILE* fp); - -extern JS_FRIEND_API(void) -DumpAtom(JSAtom* atom, FILE* fp); - -extern JS_FRIEND_API(void) -DumpObject(JSObject* obj, FILE* fp); - -extern JS_FRIEND_API(void) -DumpChars(const char16_t* s, size_t n, FILE* fp); - -extern JS_FRIEND_API(void) -DumpValue(const JS::Value& val, FILE* fp); - -extern JS_FRIEND_API(void) -DumpId(jsid id, FILE* fp); - -extern JS_FRIEND_API(void) -DumpInterpreterFrame(JSContext* cx, FILE* fp, InterpreterFrame* start = nullptr); - -extern JS_FRIEND_API(bool) -DumpPC(JSContext* cx, FILE* fp); - -extern JS_FRIEND_API(bool) -DumpScript(JSContext* cx, JSScript* scriptArg, FILE* fp); - -// Versions for use directly in a debugger (default parameters are not handled -// well in gdb; built-in handles like stderr are not handled well in lldb.) -extern JS_FRIEND_API(void) DumpString(JSString* str); -extern JS_FRIEND_API(void) DumpAtom(JSAtom* atom); -extern JS_FRIEND_API(void) DumpObject(JSObject* obj); -extern JS_FRIEND_API(void) DumpChars(const char16_t* s, size_t n); -extern JS_FRIEND_API(void) DumpValue(const JS::Value& val); -extern JS_FRIEND_API(void) DumpId(jsid id); -extern JS_FRIEND_API(void) DumpInterpreterFrame(JSContext* cx, InterpreterFrame* start = nullptr); -extern JS_FRIEND_API(bool) DumpPC(JSContext* cx); -extern JS_FRIEND_API(bool) DumpScript(JSContext* cx, JSScript* scriptArg); - -#endif - -extern JS_FRIEND_API(void) -DumpBacktrace(JSContext* cx, FILE* fp); - -extern JS_FRIEND_API(void) -DumpBacktrace(JSContext* cx); - -} // namespace js - -namespace JS { - -/** Exposed for DumpJSStack */ -extern JS_FRIEND_API(char*) -FormatStackDump(JSContext* cx, char* buf, bool showArgs, bool showLocals, bool showThisProps); - -/** - * Set all of the uninitialized lexicals on an object to undefined. Return - * true if any lexicals were initialized and false otherwise. - * */ -extern JS_FRIEND_API(bool) -ForceLexicalInitialization(JSContext *cx, HandleObject obj); - -} // namespace JS - -/** - * Copies all own properties from |obj| to |target|. |obj| must be a "native" - * object (that is to say, normal-ish - not an Array or a Proxy). - * - * This function immediately enters a compartment, and does not impose any - * restrictions on the compartment of |cx|. - */ -extern JS_FRIEND_API(bool) -JS_CopyPropertiesFrom(JSContext* cx, JS::HandleObject target, JS::HandleObject obj); - -/* - * Single-property version of the above. This function asserts that an |own| - * property of the given name exists on |obj|. - * - * On entry, |cx| must be same-compartment with |obj|. - * - * The copyBehavior argument controls what happens with - * non-configurable properties. - */ -typedef enum { - MakeNonConfigurableIntoConfigurable, - CopyNonConfigurableAsIs -} PropertyCopyBehavior; - -extern JS_FRIEND_API(bool) -JS_CopyPropertyFrom(JSContext* cx, JS::HandleId id, JS::HandleObject target, - JS::HandleObject obj, - PropertyCopyBehavior copyBehavior = CopyNonConfigurableAsIs); - -extern JS_FRIEND_API(bool) -JS_WrapPropertyDescriptor(JSContext* cx, JS::MutableHandle desc); - -struct JSFunctionSpecWithHelp { - const char* name; - JSNative call; - uint16_t nargs; - uint16_t flags; - const JSJitInfo* jitInfo; - const char* usage; - const char* help; -}; - -#define JS_FN_HELP(name,call,nargs,flags,usage,help) \ - {name, call, nargs, (flags) | JSPROP_ENUMERATE | JSFUN_STUB_GSOPS, nullptr, usage, help} -#define JS_INLINABLE_FN_HELP(name,call,nargs,flags,native,usage,help) \ - {name, call, nargs, (flags) | JSPROP_ENUMERATE | JSFUN_STUB_GSOPS, &js::jit::JitInfo_##native,\ - usage, help} -#define JS_FS_HELP_END \ - {nullptr, nullptr, 0, 0, nullptr, nullptr} - -extern JS_FRIEND_API(bool) -JS_DefineFunctionsWithHelp(JSContext* cx, JS::HandleObject obj, const JSFunctionSpecWithHelp* fs); - -namespace js { - -extern JS_FRIEND_DATA(const js::ClassOps) ProxyClassOps; -extern JS_FRIEND_DATA(const js::ClassExtension) ProxyClassExtension; -extern JS_FRIEND_DATA(const js::ObjectOps) ProxyObjectOps; - -/* - * Helper Macros for creating JSClasses that function as proxies. - * - * NB: The macro invocation must be surrounded by braces, so as to - * allow for potential JSClass extensions. - */ -#define PROXY_MAKE_EXT(objectMoved) \ - { \ - js::proxy_WeakmapKeyDelegate, \ - objectMoved \ - } - -#define PROXY_CLASS_WITH_EXT(name, flags, extPtr) \ - { \ - name, \ - js::Class::NON_NATIVE | \ - JSCLASS_IS_PROXY | \ - JSCLASS_DELAY_METADATA_BUILDER | \ - flags, \ - &js::ProxyClassOps, \ - JS_NULL_CLASS_SPEC, \ - extPtr, \ - &js::ProxyObjectOps \ - } - -#define PROXY_CLASS_DEF(name, flags) \ - PROXY_CLASS_WITH_EXT(name, flags, &js::ProxyClassExtension) - -/* - * Proxy stubs, similar to JS_*Stub, for embedder proxy class definitions. - * - * NB: Should not be called directly. - */ - -extern JS_FRIEND_API(bool) -proxy_LookupProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleObject objp, - JS::MutableHandle propp); -extern JS_FRIEND_API(bool) -proxy_DefineProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::Handle desc, - JS::ObjectOpResult& result); -extern JS_FRIEND_API(bool) -proxy_HasProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp); -extern JS_FRIEND_API(bool) -proxy_GetProperty(JSContext* cx, JS::HandleObject obj, JS::HandleValue receiver, JS::HandleId id, - JS::MutableHandleValue vp); -extern JS_FRIEND_API(bool) -proxy_SetProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue bp, - JS::HandleValue receiver, JS::ObjectOpResult& result); -extern JS_FRIEND_API(bool) -proxy_GetOwnPropertyDescriptor(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandle desc); -extern JS_FRIEND_API(bool) -proxy_DeleteProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::ObjectOpResult& result); - -extern JS_FRIEND_API(void) -proxy_Trace(JSTracer* trc, JSObject* obj); -extern JS_FRIEND_API(JSObject*) -proxy_WeakmapKeyDelegate(JSObject* obj); -extern JS_FRIEND_API(bool) -proxy_Convert(JSContext* cx, JS::HandleObject proxy, JSType hint, JS::MutableHandleValue vp); -extern JS_FRIEND_API(void) -proxy_Finalize(FreeOp* fop, JSObject* obj); -extern JS_FRIEND_API(void) -proxy_ObjectMoved(JSObject* obj, const JSObject* old); -extern JS_FRIEND_API(bool) -proxy_HasInstance(JSContext* cx, JS::HandleObject proxy, JS::MutableHandleValue v, bool* bp); -extern JS_FRIEND_API(bool) -proxy_Call(JSContext* cx, unsigned argc, JS::Value* vp); -extern JS_FRIEND_API(bool) -proxy_Construct(JSContext* cx, unsigned argc, JS::Value* vp); -extern JS_FRIEND_API(JSObject*) -proxy_innerObject(JSObject* obj); -extern JS_FRIEND_API(bool) -proxy_Watch(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable); -extern JS_FRIEND_API(bool) -proxy_Unwatch(JSContext* cx, JS::HandleObject obj, JS::HandleId id); -extern JS_FRIEND_API(bool) -proxy_GetElements(JSContext* cx, JS::HandleObject proxy, uint32_t begin, uint32_t end, - ElementAdder* adder); -extern JS_FRIEND_API(JSString*) -proxy_FunToString(JSContext* cx, JS::HandleObject proxy, unsigned indent); - -/** - * A class of objects that return source code on demand. - * - * When code is compiled with setSourceIsLazy(true), SpiderMonkey doesn't - * retain the source code (and doesn't do lazy bytecode generation). If we ever - * need the source code, say, in response to a call to Function.prototype. - * toSource or Debugger.Source.prototype.text, then we call the 'load' member - * function of the instance of this class that has hopefully been registered - * with the runtime, passing the code's URL, and hope that it will be able to - * find the source. - */ -class SourceHook { - public: - virtual ~SourceHook() { } - - /** - * Set |*src| and |*length| to refer to the source code for |filename|. - * On success, the caller owns the buffer to which |*src| points, and - * should use JS_free to free it. - */ - virtual bool load(JSContext* cx, const char* filename, char16_t** src, size_t* length) = 0; -}; - -/** - * Have |cx| use |hook| to retrieve lazily-retrieved source code. See the - * comments for SourceHook. The context takes ownership of the hook, and - * will delete it when the context itself is deleted, or when a new hook is - * set. - */ -extern JS_FRIEND_API(void) -SetSourceHook(JSContext* cx, mozilla::UniquePtr hook); - -/** Remove |cx|'s source hook, and return it. The caller now owns the hook. */ -extern JS_FRIEND_API(mozilla::UniquePtr) -ForgetSourceHook(JSContext* cx); - -extern JS_FRIEND_API(JS::Zone*) -GetCompartmentZone(JSCompartment* comp); - -typedef bool -(* PreserveWrapperCallback)(JSContext* cx, JSObject* obj); - -typedef enum { - CollectNurseryBeforeDump, - IgnoreNurseryObjects -} DumpHeapNurseryBehaviour; - - /** - * Dump the complete object graph of heap-allocated things. - * fp is the file for the dump output. - */ -extern JS_FRIEND_API(void) -DumpHeap(JSContext* cx, FILE* fp, DumpHeapNurseryBehaviour nurseryBehaviour); - -#ifdef JS_OLD_GETTER_SETTER_METHODS -JS_FRIEND_API(bool) obj_defineGetter(JSContext* cx, unsigned argc, JS::Value* vp); -JS_FRIEND_API(bool) obj_defineSetter(JSContext* cx, unsigned argc, JS::Value* vp); -#endif - -extern JS_FRIEND_API(bool) -IsSystemCompartment(JSCompartment* comp); - -extern JS_FRIEND_API(bool) -IsSystemZone(JS::Zone* zone); - -extern JS_FRIEND_API(bool) -IsAtomsCompartment(JSCompartment* comp); - -extern JS_FRIEND_API(bool) -IsAtomsZone(JS::Zone* zone); - -struct WeakMapTracer -{ - JSContext* context; - - explicit WeakMapTracer(JSContext* cx) : context(cx) {} - - // Weak map tracer callback, called once for every binding of every - // weak map that was live at the time of the last garbage collection. - // - // m will be nullptr if the weak map is not contained in a JS Object. - // - // The callback should not GC (and will assert in a debug build if it does so.) - virtual void trace(JSObject* m, JS::GCCellPtr key, JS::GCCellPtr value) = 0; -}; - -extern JS_FRIEND_API(void) -TraceWeakMaps(WeakMapTracer* trc); - -extern JS_FRIEND_API(bool) -AreGCGrayBitsValid(JSContext* cx); - -extern JS_FRIEND_API(bool) -ZoneGlobalsAreAllGray(JS::Zone* zone); - -typedef void -(*GCThingCallback)(void* closure, JS::GCCellPtr thing); - -extern JS_FRIEND_API(void) -VisitGrayWrapperTargets(JS::Zone* zone, GCThingCallback callback, void* closure); - -extern JS_FRIEND_API(JSObject*) -GetWeakmapKeyDelegate(JSObject* key); - -/** - * Invoke cellCallback on every gray JSObject in the given zone. - */ -extern JS_FRIEND_API(void) -IterateGrayObjects(JS::Zone* zone, GCThingCallback cellCallback, void* data); - -/** - * Invoke cellCallback on every gray JSObject in the given zone while cycle - * collection is in progress. - */ -extern JS_FRIEND_API(void) -IterateGrayObjectsUnderCC(JS::Zone* zone, GCThingCallback cellCallback, void* data); - -#ifdef JS_HAS_CTYPES -extern JS_FRIEND_API(size_t) -SizeOfDataIfCDataObject(mozilla::MallocSizeOf mallocSizeOf, JSObject* obj); -#endif - -extern JS_FRIEND_API(JSCompartment*) -GetAnyCompartmentInZone(JS::Zone* zone); - -/* - * Shadow declarations of JS internal structures, for access by inline access - * functions below. Do not use these structures in any other way. When adding - * new fields for access by inline methods, make sure to add static asserts to - * the original header file to ensure that offsets are consistent. - */ -namespace shadow { - -struct ObjectGroup { - const Class* clasp; - JSObject* proto; - JSCompartment* compartment; -}; - -struct BaseShape { - const js::Class* clasp_; - JSObject* parent; -}; - -class Shape { -public: - shadow::BaseShape* base; - jsid _1; - uint32_t slotInfo; - - static const uint32_t FIXED_SLOTS_SHIFT = 27; -}; - -/** - * This layout is shared by all native objects. For non-native objects, the - * group may always be accessed safely, and other members may be as well, - * depending on the object's specific layout. - */ -struct Object { - shadow::ObjectGroup* group; - shadow::Shape* shape; - JS::Value* slots; - void* _1; - - size_t numFixedSlots() const { return shape->slotInfo >> Shape::FIXED_SLOTS_SHIFT; } - JS::Value* fixedSlots() const { - return (JS::Value*)(uintptr_t(this) + sizeof(shadow::Object)); - } - - JS::Value& slotRef(size_t slot) const { - size_t nfixed = numFixedSlots(); - if (slot < nfixed) - return fixedSlots()[slot]; - return slots[slot - nfixed]; - } -}; - -struct Function { - Object base; - uint16_t nargs; - uint16_t flags; - /* Used only for natives */ - JSNative native; - const JSJitInfo* jitinfo; - void* _1; -}; - -struct String -{ - static const uint32_t INLINE_CHARS_BIT = JS_BIT(2); - static const uint32_t LATIN1_CHARS_BIT = JS_BIT(6); - static const uint32_t ROPE_FLAGS = 0; - static const uint32_t TYPE_FLAGS_MASK = JS_BIT(6) - 1; - uint32_t flags; - uint32_t length; - union { - const JS::Latin1Char* nonInlineCharsLatin1; - const char16_t* nonInlineCharsTwoByte; - JS::Latin1Char inlineStorageLatin1[1]; - char16_t inlineStorageTwoByte[1]; - }; -}; - -} /* namespace shadow */ - -// This is equal to |&JSObject::class_|. Use it in places where you don't want -// to #include jsobj.h. -extern JS_FRIEND_DATA(const js::Class* const) ObjectClassPtr; - -inline const js::Class* -GetObjectClass(const JSObject* obj) -{ - return reinterpret_cast(obj)->group->clasp; -} - -inline const JSClass* -GetObjectJSClass(JSObject* obj) -{ - return js::Jsvalify(GetObjectClass(obj)); -} - -JS_FRIEND_API(const Class*) -ProtoKeyToClass(JSProtoKey key); - -// Returns the key for the class inherited by a given standard class (that -// is to say, the prototype of this standard class's prototype). -// -// You must be sure that this corresponds to a standard class with a cached -// JSProtoKey before calling this function. In general |key| will match the -// cached proto key, except in cases where multiple JSProtoKeys share a -// JSClass. -inline JSProtoKey -InheritanceProtoKeyForStandardClass(JSProtoKey key) -{ - // [Object] has nothing to inherit from. - if (key == JSProto_Object) - return JSProto_Null; - - // If we're ClassSpec defined return the proto key from that - if (ProtoKeyToClass(key)->specDefined()) - return ProtoKeyToClass(key)->specInheritanceProtoKey(); - - // Otherwise, we inherit [Object]. - return JSProto_Object; -} - -JS_FRIEND_API(bool) -IsFunctionObject(JSObject* obj); - -static MOZ_ALWAYS_INLINE JSCompartment* -GetObjectCompartment(JSObject* obj) -{ - return reinterpret_cast(obj)->group->compartment; -} - -JS_FRIEND_API(JSObject*) -GetGlobalForObjectCrossCompartment(JSObject* obj); - -JS_FRIEND_API(JSObject*) -GetPrototypeNoProxy(JSObject* obj); - -JS_FRIEND_API(void) -AssertSameCompartment(JSContext* cx, JSObject* obj); - -#ifdef JS_DEBUG -JS_FRIEND_API(void) -AssertSameCompartment(JSObject* objA, JSObject* objB); -#else -inline void AssertSameCompartment(JSObject* objA, JSObject* objB) {} -#endif - -JS_FRIEND_API(void) -NotifyAnimationActivity(JSObject* obj); - -/** - * Return the outermost enclosing function (script) of the scripted caller. - * This function returns nullptr in several cases: - * - no script is running on the context - * - the caller is in global or eval code - * In particular, this function will "stop" its outermost search at eval() and - * thus it will really return the outermost enclosing function *since the - * innermost eval*. - */ -JS_FRIEND_API(JSFunction*) -GetOutermostEnclosingFunctionOfScriptedCaller(JSContext* cx); - -JS_FRIEND_API(JSFunction*) -DefineFunctionWithReserved(JSContext* cx, JSObject* obj, const char* name, JSNative call, - unsigned nargs, unsigned attrs); - -JS_FRIEND_API(JSFunction*) -NewFunctionWithReserved(JSContext* cx, JSNative call, unsigned nargs, unsigned flags, - const char* name); - -JS_FRIEND_API(JSFunction*) -NewFunctionByIdWithReserved(JSContext* cx, JSNative native, unsigned nargs, unsigned flags, - jsid id); - -JS_FRIEND_API(const JS::Value&) -GetFunctionNativeReserved(JSObject* fun, size_t which); - -JS_FRIEND_API(void) -SetFunctionNativeReserved(JSObject* fun, size_t which, const JS::Value& val); - -JS_FRIEND_API(bool) -FunctionHasNativeReserved(JSObject* fun); - -JS_FRIEND_API(bool) -GetObjectProto(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject proto); - -extern JS_FRIEND_API(JSObject*) -GetStaticPrototype(JSObject* obj); - -JS_FRIEND_API(bool) -GetOriginalEval(JSContext* cx, JS::HandleObject scope, - JS::MutableHandleObject eval); - -inline void* -GetObjectPrivate(JSObject* obj) -{ - MOZ_ASSERT(GetObjectClass(obj)->flags & JSCLASS_HAS_PRIVATE); - const shadow::Object* nobj = reinterpret_cast(obj); - void** addr = reinterpret_cast(&nobj->fixedSlots()[nobj->numFixedSlots()]); - return *addr; -} - -inline const JS::Value& -GetReservedSlot(JSObject* obj, size_t slot) -{ - MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj))); - return reinterpret_cast(obj)->slotRef(slot); -} - -JS_FRIEND_API(void) -SetReservedOrProxyPrivateSlotWithBarrier(JSObject* obj, size_t slot, const JS::Value& value); - -inline void -SetReservedSlot(JSObject* obj, size_t slot, const JS::Value& value) -{ - MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj))); - shadow::Object* sobj = reinterpret_cast(obj); - if (sobj->slotRef(slot).isMarkable() || value.isMarkable()) - SetReservedOrProxyPrivateSlotWithBarrier(obj, slot, value); - else - sobj->slotRef(slot) = value; -} - -JS_FRIEND_API(uint32_t) -GetObjectSlotSpan(JSObject* obj); - -inline const JS::Value& -GetObjectSlot(JSObject* obj, size_t slot) -{ - MOZ_ASSERT(slot < GetObjectSlotSpan(obj)); - return reinterpret_cast(obj)->slotRef(slot); -} - -MOZ_ALWAYS_INLINE size_t -GetAtomLength(JSAtom* atom) -{ - return reinterpret_cast(atom)->length; -} - -static const uint32_t MaxStringLength = (1 << 28) - 1; - -MOZ_ALWAYS_INLINE size_t -GetStringLength(JSString* s) -{ - return reinterpret_cast(s)->length; -} - -MOZ_ALWAYS_INLINE size_t -GetFlatStringLength(JSFlatString* s) -{ - return reinterpret_cast(s)->length; -} - -MOZ_ALWAYS_INLINE size_t -GetLinearStringLength(JSLinearString* s) -{ - return reinterpret_cast(s)->length; -} - -MOZ_ALWAYS_INLINE bool -LinearStringHasLatin1Chars(JSLinearString* s) -{ - return reinterpret_cast(s)->flags & shadow::String::LATIN1_CHARS_BIT; -} - -MOZ_ALWAYS_INLINE bool -AtomHasLatin1Chars(JSAtom* atom) -{ - return reinterpret_cast(atom)->flags & shadow::String::LATIN1_CHARS_BIT; -} - -MOZ_ALWAYS_INLINE bool -StringHasLatin1Chars(JSString* s) -{ - return reinterpret_cast(s)->flags & shadow::String::LATIN1_CHARS_BIT; -} - -MOZ_ALWAYS_INLINE const JS::Latin1Char* -GetLatin1LinearStringChars(const JS::AutoCheckCannotGC& nogc, JSLinearString* linear) -{ - MOZ_ASSERT(LinearStringHasLatin1Chars(linear)); - - using shadow::String; - String* s = reinterpret_cast(linear); - if (s->flags & String::INLINE_CHARS_BIT) - return s->inlineStorageLatin1; - return s->nonInlineCharsLatin1; -} - -MOZ_ALWAYS_INLINE const char16_t* -GetTwoByteLinearStringChars(const JS::AutoCheckCannotGC& nogc, JSLinearString* linear) -{ - MOZ_ASSERT(!LinearStringHasLatin1Chars(linear)); - - using shadow::String; - String* s = reinterpret_cast(linear); - if (s->flags & String::INLINE_CHARS_BIT) - return s->inlineStorageTwoByte; - return s->nonInlineCharsTwoByte; -} - -MOZ_ALWAYS_INLINE JSLinearString* -AtomToLinearString(JSAtom* atom) -{ - return reinterpret_cast(atom); -} - -MOZ_ALWAYS_INLINE JSFlatString* -AtomToFlatString(JSAtom* atom) -{ - return reinterpret_cast(atom); -} - -MOZ_ALWAYS_INLINE JSLinearString* -FlatStringToLinearString(JSFlatString* s) -{ - return reinterpret_cast(s); -} - -MOZ_ALWAYS_INLINE const JS::Latin1Char* -GetLatin1AtomChars(const JS::AutoCheckCannotGC& nogc, JSAtom* atom) -{ - return GetLatin1LinearStringChars(nogc, AtomToLinearString(atom)); -} - -MOZ_ALWAYS_INLINE const char16_t* -GetTwoByteAtomChars(const JS::AutoCheckCannotGC& nogc, JSAtom* atom) -{ - return GetTwoByteLinearStringChars(nogc, AtomToLinearString(atom)); -} - -JS_FRIEND_API(JSLinearString*) -StringToLinearStringSlow(JSContext* cx, JSString* str); - -MOZ_ALWAYS_INLINE JSLinearString* -StringToLinearString(JSContext* cx, JSString* str) -{ - using shadow::String; - String* s = reinterpret_cast(str); - if (MOZ_UNLIKELY((s->flags & String::TYPE_FLAGS_MASK) == String::ROPE_FLAGS)) - return StringToLinearStringSlow(cx, str); - return reinterpret_cast(str); -} - -template -MOZ_ALWAYS_INLINE void -CopyLinearStringChars(CharType* dest, JSLinearString* s, size_t len, size_t start = 0); - -MOZ_ALWAYS_INLINE void -CopyLinearStringChars(char16_t* dest, JSLinearString* s, size_t len, size_t start = 0) -{ - MOZ_ASSERT(start + len <= GetLinearStringLength(s)); - JS::AutoCheckCannotGC nogc; - if (LinearStringHasLatin1Chars(s)) { - const JS::Latin1Char* src = GetLatin1LinearStringChars(nogc, s); - for (size_t i = 0; i < len; i++) - dest[i] = src[start + i]; - } else { - const char16_t* src = GetTwoByteLinearStringChars(nogc, s); - mozilla::PodCopy(dest, src + start, len); - } -} - -MOZ_ALWAYS_INLINE void -CopyLinearStringChars(char* dest, JSLinearString* s, size_t len, size_t start = 0) -{ - MOZ_ASSERT(start + len <= GetLinearStringLength(s)); - JS::AutoCheckCannotGC nogc; - if (LinearStringHasLatin1Chars(s)) { - const JS::Latin1Char* src = GetLatin1LinearStringChars(nogc, s); - for (size_t i = 0; i < len; i++) - dest[i] = char(src[start + i]); - } else { - const char16_t* src = GetTwoByteLinearStringChars(nogc, s); - for (size_t i = 0; i < len; i++) - dest[i] = char(src[start + i]); - } -} - -template -inline bool -CopyStringChars(JSContext* cx, CharType* dest, JSString* s, size_t len, size_t start = 0) -{ - JSLinearString* linear = StringToLinearString(cx, s); - if (!linear) - return false; - - CopyLinearStringChars(dest, linear, len, start); - return true; -} - -inline void -CopyFlatStringChars(char16_t* dest, JSFlatString* s, size_t len) -{ - CopyLinearStringChars(dest, FlatStringToLinearString(s), len); -} - -/** - * Add some or all property keys of obj to the id vector *props. - * - * The flags parameter controls which property keys are added. Pass a - * combination of the following bits: - * - * JSITER_OWNONLY - Don't also search the prototype chain; only consider - * obj's own properties. - * - * JSITER_HIDDEN - Include nonenumerable properties. - * - * JSITER_SYMBOLS - Include property keys that are symbols. The default - * behavior is to filter out symbols. - * - * JSITER_SYMBOLSONLY - Exclude non-symbol property keys. - * - * This is the closest C++ API we have to `Reflect.ownKeys(obj)`, or - * equivalently, the ES6 [[OwnPropertyKeys]] internal method. Pass - * `JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS` as flags to get - * results that match the output of Reflect.ownKeys. - */ -JS_FRIEND_API(bool) -GetPropertyKeys(JSContext* cx, JS::HandleObject obj, unsigned flags, JS::AutoIdVector* props); - -JS_FRIEND_API(bool) -AppendUnique(JSContext* cx, JS::AutoIdVector& base, JS::AutoIdVector& others); - -JS_FRIEND_API(bool) -StringIsArrayIndex(JSLinearString* str, uint32_t* indexp); - -JS_FRIEND_API(void) -SetPreserveWrapperCallback(JSContext* cx, PreserveWrapperCallback callback); - -JS_FRIEND_API(bool) -IsObjectInContextCompartment(JSObject* obj, const JSContext* cx); - -/* - * NB: keep these in sync with the copy in builtin/SelfHostingDefines.h. - * The first three are omitted because they shouldn't be used in new code. - */ -#define JSITER_ENUMERATE 0x1 /* for-in compatible hidden default iterator */ -#define JSITER_FOREACH 0x2 /* get obj[key] for each property */ -#define JSITER_KEYVALUE 0x4 /* obsolete destructuring for-in wants [key, value] */ -#define JSITER_OWNONLY 0x8 /* iterate over obj's own properties only */ -#define JSITER_HIDDEN 0x10 /* also enumerate non-enumerable properties */ -#define JSITER_SYMBOLS 0x20 /* also include symbol property keys */ -#define JSITER_SYMBOLSONLY 0x40 /* exclude string property keys */ - -JS_FRIEND_API(bool) -RunningWithTrustedPrincipals(JSContext* cx); - -inline uintptr_t -GetNativeStackLimit(JSContext* cx, StackKind kind, int extraAllowance = 0) -{ - uintptr_t limit = ContextFriendFields::get(cx)->nativeStackLimit[kind]; -#if JS_STACK_GROWTH_DIRECTION > 0 - limit += extraAllowance; -#else - limit -= extraAllowance; -#endif - return limit; -} - -inline uintptr_t -GetNativeStackLimit(JSContext* cx, int extraAllowance = 0) -{ - StackKind kind = RunningWithTrustedPrincipals(cx) ? StackForTrustedScript - : StackForUntrustedScript; - return GetNativeStackLimit(cx, kind, extraAllowance); -} - -/* - * These macros report a stack overflow and run |onerror| if we are close to - * using up the C stack. The JS_CHECK_CHROME_RECURSION variant gives us a - * little extra space so that we can ensure that crucial code is able to run. - * JS_CHECK_RECURSION_CONSERVATIVE allows less space than any other check, - * including a safety buffer (as in, it uses the untrusted limit and subtracts - * a little more from it). - */ - -#define JS_CHECK_RECURSION_LIMIT(cx, limit, onerror) \ - JS_BEGIN_MACRO \ - int stackDummy_; \ - if (!JS_CHECK_STACK_SIZE(limit, &stackDummy_)) { \ - js::ReportOverRecursed(cx); \ - onerror; \ - } \ - JS_END_MACRO - -#define JS_CHECK_RECURSION(cx, onerror) \ - JS_CHECK_RECURSION_LIMIT(cx, js::GetNativeStackLimit(cx), onerror) - -#define JS_CHECK_RECURSION_LIMIT_DONT_REPORT(cx, limit, onerror) \ - JS_BEGIN_MACRO \ - int stackDummy_; \ - if (!JS_CHECK_STACK_SIZE(limit, &stackDummy_)) { \ - onerror; \ - } \ - JS_END_MACRO - -#define JS_CHECK_RECURSION_DONT_REPORT(cx, onerror) \ - JS_CHECK_RECURSION_LIMIT_DONT_REPORT(cx, js::GetNativeStackLimit(cx), onerror) - -#define JS_CHECK_RECURSION_WITH_SP_DONT_REPORT(cx, sp, onerror) \ - JS_BEGIN_MACRO \ - if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) { \ - onerror; \ - } \ - JS_END_MACRO - -#define JS_CHECK_RECURSION_WITH_SP(cx, sp, onerror) \ - JS_BEGIN_MACRO \ - if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) { \ - js::ReportOverRecursed(cx); \ - onerror; \ - } \ - JS_END_MACRO - -#define JS_CHECK_SYSTEM_RECURSION(cx, onerror) \ - JS_CHECK_RECURSION_LIMIT(cx, js::GetNativeStackLimit(cx, js::StackForSystemCode), onerror) - -#define JS_CHECK_RECURSION_CONSERVATIVE(cx, onerror) \ - JS_CHECK_RECURSION_LIMIT(cx, \ - js::GetNativeStackLimit(cx, js::StackForUntrustedScript, -1024 * int(sizeof(size_t))), \ - onerror) - -#define JS_CHECK_RECURSION_CONSERVATIVE_DONT_REPORT(cx, onerror) \ - JS_CHECK_RECURSION_LIMIT_DONT_REPORT(cx, \ - js::GetNativeStackLimit(cx, js::StackForUntrustedScript, -1024 * int(sizeof(size_t))), \ - onerror) - -JS_FRIEND_API(void) -StartPCCountProfiling(JSContext* cx); - -JS_FRIEND_API(void) -StopPCCountProfiling(JSContext* cx); - -JS_FRIEND_API(void) -PurgePCCounts(JSContext* cx); - -JS_FRIEND_API(size_t) -GetPCCountScriptCount(JSContext* cx); - -JS_FRIEND_API(JSString*) -GetPCCountScriptSummary(JSContext* cx, size_t script); - -JS_FRIEND_API(JSString*) -GetPCCountScriptContents(JSContext* cx, size_t script); - -/** - * Generate lcov trace file content for the current compartment, and allocate a - * new buffer and return the content in it, the size of the newly allocated - * content within the buffer would be set to the length out-param. - * - * In case of out-of-memory, this function returns nullptr and does not set any - * value to the length out-param. - */ -JS_FRIEND_API(char*) -GetCodeCoverageSummary(JSContext* cx, size_t* length); - -typedef void -(* ActivityCallback)(void* arg, bool active); - -/** - * Sets a callback that is run whenever the runtime goes idle - the - * last active request ceases - and begins activity - when it was - * idle and a request begins. - */ -JS_FRIEND_API(void) -SetActivityCallback(JSContext* cx, ActivityCallback cb, void* arg); - -typedef bool -(* DOMInstanceClassHasProtoAtDepth)(const Class* instanceClass, - uint32_t protoID, uint32_t depth); -struct JSDOMCallbacks { - DOMInstanceClassHasProtoAtDepth instanceClassMatchesProto; -}; -typedef struct JSDOMCallbacks DOMCallbacks; - -extern JS_FRIEND_API(void) -SetDOMCallbacks(JSContext* cx, const DOMCallbacks* callbacks); - -extern JS_FRIEND_API(const DOMCallbacks*) -GetDOMCallbacks(JSContext* cx); - -extern JS_FRIEND_API(JSObject*) -GetTestingFunctions(JSContext* cx); - -/** - * Helper to convert FreeOp to JSFreeOp when the definition of FreeOp is not - * available and the compiler does not know that FreeOp inherits from - * JSFreeOp. - */ -inline JSFreeOp* -CastToJSFreeOp(FreeOp* fop) -{ - return reinterpret_cast(fop); -} - -/* Implemented in jsexn.cpp. */ - -/** - * Get an error type name from a JSExnType constant. - * Returns nullptr for invalid arguments and JSEXN_INTERNALERR - */ -extern JS_FRIEND_API(JSFlatString*) -GetErrorTypeName(JSContext* cx, int16_t exnType); - -#ifdef JS_DEBUG -extern JS_FRIEND_API(unsigned) -GetEnterCompartmentDepth(JSContext* cx); -#endif - -class RegExpGuard; -extern JS_FRIEND_API(bool) -RegExpToSharedNonInline(JSContext* cx, JS::HandleObject regexp, RegExpGuard* shared); - -/* Implemented in jswrapper.cpp. */ -typedef enum NukeReferencesToWindow { - NukeWindowReferences, - DontNukeWindowReferences -} NukeReferencesToWindow; - -/* - * These filters are designed to be ephemeral stack classes, and thus don't - * do any rooting or holding of their members. - */ -struct CompartmentFilter { - virtual bool match(JSCompartment* c) const = 0; -}; - -struct AllCompartments : public CompartmentFilter { - virtual bool match(JSCompartment* c) const override { return true; } -}; - -struct ContentCompartmentsOnly : public CompartmentFilter { - virtual bool match(JSCompartment* c) const override { - return !IsSystemCompartment(c); - } -}; - -struct ChromeCompartmentsOnly : public CompartmentFilter { - virtual bool match(JSCompartment* c) const override { - return IsSystemCompartment(c); - } -}; - -struct SingleCompartment : public CompartmentFilter { - JSCompartment* ours; - explicit SingleCompartment(JSCompartment* c) : ours(c) {} - virtual bool match(JSCompartment* c) const override { return c == ours; } -}; - -struct CompartmentsWithPrincipals : public CompartmentFilter { - JSPrincipals* principals; - explicit CompartmentsWithPrincipals(JSPrincipals* p) : principals(p) {} - virtual bool match(JSCompartment* c) const override { - return JS_GetCompartmentPrincipals(c) == principals; - } -}; - -extern JS_FRIEND_API(bool) -NukeCrossCompartmentWrappers(JSContext* cx, - const CompartmentFilter& sourceFilter, - const CompartmentFilter& targetFilter, - NukeReferencesToWindow nukeReferencesToWindow); - -/* Specify information about DOMProxy proxies in the DOM, for use by ICs. */ - -/* - * The DOMProxyShadowsCheck function will be called to check if the property for - * id should be gotten from the prototype, or if there is an own property that - * shadows it. - * * If ShadowsViaDirectExpando is returned, then the slot at - * listBaseExpandoSlot contains an expando object which has the property in - * question. - * * If ShadowsViaIndirectExpando is returned, then the slot at - * listBaseExpandoSlot contains a private pointer to an ExpandoAndGeneration - * and the expando object in the ExpandoAndGeneration has the property in - * question. - * * If DoesntShadow is returned then the slot at listBaseExpandoSlot should - * either be undefined or point to an expando object that would contain the - * own property. - * * If DoesntShadowUnique is returned then the slot at listBaseExpandoSlot - * should contain a private pointer to a ExpandoAndGeneration, which contains - * a JS::Value that should either be undefined or point to an expando object, - * and a uint64 value. If that value changes then the IC for getting a - * property will be invalidated. - * * If Shadows is returned, that means the property is an own property of the - * proxy but doesn't live on the expando object. - */ - -struct ExpandoAndGeneration { - ExpandoAndGeneration() - : expando(JS::UndefinedValue()), - generation(0) - {} - - void OwnerUnlinked() - { - ++generation; - } - - static size_t offsetOfExpando() - { - return offsetof(ExpandoAndGeneration, expando); - } - - static size_t offsetOfGeneration() - { - return offsetof(ExpandoAndGeneration, generation); - } - - JS::Heap expando; - uint64_t generation; -}; - -typedef enum DOMProxyShadowsResult { - ShadowCheckFailed, - Shadows, - DoesntShadow, - DoesntShadowUnique, - ShadowsViaDirectExpando, - ShadowsViaIndirectExpando -} DOMProxyShadowsResult; -typedef DOMProxyShadowsResult -(* DOMProxyShadowsCheck)(JSContext* cx, JS::HandleObject object, JS::HandleId id); -JS_FRIEND_API(void) -SetDOMProxyInformation(const void* domProxyHandlerFamily, uint32_t domProxyExpandoSlot, - DOMProxyShadowsCheck domProxyShadowsCheck); - -const void* GetDOMProxyHandlerFamily(); -uint32_t GetDOMProxyExpandoSlot(); -DOMProxyShadowsCheck GetDOMProxyShadowsCheck(); -inline bool DOMProxyIsShadowing(DOMProxyShadowsResult result) { - return result == Shadows || - result == ShadowsViaDirectExpando || - result == ShadowsViaIndirectExpando; -} - -/* Implemented in jsdate.cpp. */ - -/** Detect whether the internal date value is NaN. */ -extern JS_FRIEND_API(bool) -DateIsValid(JSContext* cx, JS::HandleObject obj, bool* isValid); - -extern JS_FRIEND_API(bool) -DateGetMsecSinceEpoch(JSContext* cx, JS::HandleObject obj, double* msecSinceEpoch); - -} /* namespace js */ - -/* Implemented in jscntxt.cpp. */ - -/** - * Report an exception, which is currently realized as a printf-style format - * string and its arguments. - */ -typedef enum JSErrNum { -#define MSG_DEF(name, count, exception, format) \ - name, -#include "js.msg" -#undef MSG_DEF - JSErr_Limit -} JSErrNum; - -namespace js { - -extern JS_FRIEND_API(const JSErrorFormatString*) -GetErrorMessage(void* userRef, const unsigned errorNumber); - -// AutoStableStringChars is here so we can use it in ErrorReport. It -// should get moved out of here if we can manage it. See bug 1040316. - -/** - * This class provides safe access to a string's chars across a GC. Once - * we allocate strings and chars in the nursery (bug 903519), this class - * will have to make a copy of the string's chars if they are allocated - * in the nursery, so it's best to avoid using this class unless you really - * need it. It's usually more efficient to use the latin1Chars/twoByteChars - * JSString methods and often the code can be rewritten so that only indexes - * instead of char pointers are used in parts of the code that can GC. - */ -class MOZ_STACK_CLASS AutoStableStringChars -{ - /* - * When copying string char, use this many bytes of inline storage. This is - * chosen to allow the inline string types to be copied without allocating. - * This is asserted in AutoStableStringChars::allocOwnChars. - */ - static const size_t InlineCapacity = 24; - - /* Ensure the string is kept alive while we're using its chars. */ - JS::RootedString s_; - union { - const char16_t* twoByteChars_; - const JS::Latin1Char* latin1Chars_; - }; - mozilla::Maybe> ownChars_; - enum State { Uninitialized, Latin1, TwoByte }; - State state_; - - public: - explicit AutoStableStringChars(JSContext* cx) - : s_(cx), state_(Uninitialized) - {} - - MOZ_MUST_USE - bool init(JSContext* cx, JSString* s); - - /* Like init(), but Latin1 chars are inflated to TwoByte. */ - MOZ_MUST_USE - bool initTwoByte(JSContext* cx, JSString* s); - - bool isLatin1() const { return state_ == Latin1; } - bool isTwoByte() const { return state_ == TwoByte; } - - const char16_t* twoByteChars() const { - MOZ_ASSERT(state_ == TwoByte); - return twoByteChars_; - } - - mozilla::Range latin1Range() const { - MOZ_ASSERT(state_ == Latin1); - return mozilla::Range(latin1Chars_, - GetStringLength(s_)); - } - - mozilla::Range twoByteRange() const { - MOZ_ASSERT(state_ == TwoByte); - return mozilla::Range(twoByteChars_, - GetStringLength(s_)); - } - - /* If we own the chars, transfer ownership to the caller. */ - bool maybeGiveOwnershipToCaller() { - MOZ_ASSERT(state_ != Uninitialized); - if (!ownChars_.isSome() || !ownChars_->extractRawBuffer()) - return false; - state_ = Uninitialized; - ownChars_.reset(); - return true; - } - - private: - AutoStableStringChars(const AutoStableStringChars& other) = delete; - void operator=(const AutoStableStringChars& other) = delete; - - bool baseIsInline(JS::Handle linearString); - template T* allocOwnChars(JSContext* cx, size_t count); - bool copyLatin1Chars(JSContext* cx, JS::Handle linearString); - bool copyTwoByteChars(JSContext* cx, JS::Handle linearString); - bool copyAndInflateLatin1Chars(JSContext*, JS::Handle linearString); -}; - -struct MOZ_STACK_CLASS JS_FRIEND_API(ErrorReport) -{ - explicit ErrorReport(JSContext* cx); - ~ErrorReport(); - - enum SniffingBehavior { - WithSideEffects, - NoSideEffects - }; - - /** - * Generate a JSErrorReport from the provided thrown value. - * - * If the value is a (possibly wrapped) Error object, the JSErrorReport will - * be exactly initialized from the Error object's information, without - * observable side effects. (The Error object's JSErrorReport is reused, if - * it has one.) - * - * Otherwise various attempts are made to derive JSErrorReport information - * from |exn| and from the current execution state. This process is - * *definitely* inconsistent with any standard, and particulars of the - * behavior implemented here generally shouldn't be relied upon. - * - * If the value of |sniffingBehavior| is |WithSideEffects|, some of these - * attempts *may* invoke user-configurable behavior when |exn| is an object: - * converting |exn| to a string, detecting and getting properties on |exn|, - * accessing |exn|'s prototype chain, and others are possible. Users *must* - * tolerate |ErrorReport::init| potentially having arbitrary effects. Any - * exceptions thrown by these operations will be caught and silently - * ignored, and "default" values will be substituted into the JSErrorReport. - * - * But if the value of |sniffingBehavior| is |NoSideEffects|, these attempts - * *will not* invoke any observable side effects. The JSErrorReport will - * simply contain fewer, less precise details. - * - * Unlike some functions involved in error handling, this function adheres - * to the usual JSAPI return value error behavior. - */ - bool init(JSContext* cx, JS::HandleValue exn, - SniffingBehavior sniffingBehavior); - - JSErrorReport* report() - { - return reportp; - } - - const JS::ConstUTF8CharsZ toStringResult() - { - return toStringResult_; - } - - private: - // More or less an equivalent of JS_ReportErrorNumber/js::ReportErrorNumberVA - // but fills in an ErrorReport instead of reporting it. Uses varargs to - // make it simpler to call js::ExpandErrorArgumentsVA. - // - // Returns false if we fail to actually populate the ErrorReport - // for some reason (probably out of memory). - bool populateUncaughtExceptionReportUTF8(JSContext* cx, ...); - bool populateUncaughtExceptionReportUTF8VA(JSContext* cx, va_list ap); - - // Reports exceptions from add-on scopes to telementry. - void ReportAddonExceptionToTelementry(JSContext* cx); - - // We may have a provided JSErrorReport, so need a way to represent that. - JSErrorReport* reportp; - - // Or we may need to synthesize a JSErrorReport one of our own. - JSErrorReport ownedReport; - - // And we have a string to maybe keep alive that has pointers into - // it from ownedReport. - JS::RootedString str; - - // And keep its chars alive too. - AutoStableStringChars strChars; - - // And we need to root our exception value. - JS::RootedObject exnObject; - - // And for our filename. - JSAutoByteString filename; - - // We may have a result of error.toString(). - // FIXME: We should not call error.toString(), since it could have side - // effect (see bug 633623). - JS::ConstUTF8CharsZ toStringResult_; - JSAutoByteString toStringResultBytesStorage; -}; - -/* Implemented in vm/StructuredClone.cpp. */ -extern JS_FRIEND_API(uint64_t) -GetSCOffset(JSStructuredCloneWriter* writer); - -namespace Scalar { - -/** - * Scalar types that can appear in typed arrays and typed objects. The enum - * values must to be kept in sync with the JS_SCALARTYPEREPR_ constants, as - * well as the TypedArrayObject::classes and TypedArrayObject::protoClasses - * definitions. - */ -enum Type { - Int8 = 0, - Uint8, - Int16, - Uint16, - Int32, - Uint32, - Float32, - Float64, - - /** - * Special type that is a uint8_t, but assignments are clamped to [0, 256). - * Treat the raw data type as a uint8_t. - */ - Uint8Clamped, - - /** - * Types that don't have their own TypedArray equivalent, for now. - */ - MaxTypedArrayViewType, - - Int64, - Float32x4, - Int8x16, - Int16x8, - Int32x4 -}; - -static inline size_t -byteSize(Type atype) -{ - switch (atype) { - case Int8: - case Uint8: - case Uint8Clamped: - return 1; - case Int16: - case Uint16: - return 2; - case Int32: - case Uint32: - case Float32: - return 4; - case Int64: - case Float64: - return 8; - case Int8x16: - case Int16x8: - case Int32x4: - case Float32x4: - return 16; - default: - MOZ_CRASH("invalid scalar type"); - } -} - -static inline bool -isSignedIntType(Type atype) { - switch (atype) { - case Int8: - case Int16: - case Int32: - case Int64: - case Int8x16: - case Int16x8: - case Int32x4: - return true; - case Uint8: - case Uint8Clamped: - case Uint16: - case Uint32: - case Float32: - case Float64: - case Float32x4: - return false; - default: - MOZ_CRASH("invalid scalar type"); - } -} - -static inline bool -isSimdType(Type atype) { - switch (atype) { - case Int8: - case Uint8: - case Uint8Clamped: - case Int16: - case Uint16: - case Int32: - case Uint32: - case Int64: - case Float32: - case Float64: - return false; - case Int8x16: - case Int16x8: - case Int32x4: - case Float32x4: - return true; - case MaxTypedArrayViewType: - break; - } - MOZ_CRASH("invalid scalar type"); -} - -static inline size_t -scalarByteSize(Type atype) { - switch (atype) { - case Int8x16: - return 1; - case Int16x8: - return 2; - case Int32x4: - case Float32x4: - return 4; - case Int8: - case Uint8: - case Uint8Clamped: - case Int16: - case Uint16: - case Int32: - case Uint32: - case Int64: - case Float32: - case Float64: - case MaxTypedArrayViewType: - break; - } - MOZ_CRASH("invalid simd type"); -} - -} /* namespace Scalar */ -} /* namespace js */ - -/* - * Create a new typed array with nelements elements. - * - * These functions (except the WithBuffer variants) fill in the array with zeros. - */ - -extern JS_FRIEND_API(JSObject*) -JS_NewInt8Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8ClampedArray(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewInt16Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewUint16Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewInt32Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewUint32Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat32Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat64Array(JSContext* cx, uint32_t nelements); - -/* - * Create a new typed array and copy in values from the given object. The - * object is used as if it were an array; that is, the new array (if - * successfully created) will have length given by array.length, and its - * elements will be those specified by array[0], array[1], and so on, after - * conversion to the typed array element type. - */ - -extern JS_FRIEND_API(JSObject*) -JS_NewInt8ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8ClampedArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewInt16ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewUint16ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewInt32ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewUint32ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat32ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat64ArrayFromArray(JSContext* cx, JS::HandleObject array); - -/* - * Create a new typed array using the given ArrayBuffer or - * SharedArrayBuffer for storage. The length value is optional; if -1 - * is passed, enough elements to use up the remainder of the byte - * array is used as the default value. - */ - -extern JS_FRIEND_API(JSObject*) -JS_NewInt8ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8ClampedArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewInt16ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewUint16ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewInt32ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewUint32ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat32ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat64ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); - -/** - * Create a new SharedArrayBuffer with the given byte length. This - * may only be called if - * JS::CompartmentCreationOptionsRef(cx).getSharedMemoryAndAtomicsEnabled() is - * true. - */ -extern JS_FRIEND_API(JSObject*) -JS_NewSharedArrayBuffer(JSContext* cx, uint32_t nbytes); - -/** - * Create a new ArrayBuffer with the given byte length. - */ -extern JS_FRIEND_API(JSObject*) -JS_NewArrayBuffer(JSContext* cx, uint32_t nbytes); - -/** - * Check whether obj supports JS_GetTypedArray* APIs. Note that this may return - * false if a security wrapper is encountered that denies the unwrapping. If - * this test or one of the JS_Is*Array tests succeeds, then it is safe to call - * the various accessor JSAPI calls defined below. - */ -extern JS_FRIEND_API(bool) -JS_IsTypedArrayObject(JSObject* obj); - -/** - * Check whether obj supports JS_GetArrayBufferView* APIs. Note that this may - * return false if a security wrapper is encountered that denies the - * unwrapping. If this test or one of the more specific tests succeeds, then it - * is safe to call the various ArrayBufferView accessor JSAPI calls defined - * below. - */ -extern JS_FRIEND_API(bool) -JS_IsArrayBufferViewObject(JSObject* obj); - -/* - * Test for specific typed array types (ArrayBufferView subtypes) - */ - -extern JS_FRIEND_API(bool) -JS_IsInt8Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsUint8Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsUint8ClampedArray(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsInt16Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsUint16Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsInt32Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsUint32Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsFloat32Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsFloat64Array(JSObject* obj); - -/** - * Return the isShared flag of a typed array, which denotes whether - * the underlying buffer is a SharedArrayBuffer. - * - * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow - * be known that it would pass such a test: it is a typed array or a wrapper of - * a typed array, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(bool) -JS_GetTypedArraySharedness(JSObject* obj); - -/* - * Test for specific typed array types (ArrayBufferView subtypes) and return - * the unwrapped object if so, else nullptr. Never throws. - */ - -namespace js { - -extern JS_FRIEND_API(JSObject*) -UnwrapInt8Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapUint8Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapUint8ClampedArray(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapInt16Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapUint16Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapInt32Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapUint32Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapFloat32Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapFloat64Array(JSObject* obj); - -extern JS_FRIEND_API(JSObject*) -UnwrapArrayBuffer(JSObject* obj); - -extern JS_FRIEND_API(JSObject*) -UnwrapArrayBufferView(JSObject* obj); - -extern JS_FRIEND_API(JSObject*) -UnwrapSharedArrayBuffer(JSObject* obj); - - -namespace detail { - -extern JS_FRIEND_DATA(const Class* const) Int8ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Uint8ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Uint8ClampedArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Int16ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Uint16ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Int32ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Uint32ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Float32ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Float64ArrayClassPtr; - -const size_t TypedArrayLengthSlot = 1; - -} // namespace detail - -#define JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Type, type) \ -inline void \ -Get ## Type ## ArrayLengthAndData(JSObject* obj, uint32_t* length, bool* isSharedMemory, type** data) \ -{ \ - MOZ_ASSERT(GetObjectClass(obj) == detail::Type ## ArrayClassPtr); \ - const JS::Value& lenSlot = GetReservedSlot(obj, detail::TypedArrayLengthSlot); \ - *length = mozilla::AssertedCast(lenSlot.toInt32()); \ - *isSharedMemory = JS_GetTypedArraySharedness(obj); \ - *data = static_cast(GetObjectPrivate(obj)); \ -} - -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int8, int8_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint8, uint8_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint8Clamped, uint8_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int16, int16_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint16, uint16_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int32, int32_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint32, uint32_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float32, float) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float64, double) - -#undef JS_DEFINE_DATA_AND_LENGTH_ACCESSOR - -// This one isn't inlined because it's rather tricky (by dint of having to deal -// with a dozen-plus classes and varying slot layouts. -extern JS_FRIEND_API(void) -GetArrayBufferViewLengthAndData(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); - -// This one isn't inlined because there are a bunch of different ArrayBuffer -// classes that would have to be individually handled here. -// -// There is an isShared out argument for API consistency (eases use from DOM). -// It will always be set to false. -extern JS_FRIEND_API(void) -GetArrayBufferLengthAndData(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); - -// Ditto for SharedArrayBuffer. -// -// There is an isShared out argument for API consistency (eases use from DOM). -// It will always be set to true. -extern JS_FRIEND_API(void) -GetSharedArrayBufferLengthAndData(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); - -} // namespace js - -JS_FRIEND_API(uint8_t*) -JS_GetSharedArrayBufferData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); - -/* - * Unwrap Typed arrays all at once. Return nullptr without throwing if the - * object cannot be viewed as the correct typed array, or the typed array - * object on success, filling both outparameters. - */ -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsInt8Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, int8_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsUint8Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsUint8ClampedArray(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsInt16Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, int16_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsUint16Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint16_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsInt32Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, int32_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsUint32Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint32_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsFloat32Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, float** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsFloat64Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, double** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsArrayBufferView(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); - -/* - * Unwrap an ArrayBuffer, return nullptr if it's a different type. - */ -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsArrayBuffer(JSObject* obj, uint32_t* length, uint8_t** data); - -/* - * Get the type of elements in a typed array, or MaxTypedArrayViewType if a DataView. - * - * |obj| must have passed a JS_IsArrayBufferView/JS_Is*Array test, or somehow - * be known that it would pass such a test: it is an ArrayBufferView or a - * wrapper of an ArrayBufferView, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(js::Scalar::Type) -JS_GetArrayBufferViewType(JSObject* obj); - -extern JS_FRIEND_API(js::Scalar::Type) -JS_GetSharedArrayBufferViewType(JSObject* obj); - -/* - * Check whether obj supports the JS_GetArrayBuffer* APIs. Note that this may - * return false if a security wrapper is encountered that denies the - * unwrapping. If this test succeeds, then it is safe to call the various - * accessor JSAPI calls defined below. - */ -extern JS_FRIEND_API(bool) -JS_IsArrayBufferObject(JSObject* obj); - -extern JS_FRIEND_API(bool) -JS_IsSharedArrayBufferObject(JSObject* obj); - -/** - * Return the available byte length of an array buffer. - * - * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known - * that it would pass such a test: it is an ArrayBuffer or a wrapper of an - * ArrayBuffer, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(uint32_t) -JS_GetArrayBufferByteLength(JSObject* obj); - -extern JS_FRIEND_API(uint32_t) -JS_GetSharedArrayBufferByteLength(JSObject* obj); - -/** - * Return true if the arrayBuffer contains any data. This will return false for - * ArrayBuffer.prototype and detached ArrayBuffers. - * - * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known - * that it would pass such a test: it is an ArrayBuffer or a wrapper of an - * ArrayBuffer, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(bool) -JS_ArrayBufferHasData(JSObject* obj); - -/** - * Return a pointer to the start of the data referenced by a typed array. The - * data is still owned by the typed array, and should not be modified on - * another thread. Furthermore, the pointer can become invalid on GC (if the - * data is small and fits inside the array's GC header), so callers must take - * care not to hold on across anything that could GC. - * - * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known - * that it would pass such a test: it is an ArrayBuffer or a wrapper of an - * ArrayBuffer, and the unwrapping will succeed. - * - * *isSharedMemory will be set to false, the argument is present to simplify - * its use from code that also interacts with SharedArrayBuffer. - */ -extern JS_FRIEND_API(uint8_t*) -JS_GetArrayBufferData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); - -/** - * Check whether the obj is ArrayBufferObject and memory mapped. Note that this - * may return false if a security wrapper is encountered that denies the - * unwrapping. - */ -extern JS_FRIEND_API(bool) -JS_IsMappedArrayBufferObject(JSObject* obj); - -/** - * Return the number of elements in a typed array. - * - * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow - * be known that it would pass such a test: it is a typed array or a wrapper of - * a typed array, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(uint32_t) -JS_GetTypedArrayLength(JSObject* obj); - -/** - * Return the byte offset from the start of an array buffer to the start of a - * typed array view. - * - * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow - * be known that it would pass such a test: it is a typed array or a wrapper of - * a typed array, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(uint32_t) -JS_GetTypedArrayByteOffset(JSObject* obj); - -/** - * Return the byte length of a typed array. - * - * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow - * be known that it would pass such a test: it is a typed array or a wrapper of - * a typed array, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(uint32_t) -JS_GetTypedArrayByteLength(JSObject* obj); - -/** - * Check whether obj supports JS_ArrayBufferView* APIs. Note that this may - * return false if a security wrapper is encountered that denies the - * unwrapping. - */ -extern JS_FRIEND_API(bool) -JS_IsArrayBufferViewObject(JSObject* obj); - -/** - * More generic name for JS_GetTypedArrayByteLength to cover DataViews as well - */ -extern JS_FRIEND_API(uint32_t) -JS_GetArrayBufferViewByteLength(JSObject* obj); - -/* - * Return a pointer to the start of the data referenced by a typed array. The - * data is still owned by the typed array, and should not be modified on - * another thread. Furthermore, the pointer can become invalid on GC (if the - * data is small and fits inside the array's GC header), so callers must take - * care not to hold on across anything that could GC. - * - * |obj| must have passed a JS_Is*Array test, or somehow be known that it would - * pass such a test: it is a typed array or a wrapper of a typed array, and the - * unwrapping will succeed. - * - * *isSharedMemory will be set to true if the typed array maps a - * SharedArrayBuffer, otherwise to false. - */ - -extern JS_FRIEND_API(int8_t*) -JS_GetInt8ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(uint8_t*) -JS_GetUint8ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(uint8_t*) -JS_GetUint8ClampedArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(int16_t*) -JS_GetInt16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(uint16_t*) -JS_GetUint16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(int32_t*) -JS_GetInt32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(uint32_t*) -JS_GetUint32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(float*) -JS_GetFloat32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(double*) -JS_GetFloat64ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); - -/** - * Same as above, but for any kind of ArrayBufferView. Prefer the type-specific - * versions when possible. - */ -extern JS_FRIEND_API(void*) -JS_GetArrayBufferViewData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); - -/** - * Return the ArrayBuffer or SharedArrayBuffer underlying an ArrayBufferView. - * This may return a detached buffer. |obj| must be an object that would - * return true for JS_IsArrayBufferViewObject(). - */ -extern JS_FRIEND_API(JSObject*) -JS_GetArrayBufferViewBuffer(JSContext* cx, JS::HandleObject obj, bool* isSharedMemory); - -/** - * Detach an ArrayBuffer, causing all associated views to no longer refer to - * the ArrayBuffer's original attached memory. - * - * The |changeData| argument is obsolete and ignored. - */ -extern JS_FRIEND_API(bool) -JS_DetachArrayBuffer(JSContext* cx, JS::HandleObject obj); - -/** - * Check whether the obj is a detached ArrayBufferObject. Note that this may - * return false if a security wrapper is encountered that denies the - * unwrapping. - */ -extern JS_FRIEND_API(bool) -JS_IsDetachedArrayBufferObject(JSObject* obj); - -/** - * Check whether obj supports JS_GetDataView* APIs. - */ -JS_FRIEND_API(bool) -JS_IsDataViewObject(JSObject* obj); - -/** - * Create a new DataView using the given ArrayBuffer for storage. The given - * buffer must be an ArrayBuffer (or a cross-compartment wrapper of an - * ArrayBuffer), and the offset and length must fit within the bounds of the - * arrayBuffer. Currently, nullptr will be returned and an exception will be - * thrown if these conditions do not hold, but do not depend on that behavior. - */ -JS_FRIEND_API(JSObject*) -JS_NewDataView(JSContext* cx, JS::HandleObject arrayBuffer, uint32_t byteOffset, int32_t byteLength); - -/** - * Return the byte offset of a data view into its array buffer. |obj| must be a - * DataView. - * - * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that - * it would pass such a test: it is a data view or a wrapper of a data view, - * and the unwrapping will succeed. - */ -JS_FRIEND_API(uint32_t) -JS_GetDataViewByteOffset(JSObject* obj); - -/** - * Return the byte length of a data view. - * - * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that - * it would pass such a test: it is a data view or a wrapper of a data view, - * and the unwrapping will succeed. If cx is nullptr, then DEBUG builds may be - * unable to assert when unwrapping should be disallowed. - */ -JS_FRIEND_API(uint32_t) -JS_GetDataViewByteLength(JSObject* obj); - -/** - * Return a pointer to the beginning of the data referenced by a DataView. - * - * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that - * it would pass such a test: it is a data view or a wrapper of a data view, - * and the unwrapping will succeed. If cx is nullptr, then DEBUG builds may be - * unable to assert when unwrapping should be disallowed. - */ -JS_FRIEND_API(void*) -JS_GetDataViewData(JSObject* obj, const JS::AutoCheckCannotGC&); - -namespace js { - -/** - * Add a watchpoint -- in the Object.prototype.watch sense -- to |obj| for the - * property |id|, using the callable object |callable| as the function to be - * called for notifications. - * - * This is an internal function exposed -- temporarily -- only so that DOM - * proxies can be watchable. Don't use it! We'll soon kill off the - * Object.prototype.{,un}watch functions, at which point this will go too. - */ -extern JS_FRIEND_API(bool) -WatchGuts(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable); - -/** - * Remove a watchpoint -- in the Object.prototype.watch sense -- from |obj| for - * the property |id|. - * - * This is an internal function exposed -- temporarily -- only so that DOM - * proxies can be watchable. Don't use it! We'll soon kill off the - * Object.prototype.{,un}watch functions, at which point this will go too. - */ -extern JS_FRIEND_API(bool) -UnwatchGuts(JSContext* cx, JS::HandleObject obj, JS::HandleId id); - -namespace jit { - -enum class InlinableNative : uint16_t; - -} // namespace jit - -} // namespace js - -/** - * A class, expected to be passed by value, which represents the CallArgs for a - * JSJitGetterOp. - */ -class JSJitGetterCallArgs : protected JS::MutableHandleValue -{ - public: - explicit JSJitGetterCallArgs(const JS::CallArgs& args) - : JS::MutableHandleValue(args.rval()) - {} - - explicit JSJitGetterCallArgs(JS::RootedValue* rooted) - : JS::MutableHandleValue(rooted) - {} - - JS::MutableHandleValue rval() { - return *this; - } -}; - -/** - * A class, expected to be passed by value, which represents the CallArgs for a - * JSJitSetterOp. - */ -class JSJitSetterCallArgs : protected JS::MutableHandleValue -{ - public: - explicit JSJitSetterCallArgs(const JS::CallArgs& args) - : JS::MutableHandleValue(args[0]) - {} - - JS::MutableHandleValue operator[](unsigned i) { - MOZ_ASSERT(i == 0); - return *this; - } - - unsigned length() const { return 1; } - - // Add get() or maybe hasDefined() as needed -}; - -struct JSJitMethodCallArgsTraits; - -/** - * A class, expected to be passed by reference, which represents the CallArgs - * for a JSJitMethodOp. - */ -class JSJitMethodCallArgs : protected JS::detail::CallArgsBase -{ - private: - typedef JS::detail::CallArgsBase Base; - friend struct JSJitMethodCallArgsTraits; - - public: - explicit JSJitMethodCallArgs(const JS::CallArgs& args) { - argv_ = args.array(); - argc_ = args.length(); - } - - JS::MutableHandleValue rval() const { - return Base::rval(); - } - - unsigned length() const { return Base::length(); } - - JS::MutableHandleValue operator[](unsigned i) const { - return Base::operator[](i); - } - - bool hasDefined(unsigned i) const { - return Base::hasDefined(i); - } - - JSObject& callee() const { - // We can't use Base::callee() because that will try to poke at - // this->usedRval_, which we don't have. - return argv_[-2].toObject(); - } - - JS::HandleValue get(unsigned i) const { - return Base::get(i); - } -}; - -struct JSJitMethodCallArgsTraits -{ - static const size_t offsetOfArgv = offsetof(JSJitMethodCallArgs, argv_); - static const size_t offsetOfArgc = offsetof(JSJitMethodCallArgs, argc_); -}; - -typedef bool -(* JSJitGetterOp)(JSContext* cx, JS::HandleObject thisObj, - void* specializedThis, JSJitGetterCallArgs args); -typedef bool -(* JSJitSetterOp)(JSContext* cx, JS::HandleObject thisObj, - void* specializedThis, JSJitSetterCallArgs args); -typedef bool -(* JSJitMethodOp)(JSContext* cx, JS::HandleObject thisObj, - void* specializedThis, const JSJitMethodCallArgs& args); - -/** - * This struct contains metadata passed from the DOM to the JS Engine for JIT - * optimizations on DOM property accessors. Eventually, this should be made - * available to general JSAPI users, but we are not currently ready to do so. - */ -struct JSJitInfo { - enum OpType { - Getter, - Setter, - Method, - StaticMethod, - InlinableNative, - // Must be last - OpTypeCount - }; - - enum ArgType { - // Basic types - String = (1 << 0), - Integer = (1 << 1), // Only 32-bit or less - Double = (1 << 2), // Maybe we want to add Float sometime too - Boolean = (1 << 3), - Object = (1 << 4), - Null = (1 << 5), - - // And derived types - Numeric = Integer | Double, - // Should "Primitive" use the WebIDL definition, which - // excludes string and null, or the typical JS one that includes them? - Primitive = Numeric | Boolean | Null | String, - ObjectOrNull = Object | Null, - Any = ObjectOrNull | Primitive, - - // Our sentinel value. - ArgTypeListEnd = (1 << 31) - }; - - static_assert(Any & String, "Any must include String."); - static_assert(Any & Integer, "Any must include Integer."); - static_assert(Any & Double, "Any must include Double."); - static_assert(Any & Boolean, "Any must include Boolean."); - static_assert(Any & Object, "Any must include Object."); - static_assert(Any & Null, "Any must include Null."); - - /** - * An enum that describes what this getter/setter/method aliases. This - * determines what things can be hoisted past this call, and if this - * call is movable what it can be hoisted past. - */ - enum AliasSet { - /** - * Alias nothing: a constant value, getting it can't affect any other - * values, nothing can affect it. - */ - AliasNone, - - /** - * Alias things that can modify the DOM but nothing else. Doing the - * call can't affect the behavior of any other function. - */ - AliasDOMSets, - - /** - * Alias the world. Calling this can change arbitrary values anywhere - * in the system. Most things fall in this bucket. - */ - AliasEverything, - - /** Must be last. */ - AliasSetCount - }; - - bool needsOuterizedThisObject() const - { - return type() != Getter && type() != Setter; - } - - bool isTypedMethodJitInfo() const - { - return isTypedMethod; - } - - OpType type() const - { - return OpType(type_); - } - - AliasSet aliasSet() const - { - return AliasSet(aliasSet_); - } - - JSValueType returnType() const - { - return JSValueType(returnType_); - } - - union { - JSJitGetterOp getter; - JSJitSetterOp setter; - JSJitMethodOp method; - /** A DOM static method, used for Promise wrappers */ - JSNative staticMethod; - }; - - union { - uint16_t protoID; - js::jit::InlinableNative inlinableNative; - }; - - union { - uint16_t depth; - - // Additional opcode for some InlinableNative functions. - uint16_t nativeOp; - }; - - // These fields are carefully packed to take up 4 bytes. If you need more - // bits for whatever reason, please see if you can steal bits from existing - // fields before adding more members to this structure. - -#define JITINFO_OP_TYPE_BITS 4 -#define JITINFO_ALIAS_SET_BITS 4 -#define JITINFO_RETURN_TYPE_BITS 8 -#define JITINFO_SLOT_INDEX_BITS 10 - - /** The OpType that says what sort of function we are. */ - uint32_t type_ : JITINFO_OP_TYPE_BITS; - - /** - * The alias set for this op. This is a _minimal_ alias set; in - * particular for a method it does not include whatever argument - * conversions might do. That's covered by argTypes and runtime - * analysis of the actual argument types being passed in. - */ - uint32_t aliasSet_ : JITINFO_ALIAS_SET_BITS; - - /** The return type tag. Might be JSVAL_TYPE_UNKNOWN. */ - uint32_t returnType_ : JITINFO_RETURN_TYPE_BITS; - - static_assert(OpTypeCount <= (1 << JITINFO_OP_TYPE_BITS), - "Not enough space for OpType"); - static_assert(AliasSetCount <= (1 << JITINFO_ALIAS_SET_BITS), - "Not enough space for AliasSet"); - static_assert((sizeof(JSValueType) * 8) <= JITINFO_RETURN_TYPE_BITS, - "Not enough space for JSValueType"); - -#undef JITINFO_RETURN_TYPE_BITS -#undef JITINFO_ALIAS_SET_BITS -#undef JITINFO_OP_TYPE_BITS - - /** Is op fallible? False in setters. */ - uint32_t isInfallible : 1; - - /** - * Is op movable? To be movable the op must - * not AliasEverything, but even that might - * not be enough (e.g. in cases when it can - * throw or is explicitly not movable). - */ - uint32_t isMovable : 1; - - /** - * Can op be dead-code eliminated? Again, this - * depends on whether the op can throw, in - * addition to the alias set. - */ - uint32_t isEliminatable : 1; - - // XXXbz should we have a JSValueType for the type of the member? - /** - * True if this is a getter that can always - * get the value from a slot of the "this" object. - */ - uint32_t isAlwaysInSlot : 1; - - /** - * True if this is a getter that can sometimes (if the slot doesn't contain - * UndefinedValue()) get the value from a slot of the "this" object. - */ - uint32_t isLazilyCachedInSlot : 1; - - /** True if this is an instance of JSTypedMethodJitInfo. */ - uint32_t isTypedMethod : 1; - - /** - * If isAlwaysInSlot or isSometimesInSlot is true, - * the index of the slot to get the value from. - * Otherwise 0. - */ - uint32_t slotIndex : JITINFO_SLOT_INDEX_BITS; - - static const size_t maxSlotIndex = (1 << JITINFO_SLOT_INDEX_BITS) - 1; - -#undef JITINFO_SLOT_INDEX_BITS -}; - -static_assert(sizeof(JSJitInfo) == (sizeof(void*) + 2 * sizeof(uint32_t)), - "There are several thousand instances of JSJitInfo stored in " - "a binary. Please don't increase its space requirements without " - "verifying that there is no other way forward (better packing, " - "smaller datatypes for fields, subclassing, etc.)."); - -struct JSTypedMethodJitInfo -{ - // We use C-style inheritance here, rather than C++ style inheritance - // because not all compilers support brace-initialization for non-aggregate - // classes. Using C++ style inheritance and constructors instead of - // brace-initialization would also force the creation of static - // constructors (on some compilers) when JSJitInfo and JSTypedMethodJitInfo - // structures are declared. Since there can be several thousand of these - // structures present and we want to have roughly equivalent performance - // across a range of compilers, we do things manually. - JSJitInfo base; - - const JSJitInfo::ArgType* const argTypes; /* For a method, a list of sets of - types that the function - expects. This can be used, - for example, to figure out - when argument coercions can - have side-effects. */ -}; - -namespace js { - -static MOZ_ALWAYS_INLINE shadow::Function* -FunctionObjectToShadowFunction(JSObject* fun) -{ - MOZ_ASSERT(GetObjectClass(fun) == FunctionClassPtr); - return reinterpret_cast(fun); -} - -/* Statically asserted in jsfun.h. */ -static const unsigned JS_FUNCTION_INTERPRETED_BITS = 0x0201; - -// Return whether the given function object is native. -static MOZ_ALWAYS_INLINE bool -FunctionObjectIsNative(JSObject* fun) -{ - return !(FunctionObjectToShadowFunction(fun)->flags & JS_FUNCTION_INTERPRETED_BITS); -} - -static MOZ_ALWAYS_INLINE JSNative -GetFunctionObjectNative(JSObject* fun) -{ - MOZ_ASSERT(FunctionObjectIsNative(fun)); - return FunctionObjectToShadowFunction(fun)->native; -} - -} // namespace js - -static MOZ_ALWAYS_INLINE const JSJitInfo* -FUNCTION_VALUE_TO_JITINFO(const JS::Value& v) -{ - MOZ_ASSERT(js::FunctionObjectIsNative(&v.toObject())); - return js::FunctionObjectToShadowFunction(&v.toObject())->jitinfo; -} - -static MOZ_ALWAYS_INLINE void -SET_JITINFO(JSFunction * func, const JSJitInfo* info) -{ - js::shadow::Function* fun = reinterpret_cast(func); - MOZ_ASSERT(!(fun->flags & js::JS_FUNCTION_INTERPRETED_BITS)); - fun->jitinfo = info; -} - -/* - * Engine-internal extensions of jsid. This code is here only until we - * eliminate Gecko's dependencies on it! - */ - -static MOZ_ALWAYS_INLINE jsid -JSID_FROM_BITS(size_t bits) -{ - jsid id; - JSID_BITS(id) = bits; - return id; -} - -namespace js { -namespace detail { -bool IdMatchesAtom(jsid id, JSAtom* atom); -} // namespace detail -} // namespace js - -/** - * Must not be used on atoms that are representable as integer jsids. - * Prefer NameToId or AtomToId over this function: - * - * A PropertyName is an atom that does not contain an integer in the range - * [0, UINT32_MAX]. However, jsid can only hold an integer in the range - * [0, JSID_INT_MAX] (where JSID_INT_MAX == 2^31-1). Thus, for the range of - * integers (JSID_INT_MAX, UINT32_MAX], to represent as a jsid 'id', it must be - * the case JSID_IS_ATOM(id) and !JSID_TO_ATOM(id)->isPropertyName(). In most - * cases when creating a jsid, code does not have to care about this corner - * case because: - * - * - When given an arbitrary JSAtom*, AtomToId must be used, which checks for - * integer atoms representable as integer jsids, and does this conversion. - * - * - When given a PropertyName*, NameToId can be used which which does not need - * to do any dynamic checks. - * - * Thus, it is only the rare third case which needs this function, which - * handles any JSAtom* that is known not to be representable with an int jsid. - */ -static MOZ_ALWAYS_INLINE jsid -NON_INTEGER_ATOM_TO_JSID(JSAtom* atom) -{ - MOZ_ASSERT(((size_t)atom & 0x7) == 0); - jsid id = JSID_FROM_BITS((size_t)atom); - MOZ_ASSERT(js::detail::IdMatchesAtom(id, atom)); - return id; -} - -/* All strings stored in jsids are atomized, but are not necessarily property names. */ -static MOZ_ALWAYS_INLINE bool -JSID_IS_ATOM(jsid id) -{ - return JSID_IS_STRING(id); -} - -static MOZ_ALWAYS_INLINE bool -JSID_IS_ATOM(jsid id, JSAtom* atom) -{ - return id == JSID_FROM_BITS((size_t)atom); -} - -static MOZ_ALWAYS_INLINE JSAtom* -JSID_TO_ATOM(jsid id) -{ - return (JSAtom*)JSID_TO_STRING(id); -} - -JS_STATIC_ASSERT(sizeof(jsid) == sizeof(void*)); - -namespace js { - -static MOZ_ALWAYS_INLINE JS::Value -IdToValue(jsid id) -{ - if (JSID_IS_STRING(id)) - return JS::StringValue(JSID_TO_STRING(id)); - if (JSID_IS_INT(id)) - return JS::Int32Value(JSID_TO_INT(id)); - if (JSID_IS_SYMBOL(id)) - return JS::SymbolValue(JSID_TO_SYMBOL(id)); - MOZ_ASSERT(JSID_IS_VOID(id)); - return JS::UndefinedValue(); -} - -/** - * If the embedder has registered a ScriptEnvironmentPreparer, - * PrepareScriptEnvironmentAndInvoke will call the preparer's 'invoke' method - * with the given |closure|, with the assumption that the preparer will set up - * any state necessary to run script in |scope|, invoke |closure| with a valid - * JSContext*, report any exceptions thrown from the closure, and return. - * - * If no preparer is registered, PrepareScriptEnvironmentAndInvoke will assert - * that |rt| has exactly one JSContext associated with it, enter the compartment - * of |scope| on that context, and invoke |closure|. - * - * In both cases, PrepareScriptEnvironmentAndInvoke will report any exceptions - * that are thrown by the closure. Consumers who want to propagate back - * whether the closure succeeded should do so via members of the closure - * itself. - */ - -struct ScriptEnvironmentPreparer { - struct Closure { - virtual bool operator()(JSContext* cx) = 0; - }; - - virtual void invoke(JS::HandleObject scope, Closure& closure) = 0; -}; - -extern JS_FRIEND_API(void) -PrepareScriptEnvironmentAndInvoke(JSContext* cx, JS::HandleObject scope, - ScriptEnvironmentPreparer::Closure& closure); - -JS_FRIEND_API(void) -SetScriptEnvironmentPreparer(JSContext* cx, ScriptEnvironmentPreparer* preparer); - -enum CTypesActivityType { - CTYPES_CALL_BEGIN, - CTYPES_CALL_END, - CTYPES_CALLBACK_BEGIN, - CTYPES_CALLBACK_END -}; - -typedef void -(* CTypesActivityCallback)(JSContext* cx, CTypesActivityType type); - -/** - * Sets a callback that is run whenever js-ctypes is about to be used when - * calling into C. - */ -JS_FRIEND_API(void) -SetCTypesActivityCallback(JSContext* cx, CTypesActivityCallback cb); - -class MOZ_RAII JS_FRIEND_API(AutoCTypesActivityCallback) { - private: - JSContext* cx; - CTypesActivityCallback callback; - CTypesActivityType endType; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - - public: - AutoCTypesActivityCallback(JSContext* cx, CTypesActivityType beginType, - CTypesActivityType endType - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - ~AutoCTypesActivityCallback() { - DoEndCallback(); - } - void DoEndCallback() { - if (callback) { - callback(cx, endType); - callback = nullptr; - } - } -}; - -// Abstract base class for objects that build allocation metadata for JavaScript -// values. -struct AllocationMetadataBuilder { - AllocationMetadataBuilder() { } - - // Return a metadata object for the newly constructed object |obj|, or - // nullptr if there's no metadata to attach. - // - // Implementations should treat all errors as fatal; there is no way to - // report errors from this callback. In particular, the caller provides an - // oomUnsafe for overriding implementations to use. - virtual JSObject* build(JSContext* cx, JS::HandleObject obj, - AutoEnterOOMUnsafeRegion& oomUnsafe) const - { - return nullptr; - } -}; - -/** - * Specify a callback to invoke when creating each JS object in the current - * compartment, which may return a metadata object to associate with the - * object. - */ -JS_FRIEND_API(void) -SetAllocationMetadataBuilder(JSContext* cx, const AllocationMetadataBuilder *callback); - -/** Get the metadata associated with an object. */ -JS_FRIEND_API(JSObject*) -GetAllocationMetadata(JSObject* obj); - -JS_FRIEND_API(bool) -GetElementsWithAdder(JSContext* cx, JS::HandleObject obj, JS::HandleObject receiver, - uint32_t begin, uint32_t end, js::ElementAdder* adder); - -JS_FRIEND_API(bool) -ForwardToNative(JSContext* cx, JSNative native, const JS::CallArgs& args); - -/** - * Helper function for HTMLDocument and HTMLFormElement. - * - * These are the only two interfaces that have [OverrideBuiltins], a named - * getter, and no named setter. They're implemented as proxies with a custom - * getOwnPropertyDescriptor() method. Unfortunately, overriding - * getOwnPropertyDescriptor() automatically affects the behavior of set(), - * which normally is just common sense but is *not* desired for these two - * interfaces. - * - * The fix is for these two interfaces to override set() to ignore the - * getOwnPropertyDescriptor() override. - * - * SetPropertyIgnoringNamedGetter is exposed to make it easier to override - * set() in this way. It carries out all the steps of BaseProxyHandler::set() - * except the initial getOwnPropertyDescriptor() call. The caller must supply - * that descriptor as the 'ownDesc' parameter. - * - * Implemented in proxy/BaseProxyHandler.cpp. - */ -JS_FRIEND_API(bool) -SetPropertyIgnoringNamedGetter(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::HandleValue v, JS::HandleValue receiver, - JS::Handle ownDesc, - JS::ObjectOpResult& result); - -JS_FRIEND_API(void) -ReportASCIIErrorWithId(JSContext* cx, const char* msg, JS::HandleId id); - -// This function is for one specific use case, please don't use this for anything else! -extern JS_FRIEND_API(bool) -ExecuteInGlobalAndReturnScope(JSContext* cx, JS::HandleObject obj, JS::HandleScript script, - JS::MutableHandleObject scope); - -#if defined(XP_WIN) && defined(_WIN64) -// Parameters use void* types to avoid #including windows.h. The return value of -// this function is returned from the exception handler. -typedef long -(*JitExceptionHandler)(void* exceptionRecord, // PEXECTION_RECORD - void* context); // PCONTEXT - -/** - * Windows uses "structured exception handling" to handle faults. When a fault - * occurs, the stack is searched for a handler (similar to C++ exception - * handling). If the search does not find a handler, the "unhandled exception - * filter" is called. Breakpad uses the unhandled exception filter to do crash - * reporting. Unfortunately, on Win64, JIT code on the stack completely throws - * off this unwinding process and prevents the unhandled exception filter from - * being called. The reason is that Win64 requires unwind information be - * registered for all code regions and JIT code has none. While it is possible - * to register full unwind information for JIT code, this is a lot of work (one - * has to be able to recover the frame pointer at any PC) so instead we register - * a handler for all JIT code that simply calls breakpad's unhandled exception - * filter (which will perform crash reporting and then terminate the process). - * This would be wrong if there was an outer __try block that expected to handle - * the fault, but this is not generally allowed. - * - * Gecko must call SetJitExceptionFilter before any JIT code is compiled and - * only once per process. - */ -extern JS_FRIEND_API(void) -SetJitExceptionHandler(JitExceptionHandler handler); -#endif - -/** - * Get the nearest enclosing with environment object for a given function. If - * the function is not scripted or is not enclosed by a with scope, returns - * the global. - */ -extern JS_FRIEND_API(JSObject*) -GetNearestEnclosingWithEnvironmentObjectForFunction(JSFunction* fun); - -/** - * Get the first SavedFrame object in this SavedFrame stack whose principals are - * subsumed by the cx's principals. If there is no such frame, return nullptr. - * - * Do NOT pass a non-SavedFrame object here. - * - * The savedFrame and cx do not need to be in the same compartment. - */ -extern JS_FRIEND_API(JSObject*) -GetFirstSubsumedSavedFrame(JSContext* cx, JS::HandleObject savedFrame, JS::SavedFrameSelfHosted selfHosted); - -extern JS_FRIEND_API(bool) -ReportIsNotFunction(JSContext* cx, JS::HandleValue v); - -extern JS_FRIEND_API(JSObject*) -ConvertArgsToArray(JSContext* cx, const JS::CallArgs& args); - -/** - * Window and WindowProxy - * - * The functions below have to do with Windows and WindowProxies. There's an - * invariant that actual Window objects (the global objects of web pages) are - * never directly exposed to script. Instead we often substitute a WindowProxy. - * - * The environment chain, on the other hand, contains the Window and never its - * WindowProxy. - * - * As a result, we have calls to these "substitute-this-object-for-that-object" - * functions sprinkled at apparently arbitrary (but actually *very* carefully - * and nervously selected) places throughout the engine and indeed the - * universe. - */ - -/** - * Tell the JS engine which Class is used for WindowProxy objects. Used by the - * functions below. - */ -extern JS_FRIEND_API(void) -SetWindowProxyClass(JSContext* cx, const Class* clasp); - -/** - * Associates a WindowProxy with a Window (global object). `windowProxy` must - * have the Class set by SetWindowProxyClass. - */ -extern JS_FRIEND_API(void) -SetWindowProxy(JSContext* cx, JS::HandleObject global, JS::HandleObject windowProxy); - -namespace detail { - -JS_FRIEND_API(bool) -IsWindowSlow(JSObject* obj); - -} // namespace detail - -/** - * Returns true iff `obj` is a global object with an associated WindowProxy, - * see SetWindowProxy. - */ -inline bool -IsWindow(JSObject* obj) -{ - if (GetObjectClass(obj)->flags & JSCLASS_IS_GLOBAL) - return detail::IsWindowSlow(obj); - return false; -} - -/** - * Returns true iff `obj` has the WindowProxy Class (see SetWindowProxyClass). - */ -JS_FRIEND_API(bool) -IsWindowProxy(JSObject* obj); - -/** - * If `obj` is a Window, get its associated WindowProxy (or a CCW or dead - * wrapper if the page was navigated away from), else return `obj`. This - * function is infallible and never returns nullptr. - */ -extern JS_FRIEND_API(JSObject*) -ToWindowProxyIfWindow(JSObject* obj); - -/** - * If `obj` is a WindowProxy, get its associated Window (the compartment's - * global), else return `obj`. This function is infallible and never returns - * nullptr. - */ -extern JS_FRIEND_API(JSObject*) -ToWindowIfWindowProxy(JSObject* obj); - -} /* namespace js */ - -class NativeProfiler -{ - public: - virtual ~NativeProfiler() {}; - virtual void sampleNative(void* addr, uint32_t size) = 0; - virtual void removeNative(void* addr) = 0; - virtual void reset() = 0; -}; - -class GCHeapProfiler -{ - public: - virtual ~GCHeapProfiler() {}; - virtual void sampleTenured(void* addr, uint32_t size) = 0; - virtual void sampleNursery(void* addr, uint32_t size) = 0; - virtual void markTenuredStart() = 0; - virtual void markTenured(void* addr) = 0; - virtual void sweepTenured() = 0; - virtual void sweepNursery() = 0; - virtual void moveNurseryToTenured(void* addrOld, void* addrNew) = 0; - virtual void reset() = 0; -}; - -class MemProfiler -{ - static mozilla::Atomic sActiveProfilerCount; - static NativeProfiler* sNativeProfiler; - - static GCHeapProfiler* GetGCHeapProfiler(void* addr); - static GCHeapProfiler* GetGCHeapProfiler(JSRuntime* runtime); - - static NativeProfiler* GetNativeProfiler() { - return sNativeProfiler; - } - - GCHeapProfiler* mGCHeapProfiler; - JSRuntime* mRuntime; - - public: - explicit MemProfiler(JSRuntime* aRuntime) : mGCHeapProfiler(nullptr), mRuntime(aRuntime) {} - - void start(GCHeapProfiler* aGCHeapProfiler); - void stop(); - - GCHeapProfiler* getGCHeapProfiler() const { - return mGCHeapProfiler; - } - - static MOZ_ALWAYS_INLINE bool enabled() { - return sActiveProfilerCount > 0; - } - - static MemProfiler* GetMemProfiler(JSContext* context); - - static void SetNativeProfiler(NativeProfiler* aProfiler) { - sNativeProfiler = aProfiler; - } - - static MOZ_ALWAYS_INLINE void SampleNative(void* addr, uint32_t size) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - NativeProfiler* profiler = GetNativeProfiler(); - if (profiler) - profiler->sampleNative(addr, size); - } - - static MOZ_ALWAYS_INLINE void SampleTenured(void* addr, uint32_t size) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(addr); - if (profiler) - profiler->sampleTenured(addr, size); - } - - static MOZ_ALWAYS_INLINE void SampleNursery(void* addr, uint32_t size) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(addr); - if (profiler) - profiler->sampleNursery(addr, size); - } - - static MOZ_ALWAYS_INLINE void RemoveNative(void* addr) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - NativeProfiler* profiler = GetNativeProfiler(); - if (profiler) - profiler->removeNative(addr); - } - - static MOZ_ALWAYS_INLINE void MarkTenuredStart(JSRuntime* runtime) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(runtime); - if (profiler) - profiler->markTenuredStart(); - } - - static MOZ_ALWAYS_INLINE void MarkTenured(void* addr) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(addr); - if (profiler) - profiler->markTenured(addr); - } - - static MOZ_ALWAYS_INLINE void SweepTenured(JSRuntime* runtime) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(runtime); - if (profiler) - profiler->sweepTenured(); - } - - static MOZ_ALWAYS_INLINE void SweepNursery(JSRuntime* runtime) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(runtime); - if (profiler) - profiler->sweepNursery(); - } - - static MOZ_ALWAYS_INLINE void MoveNurseryToTenured(void* addrOld, void* addrNew) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(addrOld); - if (profiler) - profiler->moveNurseryToTenured(addrOld, addrNew); - } -}; - -#endif /* jsfriendapi_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/jsperf.h b/android/armeabi-v7a/include/spidermonkey/jsperf.h deleted file mode 100644 index b8f2909a..00000000 --- a/android/armeabi-v7a/include/spidermonkey/jsperf.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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 perf_jsperf_h -#define perf_jsperf_h - -#include "jstypes.h" - -#include "js/TypeDecls.h" -#include "js/Utility.h" - -namespace JS { - -/* - * JS::PerfMeasurement is a generic way to access detailed performance - * measurement APIs provided by your operating system. The details of - * exactly how this works and what can be measured are highly - * system-specific, but this interface is (one hopes) implementable - * on top of all of them. - * - * To use this API, create a PerfMeasurement object, passing its - * constructor a bitmask indicating which events you are interested - * in. Thereafter, Start() zeroes all counters and starts timing; - * Stop() stops timing again; and the counters for the events you - * requested are available as data values after calling Stop(). The - * object may be reused for many measurements. - */ -class JS_FRIEND_API(PerfMeasurement) -{ - protected: - // Implementation-specific data, if any. - void* impl; - - public: - /* - * Events that may be measured. Taken directly from the list of - * "generalized hardware performance event types" in the Linux - * perf_event API, plus some of the "software events". - */ - enum EventMask { - CPU_CYCLES = 0x00000001, - INSTRUCTIONS = 0x00000002, - CACHE_REFERENCES = 0x00000004, - CACHE_MISSES = 0x00000008, - BRANCH_INSTRUCTIONS = 0x00000010, - BRANCH_MISSES = 0x00000020, - BUS_CYCLES = 0x00000040, - PAGE_FAULTS = 0x00000080, - MAJOR_PAGE_FAULTS = 0x00000100, - CONTEXT_SWITCHES = 0x00000200, - CPU_MIGRATIONS = 0x00000400, - - ALL = 0x000007ff, - NUM_MEASURABLE_EVENTS = 11 - }; - - /* - * Bitmask of events that will be measured when this object is - * active (between Start() and Stop()). This may differ from the - * bitmask passed to the constructor if the platform does not - * support measuring all of the requested events. - */ - const EventMask eventsMeasured; - - /* - * Counters for each measurable event. - * Immediately after one of these objects is created, all of the - * counters for enabled events will be zero, and all of the - * counters for disabled events will be uint64_t(-1). - */ - uint64_t cpu_cycles; - uint64_t instructions; - uint64_t cache_references; - uint64_t cache_misses; - uint64_t branch_instructions; - uint64_t branch_misses; - uint64_t bus_cycles; - uint64_t page_faults; - uint64_t major_page_faults; - uint64_t context_switches; - uint64_t cpu_migrations; - - /* - * Prepare to measure the indicated set of events. If not all of - * the requested events can be measured on the current platform, - * then the eventsMeasured bitmask will only include the subset of - * |toMeasure| corresponding to the events that can be measured. - */ - explicit PerfMeasurement(EventMask toMeasure); - - /* Done with this set of measurements, tear down OS-level state. */ - ~PerfMeasurement(); - - /* Start a measurement cycle. */ - void start(); - - /* - * End a measurement cycle, and for each enabled counter, add the - * number of measured events of that type to the appropriate - * visible variable. - */ - void stop(); - - /* Reset all enabled counters to zero. */ - void reset(); - - /* - * True if this platform supports measuring _something_, i.e. it's - * not using the stub implementation. - */ - static bool canMeasureSomething(); -}; - -/* Inject a Javascript wrapper around the above C++ class into the - * Javascript object passed as an argument (this will normally be a - * global object). The JS-visible API is identical to the C++ API. - */ -extern JS_FRIEND_API(JSObject*) - RegisterPerfMeasurement(JSContext* cx, JS::HandleObject global); - -/* - * Given a Value which contains an instance of the aforementioned - * wrapper class, extract the C++ object. Returns nullptr if the - * Value is not an instance of the wrapper. - */ -extern JS_FRIEND_API(PerfMeasurement*) - ExtractPerfMeasurement(const Value& wrapper); - -} // namespace JS - -#endif /* perf_jsperf_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/jsprf.h b/android/armeabi-v7a/include/spidermonkey/jsprf.h deleted file mode 100644 index b84b5a5c..00000000 --- a/android/armeabi-v7a/include/spidermonkey/jsprf.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsprf_h -#define jsprf_h - -/* -** API for PR printf like routines. Supports the following formats -** %d - decimal -** %u - unsigned decimal -** %x - unsigned hex -** %X - unsigned uppercase hex -** %o - unsigned octal -** %hd, %hu, %hx, %hX, %ho - "short" versions of above -** %ld, %lu, %lx, %lX, %lo - "long" versions of above -** %lld, %llu, %llx, %llX, %llo - "long long" versions of above -** %zd, %zo, %zu, %zx, %zX - size_t versions of above -** %Id, %Io, %Iu, %Ix, %IX - size_t versions of above (for Windows compat) -** You should use PRI*SIZE macros instead -** %s - string -** %c - character -** %p - pointer (deals with machine dependent pointer size) -** %f - float -** %g - float -*/ - -#include "mozilla/IntegerPrintfMacros.h" -#include "mozilla/SizePrintfMacros.h" - -#include - -#include "jstypes.h" - -/* -** sprintf into a malloc'd buffer. Return a pointer to the malloc'd -** buffer on success, nullptr on failure. Call "JS_smprintf_free" to release -** the memory returned. -*/ -extern JS_PUBLIC_API(char*) JS_smprintf(const char* fmt, ...) - MOZ_FORMAT_PRINTF(1, 2); - -/* -** Free the memory allocated, for the caller, by JS_smprintf -*/ -extern JS_PUBLIC_API(void) JS_smprintf_free(char* mem); - -/* -** "append" sprintf into a malloc'd buffer. "last" is the last value of -** the malloc'd buffer. sprintf will append data to the end of last, -** growing it as necessary using realloc. If last is nullptr, JS_sprintf_append -** will allocate the initial string. The return value is the new value of -** last for subsequent calls, or nullptr if there is a malloc failure. -*/ -extern JS_PUBLIC_API(char*) JS_sprintf_append(char* last, const char* fmt, ...) - MOZ_FORMAT_PRINTF(2, 3); - -/* -** va_list forms of the above. -*/ -extern JS_PUBLIC_API(char*) JS_vsmprintf(const char* fmt, va_list ap); -extern JS_PUBLIC_API(char*) JS_vsprintf_append(char* last, const char* fmt, va_list ap); - -#endif /* jsprf_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/jsprototypes.h b/android/armeabi-v7a/include/spidermonkey/jsprototypes.h deleted file mode 100644 index f409dce9..00000000 --- a/android/armeabi-v7a/include/spidermonkey/jsprototypes.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsprototypes_h -#define jsprototypes_h - -/* A higher-order macro for enumerating all JSProtoKey values. */ -/* - * Consumers define macros as follows: - * macro(name, code, init, clasp) - * name: The canonical name of the class. - * code: The enumerator code. There are part of the XDR API, and must not change. - * init: Initialization function. These are |extern "C";|, and clients should use - * |extern "C" {}| as appropriate when using this macro. - * clasp: The JSClass for this object, or "dummy" if it doesn't exist. - * - * - * Consumers wishing to iterate over all the JSProtoKey values, can use - * JS_FOR_EACH_PROTOTYPE. However, there are certain values that don't correspond - * to real constructors, like Null or constructors that are disabled via - * preprocessor directives. We still need to include these in the JSProtoKey list - * in order to maintain binary XDR compatibility, but we need to provide a tool - * to handle them differently. JS_FOR_PROTOTYPES fills this niche. - * - * Consumers pass two macros to JS_FOR_PROTOTYPES - |real| and |imaginary|. The - * former is invoked for entries that have real client-exposed constructors, and - * the latter is called for the rest. Consumers that don't care about this - * distinction can simply pass the same macro to both, which is exactly what - * JS_FOR_EACH_PROTOTYPE does. - */ - -#define CLASP(name) (&name##Class) -#define OCLASP(name) (&name##Object::class_) -#define TYPED_ARRAY_CLASP(type) (&TypedArrayObject::classes[Scalar::type]) -#define ERROR_CLASP(type) (&ErrorObject::classes[type]) - -#ifdef EXPOSE_INTL_API -#define IF_INTL(real,imaginary) real -#else -#define IF_INTL(real,imaginary) imaginary -#endif - -#ifdef ENABLE_BINARYDATA -#define IF_BDATA(real,imaginary) real -#else -#define IF_BDATA(real,imaginary) imaginary -#endif - -#ifdef ENABLE_SIMD -# define IF_SIMD(real,imaginary) real -#else -# define IF_SIMD(real,imaginary) imaginary -#endif - -#ifdef ENABLE_SHARED_ARRAY_BUFFER -#define IF_SAB(real,imaginary) real -#else -#define IF_SAB(real,imaginary) imaginary -#endif - -#ifdef SPIDERMONKEY_PROMISE -#define IF_PROMISE(real,imaginary) real -#else -#define IF_PROMISE(real,imaginary) imaginary -#endif - -#define JS_FOR_PROTOTYPES(real,imaginary) \ - imaginary(Null, 0, InitNullClass, dummy) \ - real(Object, 1, InitViaClassSpec, OCLASP(Plain)) \ - real(Function, 2, InitViaClassSpec, &JSFunction::class_) \ - real(Array, 3, InitViaClassSpec, OCLASP(Array)) \ - real(Boolean, 4, InitBooleanClass, OCLASP(Boolean)) \ - real(JSON, 5, InitJSONClass, CLASP(JSON)) \ - real(Date, 6, InitViaClassSpec, OCLASP(Date)) \ - real(Math, 7, InitMathClass, CLASP(Math)) \ - real(Number, 8, InitNumberClass, OCLASP(Number)) \ - real(String, 9, InitStringClass, OCLASP(String)) \ - real(RegExp, 10, InitViaClassSpec, OCLASP(RegExp)) \ - real(Error, 11, InitViaClassSpec, ERROR_CLASP(JSEXN_ERR)) \ - real(InternalError, 12, InitViaClassSpec, ERROR_CLASP(JSEXN_INTERNALERR)) \ - real(EvalError, 13, InitViaClassSpec, ERROR_CLASP(JSEXN_EVALERR)) \ - real(RangeError, 14, InitViaClassSpec, ERROR_CLASP(JSEXN_RANGEERR)) \ - real(ReferenceError, 15, InitViaClassSpec, ERROR_CLASP(JSEXN_REFERENCEERR)) \ - real(SyntaxError, 16, InitViaClassSpec, ERROR_CLASP(JSEXN_SYNTAXERR)) \ - real(TypeError, 17, InitViaClassSpec, ERROR_CLASP(JSEXN_TYPEERR)) \ - real(URIError, 18, InitViaClassSpec, ERROR_CLASP(JSEXN_URIERR)) \ - real(DebuggeeWouldRun, 19, InitViaClassSpec, ERROR_CLASP(JSEXN_DEBUGGEEWOULDRUN)) \ - real(CompileError, 20, InitViaClassSpec, ERROR_CLASP(JSEXN_WASMCOMPILEERROR)) \ - real(RuntimeError, 21, InitViaClassSpec, ERROR_CLASP(JSEXN_WASMRUNTIMEERROR)) \ - real(Iterator, 22, InitLegacyIteratorClass,OCLASP(PropertyIterator)) \ - real(StopIteration, 23, InitStopIterationClass, OCLASP(StopIteration)) \ - real(ArrayBuffer, 24, InitViaClassSpec, OCLASP(ArrayBuffer)) \ - real(Int8Array, 25, InitViaClassSpec, TYPED_ARRAY_CLASP(Int8)) \ - real(Uint8Array, 26, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint8)) \ - real(Int16Array, 27, InitViaClassSpec, TYPED_ARRAY_CLASP(Int16)) \ - real(Uint16Array, 28, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint16)) \ - real(Int32Array, 29, InitViaClassSpec, TYPED_ARRAY_CLASP(Int32)) \ - real(Uint32Array, 30, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint32)) \ - real(Float32Array, 31, InitViaClassSpec, TYPED_ARRAY_CLASP(Float32)) \ - real(Float64Array, 32, InitViaClassSpec, TYPED_ARRAY_CLASP(Float64)) \ - real(Uint8ClampedArray, 33, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint8Clamped)) \ - real(Proxy, 34, InitProxyClass, js::ProxyClassPtr) \ - real(WeakMap, 35, InitWeakMapClass, OCLASP(WeakMap)) \ - real(Map, 36, InitMapClass, OCLASP(Map)) \ - real(Set, 37, InitSetClass, OCLASP(Set)) \ - real(DataView, 38, InitDataViewClass, OCLASP(DataView)) \ - real(Symbol, 39, InitSymbolClass, OCLASP(Symbol)) \ -IF_SAB(real,imaginary)(SharedArrayBuffer, 40, InitViaClassSpec, OCLASP(SharedArrayBuffer)) \ -IF_INTL(real,imaginary) (Intl, 41, InitIntlClass, CLASP(Intl)) \ -IF_BDATA(real,imaginary)(TypedObject, 42, InitTypedObjectModuleObject, OCLASP(TypedObjectModule)) \ - real(Reflect, 43, InitReflect, nullptr) \ -IF_SIMD(real,imaginary)(SIMD, 44, InitSimdClass, OCLASP(Simd)) \ - real(WeakSet, 45, InitWeakSetClass, OCLASP(WeakSet)) \ - real(TypedArray, 46, InitViaClassSpec, &js::TypedArrayObject::sharedTypedArrayPrototypeClass) \ -IF_SAB(real,imaginary)(Atomics, 47, InitAtomicsClass, OCLASP(Atomics)) \ - real(SavedFrame, 48, InitViaClassSpec, &js::SavedFrame::class_) \ - real(WebAssembly, 49, InitWebAssemblyClass, CLASP(WebAssembly)) \ - imaginary(WasmModule, 50, dummy, dummy) \ - imaginary(WasmInstance, 51, dummy, dummy) \ - imaginary(WasmMemory, 52, dummy, dummy) \ - imaginary(WasmTable, 53, dummy, dummy) \ -IF_PROMISE(real,imaginary)(Promise, 54, InitViaClassSpec, OCLASP(Promise)) \ - -#define JS_FOR_EACH_PROTOTYPE(macro) JS_FOR_PROTOTYPES(macro,macro) - -#endif /* jsprototypes_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/jspubtd.h b/android/armeabi-v7a/include/spidermonkey/jspubtd.h deleted file mode 100644 index 309b9d74..00000000 --- a/android/armeabi-v7a/include/spidermonkey/jspubtd.h +++ /dev/null @@ -1,476 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jspubtd_h -#define jspubtd_h - -/* - * JS public API typedefs. - */ - -#include "mozilla/Assertions.h" -#include "mozilla/EnumeratedArray.h" -#include "mozilla/LinkedList.h" -#include "mozilla/PodOperations.h" - -#include "jsprototypes.h" -#include "jstypes.h" - -#include "js/TraceKind.h" -#include "js/TypeDecls.h" - -#if defined(JS_GC_ZEAL) || defined(DEBUG) -# define JSGC_HASH_TABLE_CHECKS -#endif - -namespace JS { - -class AutoIdVector; -class CallArgs; - -template -class Rooted; - -class JS_FRIEND_API(CompileOptions); -class JS_FRIEND_API(ReadOnlyCompileOptions); -class JS_FRIEND_API(OwningCompileOptions); -class JS_FRIEND_API(TransitiveCompileOptions); -class JS_PUBLIC_API(CompartmentOptions); - -struct RootingContext; -class Value; -struct Zone; - -namespace shadow { -struct Runtime; -} // namespace shadow - -} // namespace JS - -namespace js { -class RootLists; -} // namespace js - -/* - * Run-time version enumeration. For compile-time version checking, please use - * the JS_HAS_* macros in jsversion.h, or use MOZJS_MAJOR_VERSION, - * MOZJS_MINOR_VERSION, MOZJS_PATCH_VERSION, and MOZJS_ALPHA definitions. - */ -enum JSVersion { - JSVERSION_ECMA_3 = 148, - JSVERSION_1_6 = 160, - JSVERSION_1_7 = 170, - JSVERSION_1_8 = 180, - JSVERSION_ECMA_5 = 185, - JSVERSION_DEFAULT = 0, - JSVERSION_UNKNOWN = -1, - JSVERSION_LATEST = JSVERSION_ECMA_5 -}; - -/* Result of typeof operator enumeration. */ -enum JSType { - JSTYPE_VOID, /* undefined */ - JSTYPE_OBJECT, /* object */ - JSTYPE_FUNCTION, /* function */ - JSTYPE_STRING, /* string */ - JSTYPE_NUMBER, /* number */ - JSTYPE_BOOLEAN, /* boolean */ - JSTYPE_NULL, /* null */ - JSTYPE_SYMBOL, /* symbol */ - JSTYPE_LIMIT -}; - -/* Dense index into cached prototypes and class atoms for standard objects. */ -enum JSProtoKey { -#define PROTOKEY_AND_INITIALIZER(name,code,init,clasp) JSProto_##name = code, - JS_FOR_EACH_PROTOTYPE(PROTOKEY_AND_INITIALIZER) -#undef PROTOKEY_AND_INITIALIZER - JSProto_LIMIT -}; - -/* Struct forward declarations. */ -struct JSClass; -struct JSCompartment; -struct JSCrossCompartmentCall; -class JSErrorReport; -struct JSExceptionState; -struct JSFunctionSpec; -struct JSLocaleCallbacks; -struct JSObjectMap; -struct JSPrincipals; -struct JSPropertyName; -struct JSPropertySpec; -struct JSRuntime; -struct JSSecurityCallbacks; -struct JSStructuredCloneCallbacks; -struct JSStructuredCloneReader; -struct JSStructuredCloneWriter; -class JS_PUBLIC_API(JSTracer); - -class JSFlatString; - -typedef bool (*JSInitCallback)(void); - -template struct JSConstScalarSpec; -typedef JSConstScalarSpec JSConstDoubleSpec; -typedef JSConstScalarSpec JSConstIntegerSpec; - -/* - * Generic trace operation that calls JS::TraceEdge on each traceable thing's - * location reachable from data. - */ -typedef void -(* JSTraceDataOp)(JSTracer* trc, void* data); - -namespace js { -namespace gc { -class AutoTraceSession; -class StoreBuffer; -} // namespace gc - -// Whether the current thread is permitted access to any part of the specified -// runtime or zone. -JS_FRIEND_API(bool) -CurrentThreadCanAccessRuntime(const JSRuntime* rt); - -#ifdef DEBUG -JS_FRIEND_API(bool) -CurrentThreadIsPerformingGC(); -#endif - -} // namespace js - -namespace JS { - -class JS_PUBLIC_API(AutoEnterCycleCollection); -class JS_PUBLIC_API(AutoAssertOnBarrier); -struct JS_PUBLIC_API(PropertyDescriptor); - -typedef void (*OffThreadCompileCallback)(void* token, void* callbackData); - -enum class HeapState { - Idle, // doing nothing with the GC heap - Tracing, // tracing the GC heap without collecting, e.g. IterateCompartments() - MajorCollecting, // doing a GC of the major heap - MinorCollecting, // doing a GC of the minor heap (nursery) - CycleCollecting // in the "Unlink" phase of cycle collection -}; - -namespace shadow { - -struct Runtime -{ - private: - JS::HeapState heapState_; - - protected: - void setHeapState(JS::HeapState newState) { - MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(asRuntime())); - MOZ_ASSERT(heapState_ != newState); - heapState_ = newState; - } - - JS::HeapState heapState() const { - MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(asRuntime()) || - js::CurrentThreadIsPerformingGC()); - return heapState_; - } - - // In some cases, invoking GC barriers (incremental or otherwise) will break - // things. These barriers assert if this flag is set. - bool allowGCBarriers_; - friend class JS::AutoAssertOnBarrier; - - js::gc::StoreBuffer* gcStoreBufferPtr_; - - // The gray bits can become invalid if UnmarkGray overflows the stack. A - // full GC will reset this bit, since it fills in all the gray bits. - bool gcGrayBitsValid_; - - public: - Runtime() - : heapState_(JS::HeapState::Idle) - , allowGCBarriers_(true) - , gcStoreBufferPtr_(nullptr) - , gcGrayBitsValid_(false) - {} - - bool isHeapBusy() const { return heapState() != JS::HeapState::Idle; } - bool isHeapTracing() const { return heapState() == JS::HeapState::Tracing; } - bool isHeapMajorCollecting() const { return heapState() == JS::HeapState::MajorCollecting; } - bool isHeapMinorCollecting() const { return heapState() == JS::HeapState::MinorCollecting; } - bool isHeapCollecting() const { return isHeapMinorCollecting() || isHeapMajorCollecting(); } - bool isCycleCollecting() const { - return heapState() == JS::HeapState::CycleCollecting; - } - - bool allowGCBarriers() const { return allowGCBarriers_; } - - js::gc::StoreBuffer* gcStoreBufferPtr() { return gcStoreBufferPtr_; } - - bool areGCGrayBitsValid() const { return gcGrayBitsValid_; } - void setGCGrayBitsValid(bool valid) { gcGrayBitsValid_ = valid; } - - const JSRuntime* asRuntime() const { - return reinterpret_cast(this); - } - - static JS::shadow::Runtime* asShadowRuntime(JSRuntime* rt) { - return reinterpret_cast(rt); - } - - protected: - void setGCStoreBufferPtr(js::gc::StoreBuffer* storeBuffer) { - gcStoreBufferPtr_ = storeBuffer; - } -}; - -} /* namespace shadow */ - -// Decorates the Unlinking phase of CycleCollection so that accidental use -// of barriered accessors results in assertions instead of leaks. -class MOZ_STACK_CLASS JS_PUBLIC_API(AutoEnterCycleCollection) -{ -#ifdef DEBUG - JSRuntime* runtime; - - public: - explicit AutoEnterCycleCollection(JSContext* cx); - ~AutoEnterCycleCollection(); -#else - public: - explicit AutoEnterCycleCollection(JSContext* cx) {} - ~AutoEnterCycleCollection() {} -#endif -}; - -class JS_PUBLIC_API(AutoGCRooter) -{ - public: - AutoGCRooter(JSContext* cx, ptrdiff_t tag); - AutoGCRooter(JS::RootingContext* cx, ptrdiff_t tag); - - ~AutoGCRooter() { - MOZ_ASSERT(this == *stackTop); - *stackTop = down; - } - - /* Implemented in gc/RootMarking.cpp. */ - inline void trace(JSTracer* trc); - static void traceAll(JSTracer* trc); - static void traceAllWrappers(JSTracer* trc); - - protected: - AutoGCRooter * const down; - - /* - * Discriminates actual subclass of this being used. If non-negative, the - * subclass roots an array of values of the length stored in this field. - * If negative, meaning is indicated by the corresponding value in the enum - * below. Any other negative value indicates some deeper problem such as - * memory corruption. - */ - ptrdiff_t tag_; - - enum { - VALARRAY = -2, /* js::AutoValueArray */ - PARSER = -3, /* js::frontend::Parser */ - VALVECTOR = -10, /* js::AutoValueVector */ - IDVECTOR = -11, /* js::AutoIdVector */ - OBJVECTOR = -14, /* js::AutoObjectVector */ - IONMASM = -19, /* js::jit::MacroAssembler */ - WRAPVECTOR = -20, /* js::AutoWrapperVector */ - WRAPPER = -21, /* js::AutoWrapperRooter */ - CUSTOM = -26 /* js::CustomAutoRooter */ - }; - - static ptrdiff_t GetTag(const Value& value) { return VALVECTOR; } - static ptrdiff_t GetTag(const jsid& id) { return IDVECTOR; } - static ptrdiff_t GetTag(JSObject* obj) { return OBJVECTOR; } - - private: - AutoGCRooter ** const stackTop; - - /* No copy or assignment semantics. */ - AutoGCRooter(AutoGCRooter& ida) = delete; - void operator=(AutoGCRooter& ida) = delete; -}; - -// Our instantiations of Rooted and PersistentRooted require an -// instantiation of MapTypeToRootKind. -template <> -struct MapTypeToRootKind { - static const RootKind kind = RootKind::Traceable; -}; - -} /* namespace JS */ - -namespace js { - -class ExclusiveContext; - -/* - * This list enumerates the different types of conceptual stacks we have in - * SpiderMonkey. In reality, they all share the C stack, but we allow different - * stack limits depending on the type of code running. - */ -enum StackKind -{ - StackForSystemCode, // C++, such as the GC, running on behalf of the VM. - StackForTrustedScript, // Script running with trusted principals. - StackForUntrustedScript, // Script running with untrusted principals. - StackKindCount -}; - -using RootedListHeads = mozilla::EnumeratedArray*>; - -// Abstracts JS rooting mechanisms so they can be shared between the JSContext -// and JSRuntime. -class RootLists -{ - // Stack GC roots for Rooted GC heap pointers. - RootedListHeads stackRoots_; - template friend class JS::Rooted; - - // Stack GC roots for AutoFooRooter classes. - JS::AutoGCRooter* autoGCRooters_; - friend class JS::AutoGCRooter; - - // Heap GC roots for PersistentRooted pointers. - mozilla::EnumeratedArray>> heapRoots_; - template friend class JS::PersistentRooted; - - public: - RootLists() : autoGCRooters_(nullptr) { - for (auto& stackRootPtr : stackRoots_) - stackRootPtr = nullptr; - } - - ~RootLists() { - // The semantics of PersistentRooted containing pointers and tagged - // pointers are somewhat different from those of PersistentRooted - // containing a structure with a trace method. PersistentRooted - // containing pointers are allowed to outlive the owning RootLists, - // whereas those containing a traceable structure are not. - // - // The purpose of this feature is to support lazy initialization of - // global references for the several places in Gecko that do not have - // access to a tighter context, but that still need to refer to GC - // pointers. For such pointers, FinishPersistentRootedChains ensures - // that the contained references are nulled out when the owning - // RootLists dies to prevent UAF errors. - // - // However, for RootKind::Traceable, we do not know the concrete type - // of the held thing, so we simply cannot do this without accruing - // extra overhead and complexity for all users for a case that is - // unlikely to ever be used in practice. For this reason, the following - // assertion disallows usage of PersistentRooted that - // outlives the RootLists. - MOZ_ASSERT(heapRoots_[JS::RootKind::Traceable].isEmpty()); - } - - void traceStackRoots(JSTracer* trc); - void checkNoGCRooters(); - - void tracePersistentRoots(JSTracer* trc); - void finishPersistentRoots(); -}; - -} // namespace js - -namespace JS { - -/* - * JS::RootingContext is a base class of ContextFriendFields and JSContext. - * This class can be used to let code construct a Rooted<> or PersistentRooted<> - * instance, without giving it full access to the JSContext. - */ -struct RootingContext -{ - js::RootLists roots; - -#ifdef DEBUG - // Whether the derived class is a JSContext or an ExclusiveContext. - bool isJSContext; -#endif - - explicit RootingContext(bool isJSContextArg) -#ifdef DEBUG - : isJSContext(isJSContextArg) -#endif - {} - - static RootingContext* get(JSContext* cx) { - return reinterpret_cast(cx); - } -}; - -} // namespace JS - -namespace js { - -struct ContextFriendFields : public JS::RootingContext -{ - protected: - /* The current compartment. */ - JSCompartment* compartment_; - - /* The current zone. */ - JS::Zone* zone_; - - public: - /* Limit pointer for checking native stack consumption. */ - uintptr_t nativeStackLimit[js::StackKindCount]; - - explicit ContextFriendFields(bool isJSContext); - - static const ContextFriendFields* get(const JSContext* cx) { - return reinterpret_cast(cx); - } - - static ContextFriendFields* get(JSContext* cx) { - return reinterpret_cast(cx); - } - - friend JSCompartment* GetContextCompartment(const JSContext* cx); - friend JS::Zone* GetContextZone(const JSContext* cx); - template friend class JS::Rooted; -}; - -/* - * Inlinable accessors for JSContext. - * - * - These must not be available on the more restricted superclasses of - * JSContext, so we can't simply define them on ContextFriendFields. - * - * - They're perfectly ordinary JSContext functionality, so ought to be - * usable without resorting to jsfriendapi.h, and when JSContext is an - * incomplete type. - */ -inline JSCompartment* -GetContextCompartment(const JSContext* cx) -{ - return ContextFriendFields::get(cx)->compartment_; -} - -inline JS::Zone* -GetContextZone(const JSContext* cx) -{ - return ContextFriendFields::get(cx)->zone_; -} - -} /* namespace js */ - -MOZ_BEGIN_EXTERN_C - -// Defined in NSPR prio.h. -typedef struct PRFileDesc PRFileDesc; - -MOZ_END_EXTERN_C - -#endif /* jspubtd_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/jstypes.h b/android/armeabi-v7a/include/spidermonkey/jstypes.h deleted file mode 100644 index 914674ab..00000000 --- a/android/armeabi-v7a/include/spidermonkey/jstypes.h +++ /dev/null @@ -1,219 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* -** File: jstypes.h -** Description: Definitions of NSPR's basic types -** -** Prototypes and macros used to make up for deficiencies in ANSI environments -** that we have found. -** -** Since we do not wrap and all the other standard headers, authors -** of portable code will not know in general that they need these definitions. -** Instead of requiring these authors to find the dependent uses in their code -** and take the following steps only in those C files, we take steps once here -** for all C files. -**/ - -#ifndef jstypes_h -#define jstypes_h - -#include "mozilla/Attributes.h" -#include "mozilla/Casting.h" -#include "mozilla/Types.h" - -// jstypes.h is (or should be!) included by every file in SpiderMonkey. -// js-config.h and jsversion.h also should be included by every file. -// So include them here. -// XXX: including them in js/RequiredDefines.h should be a better option, since -// that is by definition the header file that should be included in all -// SpiderMonkey code. However, Gecko doesn't do this! See bug 909576. -#include "js-config.h" -#include "jsversion.h" - -/*********************************************************************** -** MACROS: JS_EXTERN_API -** JS_EXPORT_API -** DESCRIPTION: -** These are only for externally visible routines and globals. For -** internal routines, just use "extern" for type checking and that -** will not export internal cross-file or forward-declared symbols. -** Define a macro for declaring procedures return types. We use this to -** deal with windoze specific type hackery for DLL definitions. Use -** JS_EXTERN_API when the prototype for the method is declared. Use -** JS_EXPORT_API for the implementation of the method. -** -** Example: -** in dowhim.h -** JS_EXTERN_API( void ) DoWhatIMean( void ); -** in dowhim.c -** JS_EXPORT_API( void ) DoWhatIMean( void ) { return; } -** -** -***********************************************************************/ - -#define JS_EXTERN_API(type) extern MOZ_EXPORT type -#define JS_EXPORT_API(type) MOZ_EXPORT type -#define JS_EXPORT_DATA(type) MOZ_EXPORT type -#define JS_IMPORT_API(type) MOZ_IMPORT_API type -#define JS_IMPORT_DATA(type) MOZ_IMPORT_DATA type - -/* - * The linkage of JS API functions differs depending on whether the file is - * used within the JS library or not. Any source file within the JS - * interpreter should define EXPORT_JS_API whereas any client of the library - * should not. STATIC_JS_API is used to build JS as a static library. - */ -#if defined(STATIC_JS_API) -# define JS_PUBLIC_API(t) t -# define JS_PUBLIC_DATA(t) t -# define JS_FRIEND_API(t) t -# define JS_FRIEND_DATA(t) t -#elif defined(EXPORT_JS_API) || defined(STATIC_EXPORTABLE_JS_API) -# define JS_PUBLIC_API(t) MOZ_EXPORT t -# define JS_PUBLIC_DATA(t) MOZ_EXPORT t -# define JS_FRIEND_API(t) MOZ_EXPORT t -# define JS_FRIEND_DATA(t) MOZ_EXPORT t -#else -# define JS_PUBLIC_API(t) MOZ_IMPORT_API t -# define JS_PUBLIC_DATA(t) MOZ_IMPORT_DATA t -# define JS_FRIEND_API(t) MOZ_IMPORT_API t -# define JS_FRIEND_DATA(t) MOZ_IMPORT_DATA t -#endif - -#if defined(_MSC_VER) && defined(_M_IX86) -#define JS_FASTCALL __fastcall -#elif defined(__GNUC__) && defined(__i386__) -#define JS_FASTCALL __attribute__((fastcall)) -#else -#define JS_FASTCALL -#define JS_NO_FASTCALL -#endif - -/*********************************************************************** -** MACROS: JS_BEGIN_MACRO -** JS_END_MACRO -** DESCRIPTION: -** Macro body brackets so that macros with compound statement definitions -** behave syntactically more like functions when called. -***********************************************************************/ -#define JS_BEGIN_MACRO do { - -#if defined(_MSC_VER) -# define JS_END_MACRO \ - } __pragma(warning(push)) __pragma(warning(disable:4127)) \ - while (0) __pragma(warning(pop)) -#else -# define JS_END_MACRO } while (0) -#endif - -/*********************************************************************** -** MACROS: JS_BIT -** JS_BITMASK -** DESCRIPTION: -** Bit masking macros. XXX n must be <= 31 to be portable -***********************************************************************/ -#define JS_BIT(n) ((uint32_t)1 << (n)) -#define JS_BITMASK(n) (JS_BIT(n) - 1) - -/*********************************************************************** -** MACROS: JS_HOWMANY -** JS_ROUNDUP -** DESCRIPTION: -** Commonly used macros for operations on compatible types. -***********************************************************************/ -#define JS_HOWMANY(x,y) (((x)+(y)-1)/(y)) -#define JS_ROUNDUP(x,y) (JS_HOWMANY(x,y)*(y)) - -#include "jscpucfg.h" - -/* - * Define JS_64BIT iff we are building in an environment with 64-bit - * addresses. - */ -#ifdef _MSC_VER -# if defined(_M_X64) || defined(_M_AMD64) -# define JS_64BIT -# endif -#elif defined(__GNUC__) -/* Additional GCC defines are when running on Solaris, AIX, and HPUX */ -# if defined(__x86_64__) || defined(__sparcv9) || \ - defined(__64BIT__) || defined(__LP64__) -# define JS_64BIT -# endif -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Sun Studio C/C++ */ -# if defined(__x86_64) || defined(__sparcv9) -# define JS_64BIT -# endif -#elif defined(__xlc__) || defined(__xlC__) /* IBM XL C/C++ */ -# if defined(__64BIT__) -# define JS_64BIT -# endif -#elif defined(__HP_cc) || defined(__HP_aCC) /* HP-UX cc/aCC */ -# if defined(__LP64__) -# define JS_64BIT -# endif -#else -# error "Implement me" -#endif - -/*********************************************************************** -** MACROS: JS_ARRAY_LENGTH -** JS_ARRAY_END -** DESCRIPTION: -** Macros to get the number of elements and the pointer to one past the -** last element of a C array. Use them like this: -** -** char16_t buf[10]; -** JSString* str; -** ... -** for (char16_t* s = buf; s != JS_ARRAY_END(buf); ++s) *s = ...; -** ... -** str = JS_NewStringCopyN(cx, buf, JS_ARRAY_LENGTH(buf)); -** ... -** -***********************************************************************/ - -#define JS_ARRAY_LENGTH(array) (sizeof (array) / sizeof (array)[0]) -#define JS_ARRAY_END(array) ((array) + JS_ARRAY_LENGTH(array)) - -#define JS_BITS_PER_BYTE 8 -#define JS_BITS_PER_BYTE_LOG2 3 - -#if defined(JS_64BIT) -# define JS_BITS_PER_WORD 64 -#else -# define JS_BITS_PER_WORD 32 -#endif - -/*********************************************************************** -** MACROS: JS_FUNC_TO_DATA_PTR -** JS_DATA_TO_FUNC_PTR -** DESCRIPTION: -** Macros to convert between function and data pointers of the same -** size. Use them like this: -** -** JSGetterOp nativeGetter; -** JSObject* scriptedGetter; -** ... -** scriptedGetter = JS_FUNC_TO_DATA_PTR(JSObject*, nativeGetter); -** ... -** nativeGetter = JS_DATA_TO_FUNC_PTR(JSGetterOp, scriptedGetter); -** -***********************************************************************/ - -#define JS_FUNC_TO_DATA_PTR(type, fun) (mozilla::BitwiseCast(fun)) -#define JS_DATA_TO_FUNC_PTR(type, ptr) (mozilla::BitwiseCast(ptr)) - -#ifdef __GNUC__ -# define JS_EXTENSION __extension__ -# define JS_EXTENSION_(s) __extension__ ({ s; }) -#else -# define JS_EXTENSION -# define JS_EXTENSION_(s) s -#endif - -#endif /* jstypes_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/jsversion.h b/android/armeabi-v7a/include/spidermonkey/jsversion.h deleted file mode 100644 index 8bdfe47b..00000000 --- a/android/armeabi-v7a/include/spidermonkey/jsversion.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsversion_h -#define jsversion_h - -/* - * JS Capability Macros. - */ -#define JS_HAS_STR_HTML_HELPERS 1 /* (no longer used) */ -#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ -#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */ -#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */ -#define JS_HAS_CATCH_GUARD 1 /* has exception handling catch guard */ -#define JS_HAS_UNEVAL 1 /* has uneval() top-level function */ -#define JS_HAS_CONST 1 /* (no longer used) */ -#define JS_HAS_FUN_EXPR_STMT 1 /* (no longer used) */ -#define JS_HAS_FOR_EACH_IN 1 /* has for each (lhs in iterable) */ -#define JS_HAS_GENERATORS 1 /* (no longer used) */ -#define JS_HAS_BLOCK_SCOPE 1 /* (no longer used) */ -#define JS_HAS_DESTRUCTURING 2 /* (no longer used) */ -#define JS_HAS_GENERATOR_EXPRS 1 /* (no longer used) */ -#define JS_HAS_EXPR_CLOSURES 1 /* has function (formals) listexpr */ - -/* (no longer used) */ -#define JS_HAS_NEW_GLOBAL_OBJECT 1 - -/* (no longer used) */ -#define JS_HAS_DESTRUCTURING_SHORTHAND (JS_HAS_DESTRUCTURING == 2) - -/* - * Feature for Object.prototype.__{define,lookup}{G,S}etter__ legacy support; - * support likely to be made opt-in at some future time. - */ -#define JS_OLD_GETTER_SETTER_METHODS 1 - -#endif /* jsversion_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/jswrapper.h b/android/armeabi-v7a/include/spidermonkey/jswrapper.h deleted file mode 100644 index 9b14c59e..00000000 --- a/android/armeabi-v7a/include/spidermonkey/jswrapper.h +++ /dev/null @@ -1,382 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jswrapper_h -#define jswrapper_h - -#include "mozilla/Attributes.h" - -#include "js/Proxy.h" - -namespace js { - -/* - * Helper for Wrapper::New default options. - * - * Callers of Wrapper::New() who wish to specify a prototype for the created - * Wrapper, *MUST* construct a WrapperOptions with a JSContext. - */ -class MOZ_STACK_CLASS WrapperOptions : public ProxyOptions { - public: - WrapperOptions() : ProxyOptions(false), - proto_() - {} - - explicit WrapperOptions(JSContext* cx) : ProxyOptions(false), - proto_() - { - proto_.emplace(cx); - } - - inline JSObject* proto() const; - WrapperOptions& setProto(JSObject* protoArg) { - MOZ_ASSERT(proto_); - *proto_ = protoArg; - return *this; - } - - private: - mozilla::Maybe proto_; -}; - -/* - * A wrapper is a proxy with a target object to which it generally forwards - * operations, but may restrict access to certain operations or augment those - * operations in various ways. - * - * A wrapper can be "unwrapped" in C++, exposing the underlying object. - * Callers should be careful to avoid unwrapping security wrappers in the wrong - * context. - * - * Important: If you add a method implementation here, you probably also need - * to add an override in CrossCompartmentWrapper. If you don't, you risk - * compartment mismatches. See bug 945826 comment 0. - */ -class JS_FRIEND_API(Wrapper) : public BaseProxyHandler -{ - unsigned mFlags; - - public: - explicit constexpr Wrapper(unsigned aFlags, bool aHasPrototype = false, - bool aHasSecurityPolicy = false) - : BaseProxyHandler(&family, aHasPrototype, aHasSecurityPolicy), - mFlags(aFlags) - { } - - virtual bool finalizeInBackground(const Value& priv) const override; - - /* Standard internal methods. */ - virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id, - MutableHandle desc) const override; - virtual bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id, - Handle desc, - ObjectOpResult& result) const override; - virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy, - AutoIdVector& props) const override; - virtual bool delete_(JSContext* cx, HandleObject proxy, HandleId id, - ObjectOpResult& result) const override; - virtual bool enumerate(JSContext* cx, HandleObject proxy, - MutableHandleObject objp) const override; - virtual bool getPrototype(JSContext* cx, HandleObject proxy, - MutableHandleObject protop) const override; - virtual bool setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto, - ObjectOpResult& result) const override; - virtual bool getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy, bool* isOrdinary, - MutableHandleObject protop) const override; - virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy, - bool* succeeded) const override; - virtual bool preventExtensions(JSContext* cx, HandleObject proxy, - ObjectOpResult& result) const override; - virtual bool isExtensible(JSContext* cx, HandleObject proxy, bool* extensible) const override; - virtual bool has(JSContext* cx, HandleObject proxy, HandleId id, - bool* bp) const override; - virtual bool get(JSContext* cx, HandleObject proxy, HandleValue receiver, - HandleId id, MutableHandleValue vp) const override; - virtual bool set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v, - HandleValue receiver, ObjectOpResult& result) const override; - virtual bool call(JSContext* cx, HandleObject proxy, const CallArgs& args) const override; - virtual bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const override; - - /* SpiderMonkey extensions. */ - virtual bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id, - MutableHandle desc) const override; - virtual bool hasOwn(JSContext* cx, HandleObject proxy, HandleId id, - bool* bp) const override; - virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject proxy, - AutoIdVector& props) const override; - virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl, - const CallArgs& args) const override; - virtual bool hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v, - bool* bp) const override; - virtual bool getBuiltinClass(JSContext* cx, HandleObject proxy, ESClass* cls) const override; - virtual bool isArray(JSContext* cx, HandleObject proxy, - JS::IsArrayAnswer* answer) const override; - virtual const char* className(JSContext* cx, HandleObject proxy) const override; - virtual JSString* fun_toString(JSContext* cx, HandleObject proxy, - unsigned indent) const override; - virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, - RegExpGuard* g) const override; - virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, - MutableHandleValue vp) const override; - virtual bool isCallable(JSObject* obj) const override; - virtual bool isConstructor(JSObject* obj) const override; - virtual JSObject* weakmapKeyDelegate(JSObject* proxy) const override; - - public: - using BaseProxyHandler::Action; - - enum Flags { - CROSS_COMPARTMENT = 1 << 0, - LAST_USED_FLAG = CROSS_COMPARTMENT - }; - - static JSObject* New(JSContext* cx, JSObject* obj, const Wrapper* handler, - const WrapperOptions& options = WrapperOptions()); - - static JSObject* Renew(JSContext* cx, JSObject* existing, JSObject* obj, const Wrapper* handler); - - static const Wrapper* wrapperHandler(JSObject* wrapper); - - static JSObject* wrappedObject(JSObject* wrapper); - - unsigned flags() const { - return mFlags; - } - - static const char family; - static const Wrapper singleton; - static const Wrapper singletonWithPrototype; - - static JSObject* defaultProto; -}; - -inline JSObject* -WrapperOptions::proto() const -{ - return proto_ ? *proto_ : Wrapper::defaultProto; -} - -/* Base class for all cross compartment wrapper handlers. */ -class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper -{ - public: - explicit constexpr CrossCompartmentWrapper(unsigned aFlags, bool aHasPrototype = false, - bool aHasSecurityPolicy = false) - : Wrapper(CROSS_COMPARTMENT | aFlags, aHasPrototype, aHasSecurityPolicy) - { } - - /* Standard internal methods. */ - virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id, - MutableHandle desc) const override; - virtual bool defineProperty(JSContext* cx, HandleObject wrapper, HandleId id, - Handle desc, - ObjectOpResult& result) const override; - virtual bool ownPropertyKeys(JSContext* cx, HandleObject wrapper, - AutoIdVector& props) const override; - virtual bool delete_(JSContext* cx, HandleObject wrapper, HandleId id, - ObjectOpResult& result) const override; - virtual bool enumerate(JSContext* cx, HandleObject wrapper, MutableHandleObject objp) const override; - virtual bool getPrototype(JSContext* cx, HandleObject proxy, - MutableHandleObject protop) const override; - virtual bool setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto, - ObjectOpResult& result) const override; - - virtual bool getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy, bool* isOrdinary, - MutableHandleObject protop) const override; - virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy, - bool* succeeded) const override; - virtual bool preventExtensions(JSContext* cx, HandleObject wrapper, - ObjectOpResult& result) const override; - virtual bool isExtensible(JSContext* cx, HandleObject wrapper, bool* extensible) const override; - virtual bool has(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp) const override; - virtual bool get(JSContext* cx, HandleObject wrapper, HandleValue receiver, - HandleId id, MutableHandleValue vp) const override; - virtual bool set(JSContext* cx, HandleObject wrapper, HandleId id, HandleValue v, - HandleValue receiver, ObjectOpResult& result) const override; - virtual bool call(JSContext* cx, HandleObject wrapper, const CallArgs& args) const override; - virtual bool construct(JSContext* cx, HandleObject wrapper, const CallArgs& args) const override; - - /* SpiderMonkey extensions. */ - virtual bool getPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id, - MutableHandle desc) const override; - virtual bool hasOwn(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp) const override; - virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject wrapper, - AutoIdVector& props) const override; - virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl, - const CallArgs& args) const override; - virtual bool hasInstance(JSContext* cx, HandleObject wrapper, MutableHandleValue v, - bool* bp) const override; - virtual const char* className(JSContext* cx, HandleObject proxy) const override; - virtual JSString* fun_toString(JSContext* cx, HandleObject wrapper, - unsigned indent) const override; - virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const override; - virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const override; - - // Allocate CrossCompartmentWrappers in the nursery. - virtual bool canNurseryAllocate() const override { return true; } - - static const CrossCompartmentWrapper singleton; - static const CrossCompartmentWrapper singletonWithPrototype; -}; - -class JS_FRIEND_API(OpaqueCrossCompartmentWrapper) : public CrossCompartmentWrapper -{ - public: - explicit constexpr OpaqueCrossCompartmentWrapper() : CrossCompartmentWrapper(0) - { } - - /* Standard internal methods. */ - virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id, - MutableHandle desc) const override; - virtual bool defineProperty(JSContext* cx, HandleObject wrapper, HandleId id, - Handle desc, - ObjectOpResult& result) const override; - virtual bool ownPropertyKeys(JSContext* cx, HandleObject wrapper, - AutoIdVector& props) const override; - virtual bool delete_(JSContext* cx, HandleObject wrapper, HandleId id, - ObjectOpResult& result) const override; - virtual bool enumerate(JSContext* cx, HandleObject wrapper, - MutableHandleObject objp) const override; - virtual bool getPrototype(JSContext* cx, HandleObject wrapper, - MutableHandleObject protop) const override; - virtual bool setPrototype(JSContext* cx, HandleObject wrapper, HandleObject proto, - ObjectOpResult& result) const override; - virtual bool getPrototypeIfOrdinary(JSContext* cx, HandleObject wrapper, bool* isOrdinary, - MutableHandleObject protop) const override; - virtual bool setImmutablePrototype(JSContext* cx, HandleObject wrapper, - bool* succeeded) const override; - virtual bool preventExtensions(JSContext* cx, HandleObject wrapper, - ObjectOpResult& result) const override; - virtual bool isExtensible(JSContext* cx, HandleObject wrapper, bool* extensible) const override; - virtual bool has(JSContext* cx, HandleObject wrapper, HandleId id, - bool* bp) const override; - virtual bool get(JSContext* cx, HandleObject wrapper, HandleValue receiver, - HandleId id, MutableHandleValue vp) const override; - virtual bool set(JSContext* cx, HandleObject wrapper, HandleId id, HandleValue v, - HandleValue receiver, ObjectOpResult& result) const override; - virtual bool call(JSContext* cx, HandleObject wrapper, const CallArgs& args) const override; - virtual bool construct(JSContext* cx, HandleObject wrapper, const CallArgs& args) const override; - - /* SpiderMonkey extensions. */ - virtual bool getPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id, - MutableHandle desc) const override; - virtual bool hasOwn(JSContext* cx, HandleObject wrapper, HandleId id, - bool* bp) const override; - virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject wrapper, - AutoIdVector& props) const override; - virtual bool getBuiltinClass(JSContext* cx, HandleObject wrapper, ESClass* cls) const override; - virtual bool isArray(JSContext* cx, HandleObject obj, - JS::IsArrayAnswer* answer) const override; - virtual const char* className(JSContext* cx, HandleObject wrapper) const override; - virtual JSString* fun_toString(JSContext* cx, HandleObject proxy, unsigned indent) const override; - - static const OpaqueCrossCompartmentWrapper singleton; -}; - -/* - * Base class for security wrappers. A security wrapper is potentially hiding - * all or part of some wrapped object thus SecurityWrapper defaults to denying - * access to the wrappee. This is the opposite of Wrapper which tries to be - * completely transparent. - * - * NB: Currently, only a few ProxyHandler operations are overridden to deny - * access, relying on derived SecurityWrapper to block access when necessary. - */ -template -class JS_FRIEND_API(SecurityWrapper) : public Base -{ - public: - explicit constexpr SecurityWrapper(unsigned flags, bool hasPrototype = false) - : Base(flags, hasPrototype, /* hasSecurityPolicy = */ true) - { } - - virtual bool enter(JSContext* cx, HandleObject wrapper, HandleId id, Wrapper::Action act, - bool* bp) const override; - - virtual bool defineProperty(JSContext* cx, HandleObject wrapper, HandleId id, - Handle desc, - ObjectOpResult& result) const override; - virtual bool isExtensible(JSContext* cx, HandleObject wrapper, bool* extensible) const override; - virtual bool preventExtensions(JSContext* cx, HandleObject wrapper, - ObjectOpResult& result) const override; - virtual bool setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto, - ObjectOpResult& result) const override; - virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy, bool* succeeded) const override; - - virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl, - const CallArgs& args) const override; - virtual bool getBuiltinClass(JSContext* cx, HandleObject wrapper, ESClass* cls) const override; - virtual bool isArray(JSContext* cx, HandleObject wrapper, JS::IsArrayAnswer* answer) const override; - virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const override; - virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const override; - - // Allow isCallable and isConstructor. They used to be class-level, and so could not be guarded - // against. - - virtual bool watch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, - JS::HandleObject callable) const override; - virtual bool unwatch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id) const override; - - /* - * Allow our subclasses to select the superclass behavior they want without - * needing to specify an exact superclass. - */ - typedef Base Permissive; - typedef SecurityWrapper Restrictive; -}; - -typedef SecurityWrapper CrossCompartmentSecurityWrapper; - -extern JSObject* -TransparentObjectWrapper(JSContext* cx, HandleObject existing, HandleObject obj); - -inline bool -IsWrapper(JSObject* obj) -{ - return IsProxy(obj) && GetProxyHandler(obj)->family() == &Wrapper::family; -} - -// Given a JSObject, returns that object stripped of wrappers. If -// stopAtWindowProxy is true, then this returns the WindowProxy if it was -// previously wrapped. Otherwise, this returns the first object for -// which JSObject::isWrapper returns false. -JS_FRIEND_API(JSObject*) -UncheckedUnwrap(JSObject* obj, bool stopAtWindowProxy = true, unsigned* flagsp = nullptr); - -// Given a JSObject, returns that object stripped of wrappers. At each stage, -// the security wrapper has the opportunity to veto the unwrap. If -// stopAtWindowProxy is true, then this returns the WindowProxy if it was -// previously wrapped. -JS_FRIEND_API(JSObject*) -CheckedUnwrap(JSObject* obj, bool stopAtWindowProxy = true); - -// Unwrap only the outermost security wrapper, with the same semantics as -// above. This is the checked version of Wrapper::wrappedObject. -JS_FRIEND_API(JSObject*) -UnwrapOneChecked(JSObject* obj, bool stopAtWindowProxy = true); - -JS_FRIEND_API(bool) -IsCrossCompartmentWrapper(JSObject* obj); - -void -NukeCrossCompartmentWrapper(JSContext* cx, JSObject* wrapper); - -void -RemapWrapper(JSContext* cx, JSObject* wobj, JSObject* newTarget); - -JS_FRIEND_API(bool) -RemapAllWrappersForObject(JSContext* cx, JSObject* oldTarget, - JSObject* newTarget); - -// API to recompute all cross-compartment wrappers whose source and target -// match the given filters. -JS_FRIEND_API(bool) -RecomputeWrappers(JSContext* cx, const CompartmentFilter& sourceFilter, - const CompartmentFilter& targetFilter); - -} /* namespace js */ - -#endif /* jswrapper_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Alignment.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Alignment.h deleted file mode 100644 index 4fcda4f3..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Alignment.h +++ /dev/null @@ -1,154 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Functionality related to memory alignment. */ - -#ifndef mozilla_Alignment_h -#define mozilla_Alignment_h - -#include "mozilla/Attributes.h" -#include -#include - -namespace mozilla { - -/* - * This class, and the corresponding macro MOZ_ALIGNOF, figures out how many - * bytes of alignment a given type needs. - */ -template -class AlignmentFinder -{ - struct Aligner - { - char mChar; - T mT; - }; - -public: - static const size_t alignment = sizeof(Aligner) - sizeof(T); -}; - -#define MOZ_ALIGNOF(T) mozilla::AlignmentFinder::alignment - -/* - * Declare the MOZ_ALIGNED_DECL macro for declaring aligned types. - * - * For instance, - * - * MOZ_ALIGNED_DECL(char arr[2], 8); - * - * will declare a two-character array |arr| aligned to 8 bytes. - */ - -#if defined(__GNUC__) -# define MOZ_ALIGNED_DECL(_type, _align) \ - _type __attribute__((aligned(_align))) -#elif defined(_MSC_VER) -# define MOZ_ALIGNED_DECL(_type, _align) \ - __declspec(align(_align)) _type -#else -# warning "We don't know how to align variables on this compiler." -# define MOZ_ALIGNED_DECL(_type, _align) _type -#endif - -/* - * AlignedElem is a structure whose alignment is guaranteed to be at least N - * bytes. - * - * We support 1, 2, 4, 8, and 16-bit alignment. - */ -template -struct AlignedElem; - -/* - * We have to specialize this template because GCC doesn't like - * __attribute__((aligned(foo))) where foo is a template parameter. - */ - -template<> -struct AlignedElem<1> -{ - MOZ_ALIGNED_DECL(uint8_t elem, 1); -}; - -template<> -struct AlignedElem<2> -{ - MOZ_ALIGNED_DECL(uint8_t elem, 2); -}; - -template<> -struct AlignedElem<4> -{ - MOZ_ALIGNED_DECL(uint8_t elem, 4); -}; - -template<> -struct AlignedElem<8> -{ - MOZ_ALIGNED_DECL(uint8_t elem, 8); -}; - -template<> -struct AlignedElem<16> -{ - MOZ_ALIGNED_DECL(uint8_t elem, 16); -}; - -/* - * This utility pales in comparison to Boost's aligned_storage. The utility - * simply assumes that uint64_t is enough alignment for anyone. This may need - * to be extended one day... - * - * As an important side effect, pulling the storage into this template is - * enough obfuscation to confuse gcc's strict-aliasing analysis into not giving - * false negatives when we cast from the char buffer to whatever type we've - * constructed using the bytes. - */ -template -struct AlignedStorage -{ - union U - { - char mBytes[Nbytes]; - uint64_t mDummy; - } u; - - const void* addr() const { return u.mBytes; } - void* addr() { return u.mBytes; } - - AlignedStorage() = default; - - // AlignedStorage is non-copyable: the default copy constructor violates - // strict aliasing rules, per bug 1269319. - AlignedStorage(const AlignedStorage&) = delete; - void operator=(const AlignedStorage&) = delete; -}; - -template -struct MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS AlignedStorage2 -{ - union U - { - char mBytes[sizeof(T)]; - uint64_t mDummy; - } u; - - const T* addr() const { return reinterpret_cast(u.mBytes); } - T* addr() { return static_cast(static_cast(u.mBytes)); } - - AlignedStorage2() = default; - - // AlignedStorage2 is non-copyable: the default copy constructor violates - // strict aliasing rules, per bug 1269319. - AlignedStorage2(const AlignedStorage2&) = delete; - void operator=(const AlignedStorage2&) = delete; -}; - -} /* namespace mozilla */ - -#endif /* mozilla_Alignment_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/AllocPolicy.h b/android/armeabi-v7a/include/spidermonkey/mozilla/AllocPolicy.h deleted file mode 100644 index 81f62b03..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/AllocPolicy.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * An allocation policy concept, usable for structures and algorithms to - * control how memory is allocated and how failures are handled. - */ - -#ifndef mozilla_AllocPolicy_h -#define mozilla_AllocPolicy_h - -#include "mozilla/Attributes.h" -#include "mozilla/TemplateLib.h" - -#include -#include - -namespace mozilla { - -/* - * Allocation policies are used to implement the standard allocation behaviors - * in a customizable way. Additionally, custom behaviors may be added to these - * behaviors, such as additionally reporting an error through an out-of-band - * mechanism when OOM occurs. The concept modeled here is as follows: - * - * - public copy constructor, assignment, destructor - * - template T* maybe_pod_malloc(size_t) - * Fallible, but doesn't report an error on OOM. - * - template T* maybe_pod_calloc(size_t) - * Fallible, but doesn't report an error on OOM. - * - template T* maybe_pod_realloc(T*, size_t, size_t) - * Fallible, but doesn't report an error on OOM. The old allocation - * size is passed in, in addition to the new allocation size requested. - * - template T* pod_malloc(size_t) - * Responsible for OOM reporting when null is returned. - * - template T* pod_calloc(size_t) - * Responsible for OOM reporting when null is returned. - * - template T* pod_realloc(T*, size_t, size_t) - * Responsible for OOM reporting when null is returned. The old allocation - * size is passed in, in addition to the new allocation size requested. - * - void free_(void*) - * - void reportAllocOverflow() const - * Called on allocation overflow (that is, an allocation implicitly tried - * to allocate more than the available memory space -- think allocating an - * array of large-size objects, where N * size overflows) before null is - * returned. - * - bool checkSimulatedOOM() const - * Some clients generally allocate memory yet in some circumstances won't - * need to do so. For example, appending to a vector with a small amount of - * inline storage generally allocates memory, but no allocation occurs - * unless appending exceeds inline storage. But for testing purposes, it - * can be useful to treat *every* operation as allocating. - * Clients (such as this hypothetical append method implementation) should - * call this method in situations that don't allocate, but could generally, - * to support this. The default behavior should return true; more - * complicated behavior might be to return false only after a certain - * number of allocations-or-check-simulated-OOMs (coordinating with the - * other AllocPolicy methods) have occurred. - * - * mfbt provides (and typically uses by default) only MallocAllocPolicy, which - * does nothing more than delegate to the malloc/alloc/free functions. - */ - -/* - * A policy that straightforwardly uses malloc/calloc/realloc/free and adds no - * extra behaviors. - */ -class MallocAllocPolicy -{ -public: - template - T* maybe_pod_malloc(size_t aNumElems) - { - if (aNumElems & mozilla::tl::MulOverflowMask::value) { - return nullptr; - } - return static_cast(malloc(aNumElems * sizeof(T))); - } - - template - T* maybe_pod_calloc(size_t aNumElems) - { - return static_cast(calloc(aNumElems, sizeof(T))); - } - - template - T* maybe_pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) - { - if (aNewSize & mozilla::tl::MulOverflowMask::value) { - return nullptr; - } - return static_cast(realloc(aPtr, aNewSize * sizeof(T))); - } - - template - T* pod_malloc(size_t aNumElems) - { - return maybe_pod_malloc(aNumElems); - } - - template - T* pod_calloc(size_t aNumElems) - { - return maybe_pod_calloc(aNumElems); - } - - template - T* pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) - { - return maybe_pod_realloc(aPtr, aOldSize, aNewSize); - } - - void free_(void* aPtr) - { - free(aPtr); - } - - void reportAllocOverflow() const - { - } - - MOZ_MUST_USE bool checkSimulatedOOM() const - { - return true; - } -}; - -} // namespace mozilla - -#endif /* mozilla_AllocPolicy_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/AlreadyAddRefed.h b/android/armeabi-v7a/include/spidermonkey/mozilla/AlreadyAddRefed.h deleted file mode 100644 index 0d7b0cae..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/AlreadyAddRefed.h +++ /dev/null @@ -1,147 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Typed temporary pointers for reference-counted smart pointers. */ - -#ifndef AlreadyAddRefed_h -#define AlreadyAddRefed_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" - -namespace mozilla { - -struct unused_t; - -} // namespace mozilla - -/** - * already_AddRefed cooperates with reference counting smart pointers to enable - * you to assign in a pointer _without_ |AddRef|ing it. You might want to use - * this as a return type from a function that returns an already |AddRef|ed - * pointer. - * - * TODO Move already_AddRefed to namespace mozilla. This has not yet been done - * because of the sheer number of usages of already_AddRefed. - */ -template -struct MOZ_MUST_USE_TYPE MOZ_NON_AUTOABLE already_AddRefed -{ - /* - * We want to allow returning nullptr from functions returning - * already_AddRefed, for simplicity. But we also don't want to allow - * returning raw T*, instead preferring creation of already_AddRefed from - * a reference counting smart pointer. - * - * We address the latter requirement by making the (T*) constructor explicit. - * But |return nullptr| won't consider an explicit constructor, so we need - * another constructor to handle it. Plain old (decltype(nullptr)) doesn't - * cut it, because if nullptr is emulated as __null (with type int or long), - * passing nullptr to an int/long parameter triggers compiler warnings. We - * need a type that no one can pass accidentally; a pointer-to-member-function - * (where no such function exists) does the trick nicely. - * - * That handles the return-value case. What about for locals, argument types, - * and so on? |already_AddRefed(nullptr)| considers both overloads (and - * the (already_AddRefed&&) overload as well!), so there's an ambiguity. - * We can target true nullptr using decltype(nullptr), but we can't target - * emulated nullptr the same way, because passing __null to an int/long - * parameter triggers compiler warnings. So just give up on this, and provide - * this behavior through the default constructor. - * - * We can revert to simply explicit (T*) and implicit (decltype(nullptr)) when - * nullptr no longer needs to be emulated to support the ancient b2g compiler. - * (The () overload could also be removed, if desired, if we changed callers.) - */ - already_AddRefed() : mRawPtr(nullptr) {} - - // The return and argument types here are arbitrarily selected so no - // corresponding member function exists. - typedef void (already_AddRefed::* MatchNullptr)(double, float); - MOZ_IMPLICIT already_AddRefed(MatchNullptr aRawPtr) : mRawPtr(nullptr) {} - - explicit already_AddRefed(T* aRawPtr) : mRawPtr(aRawPtr) {} - - // Disallow copy constructor and copy assignment operator: move semantics used instead. - already_AddRefed(const already_AddRefed& aOther) = delete; - already_AddRefed& operator=(const already_AddRefed& aOther) = delete; - - already_AddRefed(already_AddRefed&& aOther) : mRawPtr(aOther.take()) {} - - already_AddRefed& operator=(already_AddRefed&& aOther) - { - mRawPtr = aOther.take(); - return *this; - } - - /** - * This helper is useful in cases like - * - * already_AddRefed - * Foo() - * { - * RefPtr x = ...; - * return x.forget(); - * } - * - * The autoconversion allows one to omit the idiom - * - * RefPtr y = x.forget(); - * return y.forget(); - * - * Note that nsRefPtr is the XPCOM reference counting smart pointer class. - */ - template - MOZ_IMPLICIT already_AddRefed(already_AddRefed&& aOther) : mRawPtr(aOther.take()) {} - - ~already_AddRefed() { MOZ_ASSERT(!mRawPtr); } - - // Specialize the unused operator<< for already_AddRefed, to allow - // nsCOMPtr foo; - // Unused << foo.forget(); - // Note that nsCOMPtr is the XPCOM reference counting smart pointer class. - friend void operator<<(const mozilla::unused_t& aUnused, - const already_AddRefed& aRhs) - { - auto mutableAlreadyAddRefed = const_cast*>(&aRhs); - aUnused << mutableAlreadyAddRefed->take(); - } - - MOZ_MUST_USE T* take() - { - T* rawPtr = mRawPtr; - mRawPtr = nullptr; - return rawPtr; - } - - /** - * This helper provides a static_cast replacement for already_AddRefed, so - * if you have - * - * already_AddRefed F(); - * - * you can write - * - * already_AddRefed - * G() - * { - * return F().downcast(); - * } - */ - template - already_AddRefed downcast() - { - U* tmp = static_cast(mRawPtr); - mRawPtr = nullptr; - return already_AddRefed(tmp); - } - -private: - T* MOZ_OWNING_REF mRawPtr; -}; - -#endif // AlreadyAddRefed_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Array.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Array.h deleted file mode 100644 index 72b89ede..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Array.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A compile-time constant-length array with bounds-checking assertions. */ - -#ifndef mozilla_Array_h -#define mozilla_Array_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" -#include "mozilla/ReverseIterator.h" - -#include - -namespace mozilla { - -template -class Array -{ - T mArr[Length]; - -public: - Array() {} - - template - MOZ_IMPLICIT Array(Args&&... aArgs) - : mArr{mozilla::Forward(aArgs)...} - { - static_assert(sizeof...(aArgs) == Length, - "The number of arguments should be equal to the template parameter Length"); - } - - T& operator[](size_t aIndex) - { - MOZ_ASSERT(aIndex < Length); - return mArr[aIndex]; - } - - const T& operator[](size_t aIndex) const - { - MOZ_ASSERT(aIndex < Length); - return mArr[aIndex]; - } - - typedef T* iterator; - typedef const T* const_iterator; - typedef ReverseIterator reverse_iterator; - typedef ReverseIterator const_reverse_iterator; - - // Methods for range-based for loops. - iterator begin() { return mArr; } - const_iterator begin() const { return mArr; } - const_iterator cbegin() const { return begin(); } - iterator end() { return mArr + Length; } - const_iterator end() const { return mArr + Length; } - const_iterator cend() const { return end(); } - - // Methods for reverse iterating. - reverse_iterator rbegin() { return reverse_iterator(end()); } - const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } - const_reverse_iterator crbegin() const { return rbegin(); } - reverse_iterator rend() { return reverse_iterator(begin()); } - const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } - const_reverse_iterator crend() const { return rend(); } -}; - -template -class Array -{ -public: - T& operator[](size_t aIndex) - { - MOZ_CRASH("indexing into zero-length array"); - } - - const T& operator[](size_t aIndex) const - { - MOZ_CRASH("indexing into zero-length array"); - } -}; - -} /* namespace mozilla */ - -#endif /* mozilla_Array_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/ArrayUtils.h b/android/armeabi-v7a/include/spidermonkey/mozilla/ArrayUtils.h deleted file mode 100644 index 50236ccb..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/ArrayUtils.h +++ /dev/null @@ -1,194 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Implements various helper functions related to arrays. - */ - -#ifndef mozilla_ArrayUtils_h -#define mozilla_ArrayUtils_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -#include - -#ifdef __cplusplus - -#include "mozilla/Alignment.h" -#include "mozilla/Array.h" -#include "mozilla/EnumeratedArray.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -/* - * Safely subtract two pointers when it is known that aEnd >= aBegin, yielding a - * size_t result. - * - * Ordinary pointer subtraction yields a ptrdiff_t result, which, being signed, - * has insufficient range to express the distance between pointers at opposite - * ends of the address space. Furthermore, most compilers use ptrdiff_t to - * represent the intermediate byte address distance, before dividing by - * sizeof(T); if that intermediate result overflows, they'll produce results - * with the wrong sign even when the correct scaled distance would fit in a - * ptrdiff_t. - */ -template -MOZ_ALWAYS_INLINE size_t -PointerRangeSize(T* aBegin, T* aEnd) -{ - MOZ_ASSERT(aEnd >= aBegin); - return (size_t(aEnd) - size_t(aBegin)) / sizeof(T); -} - -/* - * Compute the length of an array with constant length. (Use of this method - * with a non-array pointer will not compile.) - * - * Beware of the implicit trailing '\0' when using this with string constants. - */ -template -constexpr size_t -ArrayLength(T (&aArr)[N]) -{ - return N; -} - -template -constexpr size_t -ArrayLength(const Array& aArr) -{ - return N; -} - -template -constexpr size_t -ArrayLength(const EnumeratedArray& aArr) -{ - return size_t(N); -} - -/* - * Compute the address one past the last element of a constant-length array. - * - * Beware of the implicit trailing '\0' when using this with string constants. - */ -template -constexpr T* -ArrayEnd(T (&aArr)[N]) -{ - return aArr + ArrayLength(aArr); -} - -template -constexpr T* -ArrayEnd(Array& aArr) -{ - return &aArr[0] + ArrayLength(aArr); -} - -template -constexpr const T* -ArrayEnd(const Array& aArr) -{ - return &aArr[0] + ArrayLength(aArr); -} - -namespace detail { - -template::value>> -struct AlignedChecker -{ - static void - test(const Pointee* aPtr) - { - MOZ_ASSERT((uintptr_t(aPtr) % MOZ_ALIGNOF(AlignType)) == 0, - "performing a range-check with a misaligned pointer"); - } -}; - -template -struct AlignedChecker -{ - static void - test(const Pointee* aPtr) - { - } -}; - -} // namespace detail - -/** - * Determines whether |aPtr| points at an object in the range [aBegin, aEnd). - * - * |aPtr| must have the same alignment as |aBegin| and |aEnd|. This usually - * should be achieved by ensuring |aPtr| points at a |U|, not just that it - * points at a |T|. - * - * It is a usage error for any argument to be misaligned. - * - * It's okay for T* to be void*, and if so U* may also be void*. In the latter - * case no argument is required to be aligned (obviously, as void* implies no - * particular alignment). - */ -template -inline typename EnableIf::value || - IsBaseOf::value || - IsVoid::value, - bool>::Type -IsInRange(const T* aPtr, const U* aBegin, const U* aEnd) -{ - MOZ_ASSERT(aBegin <= aEnd); - detail::AlignedChecker::test(aPtr); - detail::AlignedChecker::test(aBegin); - detail::AlignedChecker::test(aEnd); - return aBegin <= reinterpret_cast(aPtr) && - reinterpret_cast(aPtr) < aEnd; -} - -/** - * Convenience version of the above method when the valid range is specified as - * uintptr_t values. As above, |aPtr| must be aligned, and |aBegin| and |aEnd| - * must be aligned with respect to |T|. - */ -template -inline bool -IsInRange(const T* aPtr, uintptr_t aBegin, uintptr_t aEnd) -{ - return IsInRange(aPtr, - reinterpret_cast(aBegin), - reinterpret_cast(aEnd)); -} - -namespace detail { - -/* - * Helper for the MOZ_ARRAY_LENGTH() macro to make the length a typesafe - * compile-time constant even on compilers lacking constexpr support. - */ -template -char (&ArrayLengthHelper(T (&array)[N]))[N]; - -} /* namespace detail */ - -} /* namespace mozilla */ - -#endif /* __cplusplus */ - -/* - * MOZ_ARRAY_LENGTH() is an alternative to mozilla::ArrayLength() for C files - * that can't use C++ template functions and for static_assert() calls that - * can't call ArrayLength() when it is not a C++11 constexpr function. - */ -#ifdef __cplusplus -# define MOZ_ARRAY_LENGTH(array) sizeof(mozilla::detail::ArrayLengthHelper(array)) -#else -# define MOZ_ARRAY_LENGTH(array) (sizeof(array)/sizeof((array)[0])) -#endif - -#endif /* mozilla_ArrayUtils_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Assertions.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Assertions.h deleted file mode 100644 index e978af3d..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Assertions.h +++ /dev/null @@ -1,585 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implementations of runtime and static assertion macros for C and C++. */ - -#ifndef mozilla_Assertions_h -#define mozilla_Assertions_h - -#if defined(MOZILLA_INTERNAL_API) && defined(__cplusplus) -#define MOZ_DUMP_ASSERTION_STACK -#endif - -#include "mozilla/Attributes.h" -#include "mozilla/Compiler.h" -#include "mozilla/Likely.h" -#include "mozilla/MacroArgs.h" -#include "mozilla/StaticAnalysisFunctions.h" -#include "mozilla/Types.h" -#ifdef MOZ_DUMP_ASSERTION_STACK -#include "nsTraceRefcnt.h" -#endif - -#if defined(MOZ_HAS_MOZGLUE) || defined(MOZILLA_INTERNAL_API) -/* - * The crash reason set by MOZ_CRASH_ANNOTATE is consumed by the crash reporter - * if present. It is declared here (and defined in Assertions.cpp) to make it - * available to all code, even libraries that don't link with the crash reporter - * directly. - */ -MOZ_BEGIN_EXTERN_C -extern MFBT_DATA const char* gMozCrashReason; -MOZ_END_EXTERN_C - -static inline void -AnnotateMozCrashReason(const char* reason) -{ - gMozCrashReason = reason; -} -# define MOZ_CRASH_ANNOTATE(...) AnnotateMozCrashReason(__VA_ARGS__) -#else -# define MOZ_CRASH_ANNOTATE(...) do { /* nothing */ } while (0) -#endif - -#include -#include -#include -#ifdef WIN32 - /* - * TerminateProcess and GetCurrentProcess are defined in , which - * further depends on . We hardcode these few definitions manually - * because those headers clutter the global namespace with a significant - * number of undesired macros and symbols. - */ -# ifdef __cplusplus -extern "C" { -# endif -__declspec(dllimport) int __stdcall -TerminateProcess(void* hProcess, unsigned int uExitCode); -__declspec(dllimport) void* __stdcall GetCurrentProcess(void); -# ifdef __cplusplus -} -# endif -#else -# include -#endif -#ifdef ANDROID -# include -#endif - -/* - * MOZ_STATIC_ASSERT may be used to assert a condition *at compile time* in C. - * In C++11, static_assert is provided by the compiler to the same effect. - * This can be useful when you make certain assumptions about what must hold for - * optimal, or even correct, behavior. For example, you might assert that the - * size of a struct is a multiple of the target architecture's word size: - * - * struct S { ... }; - * // C - * MOZ_STATIC_ASSERT(sizeof(S) % sizeof(size_t) == 0, - * "S should be a multiple of word size for efficiency"); - * // C++11 - * static_assert(sizeof(S) % sizeof(size_t) == 0, - * "S should be a multiple of word size for efficiency"); - * - * This macro can be used in any location where both an extern declaration and a - * typedef could be used. - */ -#ifndef __cplusplus - /* - * Some of the definitions below create an otherwise-unused typedef. This - * triggers compiler warnings with some versions of gcc, so mark the typedefs - * as permissibly-unused to disable the warnings. - */ -# if defined(__GNUC__) -# define MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) -# else -# define MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE /* nothing */ -# endif -# define MOZ_STATIC_ASSERT_GLUE1(x, y) x##y -# define MOZ_STATIC_ASSERT_GLUE(x, y) MOZ_STATIC_ASSERT_GLUE1(x, y) -# if defined(__SUNPRO_CC) - /* - * The Sun Studio C++ compiler is buggy when declaring, inside a function, - * another extern'd function with an array argument whose length contains a - * sizeof, triggering the error message "sizeof expression not accepted as - * size of array parameter". This bug (6688515, not public yet) would hit - * defining moz_static_assert as a function, so we always define an extern - * array for Sun Studio. - * - * We include the line number in the symbol name in a best-effort attempt - * to avoid conflicts (see below). - */ -# define MOZ_STATIC_ASSERT(cond, reason) \ - extern char MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __LINE__)[(cond) ? 1 : -1] -# elif defined(__COUNTER__) - /* - * If there was no preferred alternative, use a compiler-agnostic version. - * - * Note that the non-__COUNTER__ version has a bug in C++: it can't be used - * in both |extern "C"| and normal C++ in the same translation unit. (Alas - * |extern "C"| isn't allowed in a function.) The only affected compiler - * we really care about is gcc 4.2. For that compiler and others like it, - * we include the line number in the function name to do the best we can to - * avoid conflicts. These should be rare: a conflict would require use of - * MOZ_STATIC_ASSERT on the same line in separate files in the same - * translation unit, *and* the uses would have to be in code with - * different linkage, *and* the first observed use must be in C++-linkage - * code. - */ -# define MOZ_STATIC_ASSERT(cond, reason) \ - typedef int MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __COUNTER__)[(cond) ? 1 : -1] MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE -# else -# define MOZ_STATIC_ASSERT(cond, reason) \ - extern void MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __LINE__)(int arg[(cond) ? 1 : -1]) MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE -# endif - -#define MOZ_STATIC_ASSERT_IF(cond, expr, reason) MOZ_STATIC_ASSERT(!(cond) || (expr), reason) -#else -#define MOZ_STATIC_ASSERT_IF(cond, expr, reason) static_assert(!(cond) || (expr), reason) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Prints |aStr| as an assertion failure (using aFilename and aLine as the - * location of the assertion) to the standard debug-output channel. - * - * Usually you should use MOZ_ASSERT or MOZ_CRASH instead of this method. This - * method is primarily for internal use in this header, and only secondarily - * for use in implementing release-build assertions. - */ -static MOZ_COLD MOZ_ALWAYS_INLINE void -MOZ_ReportAssertionFailure(const char* aStr, const char* aFilename, int aLine) - MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS -{ -#ifdef ANDROID - __android_log_print(ANDROID_LOG_FATAL, "MOZ_Assert", - "Assertion failure: %s, at %s:%d\n", - aStr, aFilename, aLine); -#else - fprintf(stderr, "Assertion failure: %s, at %s:%d\n", aStr, aFilename, aLine); -#if defined (MOZ_DUMP_ASSERTION_STACK) - nsTraceRefcnt::WalkTheStack(stderr); -#endif - fflush(stderr); -#endif -} - -static MOZ_COLD MOZ_ALWAYS_INLINE void -MOZ_ReportCrash(const char* aStr, const char* aFilename, int aLine) - MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS -{ -#ifdef ANDROID - __android_log_print(ANDROID_LOG_FATAL, "MOZ_CRASH", - "Hit MOZ_CRASH(%s) at %s:%d\n", aStr, aFilename, aLine); -#else - fprintf(stderr, "Hit MOZ_CRASH(%s) at %s:%d\n", aStr, aFilename, aLine); -#if defined(MOZ_DUMP_ASSERTION_STACK) - nsTraceRefcnt::WalkTheStack(stderr); -#endif - fflush(stderr); -#endif -} - -/** - * MOZ_REALLY_CRASH is used in the implementation of MOZ_CRASH(). You should - * call MOZ_CRASH instead. - */ -#if defined(_MSC_VER) - /* - * On MSVC use the __debugbreak compiler intrinsic, which produces an inline - * (not nested in a system function) breakpoint. This distinctively invokes - * Breakpad without requiring system library symbols on all stack-processing - * machines, as a nested breakpoint would require. - * - * We use TerminateProcess with the exit code aborting would generate - * because we don't want to invoke atexit handlers, destructors, library - * unload handlers, and so on when our process might be in a compromised - * state. - * - * We don't use abort() because it'd cause Windows to annoyingly pop up the - * process error dialog multiple times. See bug 345118 and bug 426163. - * - * We follow TerminateProcess() with a call to MOZ_NoReturn() so that the - * compiler doesn't hassle us to provide a return statement after a - * MOZ_REALLY_CRASH() call. - * - * (Technically these are Windows requirements, not MSVC requirements. But - * practically you need MSVC for debugging, and we only ship builds created - * by MSVC, so doing it this way reduces complexity.) - */ - -__declspec(noreturn) __inline void MOZ_NoReturn() {} - -# ifdef __cplusplus -# define MOZ_REALLY_CRASH() \ - do { \ - ::__debugbreak(); \ - *((volatile int*) NULL) = __LINE__; \ - ::TerminateProcess(::GetCurrentProcess(), 3); \ - ::MOZ_NoReturn(); \ - } while (0) -# else -# define MOZ_REALLY_CRASH() \ - do { \ - __debugbreak(); \ - *((volatile int*) NULL) = __LINE__; \ - TerminateProcess(GetCurrentProcess(), 3); \ - MOZ_NoReturn(); \ - } while (0) -# endif -#else -# ifdef __cplusplus -# define MOZ_REALLY_CRASH() \ - do { \ - *((volatile int*) NULL) = __LINE__; \ - ::abort(); \ - } while (0) -# else -# define MOZ_REALLY_CRASH() \ - do { \ - *((volatile int*) NULL) = __LINE__; \ - abort(); \ - } while (0) -# endif -#endif - -/* - * MOZ_CRASH([explanation-string]) crashes the program, plain and simple, in a - * Breakpad-compatible way, in both debug and release builds. - * - * MOZ_CRASH is a good solution for "handling" failure cases when you're - * unwilling or unable to handle them more cleanly -- for OOM, for likely memory - * corruption, and so on. It's also a good solution if you need safe behavior - * in release builds as well as debug builds. But if the failure is one that - * should be debugged and fixed, MOZ_ASSERT is generally preferable. - * - * The optional explanation-string, if provided, must be a string literal - * explaining why we're crashing. This argument is intended for use with - * MOZ_CRASH() calls whose rationale is non-obvious; don't use it if it's - * obvious why we're crashing. - * - * If we're a DEBUG build and we crash at a MOZ_CRASH which provides an - * explanation-string, we print the string to stderr. Otherwise, we don't - * print anything; this is because we want MOZ_CRASH to be 100% safe in release - * builds, and it's hard to print to stderr safely when memory might have been - * corrupted. - */ -#ifndef DEBUG -# define MOZ_CRASH(...) \ - do { \ - MOZ_CRASH_ANNOTATE("MOZ_CRASH(" __VA_ARGS__ ")"); \ - MOZ_REALLY_CRASH(); \ - } while (0) -#else -# define MOZ_CRASH(...) \ - do { \ - MOZ_ReportCrash("" __VA_ARGS__, __FILE__, __LINE__); \ - MOZ_CRASH_ANNOTATE("MOZ_CRASH(" __VA_ARGS__ ")"); \ - MOZ_REALLY_CRASH(); \ - } while (0) -#endif - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -/* - * MOZ_ASSERT(expr [, explanation-string]) asserts that |expr| must be truthy in - * debug builds. If it is, execution continues. Otherwise, an error message - * including the expression and the explanation-string (if provided) is printed, - * an attempt is made to invoke any existing debugger, and execution halts. - * MOZ_ASSERT is fatal: no recovery is possible. Do not assert a condition - * which can correctly be falsy. - * - * The optional explanation-string, if provided, must be a string literal - * explaining the assertion. It is intended for use with assertions whose - * correctness or rationale is non-obvious, and for assertions where the "real" - * condition being tested is best described prosaically. Don't provide an - * explanation if it's not actually helpful. - * - * // No explanation needed: pointer arguments often must not be NULL. - * MOZ_ASSERT(arg); - * - * // An explanation can be helpful to explain exactly how we know an - * // assertion is valid. - * MOZ_ASSERT(state == WAITING_FOR_RESPONSE, - * "given that and , we must have..."); - * - * // Or it might disambiguate multiple identical (save for their location) - * // assertions of the same expression. - * MOZ_ASSERT(getSlot(PRIMITIVE_THIS_SLOT).isUndefined(), - * "we already set [[PrimitiveThis]] for this Boolean object"); - * MOZ_ASSERT(getSlot(PRIMITIVE_THIS_SLOT).isUndefined(), - * "we already set [[PrimitiveThis]] for this String object"); - * - * MOZ_ASSERT has no effect in non-debug builds. It is designed to catch bugs - * *only* during debugging, not "in the field". If you want the latter, use - * MOZ_RELEASE_ASSERT, which applies to non-debug builds as well. - * - * MOZ_DIAGNOSTIC_ASSERT works like MOZ_RELEASE_ASSERT in Nightly/Aurora and - * MOZ_ASSERT in Beta/Release - use this when a condition is potentially rare - * enough to require real user testing to hit, but is not security-sensitive. - * This can cause user pain, so use it sparingly. If a MOZ_DIAGNOSTIC_ASSERT - * is firing, it should promptly be converted to a MOZ_ASSERT while the failure - * is being investigated, rather than letting users suffer. - */ - -/* - * Implement MOZ_VALIDATE_ASSERT_CONDITION_TYPE, which is used to guard against - * accidentally passing something unintended in lieu of an assertion condition. - */ - -#ifdef __cplusplus -# include "mozilla/TypeTraits.h" -namespace mozilla { -namespace detail { - -template -struct AssertionConditionType -{ - typedef typename RemoveReference::Type ValueT; - static_assert(!IsArray::value, - "Expected boolean assertion condition, got an array or a " - "string!"); - static_assert(!IsFunction::value, - "Expected boolean assertion condition, got a function! Did " - "you intend to call that function?"); - static_assert(!IsFloatingPoint::value, - "It's often a bad idea to assert that a floating-point number " - "is nonzero, because such assertions tend to intermittently " - "fail. Shouldn't your code gracefully handle this case instead " - "of asserting? Anyway, if you really want to do that, write an " - "explicit boolean condition, like !!x or x!=0."); - - static const bool isValid = true; -}; - -} // namespace detail -} // namespace mozilla -# define MOZ_VALIDATE_ASSERT_CONDITION_TYPE(x) \ - static_assert(mozilla::detail::AssertionConditionType::isValid, \ - "invalid assertion condition") -#else -# define MOZ_VALIDATE_ASSERT_CONDITION_TYPE(x) -#endif - -/* First the single-argument form. */ -#define MOZ_ASSERT_HELPER1(expr) \ - do { \ - MOZ_VALIDATE_ASSERT_CONDITION_TYPE(expr); \ - if (MOZ_UNLIKELY(!MOZ_CHECK_ASSERT_ASSIGNMENT(expr))) { \ - MOZ_ReportAssertionFailure(#expr, __FILE__, __LINE__); \ - MOZ_CRASH_ANNOTATE("MOZ_RELEASE_ASSERT(" #expr ")"); \ - MOZ_REALLY_CRASH(); \ - } \ - } while (0) -/* Now the two-argument form. */ -#define MOZ_ASSERT_HELPER2(expr, explain) \ - do { \ - MOZ_VALIDATE_ASSERT_CONDITION_TYPE(expr); \ - if (MOZ_UNLIKELY(!MOZ_CHECK_ASSERT_ASSIGNMENT(expr))) { \ - MOZ_ReportAssertionFailure(#expr " (" explain ")", __FILE__, __LINE__); \ - MOZ_CRASH_ANNOTATE("MOZ_RELEASE_ASSERT(" #expr ") (" explain ")"); \ - MOZ_REALLY_CRASH(); \ - } \ - } while (0) - -#define MOZ_RELEASE_ASSERT_GLUE(a, b) a b -#define MOZ_RELEASE_ASSERT(...) \ - MOZ_RELEASE_ASSERT_GLUE( \ - MOZ_PASTE_PREFIX_AND_ARG_COUNT(MOZ_ASSERT_HELPER, __VA_ARGS__), \ - (__VA_ARGS__)) - -#ifdef DEBUG -# define MOZ_ASSERT(...) MOZ_RELEASE_ASSERT(__VA_ARGS__) -#else -# define MOZ_ASSERT(...) do { } while (0) -#endif /* DEBUG */ - -#ifdef RELEASE_OR_BETA -# define MOZ_DIAGNOSTIC_ASSERT MOZ_ASSERT -#else -# define MOZ_DIAGNOSTIC_ASSERT MOZ_RELEASE_ASSERT -#endif - -/* - * MOZ_ASSERT_IF(cond1, cond2) is equivalent to MOZ_ASSERT(cond2) if cond1 is - * true. - * - * MOZ_ASSERT_IF(isPrime(num), num == 2 || isOdd(num)); - * - * As with MOZ_ASSERT, MOZ_ASSERT_IF has effect only in debug builds. It is - * designed to catch bugs during debugging, not "in the field". - */ -#ifdef DEBUG -# define MOZ_ASSERT_IF(cond, expr) \ - do { \ - if (cond) { \ - MOZ_ASSERT(expr); \ - } \ - } while (0) -#else -# define MOZ_ASSERT_IF(cond, expr) do { } while (0) -#endif - -/* - * MOZ_ASSUME_UNREACHABLE_MARKER() expands to an expression which states that - * it is undefined behavior for execution to reach this point. No guarantees - * are made about what will happen if this is reached at runtime. Most code - * should use MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE because it has extra - * asserts. - */ -#if defined(__clang__) || defined(__GNUC__) -# define MOZ_ASSUME_UNREACHABLE_MARKER() __builtin_unreachable() -#elif defined(_MSC_VER) -# define MOZ_ASSUME_UNREACHABLE_MARKER() __assume(0) -#else -# ifdef __cplusplus -# define MOZ_ASSUME_UNREACHABLE_MARKER() ::abort() -# else -# define MOZ_ASSUME_UNREACHABLE_MARKER() abort() -# endif -#endif - -/* - * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE([reason]) tells the compiler that it - * can assume that the macro call cannot be reached during execution. This lets - * the compiler generate better-optimized code under some circumstances, at the - * expense of the program's behavior being undefined if control reaches the - * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE. - * - * In Gecko, you probably should not use this macro outside of performance- or - * size-critical code, because it's unsafe. If you don't care about code size - * or performance, you should probably use MOZ_ASSERT or MOZ_CRASH. - * - * SpiderMonkey is a different beast, and there it's acceptable to use - * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE more widely. - * - * Note that MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE is noreturn, so it's valid - * not to return a value following a MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE - * call. - * - * Example usage: - * - * enum ValueType { - * VALUE_STRING, - * VALUE_INT, - * VALUE_FLOAT - * }; - * - * int ptrToInt(ValueType type, void* value) { - * { - * // We know for sure that type is either INT or FLOAT, and we want this - * // code to run as quickly as possible. - * switch (type) { - * case VALUE_INT: - * return *(int*) value; - * case VALUE_FLOAT: - * return (int) *(float*) value; - * default: - * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unexpected ValueType"); - * } - * } - */ - -/* - * Unconditional assert in debug builds for (assumed) unreachable code paths - * that have a safe return without crashing in release builds. - */ -#define MOZ_ASSERT_UNREACHABLE(reason) \ - MOZ_ASSERT(false, "MOZ_ASSERT_UNREACHABLE: " reason) - -#define MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE(reason) \ - do { \ - MOZ_ASSERT_UNREACHABLE(reason); \ - MOZ_ASSUME_UNREACHABLE_MARKER(); \ - } while (0) - -/** - * MOZ_FALLTHROUGH_ASSERT is an annotation to suppress compiler warnings about - * switch cases that MOZ_ASSERT(false) (or its alias MOZ_ASSERT_UNREACHABLE) in - * debug builds, but intentionally fall through in release builds to handle - * unexpected values. - * - * Why do we need MOZ_FALLTHROUGH_ASSERT in addition to MOZ_FALLTHROUGH? In - * release builds, the MOZ_ASSERT(false) will expand to `do { } while (0)`, - * requiring a MOZ_FALLTHROUGH annotation to suppress a -Wimplicit-fallthrough - * warning. In debug builds, the MOZ_ASSERT(false) will expand to something like - * `if (true) { MOZ_CRASH(); }` and the MOZ_FALLTHROUGH annotation will cause - * a -Wunreachable-code warning. The MOZ_FALLTHROUGH_ASSERT macro breaks this - * warning stalemate. - * - * // Example before MOZ_FALLTHROUGH_ASSERT: - * switch (foo) { - * default: - * // This case wants to assert in debug builds, fall through in release. - * MOZ_ASSERT(false); // -Wimplicit-fallthrough warning in release builds! - * MOZ_FALLTHROUGH; // but -Wunreachable-code warning in debug builds! - * case 5: - * return 5; - * } - * - * // Example with MOZ_FALLTHROUGH_ASSERT: - * switch (foo) { - * default: - * // This case asserts in debug builds, falls through in release. - * MOZ_FALLTHROUGH_ASSERT("Unexpected foo value?!"); - * case 5: - * return 5; - * } - */ -#ifdef DEBUG -# define MOZ_FALLTHROUGH_ASSERT(reason) MOZ_CRASH("MOZ_FALLTHROUGH_ASSERT: " reason) -#else -# define MOZ_FALLTHROUGH_ASSERT(...) MOZ_FALLTHROUGH -#endif - -/* - * MOZ_ALWAYS_TRUE(expr) and MOZ_ALWAYS_FALSE(expr) always evaluate the provided - * expression, in debug builds and in release builds both. Then, in debug - * builds only, the value of the expression is asserted either true or false - * using MOZ_ASSERT. - */ -#ifdef DEBUG -# define MOZ_ALWAYS_TRUE(expr) \ - do { \ - if ((expr)) { \ - /* Do nothing. */ \ - } else { \ - MOZ_ASSERT(false, #expr); \ - } \ - } while (0) -# define MOZ_ALWAYS_FALSE(expr) \ - do { \ - if ((expr)) { \ - MOZ_ASSERT(false, #expr); \ - } else { \ - /* Do nothing. */ \ - } \ - } while (0) -#else -# define MOZ_ALWAYS_TRUE(expr) \ - do { \ - if ((expr)) { \ - /* Silence MOZ_MUST_USE. */ \ - } \ - } while (0) -# define MOZ_ALWAYS_FALSE(expr) \ - do { \ - if ((expr)) { \ - /* Silence MOZ_MUST_USE. */ \ - } \ - } while (0) -#endif - -#undef MOZ_DUMP_ASSERTION_STACK -#undef MOZ_CRASH_CRASHREPORT - -#endif /* mozilla_Assertions_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Atomics.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Atomics.h deleted file mode 100644 index 213d1b9f..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Atomics.h +++ /dev/null @@ -1,800 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Implements (almost always) lock-free atomic operations. The operations here - * are a subset of that which can be found in C++11's header, with a - * different API to enforce consistent memory ordering constraints. - * - * Anyone caught using |volatile| for inter-thread memory safety needs to be - * sent a copy of this header and the C++11 standard. - */ - -#ifndef mozilla_Atomics_h -#define mozilla_Atomics_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Compiler.h" -#include "mozilla/TypeTraits.h" - -#include - -/* - * Our minimum deployment target on clang/OS X is OS X 10.6, whose SDK - * does not have . So be sure to check for support - * along with C++0x support. - */ -#if defined(_MSC_VER) -# define MOZ_HAVE_CXX11_ATOMICS -#elif defined(__clang__) || defined(__GNUC__) - /* - * Clang doesn't like from libstdc++ before 4.7 due to the - * loose typing of the atomic builtins. GCC 4.5 and 4.6 lacks inline - * definitions for unspecialized std::atomic and causes linking errors. - * Therefore, we require at least 4.7.0 for using libstdc++. - * - * libc++ is only functional with clang. - */ -# if MOZ_USING_LIBSTDCXX && MOZ_LIBSTDCXX_VERSION_AT_LEAST(4, 7, 0) -# define MOZ_HAVE_CXX11_ATOMICS -# elif MOZ_USING_LIBCXX && defined(__clang__) -# define MOZ_HAVE_CXX11_ATOMICS -# endif -#endif - -namespace mozilla { - -/** - * An enum of memory ordering possibilities for atomics. - * - * Memory ordering is the observable state of distinct values in memory. - * (It's a separate concept from atomicity, which concerns whether an - * operation can ever be observed in an intermediate state. Don't - * conflate the two!) Given a sequence of operations in source code on - * memory, it is *not* always the case that, at all times and on all - * cores, those operations will appear to have occurred in that exact - * sequence. First, the compiler might reorder that sequence, if it - * thinks another ordering will be more efficient. Second, the CPU may - * not expose so consistent a view of memory. CPUs will often perform - * their own instruction reordering, above and beyond that performed by - * the compiler. And each core has its own memory caches, and accesses - * (reads and writes both) to "memory" may only resolve to out-of-date - * cache entries -- not to the "most recently" performed operation in - * some global sense. Any access to a value that may be used by - * multiple threads, potentially across multiple cores, must therefore - * have a memory ordering imposed on it, for all code on all - * threads/cores to have a sufficiently coherent worldview. - * - * http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync and - * http://en.cppreference.com/w/cpp/atomic/memory_order go into more - * detail on all this, including examples of how each mode works. - * - * Note that for simplicity and practicality, not all of the modes in - * C++11 are supported. The missing C++11 modes are either subsumed by - * the modes we provide below, or not relevant for the CPUs we support - * in Gecko. These three modes are confusing enough as it is! - */ -enum MemoryOrdering { - /* - * Relaxed ordering is the simplest memory ordering: none at all. - * When the result of a write is observed, nothing may be inferred - * about other memory. Writes ostensibly performed "before" on the - * writing thread may not yet be visible. Writes performed "after" on - * the writing thread may already be visible, if the compiler or CPU - * reordered them. (The latter can happen if reads and/or writes get - * held up in per-processor caches.) Relaxed ordering means - * operations can always use cached values (as long as the actual - * updates to atomic values actually occur, correctly, eventually), so - * it's usually the fastest sort of atomic access. For this reason, - * *it's also the most dangerous kind of access*. - * - * Relaxed ordering is good for things like process-wide statistics - * counters that don't need to be consistent with anything else, so - * long as updates themselves are atomic. (And so long as any - * observations of that value can tolerate being out-of-date -- if you - * need some sort of up-to-date value, you need some sort of other - * synchronizing operation.) It's *not* good for locks, mutexes, - * reference counts, etc. that mediate access to other memory, or must - * be observably consistent with other memory. - * - * x86 architectures don't take advantage of the optimization - * opportunities that relaxed ordering permits. Thus it's possible - * that using relaxed ordering will "work" on x86 but fail elsewhere - * (ARM, say, which *does* implement non-sequentially-consistent - * relaxed ordering semantics). Be extra-careful using relaxed - * ordering if you can't easily test non-x86 architectures! - */ - Relaxed, - - /* - * When an atomic value is updated with ReleaseAcquire ordering, and - * that new value is observed with ReleaseAcquire ordering, prior - * writes (atomic or not) are also observable. What ReleaseAcquire - * *doesn't* give you is any observable ordering guarantees for - * ReleaseAcquire-ordered operations on different objects. For - * example, if there are two cores that each perform ReleaseAcquire - * operations on separate objects, each core may or may not observe - * the operations made by the other core. The only way the cores can - * be synchronized with ReleaseAcquire is if they both - * ReleaseAcquire-access the same object. This implies that you can't - * necessarily describe some global total ordering of ReleaseAcquire - * operations. - * - * ReleaseAcquire ordering is good for (as the name implies) atomic - * operations on values controlling ownership of things: reference - * counts, mutexes, and the like. However, if you are thinking about - * using these to implement your own locks or mutexes, you should take - * a good, hard look at actual lock or mutex primitives first. - */ - ReleaseAcquire, - - /* - * When an atomic value is updated with SequentiallyConsistent - * ordering, all writes observable when the update is observed, just - * as with ReleaseAcquire ordering. But, furthermore, a global total - * ordering of SequentiallyConsistent operations *can* be described. - * For example, if two cores perform SequentiallyConsistent operations - * on separate objects, one core will observably perform its update - * (and all previous operations will have completed), then the other - * core will observably perform its update (and all previous - * operations will have completed). (Although those previous - * operations aren't themselves ordered -- they could be intermixed, - * or ordered if they occur on atomic values with ordering - * requirements.) SequentiallyConsistent is the *simplest and safest* - * ordering of atomic operations -- it's always as if one operation - * happens, then another, then another, in some order -- and every - * core observes updates to happen in that single order. Because it - * has the most synchronization requirements, operations ordered this - * way also tend to be slowest. - * - * SequentiallyConsistent ordering can be desirable when multiple - * threads observe objects, and they all have to agree on the - * observable order of changes to them. People expect - * SequentiallyConsistent ordering, even if they shouldn't, when - * writing code, atomic or otherwise. SequentiallyConsistent is also - * the ordering of choice when designing lockless data structures. If - * you don't know what order to use, use this one. - */ - SequentiallyConsistent, -}; - -} // namespace mozilla - -// Build up the underlying intrinsics. -#ifdef MOZ_HAVE_CXX11_ATOMICS - -# include - -namespace mozilla { -namespace detail { - -/* - * We provide CompareExchangeFailureOrder to work around a bug in some - * versions of GCC's header. See bug 898491. - */ -template struct AtomicOrderConstraints; - -template<> -struct AtomicOrderConstraints -{ - static const std::memory_order AtomicRMWOrder = std::memory_order_relaxed; - static const std::memory_order LoadOrder = std::memory_order_relaxed; - static const std::memory_order StoreOrder = std::memory_order_relaxed; - static const std::memory_order CompareExchangeFailureOrder = - std::memory_order_relaxed; -}; - -template<> -struct AtomicOrderConstraints -{ - static const std::memory_order AtomicRMWOrder = std::memory_order_acq_rel; - static const std::memory_order LoadOrder = std::memory_order_acquire; - static const std::memory_order StoreOrder = std::memory_order_release; - static const std::memory_order CompareExchangeFailureOrder = - std::memory_order_acquire; -}; - -template<> -struct AtomicOrderConstraints -{ - static const std::memory_order AtomicRMWOrder = std::memory_order_seq_cst; - static const std::memory_order LoadOrder = std::memory_order_seq_cst; - static const std::memory_order StoreOrder = std::memory_order_seq_cst; - static const std::memory_order CompareExchangeFailureOrder = - std::memory_order_seq_cst; -}; - -template -struct IntrinsicBase -{ - typedef std::atomic ValueType; - typedef AtomicOrderConstraints OrderedOp; -}; - -template -struct IntrinsicMemoryOps : public IntrinsicBase -{ - typedef IntrinsicBase Base; - - static T load(const typename Base::ValueType& aPtr) - { - return aPtr.load(Base::OrderedOp::LoadOrder); - } - - static void store(typename Base::ValueType& aPtr, T aVal) - { - aPtr.store(aVal, Base::OrderedOp::StoreOrder); - } - - static T exchange(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.exchange(aVal, Base::OrderedOp::AtomicRMWOrder); - } - - static bool compareExchange(typename Base::ValueType& aPtr, - T aOldVal, T aNewVal) - { - return aPtr.compare_exchange_strong(aOldVal, aNewVal, - Base::OrderedOp::AtomicRMWOrder, - Base::OrderedOp::CompareExchangeFailureOrder); - } -}; - -template -struct IntrinsicAddSub : public IntrinsicBase -{ - typedef IntrinsicBase Base; - - static T add(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.fetch_add(aVal, Base::OrderedOp::AtomicRMWOrder); - } - - static T sub(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.fetch_sub(aVal, Base::OrderedOp::AtomicRMWOrder); - } -}; - -template -struct IntrinsicAddSub : public IntrinsicBase -{ - typedef IntrinsicBase Base; - - static T* add(typename Base::ValueType& aPtr, ptrdiff_t aVal) - { - return aPtr.fetch_add(aVal, Base::OrderedOp::AtomicRMWOrder); - } - - static T* sub(typename Base::ValueType& aPtr, ptrdiff_t aVal) - { - return aPtr.fetch_sub(aVal, Base::OrderedOp::AtomicRMWOrder); - } -}; - -template -struct IntrinsicIncDec : public IntrinsicAddSub -{ - typedef IntrinsicBase Base; - - static T inc(typename Base::ValueType& aPtr) - { - return IntrinsicAddSub::add(aPtr, 1); - } - - static T dec(typename Base::ValueType& aPtr) - { - return IntrinsicAddSub::sub(aPtr, 1); - } -}; - -template -struct AtomicIntrinsics : public IntrinsicMemoryOps, - public IntrinsicIncDec -{ - typedef IntrinsicBase Base; - - static T or_(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.fetch_or(aVal, Base::OrderedOp::AtomicRMWOrder); - } - - static T xor_(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.fetch_xor(aVal, Base::OrderedOp::AtomicRMWOrder); - } - - static T and_(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.fetch_and(aVal, Base::OrderedOp::AtomicRMWOrder); - } -}; - -template -struct AtomicIntrinsics - : public IntrinsicMemoryOps, public IntrinsicIncDec -{ -}; - -template -struct ToStorageTypeArgument -{ - static constexpr T convert (T aT) { return aT; } -}; - -} // namespace detail -} // namespace mozilla - -#elif defined(__GNUC__) - -namespace mozilla { -namespace detail { - -/* - * The __sync_* family of intrinsics is documented here: - * - * http://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Atomic-Builtins.html - * - * While these intrinsics are deprecated in favor of the newer __atomic_* - * family of intrincs: - * - * http://gcc.gnu.org/onlinedocs/gcc-4.7.3/gcc/_005f_005fatomic-Builtins.html - * - * any GCC version that supports the __atomic_* intrinsics will also support - * the header and so will be handled above. We provide a version of - * atomics using the __sync_* intrinsics to support older versions of GCC. - * - * All __sync_* intrinsics that we use below act as full memory barriers, for - * both compiler and hardware reordering, except for __sync_lock_test_and_set, - * which is a only an acquire barrier. When we call __sync_lock_test_and_set, - * we add a barrier above it as appropriate. - */ - -template struct Barrier; - -/* - * Some processors (in particular, x86) don't require quite so many calls to - * __sync_sychronize as our specializations of Barrier produce. If - * performance turns out to be an issue, defining these specializations - * on a per-processor basis would be a good first tuning step. - */ - -template<> -struct Barrier -{ - static void beforeLoad() {} - static void afterLoad() {} - static void beforeStore() {} - static void afterStore() {} -}; - -template<> -struct Barrier -{ - static void beforeLoad() {} - static void afterLoad() { __sync_synchronize(); } - static void beforeStore() { __sync_synchronize(); } - static void afterStore() {} -}; - -template<> -struct Barrier -{ - static void beforeLoad() { __sync_synchronize(); } - static void afterLoad() { __sync_synchronize(); } - static void beforeStore() { __sync_synchronize(); } - static void afterStore() { __sync_synchronize(); } -}; - -template::value> -struct AtomicStorageType -{ - // For non-enums, just use the type directly. - typedef T Type; -}; - -template -struct AtomicStorageType - : Conditional -{ - static_assert(sizeof(T) == 4 || sizeof(T) == 8, - "wrong type computed in conditional above"); -}; - -template -struct IntrinsicMemoryOps -{ - typedef typename AtomicStorageType::Type ValueType; - - static T load(const ValueType& aPtr) - { - Barrier::beforeLoad(); - T val = T(aPtr); - Barrier::afterLoad(); - return val; - } - - static void store(ValueType& aPtr, T aVal) - { - Barrier::beforeStore(); - aPtr = ValueType(aVal); - Barrier::afterStore(); - } - - static T exchange(ValueType& aPtr, T aVal) - { - // __sync_lock_test_and_set is only an acquire barrier; loads and stores - // can't be moved up from after to before it, but they can be moved down - // from before to after it. We may want a stricter ordering, so we need - // an explicit barrier. - Barrier::beforeStore(); - return T(__sync_lock_test_and_set(&aPtr, ValueType(aVal))); - } - - static bool compareExchange(ValueType& aPtr, T aOldVal, T aNewVal) - { - return __sync_bool_compare_and_swap(&aPtr, ValueType(aOldVal), ValueType(aNewVal)); - } -}; - -template -struct IntrinsicAddSub - : public IntrinsicMemoryOps -{ - typedef IntrinsicMemoryOps Base; - typedef typename Base::ValueType ValueType; - - static T add(ValueType& aPtr, T aVal) - { - return T(__sync_fetch_and_add(&aPtr, ValueType(aVal))); - } - - static T sub(ValueType& aPtr, T aVal) - { - return T(__sync_fetch_and_sub(&aPtr, ValueType(aVal))); - } -}; - -template -struct IntrinsicAddSub - : public IntrinsicMemoryOps -{ - typedef IntrinsicMemoryOps Base; - typedef typename Base::ValueType ValueType; - - /* - * The reinterpret_casts are needed so that - * __sync_fetch_and_{add,sub} will properly type-check. - * - * Also, these functions do not provide standard semantics for - * pointer types, so we need to adjust the addend. - */ - static ValueType add(ValueType& aPtr, ptrdiff_t aVal) - { - ValueType amount = reinterpret_cast(aVal * sizeof(T)); - return __sync_fetch_and_add(&aPtr, amount); - } - - static ValueType sub(ValueType& aPtr, ptrdiff_t aVal) - { - ValueType amount = reinterpret_cast(aVal * sizeof(T)); - return __sync_fetch_and_sub(&aPtr, amount); - } -}; - -template -struct IntrinsicIncDec : public IntrinsicAddSub -{ - typedef IntrinsicAddSub Base; - typedef typename Base::ValueType ValueType; - - static T inc(ValueType& aPtr) { return Base::add(aPtr, 1); } - static T dec(ValueType& aPtr) { return Base::sub(aPtr, 1); } -}; - -template -struct AtomicIntrinsics : public IntrinsicIncDec -{ - static T or_( T& aPtr, T aVal) { return __sync_fetch_and_or(&aPtr, aVal); } - static T xor_(T& aPtr, T aVal) { return __sync_fetch_and_xor(&aPtr, aVal); } - static T and_(T& aPtr, T aVal) { return __sync_fetch_and_and(&aPtr, aVal); } -}; - -template -struct AtomicIntrinsics : public IntrinsicIncDec -{ -}; - -template::value> -struct ToStorageTypeArgument -{ - typedef typename AtomicStorageType::Type ResultType; - - static constexpr ResultType convert (T aT) { return ResultType(aT); } -}; - -template -struct ToStorageTypeArgument -{ - static constexpr T convert (T aT) { return aT; } -}; - -} // namespace detail -} // namespace mozilla - -#else -# error "Atomic compiler intrinsics are not supported on your platform" -#endif - -namespace mozilla { - -namespace detail { - -template -class AtomicBase -{ - static_assert(sizeof(T) == 4 || sizeof(T) == 8, - "mozilla/Atomics.h only supports 32-bit and 64-bit types"); - -protected: - typedef typename detail::AtomicIntrinsics Intrinsics; - typedef typename Intrinsics::ValueType ValueType; - ValueType mValue; - -public: - constexpr AtomicBase() : mValue() {} - explicit constexpr AtomicBase(T aInit) - : mValue(ToStorageTypeArgument::convert(aInit)) - {} - - // Note: we can't provide operator T() here because Atomic inherits - // from AtomcBase with T=uint32_t and not T=bool. If we implemented - // operator T() here, it would cause errors when comparing Atomic with - // a regular bool. - - T operator=(T aVal) - { - Intrinsics::store(mValue, aVal); - return aVal; - } - - /** - * Performs an atomic swap operation. aVal is stored and the previous - * value of this variable is returned. - */ - T exchange(T aVal) - { - return Intrinsics::exchange(mValue, aVal); - } - - /** - * Performs an atomic compare-and-swap operation and returns true if it - * succeeded. This is equivalent to atomically doing - * - * if (mValue == aOldValue) { - * mValue = aNewValue; - * return true; - * } else { - * return false; - * } - */ - bool compareExchange(T aOldValue, T aNewValue) - { - return Intrinsics::compareExchange(mValue, aOldValue, aNewValue); - } - -private: - template - AtomicBase(const AtomicBase& aCopy) = delete; -}; - -template -class AtomicBaseIncDec : public AtomicBase -{ - typedef typename detail::AtomicBase Base; - -public: - constexpr AtomicBaseIncDec() : Base() {} - explicit constexpr AtomicBaseIncDec(T aInit) : Base(aInit) {} - - using Base::operator=; - - operator T() const { return Base::Intrinsics::load(Base::mValue); } - T operator++(int) { return Base::Intrinsics::inc(Base::mValue); } - T operator--(int) { return Base::Intrinsics::dec(Base::mValue); } - T operator++() { return Base::Intrinsics::inc(Base::mValue) + 1; } - T operator--() { return Base::Intrinsics::dec(Base::mValue) - 1; } - -private: - template - AtomicBaseIncDec(const AtomicBaseIncDec& aCopy) = delete; -}; - -} // namespace detail - -/** - * A wrapper for a type that enforces that all memory accesses are atomic. - * - * In general, where a variable |T foo| exists, |Atomic foo| can be used in - * its place. Implementations for integral and pointer types are provided - * below. - * - * Atomic accesses are sequentially consistent by default. You should - * use the default unless you are tall enough to ride the - * memory-ordering roller coaster (if you're not sure, you aren't) and - * you have a compelling reason to do otherwise. - * - * There is one exception to the case of atomic memory accesses: providing an - * initial value of the atomic value is not guaranteed to be atomic. This is a - * deliberate design choice that enables static atomic variables to be declared - * without introducing extra static constructors. - */ -template -class Atomic; - -/** - * Atomic implementation for integral types. - * - * In addition to atomic store and load operations, compound assignment and - * increment/decrement operators are implemented which perform the - * corresponding read-modify-write operation atomically. Finally, an atomic - * swap method is provided. - */ -template -class Atomic::value && - !IsSame::value>::Type> - : public detail::AtomicBaseIncDec -{ - typedef typename detail::AtomicBaseIncDec Base; - -public: - constexpr Atomic() : Base() {} - explicit constexpr Atomic(T aInit) : Base(aInit) {} - - using Base::operator=; - - T operator+=(T aDelta) - { - return Base::Intrinsics::add(Base::mValue, aDelta) + aDelta; - } - - T operator-=(T aDelta) - { - return Base::Intrinsics::sub(Base::mValue, aDelta) - aDelta; - } - - T operator|=(T aVal) - { - return Base::Intrinsics::or_(Base::mValue, aVal) | aVal; - } - - T operator^=(T aVal) - { - return Base::Intrinsics::xor_(Base::mValue, aVal) ^ aVal; - } - - T operator&=(T aVal) - { - return Base::Intrinsics::and_(Base::mValue, aVal) & aVal; - } - -private: - Atomic(Atomic& aOther) = delete; -}; - -/** - * Atomic implementation for pointer types. - * - * An atomic compare-and-swap primitive for pointer variables is provided, as - * are atomic increment and decement operators. Also provided are the compound - * assignment operators for addition and subtraction. Atomic swap (via - * exchange()) is included as well. - */ -template -class Atomic : public detail::AtomicBaseIncDec -{ - typedef typename detail::AtomicBaseIncDec Base; - -public: - constexpr Atomic() : Base() {} - explicit constexpr Atomic(T* aInit) : Base(aInit) {} - - using Base::operator=; - - T* operator+=(ptrdiff_t aDelta) - { - return Base::Intrinsics::add(Base::mValue, aDelta) + aDelta; - } - - T* operator-=(ptrdiff_t aDelta) - { - return Base::Intrinsics::sub(Base::mValue, aDelta) - aDelta; - } - -private: - Atomic(Atomic& aOther) = delete; -}; - -/** - * Atomic implementation for enum types. - * - * The atomic store and load operations and the atomic swap method is provided. - */ -template -class Atomic::value>::Type> - : public detail::AtomicBase -{ - typedef typename detail::AtomicBase Base; - -public: - constexpr Atomic() : Base() {} - explicit constexpr Atomic(T aInit) : Base(aInit) {} - - operator T() const { return T(Base::Intrinsics::load(Base::mValue)); } - - using Base::operator=; - -private: - Atomic(Atomic& aOther) = delete; -}; - -/** - * Atomic implementation for boolean types. - * - * The atomic store and load operations and the atomic swap method is provided. - * - * Note: - * - * - sizeof(Atomic) != sizeof(bool) for some implementations of - * bool and/or some implementations of std::atomic. This is allowed in - * [atomic.types.generic]p9. - * - * - It's not obvious whether the 8-bit atomic functions on Windows are always - * inlined or not. If they are not inlined, the corresponding functions in the - * runtime library are not available on Windows XP. This is why we implement - * Atomic with an underlying type of uint32_t. - */ -template -class Atomic - : protected detail::AtomicBase -{ - typedef typename detail::AtomicBase Base; - -public: - constexpr Atomic() : Base() {} - explicit constexpr Atomic(bool aInit) : Base(aInit) {} - - // We provide boolean wrappers for the underlying AtomicBase methods. - MOZ_IMPLICIT operator bool() const - { - return Base::Intrinsics::load(Base::mValue); - } - - bool operator=(bool aVal) - { - return Base::operator=(aVal); - } - - bool exchange(bool aVal) - { - return Base::exchange(aVal); - } - - bool compareExchange(bool aOldValue, bool aNewValue) - { - return Base::compareExchange(aOldValue, aNewValue); - } - -private: - Atomic(Atomic& aOther) = delete; -}; - -} // namespace mozilla - -#endif /* mozilla_Atomics_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Attributes.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Attributes.h deleted file mode 100644 index df6172f3..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Attributes.h +++ /dev/null @@ -1,604 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implementations of various class and method modifier attributes. */ - -#ifndef mozilla_Attributes_h -#define mozilla_Attributes_h - -#include "mozilla/Compiler.h" - -/* - * MOZ_ALWAYS_INLINE is a macro which expands to tell the compiler that the - * method decorated with it must be inlined, even if the compiler thinks - * otherwise. This is only a (much) stronger version of the inline hint: - * compilers are not guaranteed to respect it (although they're much more likely - * to do so). - * - * The MOZ_ALWAYS_INLINE_EVEN_DEBUG macro is yet stronger. It tells the - * compiler to inline even in DEBUG builds. It should be used very rarely. - */ -#if defined(_MSC_VER) -# define MOZ_ALWAYS_INLINE_EVEN_DEBUG __forceinline -#elif defined(__GNUC__) -# define MOZ_ALWAYS_INLINE_EVEN_DEBUG __attribute__((always_inline)) inline -#else -# define MOZ_ALWAYS_INLINE_EVEN_DEBUG inline -#endif - -#if !defined(DEBUG) -# define MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE_EVEN_DEBUG -#elif defined(_MSC_VER) && !defined(__cplusplus) -# define MOZ_ALWAYS_INLINE __inline -#else -# define MOZ_ALWAYS_INLINE inline -#endif - -#if defined(_MSC_VER) -/* - * g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality - * without warnings (functionality used by the macros below). These modes are - * detectable by checking whether __GXX_EXPERIMENTAL_CXX0X__ is defined or, more - * standardly, by checking whether __cplusplus has a C++11 or greater value. - * Current versions of g++ do not correctly set __cplusplus, so we check both - * for forward compatibility. - */ -# define MOZ_HAVE_NEVER_INLINE __declspec(noinline) -# define MOZ_HAVE_NORETURN __declspec(noreturn) -#elif defined(__clang__) - /* - * Per Clang documentation, "Note that marketing version numbers should not - * be used to check for language features, as different vendors use different - * numbering schemes. Instead, use the feature checking macros." - */ -# ifndef __has_extension -# define __has_extension __has_feature /* compatibility, for older versions of clang */ -# endif -# if __has_attribute(noinline) -# define MOZ_HAVE_NEVER_INLINE __attribute__((noinline)) -# endif -# if __has_attribute(noreturn) -# define MOZ_HAVE_NORETURN __attribute__((noreturn)) -# endif -#elif defined(__GNUC__) -# define MOZ_HAVE_NEVER_INLINE __attribute__((noinline)) -# define MOZ_HAVE_NORETURN __attribute__((noreturn)) -#endif - -/* - * When built with clang analyzer (a.k.a scan-build), define MOZ_HAVE_NORETURN - * to mark some false positives - */ -#ifdef __clang_analyzer__ -# if __has_extension(attribute_analyzer_noreturn) -# define MOZ_HAVE_ANALYZER_NORETURN __attribute__((analyzer_noreturn)) -# endif -#endif - -/* - * MOZ_NEVER_INLINE is a macro which expands to tell the compiler that the - * method decorated with it must never be inlined, even if the compiler would - * otherwise choose to inline the method. Compilers aren't absolutely - * guaranteed to support this, but most do. - */ -#if defined(MOZ_HAVE_NEVER_INLINE) -# define MOZ_NEVER_INLINE MOZ_HAVE_NEVER_INLINE -#else -# define MOZ_NEVER_INLINE /* no support */ -#endif - -/* - * MOZ_NORETURN, specified at the start of a function declaration, indicates - * that the given function does not return. (The function definition does not - * need to be annotated.) - * - * MOZ_NORETURN void abort(const char* msg); - * - * This modifier permits the compiler to optimize code assuming a call to such a - * function will never return. It also enables the compiler to avoid spurious - * warnings about not initializing variables, or about any other seemingly-dodgy - * operations performed after the function returns. - * - * This modifier does not affect the corresponding function's linking behavior. - */ -#if defined(MOZ_HAVE_NORETURN) -# define MOZ_NORETURN MOZ_HAVE_NORETURN -#else -# define MOZ_NORETURN /* no support */ -#endif - -/** - * MOZ_COLD tells the compiler that a function is "cold", meaning infrequently - * executed. This may lead it to optimize for size more aggressively than speed, - * or to allocate the body of the function in a distant part of the text segment - * to help keep it from taking up unnecessary icache when it isn't in use. - * - * Place this attribute at the very beginning of a function definition. For - * example, write - * - * MOZ_COLD int foo(); - * - * or - * - * MOZ_COLD int foo() { return 42; } - */ -#if defined(__GNUC__) || defined(__clang__) -# define MOZ_COLD __attribute__ ((cold)) -#else -# define MOZ_COLD -#endif - -/** - * MOZ_NONNULL tells the compiler that some of the arguments to a function are - * known to be non-null. The arguments are a list of 1-based argument indexes - * identifying arguments which are known to be non-null. - * - * Place this attribute at the very beginning of a function definition. For - * example, write - * - * MOZ_NONNULL(1, 2) int foo(char *p, char *q); - */ -#if defined(__GNUC__) || defined(__clang__) -# define MOZ_NONNULL(...) __attribute__ ((nonnull(__VA_ARGS__))) -#else -# define MOZ_NONNULL(...) -#endif - -/* - * MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS, specified at the end of a function - * declaration, indicates that for the purposes of static analysis, this - * function does not return. (The function definition does not need to be - * annotated.) - * - * MOZ_ReportCrash(const char* s, const char* file, int ln) - * MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS - * - * Some static analyzers, like scan-build from clang, can use this information - * to eliminate false positives. From the upstream documentation of scan-build: - * "This attribute is useful for annotating assertion handlers that actually - * can return, but for the purpose of using the analyzer we want to pretend - * that such functions do not return." - * - */ -#if defined(MOZ_HAVE_ANALYZER_NORETURN) -# define MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS MOZ_HAVE_ANALYZER_NORETURN -#else -# define MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS /* no support */ -#endif - -/* - * MOZ_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time - * instrumentation shipped with Clang and GCC) to not instrument the annotated - * function. Furthermore, it will prevent the compiler from inlining the - * function because inlining currently breaks the blacklisting mechanism of - * AddressSanitizer. - */ -#if defined(__has_feature) -# if __has_feature(address_sanitizer) -# define MOZ_HAVE_ASAN_BLACKLIST -# endif -#elif defined(__GNUC__) -# if defined(__SANITIZE_ADDRESS__) -# define MOZ_HAVE_ASAN_BLACKLIST -# endif -#endif - -#if defined(MOZ_HAVE_ASAN_BLACKLIST) -# define MOZ_ASAN_BLACKLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_address)) -#else -# define MOZ_ASAN_BLACKLIST /* nothing */ -#endif - -/* - * MOZ_TSAN_BLACKLIST is a macro to tell ThreadSanitizer (a compile-time - * instrumentation shipped with Clang) to not instrument the annotated function. - * Furthermore, it will prevent the compiler from inlining the function because - * inlining currently breaks the blacklisting mechanism of ThreadSanitizer. - */ -#if defined(__has_feature) -# if __has_feature(thread_sanitizer) -# define MOZ_TSAN_BLACKLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_thread)) -# else -# define MOZ_TSAN_BLACKLIST /* nothing */ -# endif -#else -# define MOZ_TSAN_BLACKLIST /* nothing */ -#endif - -/** - * MOZ_ALLOCATOR tells the compiler that the function it marks returns either a - * "fresh", "pointer-free" block of memory, or nullptr. "Fresh" means that the - * block is not pointed to by any other reachable pointer in the program. - * "Pointer-free" means that the block contains no pointers to any valid object - * in the program. It may be initialized with other (non-pointer) values. - * - * Placing this attribute on appropriate functions helps GCC analyze pointer - * aliasing more accurately in their callers. - * - * GCC warns if a caller ignores the value returned by a function marked with - * MOZ_ALLOCATOR: it is hard to imagine cases where dropping the value returned - * by a function that meets the criteria above would be intentional. - * - * Place this attribute after the argument list and 'this' qualifiers of a - * function definition. For example, write - * - * void *my_allocator(size_t) MOZ_ALLOCATOR; - * - * or - * - * void *my_allocator(size_t bytes) MOZ_ALLOCATOR { ... } - */ -#if defined(__GNUC__) || defined(__clang__) -# define MOZ_ALLOCATOR __attribute__ ((malloc, warn_unused_result)) -#else -# define MOZ_ALLOCATOR -#endif - -/** - * MOZ_MUST_USE tells the compiler to emit a warning if a function's - * return value is not used by the caller. - * - * Place this attribute at the very beginning of a function declaration. For - * example, write - * - * MOZ_MUST_USE int foo(); - * - * or - * - * MOZ_MUST_USE int foo() { return 42; } - */ -#if defined(__GNUC__) || defined(__clang__) -# define MOZ_MUST_USE __attribute__ ((warn_unused_result)) -#else -# define MOZ_MUST_USE -#endif - -/** - * MOZ_FALLTHROUGH is an annotation to suppress compiler warnings about switch - * cases that fall through without a break or return statement. MOZ_FALLTHROUGH - * is only needed on cases that have code. - * - * MOZ_FALLTHROUGH_ASSERT is an annotation to suppress compiler warnings about - * switch cases that MOZ_ASSERT(false) (or its alias MOZ_ASSERT_UNREACHABLE) in - * debug builds, but intentionally fall through in release builds. See comment - * in Assertions.h for more details. - * - * switch (foo) { - * case 1: // These cases have no code. No fallthrough annotations are needed. - * case 2: - * case 3: // This case has code, so a fallthrough annotation is needed! - * foo++; - * MOZ_FALLTHROUGH; - * case 4: - * return foo; - * - * default: - * // This case asserts in debug builds, falls through in release. - * MOZ_FALLTHROUGH_ASSERT("Unexpected foo value?!"); - * case 5: - * return 5; - * } - */ -#if defined(__clang__) && __cplusplus >= 201103L - /* clang's fallthrough annotations are only available starting in C++11. */ -# define MOZ_FALLTHROUGH [[clang::fallthrough]] -#elif defined(_MSC_VER) - /* - * MSVC's __fallthrough annotations are checked by /analyze (Code Analysis): - * https://msdn.microsoft.com/en-us/library/ms235402%28VS.80%29.aspx - */ -# include -# define MOZ_FALLTHROUGH __fallthrough -#else -# define MOZ_FALLTHROUGH /* FALLTHROUGH */ -#endif - -#ifdef __cplusplus - -/* - * The following macros are attributes that support the static analysis plugin - * included with Mozilla, and will be implemented (when such support is enabled) - * as C++11 attributes. Since such attributes are legal pretty much everywhere - * and have subtly different semantics depending on their placement, the - * following is a guide on where to place the attributes. - * - * Attributes that apply to a struct or class precede the name of the class: - * (Note that this is different from the placement of final for classes!) - * - * class MOZ_CLASS_ATTRIBUTE SomeClass {}; - * - * Attributes that apply to functions follow the parentheses and const - * qualifiers but precede final, override and the function body: - * - * void DeclaredFunction() MOZ_FUNCTION_ATTRIBUTE; - * void SomeFunction() MOZ_FUNCTION_ATTRIBUTE {} - * void PureFunction() const MOZ_FUNCTION_ATTRIBUTE = 0; - * void OverriddenFunction() MOZ_FUNCTION_ATTIRBUTE override; - * - * Attributes that apply to variables or parameters follow the variable's name: - * - * int variable MOZ_VARIABLE_ATTRIBUTE; - * - * Attributes that apply to types follow the type name: - * - * typedef int MOZ_TYPE_ATTRIBUTE MagicInt; - * int MOZ_TYPE_ATTRIBUTE someVariable; - * int* MOZ_TYPE_ATTRIBUTE magicPtrInt; - * int MOZ_TYPE_ATTRIBUTE* ptrToMagicInt; - * - * Attributes that apply to statements precede the statement: - * - * MOZ_IF_ATTRIBUTE if (x == 0) - * MOZ_DO_ATTRIBUTE do { } while (0); - * - * Attributes that apply to labels precede the label: - * - * MOZ_LABEL_ATTRIBUTE target: - * goto target; - * MOZ_CASE_ATTRIBUTE case 5: - * MOZ_DEFAULT_ATTRIBUTE default: - * - * The static analyses that are performed by the plugin are as follows: - * - * MOZ_MUST_OVERRIDE: Applies to all C++ member functions. All immediate - * subclasses must provide an exact override of this method; if a subclass - * does not override this method, the compiler will emit an error. This - * attribute is not limited to virtual methods, so if it is applied to a - * nonvirtual method and the subclass does not provide an equivalent - * definition, the compiler will emit an error. - * MOZ_STACK_CLASS: Applies to all classes. Any class with this annotation is - * expected to live on the stack, so it is a compile-time error to use it, or - * an array of such objects, as a global or static variable, or as the type of - * a new expression (unless placement new is being used). If a member of - * another class uses this class, or if another class inherits from this - * class, then it is considered to be a stack class as well, although this - * attribute need not be provided in such cases. - * MOZ_NONHEAP_CLASS: Applies to all classes. Any class with this annotation is - * expected to live on the stack or in static storage, so it is a compile-time - * error to use it, or an array of such objects, as the type of a new - * expression. If a member of another class uses this class, or if another - * class inherits from this class, then it is considered to be a non-heap class - * as well, although this attribute need not be provided in such cases. - * MOZ_HEAP_CLASS: Applies to all classes. Any class with this annotation is - * expected to live on the heap, so it is a compile-time error to use it, or - * an array of such objects, as the type of a variable declaration, or as a - * temporary object. If a member of another class uses this class, or if - * another class inherits from this class, then it is considered to be a heap - * class as well, although this attribute need not be provided in such cases. - * MOZ_NON_TEMPORARY_CLASS: Applies to all classes. Any class with this - * annotation is expected not to live in a temporary. If a member of another - * class uses this class or if another class inherits from this class, then it - * is considered to be a non-temporary class as well, although this attribute - * need not be provided in such cases. - * MOZ_RAII: Applies to all classes. Any class with this annotation is assumed - * to be a RAII guard, which is expected to live on the stack in an automatic - * allocation. It is prohibited from being allocated in a temporary, static - * storage, or on the heap. This is a combination of MOZ_STACK_CLASS and - * MOZ_NON_TEMPORARY_CLASS. - * MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS: Applies to all classes that are - * intended to prevent introducing static initializers. This attribute - * currently makes it a compile-time error to instantiate these classes - * anywhere other than at the global scope, or as a static member of a class. - * In non-debug mode, it also prohibits non-trivial constructors and - * destructors. - * MOZ_TRIVIAL_CTOR_DTOR: Applies to all classes that must have both a trivial - * or constexpr constructor and a trivial destructor. Setting this attribute - * on a class makes it a compile-time error for that class to get a - * non-trivial constructor or destructor for any reason. - * MOZ_HEAP_ALLOCATOR: Applies to any function. This indicates that the return - * value is allocated on the heap, and will as a result check such allocations - * during MOZ_STACK_CLASS and MOZ_NONHEAP_CLASS annotation checking. - * MOZ_IMPLICIT: Applies to constructors. Implicit conversion constructors - * are disallowed by default unless they are marked as MOZ_IMPLICIT. This - * attribute must be used for constructors which intend to provide implicit - * conversions. - * MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT: Applies to functions. Makes it a compile - * time error to pass arithmetic expressions on variables to the function. - * MOZ_OWNING_REF: Applies to declarations of pointers to reference counted - * types. This attribute tells the compiler that the raw pointer is a strong - * reference, where ownership through methods such as AddRef and Release is - * managed manually. This can make the compiler ignore these pointers when - * validating the usage of pointers otherwise. - * - * Example uses include owned pointers inside of unions, and pointers stored - * in POD types where a using a smart pointer class would make the object - * non-POD. - * MOZ_NON_OWNING_REF: Applies to declarations of pointers to reference counted - * types. This attribute tells the compiler that the raw pointer is a weak - * reference, which is ensured to be valid by a guarantee that the reference - * will be nulled before the pointer becomes invalid. This can make the compiler - * ignore these pointers when validating the usage of pointers otherwise. - * - * Examples include an mOwner pointer, which is nulled by the owning class's - * destructor, and is null-checked before dereferencing. - * MOZ_UNSAFE_REF: Applies to declarations of pointers to reference counted types. - * Occasionally there are non-owning references which are valid, but do not take - * the form of a MOZ_NON_OWNING_REF. Their safety may be dependent on the behaviour - * of API consumers. The string argument passed to this macro documents the safety - * conditions. This can make the compiler ignore these pointers when validating - * the usage of pointers elsewhere. - * - * Examples include an nsIAtom* member which is known at compile time to point to a - * static atom which is valid throughout the lifetime of the program, or an API which - * stores a pointer, but doesn't take ownership over it, instead requiring the API - * consumer to correctly null the value before it becomes invalid. - * - * Use of this annotation is discouraged when a strong reference or one of the above - * two annotations can be used instead. - * MOZ_NO_ADDREF_RELEASE_ON_RETURN: Applies to function declarations. Makes it - * a compile time error to call AddRef or Release on the return value of a - * function. This is intended to be used with operator->() of our smart - * pointer classes to ensure that the refcount of an object wrapped in a - * smart pointer is not manipulated directly. - * MOZ_MUST_USE_TYPE: Applies to type declarations. Makes it a compile time - * error to not use the return value of a function which has this type. This - * is intended to be used with types which it is an error to not use. - * MOZ_NEEDS_NO_VTABLE_TYPE: Applies to template class declarations. Makes it - * a compile time error to instantiate this template with a type parameter which - * has a VTable. - * MOZ_NON_MEMMOVABLE: Applies to class declarations for types that are not safe - * to be moved in memory using memmove(). - * MOZ_NEEDS_MEMMOVABLE_TYPE: Applies to template class declarations where the - * template arguments are required to be safe to move in memory using - * memmove(). Passing MOZ_NON_MEMMOVABLE types to these templates is a - * compile time error. - * MOZ_NEEDS_MEMMOVABLE_MEMBERS: Applies to class declarations where each member - * must be safe to move in memory using memmove(). MOZ_NON_MEMMOVABLE types - * used in members of these classes are compile time errors. - * MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS: Applies to template class - * declarations where an instance of the template should be considered, for - * static analysis purposes, to inherit any type annotations (such as - * MOZ_MUST_USE_TYPE and MOZ_STACK_CLASS) from its template arguments. - * MOZ_INIT_OUTSIDE_CTOR: Applies to class member declarations. Occasionally - * there are class members that are not initialized in the constructor, - * but logic elsewhere in the class ensures they are initialized prior to use. - * Using this attribute on a member disables the check that this member must be - * initialized in constructors via list-initialization, in the constructor body, - * or via functions called from the constructor body. - * MOZ_IS_CLASS_INIT: Applies to class method declarations. Occasionally the - * constructor doesn't initialize all of the member variables and another function - * is used to initialize the rest. This marker is used to make the static analysis - * tool aware that the marked function is part of the initialization process - * and to include the marked function in the scan mechanism that determines witch - * member variables still remain uninitialized. - * MOZ_NON_PARAM: Applies to types. Makes it compile time error to use the type - * in parameter without pointer or reference. - * MOZ_NON_AUTOABLE: Applies to class declarations. Makes it a compile time error to - * use `auto` in place of this type in variable declarations. This is intended to - * be used with types which are intended to be implicitly constructed into other - * other types before being assigned to variables. - * MOZ_REQUIRED_BASE_METHOD: Applies to virtual class method declarations. - * Sometimes derived classes override methods that need to be called by their - * overridden counterparts. This marker indicates that the marked method must - * be called by the method that it overrides. - */ -#ifdef MOZ_CLANG_PLUGIN -# define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override"))) -# define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class"))) -# define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class"))) -# define MOZ_HEAP_CLASS __attribute__((annotate("moz_heap_class"))) -# define MOZ_NON_TEMPORARY_CLASS __attribute__((annotate("moz_non_temporary_class"))) -# define MOZ_TRIVIAL_CTOR_DTOR __attribute__((annotate("moz_trivial_ctor_dtor"))) -# ifdef DEBUG - /* in debug builds, these classes do have non-trivial constructors. */ -# define MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS __attribute__((annotate("moz_global_class"))) -# else -# define MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS __attribute__((annotate("moz_global_class"))) \ - MOZ_TRIVIAL_CTOR_DTOR -# endif -# define MOZ_IMPLICIT __attribute__((annotate("moz_implicit"))) -# define MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT __attribute__((annotate("moz_no_arith_expr_in_arg"))) -# define MOZ_OWNING_REF __attribute__((annotate("moz_strong_ref"))) -# define MOZ_NON_OWNING_REF __attribute__((annotate("moz_weak_ref"))) -# define MOZ_UNSAFE_REF(reason) __attribute__((annotate("moz_weak_ref"))) -# define MOZ_NO_ADDREF_RELEASE_ON_RETURN __attribute__((annotate("moz_no_addref_release_on_return"))) -# define MOZ_MUST_USE_TYPE __attribute__((annotate("moz_must_use_type"))) -# define MOZ_NEEDS_NO_VTABLE_TYPE __attribute__((annotate("moz_needs_no_vtable_type"))) -# define MOZ_NON_MEMMOVABLE __attribute__((annotate("moz_non_memmovable"))) -# define MOZ_NEEDS_MEMMOVABLE_TYPE __attribute__((annotate("moz_needs_memmovable_type"))) -# define MOZ_NEEDS_MEMMOVABLE_MEMBERS __attribute__((annotate("moz_needs_memmovable_members"))) -# define MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS \ - __attribute__((annotate("moz_inherit_type_annotations_from_template_args"))) -# define MOZ_NON_AUTOABLE __attribute__((annotate("moz_non_autoable"))) -# define MOZ_INIT_OUTSIDE_CTOR \ - __attribute__((annotate("moz_ignore_ctor_initialization"))) -# define MOZ_IS_CLASS_INIT \ - __attribute__((annotate("moz_is_class_init"))) -# define MOZ_NON_PARAM \ - __attribute__((annotate("moz_non_param"))) -# define MOZ_REQUIRED_BASE_METHOD \ - __attribute__((annotate("moz_required_base_method"))) -/* - * It turns out that clang doesn't like void func() __attribute__ {} without a - * warning, so use pragmas to disable the warning. This code won't work on GCC - * anyways, so the warning is safe to ignore. - */ -# define MOZ_HEAP_ALLOCATOR \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((annotate("moz_heap_allocator"))) \ - _Pragma("clang diagnostic pop") -#else -# define MOZ_MUST_OVERRIDE /* nothing */ -# define MOZ_STACK_CLASS /* nothing */ -# define MOZ_NONHEAP_CLASS /* nothing */ -# define MOZ_HEAP_CLASS /* nothing */ -# define MOZ_NON_TEMPORARY_CLASS /* nothing */ -# define MOZ_TRIVIAL_CTOR_DTOR /* nothing */ -# define MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS /* nothing */ -# define MOZ_IMPLICIT /* nothing */ -# define MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT /* nothing */ -# define MOZ_HEAP_ALLOCATOR /* nothing */ -# define MOZ_OWNING_REF /* nothing */ -# define MOZ_NON_OWNING_REF /* nothing */ -# define MOZ_UNSAFE_REF(reason) /* nothing */ -# define MOZ_NO_ADDREF_RELEASE_ON_RETURN /* nothing */ -# define MOZ_MUST_USE_TYPE /* nothing */ -# define MOZ_NEEDS_NO_VTABLE_TYPE /* nothing */ -# define MOZ_NON_MEMMOVABLE /* nothing */ -# define MOZ_NEEDS_MEMMOVABLE_TYPE /* nothing */ -# define MOZ_NEEDS_MEMMOVABLE_MEMBERS /* nothing */ -# define MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS /* nothing */ -# define MOZ_INIT_OUTSIDE_CTOR /* nothing */ -# define MOZ_IS_CLASS_INIT /* nothing */ -# define MOZ_NON_PARAM /* nothing */ -# define MOZ_NON_AUTOABLE /* nothing */ -# define MOZ_REQUIRED_BASE_METHOD /* nothing */ -#endif /* MOZ_CLANG_PLUGIN */ - -#define MOZ_RAII MOZ_NON_TEMPORARY_CLASS MOZ_STACK_CLASS - -/* - * MOZ_HAVE_REF_QUALIFIERS is defined for compilers that support C++11's rvalue - * qualifier, "&&". - */ -#if defined(_MSC_VER) && _MSC_VER >= 1900 -# define MOZ_HAVE_REF_QUALIFIERS -#elif defined(__clang__) -// All supported Clang versions -# define MOZ_HAVE_REF_QUALIFIERS -#elif defined(__GNUC__) -# include "mozilla/Compiler.h" -# if MOZ_GCC_VERSION_AT_LEAST(4, 8, 1) -# define MOZ_HAVE_REF_QUALIFIERS -# endif -#endif - -#endif /* __cplusplus */ - -/** - * Printf style formats. MOZ_FORMAT_PRINTF can be used to annotate a - * function or method that is "printf-like"; this will let (some) - * compilers check that the arguments match the template string. - * - * This macro takes two arguments. The first argument is the argument - * number of the template string. The second argument is the argument - * number of the '...' argument holding the arguments. - * - * Argument numbers start at 1. Note that the implicit "this" - * argument of a non-static member function counts as an argument. - * - * So, for a simple case like: - * void print_something (int whatever, const char *fmt, ...); - * The corresponding annotation would be - * MOZ_FORMAT_PRINTF(2, 3) - * However, if "print_something" were a non-static member function, - * then the annotation would be: - * MOZ_FORMAT_PRINTF(3, 4) - * - * Note that the checking is limited to standards-conforming - * printf-likes, and in particular this should not be used for - * PR_snprintf and friends, which are "printf-like" but which assign - * different meanings to the various formats. - */ -#ifdef __GNUC__ -#define MOZ_FORMAT_PRINTF(stringIndex, firstToCheck) \ - __attribute__ ((format (printf, stringIndex, firstToCheck))) -#else -#define MOZ_FORMAT_PRINTF(stringIndex, firstToCheck) -#endif - -#endif /* mozilla_Attributes_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/BinarySearch.h b/android/armeabi-v7a/include/spidermonkey/mozilla/BinarySearch.h deleted file mode 100644 index 1bbe0566..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/BinarySearch.h +++ /dev/null @@ -1,139 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_BinarySearch_h -#define mozilla_BinarySearch_h - -#include "mozilla/Assertions.h" - -#include - -namespace mozilla { - -/* - * The BinarySearch() algorithm searches the given container |aContainer| over - * the sorted index range [aBegin, aEnd) for an index |i| where - * |aContainer[i] == aTarget|. - * If such an index |i| is found, BinarySearch returns |true| and the index is - * returned via the outparam |aMatchOrInsertionPoint|. If no index is found, - * BinarySearch returns |false| and the outparam returns the first index in - * [aBegin, aEnd] where |aTarget| can be inserted to maintain sorted order. - * - * Example: - * - * Vector sortedInts = ... - * - * size_t match; - * if (BinarySearch(sortedInts, 0, sortedInts.length(), 13, &match)) { - * printf("found 13 at %lu\n", match); - * } - * - * The BinarySearchIf() version behaves similarly, but takes |aComparator|, a - * functor to compare the values with, instead of a value to find. - * That functor should take one argument - the value to compare - and return an - * |int| with the comparison result: - * - * * 0, if the argument is equal to, - * * less than 0, if the argument is greater than, - * * greater than 0, if the argument is less than - * - * the value. - * - * Example: - * - * struct Comparator { - * int operator()(int aVal) const { - * if (mTarget < aVal) { return -1; } - * if (mTarget > aVal) { return 1; } - * return 0; - * } - * explicit Comparator(int aTarget) : mTarget(aTarget) {} - * const int mTarget; - * }; - * - * Vector sortedInts = ... - * - * size_t match; - * if (BinarySearchIf(sortedInts, 0, sortedInts.length(), Comparator(13), &match)) { - * printf("found 13 at %lu\n", match); - * } - * - */ - -template -bool -BinarySearchIf(const Container& aContainer, size_t aBegin, size_t aEnd, - const Comparator& aCompare, size_t* aMatchOrInsertionPoint) -{ - MOZ_ASSERT(aBegin <= aEnd); - - size_t low = aBegin; - size_t high = aEnd; - while (high != low) { - size_t middle = low + (high - low) / 2; - - // Allow any intermediate type so long as it provides a suitable ordering - // relation. - const int result = aCompare(aContainer[middle]); - - if (result == 0) { - *aMatchOrInsertionPoint = middle; - return true; - } - - if (result < 0) { - high = middle; - } else { - low = middle + 1; - } - } - - *aMatchOrInsertionPoint = low; - return false; -} - -namespace detail { - -template -class BinarySearchDefaultComparator -{ -public: - explicit BinarySearchDefaultComparator(const T& aTarget) - : mTarget(aTarget) - {} - - template - int operator()(const U& aVal) const { - if (mTarget == aVal) { - return 0; - } - - if (mTarget < aVal) { - return -1; - } - - return 1; - } - -private: - const T& mTarget; -}; - -} // namespace detail - -template -bool -BinarySearch(const Container& aContainer, size_t aBegin, size_t aEnd, - T aTarget, size_t* aMatchOrInsertionPoint) -{ - return BinarySearchIf(aContainer, aBegin, aEnd, - detail::BinarySearchDefaultComparator(aTarget), - aMatchOrInsertionPoint); -} - -} // namespace mozilla - -#endif // mozilla_BinarySearch_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/BloomFilter.h b/android/armeabi-v7a/include/spidermonkey/mozilla/BloomFilter.h deleted file mode 100644 index 6757e411..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/BloomFilter.h +++ /dev/null @@ -1,256 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * A counting Bloom filter implementation. This allows consumers to - * do fast probabilistic "is item X in set Y?" testing which will - * never answer "no" when the correct answer is "yes" (but might - * incorrectly answer "yes" when the correct answer is "no"). - */ - -#ifndef mozilla_BloomFilter_h -#define mozilla_BloomFilter_h - -#include "mozilla/Assertions.h" -#include "mozilla/Likely.h" - -#include -#include - -namespace mozilla { - -/* - * This class implements a counting Bloom filter as described at - * , with - * 8-bit counters. This allows quick probabilistic answers to the - * question "is object X in set Y?" where the contents of Y might not - * be time-invariant. The probabilistic nature of the test means that - * sometimes the answer will be "yes" when it should be "no". If the - * answer is "no", then X is guaranteed not to be in Y. - * - * The filter is parametrized on KeySize, which is the size of the key - * generated by each of hash functions used by the filter, in bits, - * and the type of object T being added and removed. T must implement - * a |uint32_t hash() const| method which returns a uint32_t hash key - * that will be used to generate the two separate hash functions for - * the Bloom filter. This hash key MUST be well-distributed for good - * results! KeySize is not allowed to be larger than 16. - * - * The filter uses exactly 2**KeySize bytes of memory. From now on we - * will refer to the memory used by the filter as M. - * - * The expected rate of incorrect "yes" answers depends on M and on - * the number N of objects in set Y. As long as N is small compared - * to M, the rate of such answers is expected to be approximately - * 4*(N/M)**2 for this filter. In practice, if Y has a few hundred - * elements then using a KeySize of 12 gives a reasonably low - * incorrect answer rate. A KeySize of 12 has the additional benefit - * of using exactly one page for the filter in typical hardware - * configurations. - */ - -template -class BloomFilter -{ - /* - * A counting Bloom filter with 8-bit counters. For now we assume - * that having two hash functions is enough, but we may revisit that - * decision later. - * - * The filter uses an array with 2**KeySize entries. - * - * Assuming a well-distributed hash function, a Bloom filter with - * array size M containing N elements and - * using k hash function has expected false positive rate exactly - * - * $ (1 - (1 - 1/M)^{kN})^k $ - * - * because each array slot has a - * - * $ (1 - 1/M)^{kN} $ - * - * chance of being 0, and the expected false positive rate is the - * probability that all of the k hash functions will hit a nonzero - * slot. - * - * For reasonable assumptions (M large, kN large, which should both - * hold if we're worried about false positives) about M and kN this - * becomes approximately - * - * $$ (1 - \exp(-kN/M))^k $$ - * - * For our special case of k == 2, that's $(1 - \exp(-2N/M))^2$, - * or in other words - * - * $$ N/M = -0.5 * \ln(1 - \sqrt(r)) $$ - * - * where r is the false positive rate. This can be used to compute - * the desired KeySize for a given load N and false positive rate r. - * - * If N/M is assumed small, then the false positive rate can - * further be approximated as 4*N^2/M^2. So increasing KeySize by - * 1, which doubles M, reduces the false positive rate by about a - * factor of 4, and a false positive rate of 1% corresponds to - * about M/N == 20. - * - * What this means in practice is that for a few hundred keys using a - * KeySize of 12 gives false positive rates on the order of 0.25-4%. - * - * Similarly, using a KeySize of 10 would lead to a 4% false - * positive rate for N == 100 and to quite bad false positive - * rates for larger N. - */ -public: - BloomFilter() - { - static_assert(KeySize <= kKeyShift, "KeySize too big"); - - // Should we have a custom operator new using calloc instead and - // require that we're allocated via the operator? - clear(); - } - - /* - * Clear the filter. This should be done before reusing it, because - * just removing all items doesn't clear counters that hit the upper - * bound. - */ - void clear(); - - /* - * Add an item to the filter. - */ - void add(const T* aValue); - - /* - * Remove an item from the filter. - */ - void remove(const T* aValue); - - /* - * Check whether the filter might contain an item. This can - * sometimes return true even if the item is not in the filter, - * but will never return false for items that are actually in the - * filter. - */ - bool mightContain(const T* aValue) const; - - /* - * Methods for add/remove/contain when we already have a hash computed - */ - void add(uint32_t aHash); - void remove(uint32_t aHash); - bool mightContain(uint32_t aHash) const; - -private: - static const size_t kArraySize = (1 << KeySize); - static const uint32_t kKeyMask = (1 << KeySize) - 1; - static const uint32_t kKeyShift = 16; - - static uint32_t hash1(uint32_t aHash) - { - return aHash & kKeyMask; - } - static uint32_t hash2(uint32_t aHash) - { - return (aHash >> kKeyShift) & kKeyMask; - } - - uint8_t& firstSlot(uint32_t aHash) - { - return mCounters[hash1(aHash)]; - } - uint8_t& secondSlot(uint32_t aHash) - { - return mCounters[hash2(aHash)]; - } - - const uint8_t& firstSlot(uint32_t aHash) const - { - return mCounters[hash1(aHash)]; - } - const uint8_t& secondSlot(uint32_t aHash) const - { - return mCounters[hash2(aHash)]; - } - - static bool full(const uint8_t& aSlot) { return aSlot == UINT8_MAX; } - - uint8_t mCounters[kArraySize]; -}; - -template -inline void -BloomFilter::clear() -{ - memset(mCounters, 0, kArraySize); -} - -template -inline void -BloomFilter::add(uint32_t aHash) -{ - uint8_t& slot1 = firstSlot(aHash); - if (MOZ_LIKELY(!full(slot1))) { - ++slot1; - } - uint8_t& slot2 = secondSlot(aHash); - if (MOZ_LIKELY(!full(slot2))) { - ++slot2; - } -} - -template -MOZ_ALWAYS_INLINE void -BloomFilter::add(const T* aValue) -{ - uint32_t hash = aValue->hash(); - return add(hash); -} - -template -inline void -BloomFilter::remove(uint32_t aHash) -{ - // If the slots are full, we don't know whether we bumped them to be - // there when we added or not, so just leave them full. - uint8_t& slot1 = firstSlot(aHash); - if (MOZ_LIKELY(!full(slot1))) { - --slot1; - } - uint8_t& slot2 = secondSlot(aHash); - if (MOZ_LIKELY(!full(slot2))) { - --slot2; - } -} - -template -MOZ_ALWAYS_INLINE void -BloomFilter::remove(const T* aValue) -{ - uint32_t hash = aValue->hash(); - remove(hash); -} - -template -MOZ_ALWAYS_INLINE bool -BloomFilter::mightContain(uint32_t aHash) const -{ - // Check that all the slots for this hash contain something - return firstSlot(aHash) && secondSlot(aHash); -} - -template -MOZ_ALWAYS_INLINE bool -BloomFilter::mightContain(const T* aValue) const -{ - uint32_t hash = aValue->hash(); - return mightContain(hash); -} - -} // namespace mozilla - -#endif /* mozilla_BloomFilter_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/BufferList.h b/android/armeabi-v7a/include/spidermonkey/mozilla/BufferList.h deleted file mode 100644 index 42aea12d..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/BufferList.h +++ /dev/null @@ -1,517 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_BufferList_h -#define mozilla_BufferList_h - -#include -#include "mozilla/AllocPolicy.h" -#include "mozilla/Move.h" -#include "mozilla/ScopeExit.h" -#include "mozilla/Types.h" -#include "mozilla/TypeTraits.h" -#include "mozilla/Vector.h" -#include - -// BufferList represents a sequence of buffers of data. A BufferList can choose -// to own its buffers or not. The class handles writing to the buffers, -// iterating over them, and reading data out. Unlike SegmentedVector, the -// buffers may be of unequal size. Like SegmentedVector, BufferList is a nice -// way to avoid large contiguous allocations (which can trigger OOMs). - -namespace mozilla { - -template -class BufferList : private AllocPolicy -{ - // Each buffer in a BufferList has a size and a capacity. The first mSize - // bytes are initialized and the remaining |mCapacity - mSize| bytes are free. - struct Segment - { - char* mData; - size_t mSize; - size_t mCapacity; - - Segment(char* aData, size_t aSize, size_t aCapacity) - : mData(aData), - mSize(aSize), - mCapacity(aCapacity) - { - } - - Segment(const Segment&) = delete; - Segment& operator=(const Segment&) = delete; - - Segment(Segment&&) = default; - Segment& operator=(Segment&&) = default; - - char* Start() const { return mData; } - char* End() const { return mData + mSize; } - }; - - template - friend class BufferList; - - public: - // For the convenience of callers, all segments are required to be a multiple - // of 8 bytes in capacity. Also, every buffer except the last one is required - // to be full (i.e., size == capacity). Therefore, a byte at offset N within - // the BufferList and stored in memory at an address A will satisfy - // (N % Align == A % Align) if Align == 2, 4, or 8. - static const size_t kSegmentAlignment = 8; - - // Allocate a BufferList. The BufferList will free all its buffers when it is - // destroyed. An initial buffer of size aInitialSize and capacity - // aInitialCapacity is allocated automatically. This data will be contiguous - // an can be accessed via |Start()|. Subsequent buffers will be allocated with - // capacity aStandardCapacity. - BufferList(size_t aInitialSize, - size_t aInitialCapacity, - size_t aStandardCapacity, - AllocPolicy aAP = AllocPolicy()) - : AllocPolicy(aAP), - mOwning(true), - mSegments(aAP), - mSize(0), - mStandardCapacity(aStandardCapacity) - { - MOZ_ASSERT(aInitialCapacity % kSegmentAlignment == 0); - MOZ_ASSERT(aStandardCapacity % kSegmentAlignment == 0); - - if (aInitialCapacity) { - AllocateSegment(aInitialSize, aInitialCapacity); - } - } - - BufferList(const BufferList& aOther) = delete; - - BufferList(BufferList&& aOther) - : mOwning(aOther.mOwning), - mSegments(Move(aOther.mSegments)), - mSize(aOther.mSize), - mStandardCapacity(aOther.mStandardCapacity) - { - aOther.mSegments.clear(); - aOther.mSize = 0; - } - - BufferList& operator=(const BufferList& aOther) = delete; - - BufferList& operator=(BufferList&& aOther) - { - Clear(); - - mOwning = aOther.mOwning; - mSegments = Move(aOther.mSegments); - mSize = aOther.mSize; - aOther.mSegments.clear(); - aOther.mSize = 0; - return *this; - } - - ~BufferList() { Clear(); } - - // Returns the sum of the sizes of all the buffers. - size_t Size() const { return mSize; } - - void Clear() - { - if (mOwning) { - for (Segment& segment : mSegments) { - this->free_(segment.mData); - } - } - mSegments.clear(); - - mSize = 0; - } - - // Iterates over bytes in the segments. You can advance it by as many bytes as - // you choose. - class IterImpl - { - // Invariants: - // (0) mSegment <= bufferList.mSegments.size() - // (1) mData <= mDataEnd - // (2) If mSegment is not the last segment, mData < mDataEnd - uintptr_t mSegment; - char* mData; - char* mDataEnd; - - friend class BufferList; - - public: - explicit IterImpl(const BufferList& aBuffers) - : mSegment(0), - mData(nullptr), - mDataEnd(nullptr) - { - if (!aBuffers.mSegments.empty()) { - mData = aBuffers.mSegments[0].Start(); - mDataEnd = aBuffers.mSegments[0].End(); - } - } - - // Returns a pointer to the raw data. It is valid to access up to - // RemainingInSegment bytes of this buffer. - char* Data() const - { - MOZ_RELEASE_ASSERT(!Done()); - return mData; - } - - // Returns true if the memory in the range [Data(), Data() + aBytes) is all - // part of one contiguous buffer. - bool HasRoomFor(size_t aBytes) const - { - MOZ_RELEASE_ASSERT(mData <= mDataEnd); - return size_t(mDataEnd - mData) >= aBytes; - } - - // Returns the maximum value aBytes for which HasRoomFor(aBytes) will be - // true. - size_t RemainingInSegment() const - { - MOZ_RELEASE_ASSERT(mData <= mDataEnd); - return mDataEnd - mData; - } - - // Advances the iterator by aBytes bytes. aBytes must be less than - // RemainingInSegment(). If advancing by aBytes takes the iterator to the - // end of a buffer, it will be moved to the beginning of the next buffer - // unless it is the last buffer. - void Advance(const BufferList& aBuffers, size_t aBytes) - { - const Segment& segment = aBuffers.mSegments[mSegment]; - MOZ_RELEASE_ASSERT(segment.Start() <= mData); - MOZ_RELEASE_ASSERT(mData <= mDataEnd); - MOZ_RELEASE_ASSERT(mDataEnd == segment.End()); - - MOZ_RELEASE_ASSERT(HasRoomFor(aBytes)); - mData += aBytes; - - if (mData == mDataEnd && mSegment + 1 < aBuffers.mSegments.length()) { - mSegment++; - const Segment& nextSegment = aBuffers.mSegments[mSegment]; - mData = nextSegment.Start(); - mDataEnd = nextSegment.End(); - MOZ_RELEASE_ASSERT(mData < mDataEnd); - } - } - - // Advance the iterator by aBytes, possibly crossing segments. This function - // returns false if it runs out of buffers to advance through. Otherwise it - // returns true. - bool AdvanceAcrossSegments(const BufferList& aBuffers, size_t aBytes) - { - size_t bytes = aBytes; - while (bytes) { - size_t toAdvance = std::min(bytes, RemainingInSegment()); - if (!toAdvance) { - return false; - } - Advance(aBuffers, toAdvance); - bytes -= toAdvance; - } - return true; - } - - // Returns true when the iterator reaches the end of the BufferList. - bool Done() const - { - return mData == mDataEnd; - } - - private: - - // Count the bytes we would need to advance in order to reach aTarget. - size_t BytesUntil(const BufferList& aBuffers, const IterImpl& aTarget) const { - size_t offset = 0; - - MOZ_ASSERT(aTarget.IsIn(aBuffers)); - - char* data = mData; - for (uintptr_t segment = mSegment; segment < aTarget.mSegment; segment++) { - offset += aBuffers.mSegments[segment].End() - data; - data = aBuffers.mSegments[segment].mData; - } - - MOZ_RELEASE_ASSERT(IsIn(aBuffers)); - MOZ_RELEASE_ASSERT(aTarget.mData >= data); - - offset += aTarget.mData - data; - return offset; - } - - bool IsIn(const BufferList& aBuffers) const { - return mSegment < aBuffers.mSegments.length() && - mData >= aBuffers.mSegments[mSegment].mData && - mData < aBuffers.mSegments[mSegment].End(); - } - }; - - // Special convenience method that returns Iter().Data(). - char* Start() { return mSegments[0].mData; } - const char* Start() const { return mSegments[0].mData; } - - IterImpl Iter() const { return IterImpl(*this); } - - // Copies aSize bytes from aData into the BufferList. The storage for these - // bytes may be split across multiple buffers. Size() is increased by aSize. - inline bool WriteBytes(const char* aData, size_t aSize); - - // Copies possibly non-contiguous byte range starting at aIter into - // aData. aIter is advanced by aSize bytes. Returns false if it runs out of - // data before aSize. - inline bool ReadBytes(IterImpl& aIter, char* aData, size_t aSize) const; - - // Return a new BufferList that shares storage with this BufferList. The new - // BufferList is read-only. It allows iteration over aSize bytes starting at - // aIter. Borrow can fail, in which case *aSuccess will be false upon - // return. The borrowed BufferList can use a different AllocPolicy than the - // original one. However, it is not responsible for freeing buffers, so the - // AllocPolicy is only used for the buffer vector. - template - BufferList Borrow(IterImpl& aIter, size_t aSize, bool* aSuccess, - BorrowingAllocPolicy aAP = BorrowingAllocPolicy()) const; - - // Return a new BufferList and move storage from this BufferList to it. The - // new BufferList owns the buffers. Move can fail, in which case *aSuccess - // will be false upon return. The new BufferList can use a different - // AllocPolicy than the original one. The new OtherAllocPolicy is responsible - // for freeing buffers, so the OtherAllocPolicy must use freeing method - // compatible to the original one. - template - BufferList MoveFallible(bool* aSuccess, OtherAllocPolicy aAP = OtherAllocPolicy()); - - // Return a new BufferList that adopts the byte range starting at Iter so that - // range [aIter, aIter + aSize) is transplanted to the returned BufferList. - // Contents of the buffer before aIter + aSize is left undefined. - // Extract can fail, in which case *aSuccess will be false upon return. The - // moved buffers are erased from the original BufferList. In case of extract - // fails, the original BufferList is intact. All other iterators except aIter - // are invalidated. - // This method requires aIter and aSize to be 8-byte aligned. - BufferList Extract(IterImpl& aIter, size_t aSize, bool* aSuccess); - - // Return the number of bytes from 'start' to 'end', two iterators within - // this BufferList. - size_t RangeLength(const IterImpl& start, const IterImpl& end) const { - MOZ_ASSERT(start.IsIn(*this) && end.IsIn(*this)); - return start.BytesUntil(*this, end); - } - -private: - explicit BufferList(AllocPolicy aAP) - : AllocPolicy(aAP), - mOwning(false), - mSize(0), - mStandardCapacity(0) - { - } - - void* AllocateSegment(size_t aSize, size_t aCapacity) - { - MOZ_RELEASE_ASSERT(mOwning); - - char* data = this->template pod_malloc(aCapacity); - if (!data) { - return nullptr; - } - if (!mSegments.append(Segment(data, aSize, aCapacity))) { - this->free_(data); - return nullptr; - } - mSize += aSize; - return data; - } - - bool mOwning; - Vector mSegments; - size_t mSize; - size_t mStandardCapacity; -}; - -template -bool -BufferList::WriteBytes(const char* aData, size_t aSize) -{ - MOZ_RELEASE_ASSERT(mOwning); - MOZ_RELEASE_ASSERT(mStandardCapacity); - - size_t copied = 0; - size_t remaining = aSize; - - if (!mSegments.empty()) { - Segment& lastSegment = mSegments.back(); - - size_t toCopy = std::min(aSize, lastSegment.mCapacity - lastSegment.mSize); - memcpy(lastSegment.mData + lastSegment.mSize, aData, toCopy); - lastSegment.mSize += toCopy; - mSize += toCopy; - - copied += toCopy; - remaining -= toCopy; - } - - while (remaining) { - size_t toCopy = std::min(remaining, mStandardCapacity); - - void* data = AllocateSegment(toCopy, mStandardCapacity); - if (!data) { - return false; - } - memcpy(data, aData + copied, toCopy); - - copied += toCopy; - remaining -= toCopy; - } - - return true; -} - -template -bool -BufferList::ReadBytes(IterImpl& aIter, char* aData, size_t aSize) const -{ - size_t copied = 0; - size_t remaining = aSize; - while (remaining) { - size_t toCopy = std::min(aIter.RemainingInSegment(), remaining); - if (!toCopy) { - // We've run out of data in the last segment. - return false; - } - memcpy(aData + copied, aIter.Data(), toCopy); - copied += toCopy; - remaining -= toCopy; - - aIter.Advance(*this, toCopy); - } - - return true; -} - -template template -BufferList -BufferList::Borrow(IterImpl& aIter, size_t aSize, bool* aSuccess, - BorrowingAllocPolicy aAP) const -{ - BufferList result(aAP); - - size_t size = aSize; - while (size) { - size_t toAdvance = std::min(size, aIter.RemainingInSegment()); - - if (!toAdvance || !result.mSegments.append(typename BufferList::Segment(aIter.mData, toAdvance, toAdvance))) { - *aSuccess = false; - return result; - } - aIter.Advance(*this, toAdvance); - size -= toAdvance; - } - - result.mSize = aSize; - *aSuccess = true; - return result; -} - -template template -BufferList -BufferList::MoveFallible(bool* aSuccess, OtherAllocPolicy aAP) -{ - BufferList result(0, 0, mStandardCapacity, aAP); - - IterImpl iter = Iter(); - while (!iter.Done()) { - size_t toAdvance = iter.RemainingInSegment(); - - if (!toAdvance || !result.mSegments.append(typename BufferList::Segment(iter.mData, toAdvance, toAdvance))) { - *aSuccess = false; - result.mSegments.clear(); - return result; - } - iter.Advance(*this, toAdvance); - } - - result.mSize = mSize; - mSegments.clear(); - mSize = 0; - *aSuccess = true; - return result; -} - -template -BufferList -BufferList::Extract(IterImpl& aIter, size_t aSize, bool* aSuccess) -{ - MOZ_RELEASE_ASSERT(aSize); - MOZ_RELEASE_ASSERT(mOwning); - MOZ_ASSERT(aSize % kSegmentAlignment == 0); - MOZ_ASSERT(intptr_t(aIter.mData) % kSegmentAlignment == 0); - - IterImpl iter = aIter; - size_t size = aSize; - size_t toCopy = std::min(size, aIter.RemainingInSegment()); - MOZ_ASSERT(toCopy % kSegmentAlignment == 0); - - BufferList result(0, toCopy, mStandardCapacity); - BufferList error(0, 0, mStandardCapacity); - - // Copy the head - if (!result.WriteBytes(aIter.mData, toCopy)) { - *aSuccess = false; - return error; - } - iter.Advance(*this, toCopy); - size -= toCopy; - - // Move segments to result - auto resultGuard = MakeScopeExit([&] { - *aSuccess = false; - result.mSegments.erase(result.mSegments.begin()+1, result.mSegments.end()); - }); - - size_t movedSize = 0; - uintptr_t toRemoveStart = iter.mSegment; - uintptr_t toRemoveEnd = iter.mSegment; - while (!iter.Done() && - !iter.HasRoomFor(size)) { - if (!result.mSegments.append(Segment(mSegments[iter.mSegment].mData, - mSegments[iter.mSegment].mSize, - mSegments[iter.mSegment].mCapacity))) { - return error; - } - movedSize += iter.RemainingInSegment(); - size -= iter.RemainingInSegment(); - toRemoveEnd++; - iter.Advance(*this, iter.RemainingInSegment()); - } - - if (size) { - if (!iter.HasRoomFor(size) || - !result.WriteBytes(iter.Data(), size)) { - return error; - } - iter.Advance(*this, size); - } - - mSegments.erase(mSegments.begin() + toRemoveStart, mSegments.begin() + toRemoveEnd); - mSize -= movedSize; - aIter.mSegment = iter.mSegment - (toRemoveEnd - toRemoveStart); - aIter.mData = iter.mData; - aIter.mDataEnd = iter.mDataEnd; - MOZ_ASSERT(aIter.mDataEnd == mSegments[aIter.mSegment].End()); - result.mSize = aSize; - - resultGuard.release(); - *aSuccess = true; - return result; -} - -} // namespace mozilla - -#endif /* mozilla_BufferList_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Casting.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Casting.h deleted file mode 100644 index a7d0fb50..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Casting.h +++ /dev/null @@ -1,243 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Cast operations to supplement the built-in casting operations. */ - -#ifndef mozilla_Casting_h -#define mozilla_Casting_h - -#include "mozilla/Assertions.h" -#include "mozilla/TypeTraits.h" - -#include - -namespace mozilla { - -/** - * Sets the outparam value of type |To| with the same underlying bit pattern of - * |aFrom|. - * - * |To| and |From| must be types of the same size; be careful of cross-platform - * size differences, or this might fail to compile on some but not all - * platforms. - * - * There is also a variant that returns the value directly. In most cases, the - * two variants should be identical. However, in the specific case of x86 - * chips, the behavior differs: returning floating-point values directly is done - * through the x87 stack, and x87 loads and stores turn signaling NaNs into - * quiet NaNs... silently. Returning floating-point values via outparam, - * however, is done entirely within the SSE registers when SSE2 floating-point - * is enabled in the compiler, which has semantics-preserving behavior you would - * expect. - * - * If preserving the distinction between signaling NaNs and quiet NaNs is - * important to you, you should use the outparam version. In all other cases, - * you should use the direct return version. - */ -template -inline void -BitwiseCast(const From aFrom, To* aResult) -{ - static_assert(sizeof(From) == sizeof(To), - "To and From must have the same size"); - union - { - From mFrom; - To mTo; - } u; - u.mFrom = aFrom; - *aResult = u.mTo; -} - -template -inline To -BitwiseCast(const From aFrom) -{ - To temp; - BitwiseCast(aFrom, &temp); - return temp; -} - -namespace detail { - -enum ToSignedness { ToIsSigned, ToIsUnsigned }; -enum FromSignedness { FromIsSigned, FromIsUnsigned }; - -template::value ? FromIsSigned : FromIsUnsigned, - ToSignedness = IsSigned::value ? ToIsSigned : ToIsUnsigned> -struct BoundsCheckImpl; - -// Implicit conversions on operands to binary operations make this all a bit -// hard to verify. Attempt to ease the pain below by *only* comparing values -// that are obviously the same type (and will undergo no further conversions), -// even when it's not strictly necessary, for explicitness. - -enum UUComparison { FromIsBigger, FromIsNotBigger }; - -// Unsigned-to-unsigned range check - -template sizeof(To)) - ? FromIsBigger - : FromIsNotBigger> -struct UnsignedUnsignedCheck; - -template -struct UnsignedUnsignedCheck -{ -public: - static bool checkBounds(const From aFrom) - { - return aFrom <= From(To(-1)); - } -}; - -template -struct UnsignedUnsignedCheck -{ -public: - static bool checkBounds(const From aFrom) - { - return true; - } -}; - -template -struct BoundsCheckImpl -{ -public: - static bool checkBounds(const From aFrom) - { - return UnsignedUnsignedCheck::checkBounds(aFrom); - } -}; - -// Signed-to-unsigned range check - -template -struct BoundsCheckImpl -{ -public: - static bool checkBounds(const From aFrom) - { - if (aFrom < 0) { - return false; - } - if (sizeof(To) >= sizeof(From)) { - return true; - } - return aFrom <= From(To(-1)); - } -}; - -// Unsigned-to-signed range check - -enum USComparison { FromIsSmaller, FromIsNotSmaller }; - -template -struct UnsignedSignedCheck; - -template -struct UnsignedSignedCheck -{ -public: - static bool checkBounds(const From aFrom) - { - return true; - } -}; - -template -struct UnsignedSignedCheck -{ -public: - static bool checkBounds(const From aFrom) - { - const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); - return aFrom <= From(MaxValue); - } -}; - -template -struct BoundsCheckImpl -{ -public: - static bool checkBounds(const From aFrom) - { - return UnsignedSignedCheck::checkBounds(aFrom); - } -}; - -// Signed-to-signed range check - -template -struct BoundsCheckImpl -{ -public: - static bool checkBounds(const From aFrom) - { - if (sizeof(From) <= sizeof(To)) { - return true; - } - const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); - const To MinValue = -MaxValue - To(1); - return From(MinValue) <= aFrom && - From(aFrom) <= From(MaxValue); - } -}; - -template::value && - IsIntegral::value> -class BoundsChecker; - -template -class BoundsChecker -{ -public: - static bool checkBounds(const From aFrom) { return true; } -}; - -template -class BoundsChecker -{ -public: - static bool checkBounds(const From aFrom) - { - return BoundsCheckImpl::checkBounds(aFrom); - } -}; - -template -inline bool -IsInBounds(const From aFrom) -{ - return BoundsChecker::checkBounds(aFrom); -} - -} // namespace detail - -/** - * Cast a value of integral type |From| to a value of integral type |To|, - * asserting that the cast will be a safe cast per C++ (that is, that |to| is in - * the range of values permitted for the type |From|). - */ -template -inline To -AssertedCast(const From aFrom) -{ - MOZ_ASSERT((detail::IsInBounds(aFrom))); - return static_cast(aFrom); -} - -} // namespace mozilla - -#endif /* mozilla_Casting_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/ChaosMode.h b/android/armeabi-v7a/include/spidermonkey/mozilla/ChaosMode.h deleted file mode 100644 index 94833c39..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/ChaosMode.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_ChaosMode_h -#define mozilla_ChaosMode_h - -#include "mozilla/Atomics.h" -#include "mozilla/EnumSet.h" - -#include -#include - -namespace mozilla { - -enum ChaosFeature { - None = 0x0, - // Altering thread scheduling. - ThreadScheduling = 0x1, - // Altering network request scheduling. - NetworkScheduling = 0x2, - // Altering timer scheduling. - TimerScheduling = 0x4, - // Read and write less-than-requested amounts. - IOAmounts = 0x8, - // Iterate over hash tables in random order. - HashTableIteration = 0x10, - // Randomly refuse to use cached version of image (when allowed by spec). - ImageCache = 0x20, - Any = 0xffffffff, -}; - -namespace detail { -extern MFBT_DATA Atomic gChaosModeCounter; -extern MFBT_DATA ChaosFeature gChaosFeatures; -} // namespace detail - -/** - * When "chaos mode" is activated, code that makes implicitly nondeterministic - * choices is encouraged to make random and extreme choices, to test more - * code paths and uncover bugs. - */ -class ChaosMode -{ -public: - static void SetChaosFeature(ChaosFeature aChaosFeature) - { - detail::gChaosFeatures = aChaosFeature; - } - - static bool isActive(ChaosFeature aFeature) - { - if (detail::gChaosModeCounter > 0) { - return true; - } - return detail::gChaosFeatures & aFeature; - } - - /** - * Increase the chaos mode activation level. An equivalent number of - * calls to leaveChaosMode must be made in order to restore the original - * chaos mode state. If the activation level is nonzero all chaos mode - * features are activated. - */ - static void enterChaosMode() - { - detail::gChaosModeCounter++; - } - - /** - * Decrease the chaos mode activation level. See enterChaosMode(). - */ - static void leaveChaosMode() - { - MOZ_ASSERT(detail::gChaosModeCounter > 0); - detail::gChaosModeCounter--; - } - - /** - * Returns a somewhat (but not uniformly) random uint32_t < aBound. - * Not to be used for anything except ChaosMode, since it's not very random. - */ - static uint32_t randomUint32LessThan(uint32_t aBound) - { - MOZ_ASSERT(aBound != 0); - return uint32_t(rand()) % aBound; - } -}; - -} /* namespace mozilla */ - -#endif /* mozilla_ChaosMode_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Char16.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Char16.h deleted file mode 100644 index 3c2f254a..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Char16.h +++ /dev/null @@ -1,194 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implements a UTF-16 character type. */ - -#ifndef mozilla_Char16_h -#define mozilla_Char16_h - -#ifdef __cplusplus - -/* - * C++11 introduces a char16_t type and support for UTF-16 string and character - * literals. C++11's char16_t is a distinct builtin type. Technically, char16_t - * is a 16-bit code unit of a Unicode code point, not a "character". - */ - -#ifdef WIN32 -# define MOZ_USE_CHAR16_WRAPPER -# include - /** - * Win32 API extensively uses wchar_t, which is represented by a separated - * builtin type than char16_t per spec. It's not the case for MSVC prior to - * MSVC 2015, but other compilers follow the spec. We want to mix wchar_t and - * char16_t on Windows builds. This class is supposed to make it easier. It - * stores char16_t const pointer, but provides implicit casts for wchar_t as - * well. On other platforms, we simply use - * |typedef const char16_t* char16ptr_t|. Here, we want to make the class as - * similar to this typedef, including providing some casts that are allowed - * by the typedef. - */ -class char16ptr_t -{ -private: - const char16_t* mPtr; - static_assert(sizeof(char16_t) == sizeof(wchar_t), - "char16_t and wchar_t sizes differ"); - -public: - char16ptr_t(const char16_t* aPtr) : mPtr(aPtr) {} - char16ptr_t(const wchar_t* aPtr) : - mPtr(reinterpret_cast(aPtr)) - {} - - /* Without this, nullptr assignment would be ambiguous. */ - constexpr char16ptr_t(decltype(nullptr)) : mPtr(nullptr) {} - - operator const char16_t*() const - { - return mPtr; - } - operator const wchar_t*() const - { - return reinterpret_cast(mPtr); - } - operator const void*() const - { - return mPtr; - } - operator bool() const - { - return mPtr != nullptr; - } - - /* Explicit cast operators to allow things like (char16_t*)str. */ - explicit operator char16_t*() const - { - return const_cast(mPtr); - } - explicit operator wchar_t*() const - { - return const_cast(static_cast(*this)); - } - explicit operator int() const - { - return reinterpret_cast(mPtr); - } - explicit operator unsigned int() const - { - return reinterpret_cast(mPtr); - } - explicit operator long() const - { - return reinterpret_cast(mPtr); - } - explicit operator unsigned long() const - { - return reinterpret_cast(mPtr); - } - explicit operator long long() const - { - return reinterpret_cast(mPtr); - } - explicit operator unsigned long long() const - { - return reinterpret_cast(mPtr); - } - - /** - * Some Windows API calls accept BYTE* but require that data actually be - * WCHAR*. Supporting this requires explicit operators to support the - * requisite explicit casts. - */ - explicit operator const char*() const - { - return reinterpret_cast(mPtr); - } - explicit operator const unsigned char*() const - { - return reinterpret_cast(mPtr); - } - explicit operator unsigned char*() const - { - return - const_cast(reinterpret_cast(mPtr)); - } - explicit operator void*() const - { - return const_cast(mPtr); - } - - /* Some operators used on pointers. */ - char16_t operator[](size_t aIndex) const - { - return mPtr[aIndex]; - } - bool operator==(const char16ptr_t& aOther) const - { - return mPtr == aOther.mPtr; - } - bool operator==(decltype(nullptr)) const - { - return mPtr == nullptr; - } - bool operator!=(const char16ptr_t& aOther) const - { - return mPtr != aOther.mPtr; - } - bool operator!=(decltype(nullptr)) const - { - return mPtr != nullptr; - } - char16ptr_t operator+(int aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(unsigned int aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(long aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(unsigned long aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(long long aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(unsigned long long aValue) const - { - return char16ptr_t(mPtr + aValue); - } - ptrdiff_t operator-(const char16ptr_t& aOther) const - { - return mPtr - aOther.mPtr; - } -}; - -inline decltype((char*)0-(char*)0) -operator-(const char16_t* aX, const char16ptr_t aY) -{ - return aX - static_cast(aY); -} - -#else - -typedef const char16_t* char16ptr_t; - -#endif - -static_assert(sizeof(char16_t) == 2, "Is char16_t type 16 bits?"); -static_assert(char16_t(-1) > char16_t(0), "Is char16_t type unsigned?"); -static_assert(sizeof(u'A') == 2, "Is unicode char literal 16 bits?"); -static_assert(sizeof(u""[0]) == 2, "Is unicode string char 16 bits?"); - -#endif - -#endif /* mozilla_Char16_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/CheckedInt.h b/android/armeabi-v7a/include/spidermonkey/mozilla/CheckedInt.h deleted file mode 100644 index 02ef8d5b..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/CheckedInt.h +++ /dev/null @@ -1,791 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Provides checked integers, detecting integer overflow and divide-by-0. */ - -#ifndef mozilla_CheckedInt_h -#define mozilla_CheckedInt_h - -#include -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/IntegerTypeTraits.h" - -namespace mozilla { - -template class CheckedInt; - -namespace detail { - -/* - * Step 1: manually record supported types - * - * What's nontrivial here is that there are different families of integer - * types: basic integer types and stdint types. It is merrily undefined which - * types from one family may be just typedefs for a type from another family. - * - * For example, on GCC 4.6, aside from the basic integer types, the only other - * type that isn't just a typedef for some of them, is int8_t. - */ - -struct UnsupportedType {}; - -template -struct IsSupportedPass2 -{ - static const bool value = false; -}; - -template -struct IsSupported -{ - static const bool value = IsSupportedPass2::value; -}; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -/* - * Step 2: Implement the actual validity checks. - * - * Ideas taken from IntegerLib, code different. - */ - -template -struct TwiceBiggerType -{ - typedef typename detail::StdintTypeForSizeAndSignedness< - sizeof(IntegerType) * 2, - IsSigned::value - >::Type Type; -}; - -template -struct TwiceBiggerType -{ - typedef UnsupportedType Type; -}; - -template -inline bool -HasSignBit(T aX) -{ - // In C++, right bit shifts on negative values is undefined by the standard. - // Notice that signed-to-unsigned conversions are always well-defined in the - // standard, as the value congruent modulo 2**n as expected. By contrast, - // unsigned-to-signed is only well-defined if the value is representable. - return bool(typename MakeUnsigned::Type(aX) >> - PositionOfSignBit::value); -} - -// Bitwise ops may return a larger type, so it's good to use this inline -// helper guaranteeing that the result is really of type T. -template -inline T -BinaryComplement(T aX) -{ - return ~aX; -} - -template::value, - bool IsUSigned = IsSigned::value> -struct DoesRangeContainRange -{ -}; - -template -struct DoesRangeContainRange -{ - static const bool value = sizeof(T) >= sizeof(U); -}; - -template -struct DoesRangeContainRange -{ - static const bool value = sizeof(T) > sizeof(U); -}; - -template -struct DoesRangeContainRange -{ - static const bool value = false; -}; - -template::value, - bool IsUSigned = IsSigned::value, - bool DoesTRangeContainURange = DoesRangeContainRange::value> -struct IsInRangeImpl {}; - -template -struct IsInRangeImpl -{ - static bool run(U) - { - return true; - } -}; - -template -struct IsInRangeImpl -{ - static bool run(U aX) - { - return aX <= MaxValue::value && aX >= MinValue::value; - } -}; - -template -struct IsInRangeImpl -{ - static bool run(U aX) - { - return aX <= MaxValue::value; - } -}; - -template -struct IsInRangeImpl -{ - static bool run(U aX) - { - return sizeof(T) > sizeof(U) || aX <= U(MaxValue::value); - } -}; - -template -struct IsInRangeImpl -{ - static bool run(U aX) - { - return sizeof(T) >= sizeof(U) - ? aX >= 0 - : aX >= 0 && aX <= U(MaxValue::value); - } -}; - -template -inline bool -IsInRange(U aX) -{ - return IsInRangeImpl::run(aX); -} - -template -inline bool -IsAddValid(T aX, T aY) -{ - // Addition is valid if the sign of aX+aY is equal to either that of aX or - // that of aY. Since the value of aX+aY is undefined if we have a signed - // type, we compute it using the unsigned type of the same size. Beware! - // These bitwise operations can return a larger integer type, if T was a - // small type like int8_t, so we explicitly cast to T. - - typename MakeUnsigned::Type ux = aX; - typename MakeUnsigned::Type uy = aY; - typename MakeUnsigned::Type result = ux + uy; - return IsSigned::value - ? HasSignBit(BinaryComplement(T((result ^ aX) & (result ^ aY)))) - : BinaryComplement(aX) >= aY; -} - -template -inline bool -IsSubValid(T aX, T aY) -{ - // Subtraction is valid if either aX and aY have same sign, or aX-aY and aX - // have same sign. Since the value of aX-aY is undefined if we have a signed - // type, we compute it using the unsigned type of the same size. - typename MakeUnsigned::Type ux = aX; - typename MakeUnsigned::Type uy = aY; - typename MakeUnsigned::Type result = ux - uy; - - return IsSigned::value - ? HasSignBit(BinaryComplement(T((result ^ aX) & (aX ^ aY)))) - : aX >= aY; -} - -template::value, - bool TwiceBiggerTypeIsSupported = - IsSupported::Type>::value> -struct IsMulValidImpl {}; - -template -struct IsMulValidImpl -{ - static bool run(T aX, T aY) - { - typedef typename TwiceBiggerType::Type TwiceBiggerType; - TwiceBiggerType product = TwiceBiggerType(aX) * TwiceBiggerType(aY); - return IsInRange(product); - } -}; - -template -struct IsMulValidImpl -{ - static bool run(T aX, T aY) - { - const T max = MaxValue::value; - const T min = MinValue::value; - - if (aX == 0 || aY == 0) { - return true; - } - if (aX > 0) { - return aY > 0 - ? aX <= max / aY - : aY >= min / aX; - } - - // If we reach this point, we know that aX < 0. - return aY > 0 - ? aX >= min / aY - : aY >= max / aX; - } -}; - -template -struct IsMulValidImpl -{ - static bool run(T aX, T aY) - { - return aY == 0 || aX <= MaxValue::value / aY; - } -}; - -template -inline bool -IsMulValid(T aX, T aY) -{ - return IsMulValidImpl::run(aX, aY); -} - -template -inline bool -IsDivValid(T aX, T aY) -{ - // Keep in mind that in the signed case, min/-1 is invalid because - // abs(min)>max. - return aY != 0 && - !(IsSigned::value && aX == MinValue::value && aY == T(-1)); -} - -template::value> -struct IsModValidImpl; - -template -inline bool -IsModValid(T aX, T aY) -{ - return IsModValidImpl::run(aX, aY); -} - -/* - * Mod is pretty simple. - * For now, let's just use the ANSI C definition: - * If aX or aY are negative, the results are implementation defined. - * Consider these invalid. - * Undefined for aY=0. - * The result will never exceed either aX or aY. - * - * Checking that aX>=0 is a warning when T is unsigned. - */ - -template -struct IsModValidImpl -{ - static inline bool run(T aX, T aY) - { - return aY >= 1; - } -}; - -template -struct IsModValidImpl -{ - static inline bool run(T aX, T aY) - { - if (aX < 0) { - return false; - } - return aY >= 1; - } -}; - -template::value> -struct NegateImpl; - -template -struct NegateImpl -{ - static CheckedInt negate(const CheckedInt& aVal) - { - // Handle negation separately for signed/unsigned, for simpler code and to - // avoid an MSVC warning negating an unsigned value. - return CheckedInt(0, aVal.isValid() && aVal.mValue == 0); - } -}; - -template -struct NegateImpl -{ - static CheckedInt negate(const CheckedInt& aVal) - { - // Watch out for the min-value, which (with twos-complement) can't be - // negated as -min-value is then (max-value + 1). - if (!aVal.isValid() || aVal.mValue == MinValue::value) { - return CheckedInt(aVal.mValue, false); - } - return CheckedInt(-aVal.mValue, true); - } -}; - -} // namespace detail - - -/* - * Step 3: Now define the CheckedInt class. - */ - -/** - * @class CheckedInt - * @brief Integer wrapper class checking for integer overflow and other errors - * @param T the integer type to wrap. Can be any type among the following: - * - any basic integer type such as |int| - * - any stdint type such as |int8_t| - * - * This class implements guarded integer arithmetic. Do a computation, check - * that isValid() returns true, you then have a guarantee that no problem, such - * as integer overflow, happened during this computation, and you can call - * value() to get the plain integer value. - * - * The arithmetic operators in this class are guaranteed not to raise a signal - * (e.g. in case of a division by zero). - * - * For example, suppose that you want to implement a function that computes - * (aX+aY)/aZ, that doesn't crash if aZ==0, and that reports on error (divide by - * zero or integer overflow). You could code it as follows: - @code - bool computeXPlusYOverZ(int aX, int aY, int aZ, int* aResult) - { - CheckedInt checkedResult = (CheckedInt(aX) + aY) / aZ; - if (checkedResult.isValid()) { - *aResult = checkedResult.value(); - return true; - } else { - return false; - } - } - @endcode - * - * Implicit conversion from plain integers to checked integers is allowed. The - * plain integer is checked to be in range before being casted to the - * destination type. This means that the following lines all compile, and the - * resulting CheckedInts are correctly detected as valid or invalid: - * @code - // 1 is of type int, is found to be in range for uint8_t, x is valid - CheckedInt x(1); - // -1 is of type int, is found not to be in range for uint8_t, x is invalid - CheckedInt x(-1); - // -1 is of type int, is found to be in range for int8_t, x is valid - CheckedInt x(-1); - // 1000 is of type int16_t, is found not to be in range for int8_t, - // x is invalid - CheckedInt x(int16_t(1000)); - // 3123456789 is of type uint32_t, is found not to be in range for int32_t, - // x is invalid - CheckedInt x(uint32_t(3123456789)); - * @endcode - * Implicit conversion from - * checked integers to plain integers is not allowed. As shown in the - * above example, to get the value of a checked integer as a normal integer, - * call value(). - * - * Arithmetic operations between checked and plain integers is allowed; the - * result type is the type of the checked integer. - * - * Checked integers of different types cannot be used in the same arithmetic - * expression. - * - * There are convenience typedefs for all stdint types, of the following form - * (these are just 2 examples): - @code - typedef CheckedInt CheckedInt32; - typedef CheckedInt CheckedUint16; - @endcode - */ -template -class CheckedInt -{ -protected: - T mValue; - bool mIsValid; - - template - CheckedInt(U aValue, bool aIsValid) : mValue(aValue), mIsValid(aIsValid) - { - static_assert(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); - } - - friend struct detail::NegateImpl; - -public: - /** - * Constructs a checked integer with given @a value. The checked integer is - * initialized as valid or invalid depending on whether the @a value - * is in range. - * - * This constructor is not explicit. Instead, the type of its argument is a - * separate template parameter, ensuring that no conversion is performed - * before this constructor is actually called. As explained in the above - * documentation for class CheckedInt, this constructor checks that its - * argument is valid. - */ - template - MOZ_IMPLICIT CheckedInt(U aValue) MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT - : mValue(T(aValue)), - mIsValid(detail::IsInRange(aValue)) - { - static_assert(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); - } - - template - friend class CheckedInt; - - template - CheckedInt toChecked() const - { - CheckedInt ret(mValue); - ret.mIsValid = ret.mIsValid && mIsValid; - return ret; - } - - /** Constructs a valid checked integer with initial value 0 */ - CheckedInt() : mValue(0), mIsValid(true) - { - static_assert(detail::IsSupported::value, - "This type is not supported by CheckedInt"); - } - - /** @returns the actual value */ - T value() const - { - MOZ_ASSERT(mIsValid, "Invalid checked integer (division by zero or integer overflow)"); - return mValue; - } - - /** - * @returns true if the checked integer is valid, i.e. is not the result - * of an invalid operation or of an operation involving an invalid checked - * integer - */ - bool isValid() const - { - return mIsValid; - } - - template - friend CheckedInt operator +(const CheckedInt& aLhs, - const CheckedInt& aRhs); - template - CheckedInt& operator +=(U aRhs); - CheckedInt& operator +=(const CheckedInt& aRhs); - - template - friend CheckedInt operator -(const CheckedInt& aLhs, - const CheckedInt& aRhs); - template - CheckedInt& operator -=(U aRhs); - CheckedInt& operator -=(const CheckedInt& aRhs); - - template - friend CheckedInt operator *(const CheckedInt& aLhs, - const CheckedInt& aRhs); - template - CheckedInt& operator *=(U aRhs); - CheckedInt& operator *=(const CheckedInt& aRhs); - - template - friend CheckedInt operator /(const CheckedInt& aLhs, - const CheckedInt& aRhs); - template - CheckedInt& operator /=(U aRhs); - CheckedInt& operator /=(const CheckedInt& aRhs); - - template - friend CheckedInt operator %(const CheckedInt& aLhs, - const CheckedInt& aRhs); - template - CheckedInt& operator %=(U aRhs); - CheckedInt& operator %=(const CheckedInt& aRhs); - - CheckedInt operator -() const - { - return detail::NegateImpl::negate(*this); - } - - /** - * @returns true if the left and right hand sides are valid - * and have the same value. - * - * Note that these semantics are the reason why we don't offer - * a operator!=. Indeed, we'd want to have a!=b be equivalent to !(a==b) - * but that would mean that whenever a or b is invalid, a!=b - * is always true, which would be very confusing. - * - * For similar reasons, operators <, >, <=, >= would be very tricky to - * specify, so we just avoid offering them. - * - * Notice that these == semantics are made more reasonable by these facts: - * 1. a==b implies equality at the raw data level - * (the converse is false, as a==b is never true among invalids) - * 2. This is similar to the behavior of IEEE floats, where a==b - * means that a and b have the same value *and* neither is NaN. - */ - bool operator ==(const CheckedInt& aOther) const - { - return mIsValid && aOther.mIsValid && mValue == aOther.mValue; - } - - /** prefix ++ */ - CheckedInt& operator++() - { - *this += 1; - return *this; - } - - /** postfix ++ */ - CheckedInt operator++(int) - { - CheckedInt tmp = *this; - *this += 1; - return tmp; - } - - /** prefix -- */ - CheckedInt& operator--() - { - *this -= 1; - return *this; - } - - /** postfix -- */ - CheckedInt operator--(int) - { - CheckedInt tmp = *this; - *this -= 1; - return tmp; - } - -private: - /** - * The !=, <, <=, >, >= operators are disabled: - * see the comment on operator==. - */ - template bool operator !=(U aOther) const = delete; - template bool operator < (U aOther) const = delete; - template bool operator <=(U aOther) const = delete; - template bool operator > (U aOther) const = delete; - template bool operator >=(U aOther) const = delete; -}; - -#define MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(NAME, OP) \ - template \ - inline CheckedInt \ - operator OP(const CheckedInt& aLhs, const CheckedInt& aRhs) \ - { \ - if (!detail::Is##NAME##Valid(aLhs.mValue, aRhs.mValue)) { \ - return CheckedInt(0, false); \ - } \ - return CheckedInt(aLhs.mValue OP aRhs.mValue, \ - aLhs.mIsValid && aRhs.mIsValid); \ - } - -MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Add, +) -MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Sub, -) -MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mul, *) -MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Div, /) -MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mod, %) - -#undef MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR - -// Implement castToCheckedInt(x), making sure that -// - it allows x to be either a CheckedInt or any integer type -// that can be casted to T -// - if x is already a CheckedInt, we just return a reference to it, -// instead of copying it (optimization) - -namespace detail { - -template -struct CastToCheckedIntImpl -{ - typedef CheckedInt ReturnType; - static CheckedInt run(U aU) { return aU; } -}; - -template -struct CastToCheckedIntImpl > -{ - typedef const CheckedInt& ReturnType; - static const CheckedInt& run(const CheckedInt& aU) { return aU; } -}; - -} // namespace detail - -template -inline typename detail::CastToCheckedIntImpl::ReturnType -castToCheckedInt(U aU) -{ - static_assert(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); - return detail::CastToCheckedIntImpl::run(aU); -} - -#define MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(OP, COMPOUND_OP) \ - template \ - template \ - CheckedInt& CheckedInt::operator COMPOUND_OP(U aRhs) \ - { \ - *this = *this OP castToCheckedInt(aRhs); \ - return *this; \ - } \ - template \ - CheckedInt& CheckedInt::operator COMPOUND_OP(const CheckedInt& aRhs) \ - { \ - *this = *this OP aRhs; \ - return *this; \ - } \ - template \ - inline CheckedInt operator OP(const CheckedInt& aLhs, U aRhs) \ - { \ - return aLhs OP castToCheckedInt(aRhs); \ - } \ - template \ - inline CheckedInt operator OP(U aLhs, const CheckedInt& aRhs) \ - { \ - return castToCheckedInt(aLhs) OP aRhs; \ - } - -MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(+, +=) -MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(*, *=) -MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(-, -=) -MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(/, /=) -MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(%, %=) - -#undef MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS - -template -inline bool -operator ==(const CheckedInt& aLhs, U aRhs) -{ - return aLhs == castToCheckedInt(aRhs); -} - -template -inline bool -operator ==(U aLhs, const CheckedInt& aRhs) -{ - return castToCheckedInt(aLhs) == aRhs; -} - -// Convenience typedefs. -typedef CheckedInt CheckedInt8; -typedef CheckedInt CheckedUint8; -typedef CheckedInt CheckedInt16; -typedef CheckedInt CheckedUint16; -typedef CheckedInt CheckedInt32; -typedef CheckedInt CheckedUint32; -typedef CheckedInt CheckedInt64; -typedef CheckedInt CheckedUint64; - -} // namespace mozilla - -#endif /* mozilla_CheckedInt_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Compiler.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Compiler.h deleted file mode 100644 index 1bd34d32..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Compiler.h +++ /dev/null @@ -1,113 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Various compiler checks. */ - -#ifndef mozilla_Compiler_h -#define mozilla_Compiler_h - -#define MOZ_IS_GCC 0 -#define MOZ_IS_MSVC 0 - -#if !defined(__clang__) && defined(__GNUC__) - -# undef MOZ_IS_GCC -# define MOZ_IS_GCC 1 - /* - * These macros should simplify gcc version checking. For example, to check - * for gcc 4.7.1 or later, check `#if MOZ_GCC_VERSION_AT_LEAST(4, 7, 1)`. - */ -# define MOZ_GCC_VERSION_AT_LEAST(major, minor, patchlevel) \ - ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) \ - >= ((major) * 10000 + (minor) * 100 + (patchlevel))) -# define MOZ_GCC_VERSION_AT_MOST(major, minor, patchlevel) \ - ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) \ - <= ((major) * 10000 + (minor) * 100 + (patchlevel))) -# if !MOZ_GCC_VERSION_AT_LEAST(4, 8, 0) -# error "mfbt (and Gecko) require at least gcc 4.8 to build." -# endif - -#elif defined(_MSC_VER) - -# undef MOZ_IS_MSVC -# define MOZ_IS_MSVC 1 - -#endif - -/* - * The situation with standard libraries is a lot worse than with compilers, - * particularly as clang and gcc could end up using one of three or so standard - * libraries, and they may not be up-to-snuff with newer C++11 versions. To - * detect the library, we're going to include cstddef (which is a small header - * which will be transitively included by everybody else at some point) to grab - * the version macros and deduce macros from there. - */ -#ifdef __cplusplus -# include -# ifdef _STLPORT_MAJOR -# define MOZ_USING_STLPORT 1 -# define MOZ_STLPORT_VERSION_AT_LEAST(major, minor, patch) \ - (_STLPORT_VERSION >= ((major) << 8 | (minor) << 4 | (patch))) -# elif defined(_LIBCPP_VERSION) - /* - * libc++, unfortunately, doesn't appear to have useful versioning macros. - * Hopefully, the recommendations of N3694 with respect to standard libraries - * will get applied instead and we won't need to worry about version numbers - * here. - */ -# define MOZ_USING_LIBCXX 1 -# elif defined(__GLIBCXX__) -# define MOZ_USING_LIBSTDCXX 1 - /* - * libstdc++ is also annoying and doesn't give us useful versioning macros - * for the library. If we're using gcc, then assume that libstdc++ matches - * the compiler version. If we're using clang, we're going to have to fake - * major/minor combinations by looking for newly-defined config macros. - */ -# if MOZ_IS_GCC -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - MOZ_GCC_VERSION_AT_LEAST(major, minor, patch) -# elif defined(_GLIBCXX_THROW_OR_ABORT) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 8)) -# elif defined(_GLIBCXX_NOEXCEPT) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 7)) -# elif defined(_GLIBCXX_USE_DEPRECATED) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 6)) -# elif defined(_GLIBCXX_PSEUDO_VISIBILITY) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 5)) -# elif defined(_GLIBCXX_BEGIN_EXTERN_C) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 4)) -# elif defined(_GLIBCXX_VISIBILITY_ATTR) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 3)) -# elif defined(_GLIBCXX_VISIBILITY) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 2)) -# else -# error "Your version of libstdc++ is unknown to us and is likely too old." -# endif -# endif - - // Flesh out the defines for everyone else -# ifndef MOZ_USING_STLPORT -# define MOZ_USING_STLPORT 0 -# define MOZ_STLPORT_VERSION_AT_LEAST(major, minor, patch) 0 -# endif -# ifndef MOZ_USING_LIBCXX -# define MOZ_USING_LIBCXX 0 -# endif -# ifndef MOZ_USING_LIBSTDCXX -# define MOZ_USING_LIBSTDCXX 0 -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) 0 -# endif -#endif /* __cplusplus */ - -#endif /* mozilla_Compiler_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Compression.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Compression.h deleted file mode 100644 index aa50211b..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Compression.h +++ /dev/null @@ -1,119 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Various simple compression/decompression functions. */ - -#ifndef mozilla_Compression_h_ -#define mozilla_Compression_h_ - -#include "mozilla/Assertions.h" -#include "mozilla/Types.h" - -namespace mozilla { -namespace Compression { - -/** - * LZ4 is a very fast byte-wise compression algorithm. - * - * Compared to Google's Snappy it is faster to compress and decompress and - * generally produces output of about the same size. - * - * Compared to zlib it compresses at about 10x the speed, decompresses at about - * 4x the speed and produces output of about 1.5x the size. - */ - -class LZ4 -{ -public: - /** - * Compresses |aInputSize| bytes from |aSource| into |aDest|. Destination - * buffer must be already allocated, and must be sized to handle worst cases - * situations (input data not compressible). Worst case size evaluation is - * provided by function maxCompressedSize() - * - * @param aInputSize is the input size. Max supported value is ~1.9GB - * @return the number of bytes written in buffer |aDest| - */ - static MFBT_API size_t - compress(const char* aSource, size_t aInputSize, char* aDest); - - /** - * Compress |aInputSize| bytes from |aSource| into an output buffer - * |aDest| of maximum size |aMaxOutputSize|. If it cannot achieve it, - * compression will stop, and result of the function will be zero, - * |aDest| will still be written to, but since the number of input - * bytes consumed is not returned the result is not usable. - * - * This function never writes outside of provided output buffer. - * - * @param aInputSize is the input size. Max supported value is ~1.9GB - * @param aMaxOutputSize is the size of the destination buffer (which must - * be already allocated) - * @return the number of bytes written in buffer |aDest| or 0 if the - * compression fails - */ - static MFBT_API size_t - compressLimitedOutput(const char* aSource, size_t aInputSize, char* aDest, - size_t aMaxOutputSize); - - /** - * If the source stream is malformed, the function will stop decoding - * and return false. - * - * This function never writes outside of provided buffers, and never - * modifies input buffer. - * - * Note: destination buffer must be already allocated, and its size must be a - * minimum of |aOutputSize| bytes. - * - * @param aOutputSize is the output size, therefore the original size - * @return true on success, false on failure - */ - static MFBT_API MOZ_MUST_USE bool - decompress(const char* aSource, char* aDest, size_t aOutputSize); - - /** - * If the source stream is malformed, the function will stop decoding - * and return false. - * - * This function never writes beyond aDest + aMaxOutputSize, and is - * therefore protected against malicious data packets. - * - * Note: Destination buffer must be already allocated. This version is - * slightly slower than the decompress without the aMaxOutputSize. - * - * @param aInputSize is the length of the input compressed data - * @param aMaxOutputSize is the size of the destination buffer (which must be - * already allocated) - * @param aOutputSize the actual number of bytes decoded in the destination - * buffer (necessarily <= aMaxOutputSize) - * @return true on success, false on failure - */ - static MFBT_API MOZ_MUST_USE bool - decompress(const char* aSource, size_t aInputSize, char* aDest, - size_t aMaxOutputSize, size_t* aOutputSize); - - /* - * Provides the maximum size that LZ4 may output in a "worst case" - * scenario (input data not compressible) primarily useful for memory - * allocation of output buffer. - * note : this function is limited by "int" range (2^31-1) - * - * @param aInputSize is the input size. Max supported value is ~1.9GB - * @return maximum output size in a "worst case" scenario - */ - static inline size_t maxCompressedSize(size_t aInputSize) - { - size_t max = (aInputSize + (aInputSize / 255) + 16); - MOZ_ASSERT(max > aInputSize); - return max; - } -}; - -} /* namespace Compression */ -} /* namespace mozilla */ - -#endif /* mozilla_Compression_h_ */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/DebugOnly.h b/android/armeabi-v7a/include/spidermonkey/mozilla/DebugOnly.h deleted file mode 100644 index a1a669db..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/DebugOnly.h +++ /dev/null @@ -1,92 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Provides DebugOnly, a type for variables used only in debug builds (i.e. by - * assertions). - */ - -#ifndef mozilla_DebugOnly_h -#define mozilla_DebugOnly_h - -#include "mozilla/Attributes.h" - -namespace mozilla { - -/** - * DebugOnly contains a value of type T, but only in debug builds. In release - * builds, it does not contain a value. This helper is intended to be used with - * MOZ_ASSERT()-style macros, allowing one to write: - * - * DebugOnly check = func(); - * MOZ_ASSERT(check); - * - * more concisely than declaring |check| conditional on #ifdef DEBUG. - * - * DebugOnly instances can only be coerced to T in debug builds. In release - * builds they don't have a value, so type coercion is not well defined. - * - * NOTE: DebugOnly instances still take up one byte of space, plus padding, even - * in optimized, non-DEBUG builds (see bug 1253094 comment 37 for more info). - * For this reason the class is MOZ_STACK_CLASS to prevent consumers using - * DebugOnly for struct/class members and unwittingly inflating the size of - * their objects in release builds. - */ -template -class MOZ_STACK_CLASS DebugOnly -{ -public: -#ifdef DEBUG - T value; - - DebugOnly() { } - MOZ_IMPLICIT DebugOnly(const T& aOther) : value(aOther) { } - DebugOnly(const DebugOnly& aOther) : value(aOther.value) { } - DebugOnly& operator=(const T& aRhs) { - value = aRhs; - return *this; - } - - void operator++(int) { value++; } - void operator--(int) { value--; } - - // Do not define operator+=(), etc. here. These will coerce via the - // implicit cast and built-in operators. Defining explicit methods here - // will create ambiguity the compiler can't deal with. - - T* operator&() { return &value; } - - operator T&() { return value; } - operator const T&() const { return value; } - - T& operator->() { return value; } - const T& operator->() const { return value; } - -#else - DebugOnly() { } - MOZ_IMPLICIT DebugOnly(const T&) { } - DebugOnly(const DebugOnly&) { } - DebugOnly& operator=(const T&) { return *this; } - void operator++(int) { } - void operator--(int) { } - DebugOnly& operator+=(const T&) { return *this; } - DebugOnly& operator-=(const T&) { return *this; } - DebugOnly& operator&=(const T&) { return *this; } - DebugOnly& operator|=(const T&) { return *this; } - DebugOnly& operator^=(const T&) { return *this; } -#endif - - /* - * DebugOnly must always have a destructor or else it will - * generate "unused variable" warnings, exactly what it's intended - * to avoid! - */ - ~DebugOnly() {} -}; - -} // namespace mozilla - -#endif /* mozilla_DebugOnly_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Decimal.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Decimal.h deleted file mode 100644 index 10d0e2c7..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Decimal.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Imported from: - * https://chromium.googlesource.com/chromium/src.git/+/master/third_party/WebKit/Source/platform/Decimal.h - * Check UPSTREAM-GIT-SHA for the commit ID of the last update from Blink core. - */ - -#ifndef Decimal_h -#define Decimal_h - -#include "mozilla/Assertions.h" -#include -#include "mozilla/Types.h" - -#include - -#ifndef ASSERT -#define DEFINED_ASSERT_FOR_DECIMAL_H 1 -#define ASSERT MOZ_ASSERT -#endif - -#define PLATFORM_EXPORT - -// To use USING_FAST_MALLOC we'd need: -// https://chromium.googlesource.com/chromium/src.git/+/master/third_party/WebKit/Source/wtf/Allocator.h -// Since we don't allocate Decimal objects, no need. -#define USING_FAST_MALLOC(type) \ - void ignore_this_dummy_method() = delete - -#define DISALLOW_NEW() \ - private: \ - void* operator new(size_t) = delete; \ - void* operator new(size_t, void*) = delete; \ - public: - -namespace blink { - -namespace DecimalPrivate { -class SpecialValueHandler; -} - -// This class represents decimal base floating point number. -// -// FIXME: Once all C++ compiler support decimal type, we should replace this -// class to compiler supported one. See below URI for current status of decimal -// type for C++: // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1977.html -class PLATFORM_EXPORT Decimal { - USING_FAST_MALLOC(Decimal); -public: - enum Sign { - Positive, - Negative, - }; - - // You should not use EncodedData other than unit testing. - class EncodedData { - DISALLOW_NEW(); - // For accessing FormatClass. - friend class Decimal; - friend class DecimalPrivate::SpecialValueHandler; - public: - EncodedData(Sign, int exponent, uint64_t coefficient); - - bool operator==(const EncodedData&) const; - bool operator!=(const EncodedData& another) const { return !operator==(another); } - - uint64_t coefficient() const { return m_coefficient; } - int countDigits() const; - int exponent() const { return m_exponent; } - bool isFinite() const { return !isSpecial(); } - bool isInfinity() const { return m_formatClass == ClassInfinity; } - bool isNaN() const { return m_formatClass == ClassNaN; } - bool isSpecial() const { return m_formatClass == ClassInfinity || m_formatClass == ClassNaN; } - bool isZero() const { return m_formatClass == ClassZero; } - Sign sign() const { return m_sign; } - void setSign(Sign sign) { m_sign = sign; } - - private: - enum FormatClass { - ClassInfinity, - ClassNormal, - ClassNaN, - ClassZero, - }; - - EncodedData(Sign, FormatClass); - FormatClass formatClass() const { return m_formatClass; } - - uint64_t m_coefficient; - int16_t m_exponent; - FormatClass m_formatClass; - Sign m_sign; - }; - - MFBT_API explicit Decimal(int32_t = 0); - MFBT_API Decimal(Sign, int exponent, uint64_t coefficient); - MFBT_API Decimal(const Decimal&); - - MFBT_API Decimal& operator=(const Decimal&); - MFBT_API Decimal& operator+=(const Decimal&); - MFBT_API Decimal& operator-=(const Decimal&); - MFBT_API Decimal& operator*=(const Decimal&); - MFBT_API Decimal& operator/=(const Decimal&); - - MFBT_API Decimal operator-() const; - - MFBT_API bool operator==(const Decimal&) const; - MFBT_API bool operator!=(const Decimal&) const; - MFBT_API bool operator<(const Decimal&) const; - MFBT_API bool operator<=(const Decimal&) const; - MFBT_API bool operator>(const Decimal&) const; - MFBT_API bool operator>=(const Decimal&) const; - - MFBT_API Decimal operator+(const Decimal&) const; - MFBT_API Decimal operator-(const Decimal&) const; - MFBT_API Decimal operator*(const Decimal&) const; - MFBT_API Decimal operator/(const Decimal&) const; - - int exponent() const - { - ASSERT(isFinite()); - return m_data.exponent(); - } - - bool isFinite() const { return m_data.isFinite(); } - bool isInfinity() const { return m_data.isInfinity(); } - bool isNaN() const { return m_data.isNaN(); } - bool isNegative() const { return sign() == Negative; } - bool isPositive() const { return sign() == Positive; } - bool isSpecial() const { return m_data.isSpecial(); } - bool isZero() const { return m_data.isZero(); } - - MFBT_API Decimal abs() const; - MFBT_API Decimal ceil() const; - MFBT_API Decimal floor() const; - MFBT_API Decimal remainder(const Decimal&) const; - MFBT_API Decimal round() const; - - MFBT_API double toDouble() const; - // Note: toString method supports infinity and nan but fromString not. - MFBT_API std::string toString() const; - MFBT_API bool toString(char* strBuf, size_t bufLength) const; - - static MFBT_API Decimal fromDouble(double); - // fromString supports following syntax EBNF: - // number ::= sign? digit+ ('.' digit*) (exponent-marker sign? digit+)? - // | sign? '.' digit+ (exponent-marker sign? digit+)? - // sign ::= '+' | '-' - // exponent-marker ::= 'e' | 'E' - // digit ::= '0' | '1' | ... | '9' - // Note: fromString doesn't support "infinity" and "nan". - static MFBT_API Decimal fromString(const std::string& aValue); - static MFBT_API Decimal infinity(Sign); - static MFBT_API Decimal nan(); - static MFBT_API Decimal zero(Sign); - - // You should not use below methods. We expose them for unit testing. - MFBT_API explicit Decimal(const EncodedData&); - const EncodedData& value() const { return m_data; } - -private: - struct AlignedOperands { - uint64_t lhsCoefficient; - uint64_t rhsCoefficient; - int exponent; - }; - - MFBT_API explicit Decimal(double); - MFBT_API Decimal compareTo(const Decimal&) const; - - static MFBT_API AlignedOperands alignOperands(const Decimal& lhs, const Decimal& rhs); - static inline Sign invertSign(Sign sign) { return sign == Negative ? Positive : Negative; } - - Sign sign() const { return m_data.sign(); } - - EncodedData m_data; -}; - -} // namespace blink - -namespace mozilla { -typedef blink::Decimal Decimal; -} // namespace mozilla - -#undef USING_FAST_MALLOC - -#ifdef DEFINED_ASSERT_FOR_DECIMAL_H -#undef DEFINED_ASSERT_FOR_DECIMAL_H -#undef ASSERT -#endif - -#endif // Decimal_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/EndianUtils.h b/android/armeabi-v7a/include/spidermonkey/mozilla/EndianUtils.h deleted file mode 100644 index 00815580..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/EndianUtils.h +++ /dev/null @@ -1,695 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Functions for reading and writing integers in various endiannesses. */ - -/* - * The classes LittleEndian and BigEndian expose static methods for - * reading and writing 16-, 32-, and 64-bit signed and unsigned integers - * in their respective endianness. The naming scheme is: - * - * {Little,Big}Endian::{read,write}{Uint,Int} - * - * For instance, LittleEndian::readInt32 will read a 32-bit signed - * integer from memory in little endian format. Similarly, - * BigEndian::writeUint16 will write a 16-bit unsigned integer to memory - * in big-endian format. - * - * The class NativeEndian exposes methods for conversion of existing - * data to and from the native endianness. These methods are intended - * for cases where data needs to be transferred, serialized, etc. - * swap{To,From}{Little,Big}Endian byteswap a single value if necessary. - * Bulk conversion functions are also provided which optimize the - * no-conversion-needed case: - * - * - copyAndSwap{To,From}{Little,Big}Endian; - * - swap{To,From}{Little,Big}EndianInPlace. - * - * The *From* variants are intended to be used for reading data and the - * *To* variants for writing data. - * - * Methods on NativeEndian work with integer data of any type. - * Floating-point data is not supported. - * - * For clarity in networking code, "Network" may be used as a synonym - * for "Big" in any of the above methods or class names. - * - * As an example, reading a file format header whose fields are stored - * in big-endian format might look like: - * - * class ExampleHeader - * { - * private: - * uint32_t mMagic; - * uint32_t mLength; - * uint32_t mTotalRecords; - * uint64_t mChecksum; - * - * public: - * ExampleHeader(const void* data) - * { - * const uint8_t* ptr = static_cast(data); - * mMagic = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); - * mLength = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); - * mTotalRecords = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); - * mChecksum = BigEndian::readUint64(ptr); - * } - * ... - * }; - */ - -#ifndef mozilla_EndianUtils_h -#define mozilla_EndianUtils_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Compiler.h" -#include "mozilla/DebugOnly.h" -#include "mozilla/TypeTraits.h" - -#include -#include - -#if defined(_MSC_VER) -# include -# pragma intrinsic(_byteswap_ushort) -# pragma intrinsic(_byteswap_ulong) -# pragma intrinsic(_byteswap_uint64) -#endif - -#if defined(_WIN64) -# if defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_) -# define MOZ_LITTLE_ENDIAN 1 -# else -# error "CPU type is unknown" -# endif -#elif defined(_WIN32) -# if defined(_M_IX86) -# define MOZ_LITTLE_ENDIAN 1 -# elif defined(_M_ARM) -# define MOZ_LITTLE_ENDIAN 1 -# else -# error "CPU type is unknown" -# endif -#elif defined(__APPLE__) || defined(__powerpc__) || defined(__ppc__) -# if __LITTLE_ENDIAN__ -# define MOZ_LITTLE_ENDIAN 1 -# elif __BIG_ENDIAN__ -# define MOZ_BIG_ENDIAN 1 -# endif -#elif defined(__GNUC__) && \ - defined(__BYTE_ORDER__) && \ - defined(__ORDER_LITTLE_ENDIAN__) && \ - defined(__ORDER_BIG_ENDIAN__) - /* - * Some versions of GCC provide architecture-independent macros for - * this. Yes, there are more than two values for __BYTE_ORDER__. - */ -# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -# define MOZ_LITTLE_ENDIAN 1 -# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -# define MOZ_BIG_ENDIAN 1 -# else -# error "Can't handle mixed-endian architectures" -# endif -/* - * We can't include useful headers like or - * here because they're not present on all platforms. Instead we have - * this big conditional that ideally will catch all the interesting - * cases. - */ -#elif defined(__sparc) || defined(__sparc__) || \ - defined(_POWER) || defined(__hppa) || \ - defined(_MIPSEB) || defined(__ARMEB__) || \ - defined(__s390__) || defined(__AARCH64EB__) || \ - (defined(__sh__) && defined(__LITTLE_ENDIAN__)) || \ - (defined(__ia64) && defined(__BIG_ENDIAN__)) -# define MOZ_BIG_ENDIAN 1 -#elif defined(__i386) || defined(__i386__) || \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_MIPSEL) || defined(__ARMEL__) || \ - defined(__alpha__) || defined(__AARCH64EL__) || \ - (defined(__sh__) && defined(__BIG_ENDIAN__)) || \ - (defined(__ia64) && !defined(__BIG_ENDIAN__)) -# define MOZ_LITTLE_ENDIAN 1 -#endif - -#if MOZ_BIG_ENDIAN -# define MOZ_LITTLE_ENDIAN 0 -#elif MOZ_LITTLE_ENDIAN -# define MOZ_BIG_ENDIAN 0 -#else -# error "Cannot determine endianness" -#endif - -#if defined(__clang__) -# if __has_builtin(__builtin_bswap16) -# define MOZ_HAVE_BUILTIN_BYTESWAP16 __builtin_bswap16 -# endif -#elif defined(__GNUC__) -# define MOZ_HAVE_BUILTIN_BYTESWAP16 __builtin_bswap16 -#elif defined(_MSC_VER) -# define MOZ_HAVE_BUILTIN_BYTESWAP16 _byteswap_ushort -#endif - -namespace mozilla { - -namespace detail { - -/* - * We need wrappers here because free functions with default template - * arguments and/or partial specialization of function templates are not - * supported by all the compilers we use. - */ -template -struct Swapper; - -template -struct Swapper -{ - static T swap(T aValue) - { -#if defined(MOZ_HAVE_BUILTIN_BYTESWAP16) - return MOZ_HAVE_BUILTIN_BYTESWAP16(aValue); -#else - return T(((aValue & 0x00ff) << 8) | ((aValue & 0xff00) >> 8)); -#endif - } -}; - -template -struct Swapper -{ - static T swap(T aValue) - { -#if defined(__clang__) || defined(__GNUC__) - return T(__builtin_bswap32(aValue)); -#elif defined(_MSC_VER) - return T(_byteswap_ulong(aValue)); -#else - return T(((aValue & 0x000000ffU) << 24) | - ((aValue & 0x0000ff00U) << 8) | - ((aValue & 0x00ff0000U) >> 8) | - ((aValue & 0xff000000U) >> 24)); -#endif - } -}; - -template -struct Swapper -{ - static inline T swap(T aValue) - { -#if defined(__clang__) || defined(__GNUC__) - return T(__builtin_bswap64(aValue)); -#elif defined(_MSC_VER) - return T(_byteswap_uint64(aValue)); -#else - return T(((aValue & 0x00000000000000ffULL) << 56) | - ((aValue & 0x000000000000ff00ULL) << 40) | - ((aValue & 0x0000000000ff0000ULL) << 24) | - ((aValue & 0x00000000ff000000ULL) << 8) | - ((aValue & 0x000000ff00000000ULL) >> 8) | - ((aValue & 0x0000ff0000000000ULL) >> 24) | - ((aValue & 0x00ff000000000000ULL) >> 40) | - ((aValue & 0xff00000000000000ULL) >> 56)); -#endif - } -}; - -enum Endianness { Little, Big }; - -#if MOZ_BIG_ENDIAN -# define MOZ_NATIVE_ENDIANNESS detail::Big -#else -# define MOZ_NATIVE_ENDIANNESS detail::Little -#endif - -class EndianUtils -{ - /** - * Assert that the memory regions [aDest, aDest+aCount) and - * [aSrc, aSrc+aCount] do not overlap. aCount is given in bytes. - */ - static void assertNoOverlap(const void* aDest, const void* aSrc, - size_t aCount) - { - DebugOnly byteDestPtr = static_cast(aDest); - DebugOnly byteSrcPtr = static_cast(aSrc); - MOZ_ASSERT((byteDestPtr <= byteSrcPtr && - byteDestPtr + aCount <= byteSrcPtr) || - (byteSrcPtr <= byteDestPtr && - byteSrcPtr + aCount <= byteDestPtr)); - } - - template - static void assertAligned(T* aPtr) - { - MOZ_ASSERT((uintptr_t(aPtr) % sizeof(T)) == 0, "Unaligned pointer!"); - } - -protected: - /** - * Return |aValue| converted from SourceEndian encoding to DestEndian - * encoding. - */ - template - static inline T maybeSwap(T aValue) - { - if (SourceEndian == DestEndian) { - return aValue; - } - return Swapper::swap(aValue); - } - - /** - * Convert |aCount| elements at |aPtr| from SourceEndian encoding to - * DestEndian encoding. - */ - template - static inline void maybeSwapInPlace(T* aPtr, size_t aCount) - { - assertAligned(aPtr); - - if (SourceEndian == DestEndian) { - return; - } - for (size_t i = 0; i < aCount; i++) { - aPtr[i] = Swapper::swap(aPtr[i]); - } - } - - /** - * Write |aCount| elements to the unaligned address |aDest| in DestEndian - * format, using elements found at |aSrc| in SourceEndian format. - */ - template - static void copyAndSwapTo(void* aDest, const T* aSrc, size_t aCount) - { - assertNoOverlap(aDest, aSrc, aCount * sizeof(T)); - assertAligned(aSrc); - - if (SourceEndian == DestEndian) { - memcpy(aDest, aSrc, aCount * sizeof(T)); - return; - } - - uint8_t* byteDestPtr = static_cast(aDest); - for (size_t i = 0; i < aCount; ++i) { - union - { - T mVal; - uint8_t mBuffer[sizeof(T)]; - } u; - u.mVal = maybeSwap(aSrc[i]); - memcpy(byteDestPtr, u.mBuffer, sizeof(T)); - byteDestPtr += sizeof(T); - } - } - - /** - * Write |aCount| elements to |aDest| in DestEndian format, using elements - * found at the unaligned address |aSrc| in SourceEndian format. - */ - template - static void copyAndSwapFrom(T* aDest, const void* aSrc, size_t aCount) - { - assertNoOverlap(aDest, aSrc, aCount * sizeof(T)); - assertAligned(aDest); - - if (SourceEndian == DestEndian) { - memcpy(aDest, aSrc, aCount * sizeof(T)); - return; - } - - const uint8_t* byteSrcPtr = static_cast(aSrc); - for (size_t i = 0; i < aCount; ++i) { - union - { - T mVal; - uint8_t mBuffer[sizeof(T)]; - } u; - memcpy(u.mBuffer, byteSrcPtr, sizeof(T)); - aDest[i] = maybeSwap(u.mVal); - byteSrcPtr += sizeof(T); - } - } -}; - -template -class Endian : private EndianUtils -{ -protected: - /** Read a uint16_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE uint16_t readUint16(const void* aPtr) - { - return read(aPtr); - } - - /** Read a uint32_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE uint32_t readUint32(const void* aPtr) - { - return read(aPtr); - } - - /** Read a uint64_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE uint64_t readUint64(const void* aPtr) - { - return read(aPtr); - } - - /** Read an int16_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE int16_t readInt16(const void* aPtr) - { - return read(aPtr); - } - - /** Read an int32_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE int32_t readInt32(const void* aPtr) - { - return read(aPtr); - } - - /** Read an int64_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE int64_t readInt64(const void* aPtr) - { - return read(aPtr); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeUint16(void* aPtr, uint16_t aValue) - { - write(aPtr, aValue); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeUint32(void* aPtr, uint32_t aValue) - { - write(aPtr, aValue); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeUint64(void* aPtr, uint64_t aValue) - { - write(aPtr, aValue); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeInt16(void* aPtr, int16_t aValue) - { - write(aPtr, aValue); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeInt32(void* aPtr, int32_t aValue) - { - write(aPtr, aValue); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeInt64(void* aPtr, int64_t aValue) - { - write(aPtr, aValue); - } - - /* - * Converts a value of type T to little-endian format. - * - * This function is intended for cases where you have data in your - * native-endian format and you need it to appear in little-endian - * format for transmission. - */ - template - MOZ_MUST_USE static T swapToLittleEndian(T aValue) - { - return maybeSwap(aValue); - } - - /* - * Copies |aCount| values of type T starting at |aSrc| to |aDest|, converting - * them to little-endian format if ThisEndian is Big. - * As with memcpy, |aDest| and |aSrc| must not overlap. - */ - template - static void copyAndSwapToLittleEndian(void* aDest, const T* aSrc, - size_t aCount) - { - copyAndSwapTo(aDest, aSrc, aCount); - } - - /* - * Likewise, but converts values in place. - */ - template - static void swapToLittleEndianInPlace(T* aPtr, size_t aCount) - { - maybeSwapInPlace(aPtr, aCount); - } - - /* - * Converts a value of type T to big-endian format. - */ - template - MOZ_MUST_USE static T swapToBigEndian(T aValue) - { - return maybeSwap(aValue); - } - - /* - * Copies |aCount| values of type T starting at |aSrc| to |aDest|, converting - * them to big-endian format if ThisEndian is Little. - * As with memcpy, |aDest| and |aSrc| must not overlap. - */ - template - static void copyAndSwapToBigEndian(void* aDest, const T* aSrc, - size_t aCount) - { - copyAndSwapTo(aDest, aSrc, aCount); - } - - /* - * Likewise, but converts values in place. - */ - template - static void swapToBigEndianInPlace(T* aPtr, size_t aCount) - { - maybeSwapInPlace(aPtr, aCount); - } - - /* - * Synonyms for the big-endian functions, for better readability - * in network code. - */ - - template - MOZ_MUST_USE static T swapToNetworkOrder(T aValue) - { - return swapToBigEndian(aValue); - } - - template - static void - copyAndSwapToNetworkOrder(void* aDest, const T* aSrc, size_t aCount) - { - copyAndSwapToBigEndian(aDest, aSrc, aCount); - } - - template - static void - swapToNetworkOrderInPlace(T* aPtr, size_t aCount) - { - swapToBigEndianInPlace(aPtr, aCount); - } - - /* - * Converts a value of type T from little-endian format. - */ - template - MOZ_MUST_USE static T swapFromLittleEndian(T aValue) - { - return maybeSwap(aValue); - } - - /* - * Copies |aCount| values of type T starting at |aSrc| to |aDest|, converting - * them to little-endian format if ThisEndian is Big. - * As with memcpy, |aDest| and |aSrc| must not overlap. - */ - template - static void copyAndSwapFromLittleEndian(T* aDest, const void* aSrc, - size_t aCount) - { - copyAndSwapFrom(aDest, aSrc, aCount); - } - - /* - * Likewise, but converts values in place. - */ - template - static void swapFromLittleEndianInPlace(T* aPtr, size_t aCount) - { - maybeSwapInPlace(aPtr, aCount); - } - - /* - * Converts a value of type T from big-endian format. - */ - template - MOZ_MUST_USE static T swapFromBigEndian(T aValue) - { - return maybeSwap(aValue); - } - - /* - * Copies |aCount| values of type T starting at |aSrc| to |aDest|, converting - * them to big-endian format if ThisEndian is Little. - * As with memcpy, |aDest| and |aSrc| must not overlap. - */ - template - static void copyAndSwapFromBigEndian(T* aDest, const void* aSrc, - size_t aCount) - { - copyAndSwapFrom(aDest, aSrc, aCount); - } - - /* - * Likewise, but converts values in place. - */ - template - static void swapFromBigEndianInPlace(T* aPtr, size_t aCount) - { - maybeSwapInPlace(aPtr, aCount); - } - - /* - * Synonyms for the big-endian functions, for better readability - * in network code. - */ - template - MOZ_MUST_USE static T swapFromNetworkOrder(T aValue) - { - return swapFromBigEndian(aValue); - } - - template - static void copyAndSwapFromNetworkOrder(T* aDest, const void* aSrc, - size_t aCount) - { - copyAndSwapFromBigEndian(aDest, aSrc, aCount); - } - - template - static void swapFromNetworkOrderInPlace(T* aPtr, size_t aCount) - { - swapFromBigEndianInPlace(aPtr, aCount); - } - -private: - /** - * Read a value of type T, encoded in endianness ThisEndian from |aPtr|. - * Return that value encoded in native endianness. - */ - template - static T read(const void* aPtr) - { - union - { - T mVal; - uint8_t mBuffer[sizeof(T)]; - } u; - memcpy(u.mBuffer, aPtr, sizeof(T)); - return maybeSwap(u.mVal); - } - - /** - * Write a value of type T, in native endianness, to |aPtr|, in ThisEndian - * endianness. - */ - template - static void write(void* aPtr, T aValue) - { - T tmp = maybeSwap(aValue); - memcpy(aPtr, &tmp, sizeof(T)); - } - - Endian() = delete; - Endian(const Endian& aTther) = delete; - void operator=(const Endian& aOther) = delete; -}; - -template -class EndianReadWrite : public Endian -{ -private: - typedef Endian super; - -public: - using super::readUint16; - using super::readUint32; - using super::readUint64; - using super::readInt16; - using super::readInt32; - using super::readInt64; - using super::writeUint16; - using super::writeUint32; - using super::writeUint64; - using super::writeInt16; - using super::writeInt32; - using super::writeInt64; -}; - -} /* namespace detail */ - -class LittleEndian final : public detail::EndianReadWrite -{}; - -class BigEndian final : public detail::EndianReadWrite -{}; - -typedef BigEndian NetworkEndian; - -class NativeEndian final : public detail::Endian -{ -private: - typedef detail::Endian super; - -public: - /* - * These functions are intended for cases where you have data in your - * native-endian format and you need the data to appear in the appropriate - * endianness for transmission, serialization, etc. - */ - using super::swapToLittleEndian; - using super::copyAndSwapToLittleEndian; - using super::swapToLittleEndianInPlace; - using super::swapToBigEndian; - using super::copyAndSwapToBigEndian; - using super::swapToBigEndianInPlace; - using super::swapToNetworkOrder; - using super::copyAndSwapToNetworkOrder; - using super::swapToNetworkOrderInPlace; - - /* - * These functions are intended for cases where you have data in the - * given endianness (e.g. reading from disk or a file-format) and you - * need the data to appear in native-endian format for processing. - */ - using super::swapFromLittleEndian; - using super::copyAndSwapFromLittleEndian; - using super::swapFromLittleEndianInPlace; - using super::swapFromBigEndian; - using super::copyAndSwapFromBigEndian; - using super::swapFromBigEndianInPlace; - using super::swapFromNetworkOrder; - using super::copyAndSwapFromNetworkOrder; - using super::swapFromNetworkOrderInPlace; -}; - -#undef MOZ_NATIVE_ENDIANNESS - -} /* namespace mozilla */ - -#endif /* mozilla_EndianUtils_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/EnumSet.h b/android/armeabi-v7a/include/spidermonkey/mozilla/EnumSet.h deleted file mode 100644 index 5282ab30..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/EnumSet.h +++ /dev/null @@ -1,344 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A set abstraction for enumeration values. */ - -#ifndef mozilla_EnumSet_h -#define mozilla_EnumSet_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -#include - -#include - -namespace mozilla { - -/** - * EnumSet is a set of values defined by an enumeration. It is implemented - * using a 32 bit mask for each value so it will only work for enums with an int - * representation less than 32. It works both for enum and enum class types. - */ -template -class EnumSet -{ -public: - EnumSet() - : mBitField(0) - { - initVersion(); - } - - MOZ_IMPLICIT EnumSet(T aEnum) - : mBitField(bitFor(aEnum)) - { } - - EnumSet(T aEnum1, T aEnum2) - : mBitField(bitFor(aEnum1) | - bitFor(aEnum2)) - { - initVersion(); - } - - EnumSet(T aEnum1, T aEnum2, T aEnum3) - : mBitField(bitFor(aEnum1) | - bitFor(aEnum2) | - bitFor(aEnum3)) - { - initVersion(); - } - - EnumSet(T aEnum1, T aEnum2, T aEnum3, T aEnum4) - : mBitField(bitFor(aEnum1) | - bitFor(aEnum2) | - bitFor(aEnum3) | - bitFor(aEnum4)) - { - initVersion(); - } - - MOZ_IMPLICIT EnumSet(std::initializer_list list) - : mBitField(0) - { - for (auto value : list) { - (*this) += value; - } - initVersion(); - } - - EnumSet(const EnumSet& aEnumSet) - : mBitField(aEnumSet.mBitField) - { - initVersion(); - } - - /** - * Add an element - */ - void operator+=(T aEnum) - { - incVersion(); - mBitField |= bitFor(aEnum); - } - - /** - * Add an element - */ - EnumSet operator+(T aEnum) const - { - EnumSet result(*this); - result += aEnum; - return result; - } - - /** - * Union - */ - void operator+=(const EnumSet aEnumSet) - { - incVersion(); - mBitField |= aEnumSet.mBitField; - } - - /** - * Union - */ - EnumSet operator+(const EnumSet aEnumSet) const - { - EnumSet result(*this); - result += aEnumSet; - return result; - } - - /** - * Remove an element - */ - void operator-=(T aEnum) - { - incVersion(); - mBitField &= ~(bitFor(aEnum)); - } - - /** - * Remove an element - */ - EnumSet operator-(T aEnum) const - { - EnumSet result(*this); - result -= aEnum; - return result; - } - - /** - * Remove a set of elements - */ - void operator-=(const EnumSet aEnumSet) - { - incVersion(); - mBitField &= ~(aEnumSet.mBitField); - } - - /** - * Remove a set of elements - */ - EnumSet operator-(const EnumSet aEnumSet) const - { - EnumSet result(*this); - result -= aEnumSet; - return result; - } - - /** - * Clear - */ - void clear() - { - incVersion(); - mBitField = 0; - } - - /** - * Intersection - */ - void operator&=(const EnumSet aEnumSet) - { - incVersion(); - mBitField &= aEnumSet.mBitField; - } - - /** - * Intersection - */ - EnumSet operator&(const EnumSet aEnumSet) const - { - EnumSet result(*this); - result &= aEnumSet; - return result; - } - - /** - * Equality - */ - bool operator==(const EnumSet aEnumSet) const - { - return mBitField == aEnumSet.mBitField; - } - - /** - * Test is an element is contained in the set. - */ - bool contains(T aEnum) const - { - return mBitField & bitFor(aEnum); - } - - /** - * Return the number of elements in the set. - */ - uint8_t size() const - { - uint8_t count = 0; - for (uint32_t bitField = mBitField; bitField; bitField >>= 1) { - if (bitField & 1) { - count++; - } - } - return count; - } - - bool isEmpty() const - { - return mBitField == 0; - } - - uint32_t serialize() const - { - return mBitField; - } - - void deserialize(uint32_t aValue) - { - incVersion(); - mBitField = aValue; - } - - class ConstIterator - { - const EnumSet* mSet; - uint32_t mPos; -#ifdef DEBUG - uint64_t mVersion; -#endif - - void checkVersion() { - // Check that the set has not been modified while being iterated. - MOZ_ASSERT_IF(mSet, mSet->mVersion == mVersion); - } - - public: - ConstIterator(const EnumSet& aSet, uint32_t aPos) - : mSet(&aSet), mPos(aPos) - { -#ifdef DEBUG - mVersion = mSet->mVersion; -#endif - MOZ_ASSERT(aPos <= kMaxBits); - if (aPos != kMaxBits && !mSet->contains(T(mPos))) - ++*this; - } - - ConstIterator(const ConstIterator& aOther) - : mSet(aOther.mSet), mPos(aOther.mPos) - { -#ifdef DEBUG - mVersion = aOther.mVersion; - checkVersion(); -#endif - } - - ConstIterator(ConstIterator&& aOther) - : mSet(aOther.mSet), mPos(aOther.mPos) - { -#ifdef DEBUG - mVersion = aOther.mVersion; - checkVersion(); -#endif - aOther.mSet = nullptr; - } - - ~ConstIterator() { - checkVersion(); - } - - bool operator==(const ConstIterator& other) { - MOZ_ASSERT(mSet == other.mSet); - checkVersion(); - return mPos == other.mPos; - } - - bool operator!=(const ConstIterator& other) { - return !(*this == other); - } - - T operator*() { - MOZ_ASSERT(mSet); - MOZ_ASSERT(mPos < kMaxBits); - MOZ_ASSERT(mSet->contains(T(mPos))); - checkVersion(); - return T(mPos); - } - - ConstIterator& operator++() { - MOZ_ASSERT(mSet); - MOZ_ASSERT(mPos < kMaxBits); - checkVersion(); - do { - mPos++; - } while (mPos < kMaxBits && !mSet->contains(T(mPos))); - return *this; - } - }; - - ConstIterator begin() const { - return ConstIterator(*this, 0); - } - - ConstIterator end() const { - return ConstIterator(*this, kMaxBits); - } - -private: - static uint32_t bitFor(T aEnum) - { - uint32_t bitNumber = (uint32_t)aEnum; - MOZ_ASSERT(bitNumber < kMaxBits); - return 1U << bitNumber; - } - - void initVersion() { -#ifdef DEBUG - mVersion = 0; -#endif - } - - void incVersion() { -#ifdef DEBUG - mVersion++; -#endif - } - - static const size_t kMaxBits = 32; - uint32_t mBitField; - -#ifdef DEBUG - uint64_t mVersion; -#endif -}; - -} // namespace mozilla - -#endif /* mozilla_EnumSet_h_*/ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/EnumTypeTraits.h b/android/armeabi-v7a/include/spidermonkey/mozilla/EnumTypeTraits.h deleted file mode 100644 index 223eaf8c..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/EnumTypeTraits.h +++ /dev/null @@ -1,70 +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/. */ - -/* Type traits for enums. */ - -#ifndef mozilla_EnumTypeTraits_h -#define mozilla_EnumTypeTraits_h - -#include - -namespace mozilla { - -namespace detail { - -template -struct EnumFitsWithinHelper; - -// Signed enum, signed storage. -template -struct EnumFitsWithinHelper - : public std::integral_constant -{}; - -// Signed enum, unsigned storage. -template -struct EnumFitsWithinHelper - : public std::integral_constant -{}; - -// Unsigned enum, signed storage. -template -struct EnumFitsWithinHelper - : public std::integral_constant -{}; - -// Unsigned enum, unsigned storage. -template -struct EnumFitsWithinHelper - : public std::integral_constant -{}; - -} // namespace detail - -/* - * Type trait that determines whether the enum type T can fit within the - * integral type Storage without data loss. This trait should be used with - * caution with an enum type whose underlying type has not been explicitly - * specified: for such enums, the C++ implementation is free to choose a type - * no smaller than int whose range encompasses all possible values of the enum. - * So for an enum with only small non-negative values, the underlying type may - * be either int or unsigned int, depending on the whims of the implementation. - */ -template -struct EnumTypeFitsWithin - : public detail::EnumFitsWithinHelper< - sizeof(T), - std::is_signed::type>::value, - sizeof(Storage), - std::is_signed::value - > -{ - static_assert(std::is_enum::value, "must provide an enum type"); - static_assert(std::is_integral::value, "must provide an integral type"); -}; - -} // namespace mozilla - -#endif /* mozilla_EnumTypeTraits_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/EnumeratedArray.h b/android/armeabi-v7a/include/spidermonkey/mozilla/EnumeratedArray.h deleted file mode 100644 index 9e74b772..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/EnumeratedArray.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* EnumeratedArray is like Array, but indexed by a typed enum. */ - -#ifndef mozilla_EnumeratedArray_h -#define mozilla_EnumeratedArray_h - -#include "mozilla/Array.h" -#include "mozilla/Move.h" - -namespace mozilla { - -/** - * EnumeratedArray is a fixed-size array container for use when an - * array is indexed by a specific enum class. - * - * This provides type safety by guarding at compile time against accidentally - * indexing such arrays with unrelated values. This also removes the need - * for manual casting when using a typed enum value to index arrays. - * - * Aside from the typing of indices, EnumeratedArray is similar to Array. - * - * Example: - * - * enum class AnimalSpecies { - * Cow, - * Sheep, - * Count - * }; - * - * EnumeratedArray headCount; - * - * headCount[AnimalSpecies::Cow] = 17; - * headCount[AnimalSpecies::Sheep] = 30; - * - */ -template -class EnumeratedArray -{ -public: - static const size_t kSize = size_t(SizeAsEnumValue); - -private: - typedef Array ArrayType; - - ArrayType mArray; - -public: - EnumeratedArray() {} - - template - MOZ_IMPLICIT EnumeratedArray(Args&&... aArgs) - : mArray{mozilla::Forward(aArgs)...} - {} - - explicit EnumeratedArray(const EnumeratedArray& aOther) - { - for (size_t i = 0; i < kSize; i++) { - mArray[i] = aOther.mArray[i]; - } - } - - EnumeratedArray(EnumeratedArray&& aOther) - { - for (size_t i = 0; i < kSize; i++) { - mArray[i] = Move(aOther.mArray[i]); - } - } - - ValueType& operator[](IndexType aIndex) - { - return mArray[size_t(aIndex)]; - } - - const ValueType& operator[](IndexType aIndex) const - { - return mArray[size_t(aIndex)]; - } - - typedef typename ArrayType::iterator iterator; - typedef typename ArrayType::const_iterator const_iterator; - typedef typename ArrayType::reverse_iterator reverse_iterator; - typedef typename ArrayType::const_reverse_iterator const_reverse_iterator; - - // Methods for range-based for loops. - iterator begin() { return mArray.begin(); } - const_iterator begin() const { return mArray.begin(); } - const_iterator cbegin() const { return mArray.cbegin(); } - iterator end() { return mArray.end(); } - const_iterator end() const { return mArray.end(); } - const_iterator cend() const { return mArray.cend(); } - - // Methods for reverse iterating. - reverse_iterator rbegin() { return mArray.rbegin(); } - const_reverse_iterator rbegin() const { return mArray.rbegin(); } - const_reverse_iterator crbegin() const { return mArray.crbegin(); } - reverse_iterator rend() { return mArray.rend(); } - const_reverse_iterator rend() const { return mArray.rend(); } - const_reverse_iterator crend() const { return mArray.crend(); } -}; - -} // namespace mozilla - -#endif // mozilla_EnumeratedArray_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/EnumeratedRange.h b/android/armeabi-v7a/include/spidermonkey/mozilla/EnumeratedRange.h deleted file mode 100644 index b158f8a3..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/EnumeratedRange.h +++ /dev/null @@ -1,201 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Iterator over contiguous enum values */ - -/* - * Implements generator functions that create a range to iterate over the values - * of a scoped or unscoped enum. Unlike IntegerRange, which can only function on - * the underlying integral type, the elements of the generated sequence will - * have the type of the enum in question. - * - * Note that the enum values should be contiguous in the iterated range; - * unfortunately there exists no way for EnumeratedRange to enforce this - * either dynamically or at compile time. - */ - -#ifndef mozilla_EnumeratedRange_h -#define mozilla_EnumeratedRange_h - -#include - -#include "mozilla/ReverseIterator.h" - -namespace mozilla { - -namespace detail { - -template -class EnumeratedIterator -{ -public: - typedef typename std::underlying_type::type IntTypeT; - - template - explicit EnumeratedIterator(EnumType aCurrent) - : mCurrent(aCurrent) { } - - template - explicit EnumeratedIterator(const EnumeratedIterator& aOther) - : mCurrent(aOther.mCurrent) { } - - EnumTypeT operator*() const { return mCurrent; } - - /* Increment and decrement operators */ - - EnumeratedIterator& operator++() - { - mCurrent = EnumTypeT(IntTypeT(mCurrent) + IntTypeT(1)); - return *this; - } - EnumeratedIterator& operator--() - { - mCurrent = EnumTypeT(IntTypeT(mCurrent) - IntTypeT(1)); - return *this; - } - EnumeratedIterator operator++(int) - { - auto ret = *this; - mCurrent = EnumTypeT(IntTypeT(mCurrent) + IntTypeT(1)); - return ret; - } - EnumeratedIterator operator--(int) - { - auto ret = *this; - mCurrent = EnumTypeT(IntTypeT(mCurrent) - IntTypeT(1)); - return ret; - } - - /* Comparison operators */ - - template - friend bool operator==(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - template - friend bool operator!=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - template - friend bool operator<(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - template - friend bool operator<=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - template - friend bool operator>(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - template - friend bool operator>=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - -private: - EnumTypeT mCurrent; -}; - -template -bool operator==(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent == aIter2.mCurrent; -} - -template -bool operator!=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent != aIter2.mCurrent; -} - -template -bool operator<(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent < aIter2.mCurrent; -} - -template -bool operator<=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent <= aIter2.mCurrent; -} - -template -bool operator>(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent > aIter2.mCurrent; -} - -template -bool operator>=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent >= aIter2.mCurrent; -} - -template -class EnumeratedRange -{ -public: - typedef EnumeratedIterator iterator; - typedef EnumeratedIterator const_iterator; - typedef ReverseIterator reverse_iterator; - typedef ReverseIterator const_reverse_iterator; - - template - EnumeratedRange(EnumType aBegin, EnumType aEnd) - : mBegin(aBegin), mEnd(aEnd) { } - - iterator begin() const { return iterator(mBegin); } - const_iterator cbegin() const { return begin(); } - iterator end() const { return iterator(mEnd); } - const_iterator cend() const { return end(); } - reverse_iterator rbegin() const { return reverse_iterator(mEnd); } - const_reverse_iterator crbegin() const { return rbegin(); } - reverse_iterator rend() const { return reverse_iterator(mBegin); } - const_reverse_iterator crend() const { return rend(); } - -private: - EnumTypeT mBegin; - EnumTypeT mEnd; -}; - -} // namespace detail - -#ifdef __GNUC__ -// Enums can have an unsigned underlying type, which makes some of the -// comparisons below always true or always false. Temporarily disable -// -Wtype-limits to avoid breaking -Werror builds. -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wtype-limits" -#endif - -// Create a range to iterate from aBegin to aEnd, exclusive. -template -inline detail::EnumeratedRange -MakeEnumeratedRange(EnumType aBegin, EnumType aEnd) -{ - MOZ_ASSERT(aBegin <= aEnd, "Cannot generate invalid, unbounded range!"); - return detail::EnumeratedRange(aBegin, aEnd); -} - -// Create a range to iterate from EnumType(0) to aEnd, exclusive. EnumType(0) -// should exist, but note that there is no way for us to ensure that it does! -template -inline detail::EnumeratedRange -MakeEnumeratedRange(EnumType aEnd) -{ - return MakeEnumeratedRange(EnumType(0), aEnd); -} - -#ifdef __GNUC__ -# pragma GCC diagnostic pop -#endif - -} // namespace mozilla - -#endif // mozilla_EnumeratedRange_h - diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/FastBernoulliTrial.h b/android/armeabi-v7a/include/spidermonkey/mozilla/FastBernoulliTrial.h deleted file mode 100644 index 7e38b70a..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/FastBernoulliTrial.h +++ /dev/null @@ -1,379 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_FastBernoulliTrial_h -#define mozilla_FastBernoulliTrial_h - -#include "mozilla/Assertions.h" -#include "mozilla/XorShift128PlusRNG.h" - -#include -#include - -namespace mozilla { - -/** - * class FastBernoulliTrial: Efficient sampling with uniform probability - * - * When gathering statistics about a program's behavior, we may be observing - * events that occur very frequently (e.g., function calls or memory - * allocations) and we may be gathering information that is somewhat expensive - * to produce (e.g., call stacks). Sampling all the events could have a - * significant impact on the program's performance. - * - * Why not just sample every N'th event? This technique is called "systematic - * sampling"; it's simple and efficient, and it's fine if we imagine a - * patternless stream of events. But what if we're sampling allocations, and the - * program happens to have a loop where each iteration does exactly N - * allocations? You would end up sampling the same allocation every time through - * the loop; the entire rest of the loop becomes invisible to your measurements! - * More generally, if each iteration does M allocations, and M and N have any - * common divisor at all, most allocation sites will never be sampled. If - * they're both even, say, the odd-numbered allocations disappear from your - * results. - * - * Ideally, we'd like each event to have some probability P of being sampled, - * independent of its neighbors and of its position in the sequence. This is - * called "Bernoulli sampling", and it doesn't suffer from any of the problems - * mentioned above. - * - * One disadvantage of Bernoulli sampling is that you can't be sure exactly how - * many samples you'll get: technically, it's possible that you might sample - * none of them, or all of them. But if the number of events N is large, these - * aren't likely outcomes; you can generally expect somewhere around P * N - * events to be sampled. - * - * The other disadvantage of Bernoulli sampling is that you have to generate a - * random number for every event, which can be slow. - * - * [significant pause] - * - * BUT NOT WITH THIS CLASS! FastBernoulliTrial lets you do true Bernoulli - * sampling, while generating a fresh random number only when we do decide to - * sample an event, not on every trial. When it decides not to sample, a call to - * |FastBernoulliTrial::trial| is nothing but decrementing a counter and - * comparing it to zero. So the lower your sampling probability is, the less - * overhead FastBernoulliTrial imposes. - * - * Probabilities of 0 and 1 are handled efficiently. (In neither case need we - * ever generate a random number at all.) - * - * The essential API: - * - * - FastBernoulliTrial(double P) - * Construct an instance that selects events with probability P. - * - * - FastBernoulliTrial::trial() - * Return true with probability P. Call this each time an event occurs, to - * decide whether to sample it or not. - * - * - FastBernoulliTrial::trial(size_t n) - * Equivalent to calling trial() |n| times, and returning true if any of those - * calls do. However, like trial, this runs in fast constant time. - * - * What is this good for? In some applications, some events are "bigger" than - * others. For example, large allocations are more significant than small - * allocations. Perhaps we'd like to imagine that we're drawing allocations - * from a stream of bytes, and performing a separate Bernoulli trial on every - * byte from the stream. We can accomplish this by calling |t.trial(S)| for - * the number of bytes S, and sampling the event if that returns true. - * - * Of course, this style of sampling needs to be paired with analysis and - * presentation that makes the size of the event apparent, lest trials with - * large values for |n| appear to be indistinguishable from those with small - * values for |n|. - */ -class FastBernoulliTrial { - /* - * This comment should just read, "Generate skip counts with a geometric - * distribution", and leave everyone to go look that up and see why it's the - * right thing to do, if they don't know already. - * - * BUT IF YOU'RE CURIOUS, COMMENTS ARE FREE... - * - * Instead of generating a fresh random number for every trial, we can - * randomly generate a count of how many times we should return false before - * the next time we return true. We call this a "skip count". Once we've - * returned true, we generate a fresh skip count, and begin counting down - * again. - * - * Here's an awesome fact: by exercising a little care in the way we generate - * skip counts, we can produce results indistinguishable from those we would - * get "rolling the dice" afresh for every trial. - * - * In short, skip counts in Bernoulli trials of probability P obey a geometric - * distribution. If a random variable X is uniformly distributed from [0..1), - * then std::floor(std::log(X) / std::log(1-P)) has the appropriate geometric - * distribution for the skip counts. - * - * Why that formula? - * - * Suppose we're to return |true| with some probability P, say, 0.3. Spread - * all possible futures along a line segment of length 1. In portion P of - * those cases, we'll return true on the next call to |trial|; the skip count - * is 0. For the remaining portion 1-P of cases, the skip count is 1 or more. - * - * skip: 0 1 or more - * |------------------^-----------------------------------------| - * portion: 0.3 0.7 - * P 1-P - * - * But the "1 or more" section of the line is subdivided the same way: *within - * that section*, in portion P the second call to |trial()| returns true, and in - * portion 1-P it returns false a second time; the skip count is two or more. - * So we return true on the second call in proportion 0.7 * 0.3, and skip at - * least the first two in proportion 0.7 * 0.7. - * - * skip: 0 1 2 or more - * |------------------^------------^----------------------------| - * portion: 0.3 0.7 * 0.3 0.7 * 0.7 - * P (1-P)*P (1-P)^2 - * - * We can continue to subdivide: - * - * skip >= 0: |------------------------------------------------- (1-P)^0 --| - * skip >= 1: | ------------------------------- (1-P)^1 --| - * skip >= 2: | ------------------ (1-P)^2 --| - * skip >= 3: | ^ ---------- (1-P)^3 --| - * skip >= 4: | . --- (1-P)^4 --| - * . - * ^X, see below - * - * In other words, the likelihood of the next n calls to |trial| returning - * false is (1-P)^n. The longer a run we require, the more the likelihood - * drops. Further calls may return false too, but this is the probability - * we'll skip at least n. - * - * This is interesting, because we can pick a point along this line segment - * and see which skip count's range it falls within; the point X above, for - * example, is within the ">= 2" range, but not within the ">= 3" range, so it - * designates a skip count of 2. So if we pick points on the line at random - * and use the skip counts they fall under, that will be indistinguishable - * from generating a fresh random number between 0 and 1 for each trial and - * comparing it to P. - * - * So to find the skip count for a point X, we must ask: To what whole power - * must we raise 1-P such that we include X, but the next power would exclude - * it? This is exactly std::floor(std::log(X) / std::log(1-P)). - * - * Our algorithm is then, simply: When constructed, compute an initial skip - * count. Return false from |trial| that many times, and then compute a new skip - * count. - * - * For a call to |trial(n)|, if the skip count is greater than n, return false - * and subtract n from the skip count. If the skip count is less than n, - * return true and compute a new skip count. Since each trial is independent, - * it doesn't matter by how much n overshoots the skip count; we can actually - * compute a new skip count at *any* time without affecting the distribution. - * This is really beautiful. - */ - public: - /** - * Construct a fast Bernoulli trial generator. Calls to |trial()| return true - * with probability |aProbability|. Use |aState0| and |aState1| to seed the - * random number generator; both may not be zero. - */ - FastBernoulliTrial(double aProbability, uint64_t aState0, uint64_t aState1) - : mProbability(0) - , mInvLogNotProbability(0) - , mGenerator(aState0, aState1) - , mSkipCount(0) - { - setProbability(aProbability); - } - - /** - * Return true with probability |mProbability|. Call this each time an event - * occurs, to decide whether to sample it or not. The lower |mProbability| is, - * the faster this function runs. - */ - bool trial() { - if (mSkipCount) { - mSkipCount--; - return false; - } - - return chooseSkipCount(); - } - - /** - * Equivalent to calling trial() |n| times, and returning true if any of those - * calls do. However, like trial, this runs in fast constant time. - * - * What is this good for? In some applications, some events are "bigger" than - * others. For example, large allocations are more significant than small - * allocations. Perhaps we'd like to imagine that we're drawing allocations - * from a stream of bytes, and performing a separate Bernoulli trial on every - * byte from the stream. We can accomplish this by calling |t.trial(S)| for - * the number of bytes S, and sampling the event if that returns true. - * - * Of course, this style of sampling needs to be paired with analysis and - * presentation that makes the "size" of the event apparent, lest trials with - * large values for |n| appear to be indistinguishable from those with small - * values for |n|, despite being potentially much more likely to be sampled. - */ - bool trial(size_t aCount) { - if (mSkipCount > aCount) { - mSkipCount -= aCount; - return false; - } - - return chooseSkipCount(); - } - - void setRandomState(uint64_t aState0, uint64_t aState1) { - mGenerator.setState(aState0, aState1); - } - - void setProbability(double aProbability) { - MOZ_ASSERT(0 <= aProbability && aProbability <= 1); - mProbability = aProbability; - if (0 < mProbability && mProbability < 1) { - /* - * Let's look carefully at how this calculation plays out in floating- - * point arithmetic. We'll assume IEEE, but the final C++ code we arrive - * at would still be fine if our numbers were mathematically perfect. So, - * while we've considered IEEE's edge cases, we haven't done anything that - * should be actively bad when using other representations. - * - * (In the below, read comparisons as exact mathematical comparisons: when - * we say something "equals 1", that means it's exactly equal to 1. We - * treat approximation using intervals with open boundaries: saying a - * value is in (0,1) doesn't specify how close to 0 or 1 the value gets. - * When we use closed boundaries like [2**-53, 1], we're careful to ensure - * the boundary values are actually representable.) - * - * - After the comparison above, we know mProbability is in (0,1). - * - * - The gaps below 1 are 2**-53, so that interval is (0, 1-2**-53]. - * - * - Because the floating-point gaps near 1 are wider than those near - * zero, there are many small positive doubles ε such that 1-ε rounds to - * exactly 1. However, 2**-53 can be represented exactly. So - * 1-mProbability is in [2**-53, 1]. - * - * - log(1 - mProbability) is thus in (-37, 0]. - * - * That range includes zero, but when we use mInvLogNotProbability, it - * would be helpful if we could trust that it's negative. So when log(1 - * - mProbability) is 0, we'll just set mProbability to 0, so that - * mInvLogNotProbability is not used in chooseSkipCount. - * - * - How much of the range of mProbability does this cause us to ignore? - * The only value for which log returns 0 is exactly 1; the slope of log - * at 1 is 1, so for small ε such that 1 - ε != 1, log(1 - ε) is -ε, - * never 0. The gaps near one are larger than the gaps near zero, so if - * 1 - ε wasn't 1, then -ε is representable. So if log(1 - mProbability) - * isn't 0, then 1 - mProbability isn't 1, which means that mProbability - * is at least 2**-53, as discussed earlier. This is a sampling - * likelihood of roughly one in ten trillion, which is unlikely to be - * distinguishable from zero in practice. - * - * So by forbidding zero, we've tightened our range to (-37, -2**-53]. - * - * - Finally, 1 / log(1 - mProbability) is in [-2**53, -1/37). This all - * falls readily within the range of an IEEE double. - * - * ALL THAT HAVING BEEN SAID: here are the five lines of actual code: - */ - double logNotProbability = std::log(1 - mProbability); - if (logNotProbability == 0.0) - mProbability = 0.0; - else - mInvLogNotProbability = 1 / logNotProbability; - } - - chooseSkipCount(); - } - - private: - /* The likelihood that any given call to |trial| should return true. */ - double mProbability; - - /* - * The value of 1/std::log(1 - mProbability), cached for repeated use. - * - * If mProbability is exactly 0 or exactly 1, we don't use this value. - * Otherwise, we guarantee this value is in the range [-2**53, -1/37), i.e. - * definitely negative, as required by chooseSkipCount. See setProbability for - * the details. - */ - double mInvLogNotProbability; - - /* Our random number generator. */ - non_crypto::XorShift128PlusRNG mGenerator; - - /* The number of times |trial| should return false before next returning true. */ - size_t mSkipCount; - - /* - * Choose the next skip count. This also returns the value that |trial| should - * return, since we have to check for the extreme values for mProbability - * anyway, and |trial| should never return true at all when mProbability is 0. - */ - bool chooseSkipCount() { - /* - * If the probability is 1.0, every call to |trial| returns true. Make sure - * mSkipCount is 0. - */ - if (mProbability == 1.0) { - mSkipCount = 0; - return true; - } - - /* - * If the probabilility is zero, |trial| never returns true. Don't bother us - * for a while. - */ - if (mProbability == 0.0) { - mSkipCount = SIZE_MAX; - return false; - } - - /* - * What sorts of values can this call to std::floor produce? - * - * Since mGenerator.nextDouble returns a value in [0, 1-2**-53], std::log - * returns a value in the range [-infinity, -2**-53], all negative. Since - * mInvLogNotProbability is negative (see its comments), the product is - * positive and possibly infinite. std::floor returns +infinity unchanged. - * So the result will always be positive. - * - * Converting a double to an integer that is out of range for that integer - * is undefined behavior, so we must clamp our result to SIZE_MAX, to ensure - * we get an acceptable value for mSkipCount. - * - * The clamp is written carefully. Note that if we had said: - * - * if (skipCount > SIZE_MAX) - * skipCount = SIZE_MAX; - * - * that leads to undefined behavior 64-bit machines: SIZE_MAX coerced to - * double is 2^64, not 2^64-1, so this doesn't actually set skipCount to a - * value that can be safely assigned to mSkipCount. - * - * Jakub Oleson cleverly suggested flipping the sense of the comparison: if - * we require that skipCount < SIZE_MAX, then because of the gaps (2048) - * between doubles at that magnitude, the highest double less than 2^64 is - * 2^64 - 2048, which is fine to store in a size_t. - * - * (On 32-bit machines, all size_t values can be represented exactly in - * double, so all is well.) - */ - double skipCount = std::floor(std::log(mGenerator.nextDouble()) - * mInvLogNotProbability); - if (skipCount < SIZE_MAX) - mSkipCount = skipCount; - else - mSkipCount = SIZE_MAX; - - return true; - } -}; - -} /* namespace mozilla */ - -#endif /* mozilla_FastBernoulliTrial_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/FloatingPoint.h b/android/armeabi-v7a/include/spidermonkey/mozilla/FloatingPoint.h deleted file mode 100644 index 59afccd1..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/FloatingPoint.h +++ /dev/null @@ -1,479 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Various predicates and operations on IEEE-754 floating point types. */ - -#ifndef mozilla_FloatingPoint_h -#define mozilla_FloatingPoint_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Casting.h" -#include "mozilla/MathAlgorithms.h" -#include "mozilla/Types.h" - -#include - -namespace mozilla { - -/* - * It's reasonable to ask why we have this header at all. Don't isnan, - * copysign, the built-in comparison operators, and the like solve these - * problems? Unfortunately, they don't. We've found that various compilers - * (MSVC, MSVC when compiling with PGO, and GCC on OS X, at least) miscompile - * the standard methods in various situations, so we can't use them. Some of - * these compilers even have problems compiling seemingly reasonable bitwise - * algorithms! But with some care we've found algorithms that seem to not - * trigger those compiler bugs. - * - * For the aforementioned reasons, be very wary of making changes to any of - * these algorithms. If you must make changes, keep a careful eye out for - * compiler bustage, particularly PGO-specific bustage. - */ - -struct FloatTypeTraits -{ - typedef uint32_t Bits; - - static const unsigned kExponentBias = 127; - static const unsigned kExponentShift = 23; - - static const Bits kSignBit = 0x80000000UL; - static const Bits kExponentBits = 0x7F800000UL; - static const Bits kSignificandBits = 0x007FFFFFUL; -}; - -struct DoubleTypeTraits -{ - typedef uint64_t Bits; - - static const unsigned kExponentBias = 1023; - static const unsigned kExponentShift = 52; - - static const Bits kSignBit = 0x8000000000000000ULL; - static const Bits kExponentBits = 0x7ff0000000000000ULL; - static const Bits kSignificandBits = 0x000fffffffffffffULL; -}; - -template struct SelectTrait; -template<> struct SelectTrait : public FloatTypeTraits {}; -template<> struct SelectTrait : public DoubleTypeTraits {}; - -/* - * This struct contains details regarding the encoding of floating-point - * numbers that can be useful for direct bit manipulation. As of now, the - * template parameter has to be float or double. - * - * The nested typedef |Bits| is the unsigned integral type with the same size - * as T: uint32_t for float and uint64_t for double (static assertions - * double-check these assumptions). - * - * kExponentBias is the offset that is subtracted from the exponent when - * computing the value, i.e. one plus the opposite of the mininum possible - * exponent. - * kExponentShift is the shift that one needs to apply to retrieve the - * exponent component of the value. - * - * kSignBit contains a bits mask. Bit-and-ing with this mask will result in - * obtaining the sign bit. - * kExponentBits contains the mask needed for obtaining the exponent bits and - * kSignificandBits contains the mask needed for obtaining the significand - * bits. - * - * Full details of how floating point number formats are encoded are beyond - * the scope of this comment. For more information, see - * http://en.wikipedia.org/wiki/IEEE_floating_point - * http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers - */ -template -struct FloatingPoint : public SelectTrait -{ - typedef SelectTrait Base; - typedef typename Base::Bits Bits; - - static_assert((Base::kSignBit & Base::kExponentBits) == 0, - "sign bit shouldn't overlap exponent bits"); - static_assert((Base::kSignBit & Base::kSignificandBits) == 0, - "sign bit shouldn't overlap significand bits"); - static_assert((Base::kExponentBits & Base::kSignificandBits) == 0, - "exponent bits shouldn't overlap significand bits"); - - static_assert((Base::kSignBit | Base::kExponentBits | Base::kSignificandBits) == - ~Bits(0), - "all bits accounted for"); - - /* - * These implementations assume float/double are 32/64-bit single/double - * format number types compatible with the IEEE-754 standard. C++ don't - * require this to be the case. But we required this in implementations of - * these algorithms that preceded this header, so we shouldn't break anything - * if we keep doing so. - */ - static_assert(sizeof(T) == sizeof(Bits), "Bits must be same size as T"); -}; - -/** Determines whether a float/double is NaN. */ -template -static MOZ_ALWAYS_INLINE bool -IsNaN(T aValue) -{ - /* - * A float/double is NaN if all exponent bits are 1 and the significand - * contains at least one non-zero bit. - */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - return (BitwiseCast(aValue) & Traits::kExponentBits) == Traits::kExponentBits && - (BitwiseCast(aValue) & Traits::kSignificandBits) != 0; -} - -/** Determines whether a float/double is +Infinity or -Infinity. */ -template -static MOZ_ALWAYS_INLINE bool -IsInfinite(T aValue) -{ - /* Infinities have all exponent bits set to 1 and an all-0 significand. */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return (bits & ~Traits::kSignBit) == Traits::kExponentBits; -} - -/** Determines whether a float/double is not NaN or infinite. */ -template -static MOZ_ALWAYS_INLINE bool -IsFinite(T aValue) -{ - /* - * NaN and Infinities are the only non-finite floats/doubles, and both have - * all exponent bits set to 1. - */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return (bits & Traits::kExponentBits) != Traits::kExponentBits; -} - -/** - * Determines whether a float/double is negative or -0. It is an error - * to call this method on a float/double which is NaN. - */ -template -static MOZ_ALWAYS_INLINE bool -IsNegative(T aValue) -{ - MOZ_ASSERT(!IsNaN(aValue), "NaN does not have a sign"); - - /* The sign bit is set if the double is negative. */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return (bits & Traits::kSignBit) != 0; -} - -/** Determines whether a float/double represents -0. */ -template -static MOZ_ALWAYS_INLINE bool -IsNegativeZero(T aValue) -{ - /* Only the sign bit is set if the value is -0. */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return bits == Traits::kSignBit; -} - -/** Determines wether a float/double represents +0. */ -template -static MOZ_ALWAYS_INLINE bool -IsPositiveZero(T aValue) -{ - /* All bits are zero if the value is +0. */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return bits == 0; -} - -/** - * Returns 0 if a float/double is NaN or infinite; - * otherwise, the float/double is returned. - */ -template -static MOZ_ALWAYS_INLINE T -ToZeroIfNonfinite(T aValue) -{ - return IsFinite(aValue) ? aValue : 0; -} - -/** - * Returns the exponent portion of the float/double. - * - * Zero is not special-cased, so ExponentComponent(0.0) is - * -int_fast16_t(Traits::kExponentBias). - */ -template -static MOZ_ALWAYS_INLINE int_fast16_t -ExponentComponent(T aValue) -{ - /* - * The exponent component of a float/double is an unsigned number, biased - * from its actual value. Subtract the bias to retrieve the actual exponent. - */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return int_fast16_t((bits & Traits::kExponentBits) >> Traits::kExponentShift) - - int_fast16_t(Traits::kExponentBias); -} - -/** Returns +Infinity. */ -template -static MOZ_ALWAYS_INLINE T -PositiveInfinity() -{ - /* - * Positive infinity has all exponent bits set, sign bit set to 0, and no - * significand. - */ - typedef FloatingPoint Traits; - return BitwiseCast(Traits::kExponentBits); -} - -/** Returns -Infinity. */ -template -static MOZ_ALWAYS_INLINE T -NegativeInfinity() -{ - /* - * Negative infinity has all exponent bits set, sign bit set to 1, and no - * significand. - */ - typedef FloatingPoint Traits; - return BitwiseCast(Traits::kSignBit | Traits::kExponentBits); -} - -/** - * Computes the bit pattern for a NaN with the specified sign bit and - * significand bits. - */ -template::Bits Significand> -struct SpecificNaNBits -{ - using Traits = FloatingPoint; - - static_assert(SignBit == 0 || SignBit == 1, "bad sign bit"); - static_assert((Significand & ~Traits::kSignificandBits) == 0, - "significand must only have significand bits set"); - static_assert(Significand & Traits::kSignificandBits, - "significand must be nonzero"); - - static constexpr typename Traits::Bits value = - (SignBit * Traits::kSignBit) | Traits::kExponentBits | Significand; -}; - -/** - * Constructs a NaN value with the specified sign bit and significand bits. - * - * There is also a variant that returns the value directly. In most cases, the - * two variants should be identical. However, in the specific case of x86 - * chips, the behavior differs: returning floating-point values directly is done - * through the x87 stack, and x87 loads and stores turn signaling NaNs into - * quiet NaNs... silently. Returning floating-point values via outparam, - * however, is done entirely within the SSE registers when SSE2 floating-point - * is enabled in the compiler, which has semantics-preserving behavior you would - * expect. - * - * If preserving the distinction between signaling NaNs and quiet NaNs is - * important to you, you should use the outparam version. In all other cases, - * you should use the direct return version. - */ -template -static MOZ_ALWAYS_INLINE void -SpecificNaN(int signbit, typename FloatingPoint::Bits significand, T* result) -{ - typedef FloatingPoint Traits; - MOZ_ASSERT(signbit == 0 || signbit == 1); - MOZ_ASSERT((significand & ~Traits::kSignificandBits) == 0); - MOZ_ASSERT(significand & Traits::kSignificandBits); - - BitwiseCast((signbit ? Traits::kSignBit : 0) | - Traits::kExponentBits | - significand, - result); - MOZ_ASSERT(IsNaN(*result)); -} - -template -static MOZ_ALWAYS_INLINE T -SpecificNaN(int signbit, typename FloatingPoint::Bits significand) -{ - T t; - SpecificNaN(signbit, significand, &t); - return t; -} - -/** Computes the smallest non-zero positive float/double value. */ -template -static MOZ_ALWAYS_INLINE T -MinNumberValue() -{ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - return BitwiseCast(Bits(1)); -} - -/** - * If aValue is equal to some int32_t value, set *aInt32 to that value and - * return true; otherwise return false. - * - * Note that negative zero is "equal" to zero here. To test whether a value can - * be losslessly converted to int32_t and back, use NumberIsInt32 instead. - */ -template -static MOZ_ALWAYS_INLINE bool -NumberEqualsInt32(T aValue, int32_t* aInt32) -{ - /* - * XXX Casting a floating-point value that doesn't truncate to int32_t, to - * int32_t, induces undefined behavior. We should definitely fix this - * (bug 744965), but as apparently it "works" in practice, it's not a - * pressing concern now. - */ - return aValue == (*aInt32 = int32_t(aValue)); -} - -/** - * If d can be converted to int32_t and back to an identical double value, - * set *aInt32 to that value and return true; otherwise return false. - * - * The difference between this and NumberEqualsInt32 is that this method returns - * false for negative zero. - */ -template -static MOZ_ALWAYS_INLINE bool -NumberIsInt32(T aValue, int32_t* aInt32) -{ - return !IsNegativeZero(aValue) && NumberEqualsInt32(aValue, aInt32); -} - -/** - * Computes a NaN value. Do not use this method if you depend upon a particular - * NaN value being returned. - */ -template -static MOZ_ALWAYS_INLINE T -UnspecifiedNaN() -{ - /* - * If we can use any quiet NaN, we might as well use the all-ones NaN, - * since it's cheap to materialize on common platforms (such as x64, where - * this value can be represented in a 32-bit signed immediate field, allowing - * it to be stored to memory in a single instruction). - */ - typedef FloatingPoint Traits; - return SpecificNaN(1, Traits::kSignificandBits); -} - -/** - * Compare two doubles for equality, *without* equating -0 to +0, and equating - * any NaN value to any other NaN value. (The normal equality operators equate - * -0 with +0, and they equate NaN to no other value.) - */ -template -static inline bool -NumbersAreIdentical(T aValue1, T aValue2) -{ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - if (IsNaN(aValue1)) { - return IsNaN(aValue2); - } - return BitwiseCast(aValue1) == BitwiseCast(aValue2); -} - -namespace detail { - -template -struct FuzzyEqualsEpsilon; - -template<> -struct FuzzyEqualsEpsilon -{ - // A number near 1e-5 that is exactly representable in a float. - static float value() { return 1.0f / (1 << 17); } -}; - -template<> -struct FuzzyEqualsEpsilon -{ - // A number near 1e-12 that is exactly representable in a double. - static double value() { return 1.0 / (1LL << 40); } -}; - -} // namespace detail - -/** - * Compare two floating point values for equality, modulo rounding error. That - * is, the two values are considered equal if they are both not NaN and if they - * are less than or equal to aEpsilon apart. The default value of aEpsilon is - * near 1e-5. - * - * For most scenarios you will want to use FuzzyEqualsMultiplicative instead, - * as it is more reasonable over the entire range of floating point numbers. - * This additive version should only be used if you know the range of the - * numbers you are dealing with is bounded and stays around the same order of - * magnitude. - */ -template -static MOZ_ALWAYS_INLINE bool -FuzzyEqualsAdditive(T aValue1, T aValue2, - T aEpsilon = detail::FuzzyEqualsEpsilon::value()) -{ - static_assert(IsFloatingPoint::value, "floating point type required"); - return Abs(aValue1 - aValue2) <= aEpsilon; -} - -/** - * Compare two floating point values for equality, allowing for rounding error - * relative to the magnitude of the values. That is, the two values are - * considered equal if they are both not NaN and they are less than or equal to - * some aEpsilon apart, where the aEpsilon is scaled by the smaller of the two - * argument values. - * - * In most cases you will want to use this rather than FuzzyEqualsAdditive, as - * this function effectively masks out differences in the bottom few bits of - * the floating point numbers being compared, regardless of what order of - * magnitude those numbers are at. - */ -template -static MOZ_ALWAYS_INLINE bool -FuzzyEqualsMultiplicative(T aValue1, T aValue2, - T aEpsilon = detail::FuzzyEqualsEpsilon::value()) -{ - static_assert(IsFloatingPoint::value, "floating point type required"); - // can't use std::min because of bug 965340 - T smaller = Abs(aValue1) < Abs(aValue2) ? Abs(aValue1) : Abs(aValue2); - return Abs(aValue1 - aValue2) <= aEpsilon * smaller; -} - -/** - * Returns true if the given value can be losslessly represented as an IEEE-754 - * single format number, false otherwise. All NaN values are considered - * representable (notwithstanding that the exact bit pattern of a double format - * NaN value can't be exactly represented in single format). - * - * This function isn't inlined to avoid buggy optimizations by MSVC. - */ -MOZ_MUST_USE -extern MFBT_API bool -IsFloat32Representable(double aFloat32); - -} /* namespace mozilla */ - -#endif /* mozilla_FloatingPoint_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Function.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Function.h deleted file mode 100644 index d6de9c83..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Function.h +++ /dev/null @@ -1,223 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A type-erased callable wrapper. */ - -#ifndef mozilla_Function_h -#define mozilla_Function_h - -#include "mozilla/Attributes.h" // for MOZ_IMPLICIT -#include "mozilla/Move.h" -#include "mozilla/RefCounted.h" -#include "mozilla/RefPtr.h" - -// |function| is a wrapper that can hold any type of callable -// object that can be invoked in a way that's compatible with |Signature|. -// The standard "type erasure" technique is used to avoid the type of the -// wrapper depending on the concrete type of the wrapped callable. -// -// Supported callable types include non-member functions, static member -// functions, and function objects (that is to say, objects with an overloaded -// call operator; this includes C++11 lambdas). Member functions aren't -// directly supported; they first need to be wrapped into a function object -// using |std::mem_fn()| or an equivalent. -// -// |Signature| is a type of the form |ReturnType(Arguments...)|. Syntactically, -// this is a function type; it's not used in any way other than serving as a -// vehicle to encode the return and argument types into a single type. -// -// |function| is default-constructible. A default-constructed instance is -// considered "empty". Invoking an empty instance is undefined behaviour. -// An empty instance can be populated with a callable by assigning to it. -// -// This class is intended to provide functionality similar to the C++11 -// standard library class |std::function|. - -namespace mozilla { - -namespace detail { - -template -class FunctionImplBase : public mozilla::RefCounted> -{ -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(FunctionImplBase) - - virtual ~FunctionImplBase() {} - virtual ReturnType call(Arguments... aArguments) = 0; -}; - -// Normal Callable Object. -template -class FunctionImpl : public FunctionImplBase -{ - public: - explicit FunctionImpl(const Callable& aCallable) - : mCallable(aCallable) {} - - ReturnType call(Arguments... aArguments) override - { - return mCallable(Forward(aArguments)...); - } - private: - Callable mCallable; -}; - -// Base class for passing pointer to member function. -template -class MemberFunctionImplBase : public FunctionImplBase -{ -public: - explicit MemberFunctionImplBase(const Callable& aCallable) - : mCallable(aCallable) {} - - ReturnType call(Arguments... aArguments) override - { - return callInternal(Forward(aArguments)...); - } -private: - template - ReturnType callInternal(ThisType* aThis, Args&&... aArguments) - { - return (aThis->*mCallable)(Forward(aArguments)...); - } - - template - ReturnType callInternal(ThisType&& aThis, Args&&... aArguments) - { - return (aThis.*mCallable)(Forward(aArguments)...); - } - Callable mCallable; -}; - -// For non-const member function specialization of FunctionImpl. -template -class FunctionImpl - : public MemberFunctionImplBase -{ -public: - explicit FunctionImpl(ReturnType(ThisType::*aMemberFunc)(Args...)) - : MemberFunctionImplBase(aMemberFunc) - {} -}; - -// For const member function specialization of FunctionImpl. -template -class FunctionImpl - : public MemberFunctionImplBase -{ -public: - explicit FunctionImpl(ReturnType(ThisType::*aConstMemberFunc)(Args...) const) - : MemberFunctionImplBase(aConstMemberFunc) - {} -}; - -} // namespace detail - -// The primary template is never defined. As |Signature| is required to be -// of the form |ReturnType(Arguments...)|, we only define a partial -// specialization that matches this form. This allows us to use |ReturnType| -// and |Arguments| in the definition of the specialization without having to -// introspect |Signature|. -template -class function; - -template -class function -{ -public: - function() {} - - // This constructor is implicit to match the interface of |std::function|. - template - MOZ_IMPLICIT function(const Callable& aCallable) - : mImpl(new detail::FunctionImpl(aCallable)) - {} - MOZ_IMPLICIT function(const function& aFunction) - : mImpl(aFunction.mImpl) - {} - MOZ_IMPLICIT function(decltype(nullptr)) - {} - - // Move constructor and move assingment operator. - // These should be generated automatically, but MSVC doesn't do that yet. - function(function&& aOther) : mImpl(Move(aOther.mImpl)) {} - function& operator=(function&& aOther) { - mImpl = Move(aOther.mImpl); - return *this; - } - - template - function& operator=(const Callable& aCallable) - { - mImpl = new detail::FunctionImpl(aCallable); - return *this; - } - function& operator=(const function& aFunction) - { - mImpl = aFunction.mImpl; - return *this; - } - function& operator=(decltype(nullptr)) - { - mImpl = nullptr; - return *this; - } - - template - ReturnType operator()(Args&&... aArguments) const - { - MOZ_ASSERT(mImpl); - return mImpl->call(Forward(aArguments)...); - } - - explicit operator bool() const - { - return bool(mImpl); - } - -private: - // TODO: Consider implementing a small object optimization. - RefPtr> mImpl; -}; - -template -bool -operator==(const function& aX, decltype(nullptr)) -{ - return !aX; -} - -template -bool -operator==(decltype(nullptr), const function& aX) -{ - return !aX; -} - -template -bool -operator!=(const function& aX, decltype(nullptr)) -{ - return bool(aX); -} - -template -bool -operator!=(decltype(nullptr), const function& aX) -{ - return bool(aX); -} - -} // namespace mozilla - -#endif /* mozilla_Function_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/GuardObjects.h b/android/armeabi-v7a/include/spidermonkey/mozilla/GuardObjects.h deleted file mode 100644 index 9440c71c..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/GuardObjects.h +++ /dev/null @@ -1,167 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implementation of macros to ensure correct use of RAII Auto* objects. */ - -#ifndef mozilla_GuardObjects_h -#define mozilla_GuardObjects_h - -#include "mozilla/Assertions.h" -#include "mozilla/Move.h" -#include "mozilla/Types.h" - -#ifdef __cplusplus - -#ifdef DEBUG - -/** - * A custom define is used rather than |mozPoisonValue()| due to cascading - * build failures relating to how mfbt is linked on different operating - * systems. See bug 1160253. - */ -#define MOZ_POISON uintptr_t(-1) - -namespace mozilla { -namespace detail { - -/* - * The following classes are designed to cause assertions to detect - * inadvertent use of guard objects as temporaries. In other words, - * when we have a guard object whose only purpose is its constructor and - * destructor (and is never otherwise referenced), the intended use - * might be: - * - * AutoRestore savePainting(mIsPainting); - * - * but is is easy to accidentally write: - * - * AutoRestore(mIsPainting); - * - * which compiles just fine, but runs the destructor well before the - * intended time. - * - * They work by adding (#ifdef DEBUG) an additional parameter to the - * guard object's constructor, with a default value, so that users of - * the guard object's API do not need to do anything. The default value - * of this parameter is a temporary object. C++ (ISO/IEC 14882:1998), - * section 12.2 [class.temporary], clauses 4 and 5 seem to assume a - * guarantee that temporaries are destroyed in the reverse of their - * construction order, but I actually can't find a statement that that - * is true in the general case (beyond the two specific cases mentioned - * there). However, it seems to be true. - * - * These classes are intended to be used only via the macros immediately - * below them: - * - * MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER declares (ifdef DEBUG) a member - * variable, and should be put where a declaration of a private - * member variable would be placed. - * MOZ_GUARD_OBJECT_NOTIFIER_PARAM should be placed at the end of the - * parameters to each constructor of the guard object; it declares - * (ifdef DEBUG) an additional parameter. (But use the *_ONLY_PARAM - * variant for constructors that take no other parameters.) - * MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL should likewise be used in - * the implementation of such constructors when they are not inline. - * MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT should be used in - * the implementation of such constructors to pass the parameter to - * a base class that also uses these macros - * MOZ_GUARD_OBJECT_NOTIFIER_INIT is a statement that belongs in each - * constructor. It uses the parameter declared by - * MOZ_GUARD_OBJECT_NOTIFIER_PARAM. - * - * For more details, and examples of using these macros, see - * https://developer.mozilla.org/en/Using_RAII_classes_in_Mozilla - */ -class GuardObjectNotifier -{ -private: - bool* mStatementDone; - -public: - GuardObjectNotifier() - : mStatementDone(reinterpret_cast(MOZ_POISON)) - { - } - - ~GuardObjectNotifier() - { - // Assert that the GuardObjectNotifier has been properly initialized by - // using the |MOZ_GUARD_OBJECT_NOTIFIER_INIT| macro. A poison value is - // used rather than a null check to appease static analyzers that were - // (incorrectly) detecting null pointer dereferences. - MOZ_ASSERT(mStatementDone != reinterpret_cast(MOZ_POISON)); - *mStatementDone = true; - } - - void setStatementDone(bool* aStatementIsDone) - { - mStatementDone = aStatementIsDone; - } -}; - -class GuardObjectNotificationReceiver -{ -private: - bool mStatementDone; - -public: - GuardObjectNotificationReceiver() : mStatementDone(false) { } - - ~GuardObjectNotificationReceiver() { - /* - * Assert that the guard object was not used as a temporary. (Note that - * this assert might also fire if init is not called because the guard - * object's implementation is not using the above macros correctly.) - */ - MOZ_ASSERT(mStatementDone); - } - - void init(GuardObjectNotifier& aNotifier) - { - aNotifier.setStatementDone(&mStatementDone); - } -}; - -} /* namespace detail */ -} /* namespace mozilla */ - -#undef MOZ_POISON - -#endif /* DEBUG */ - -#ifdef DEBUG -# define MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER \ - mozilla::detail::GuardObjectNotificationReceiver _mCheckNotUsedAsTemporary; -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM \ - , mozilla::detail::GuardObjectNotifier&& _notifier = \ - mozilla::detail::GuardObjectNotifier() -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM \ - mozilla::detail::GuardObjectNotifier&& _notifier = \ - mozilla::detail::GuardObjectNotifier() -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL \ - , mozilla::detail::GuardObjectNotifier&& _notifier -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL \ - mozilla::detail::GuardObjectNotifier&& _notifier -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT \ - , mozilla::Move(_notifier) -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT \ - mozilla::Move(_notifier) -# define MOZ_GUARD_OBJECT_NOTIFIER_INIT \ - do { _mCheckNotUsedAsTemporary.init(_notifier); } while (0) -#else -# define MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT -# define MOZ_GUARD_OBJECT_NOTIFIER_INIT do { } while (0) -#endif - -#endif /* __cplusplus */ - -#endif /* mozilla_GuardObjects_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/HashFunctions.h b/android/armeabi-v7a/include/spidermonkey/mozilla/HashFunctions.h deleted file mode 100644 index eeb192c3..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/HashFunctions.h +++ /dev/null @@ -1,389 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Utilities for hashing. */ - -/* - * This file exports functions for hashing data down to a 32-bit value, - * including: - * - * - HashString Hash a char* or char16_t/wchar_t* of known or unknown - * length. - * - * - HashBytes Hash a byte array of known length. - * - * - HashGeneric Hash one or more values. Currently, we support uint32_t, - * types which can be implicitly cast to uint32_t, data - * pointers, and function pointers. - * - * - AddToHash Add one or more values to the given hash. This supports the - * same list of types as HashGeneric. - * - * - * You can chain these functions together to hash complex objects. For example: - * - * class ComplexObject - * { - * char* mStr; - * uint32_t mUint1, mUint2; - * void (*mCallbackFn)(); - * - * public: - * uint32_t hash() - * { - * uint32_t hash = HashString(mStr); - * hash = AddToHash(hash, mUint1, mUint2); - * return AddToHash(hash, mCallbackFn); - * } - * }; - * - * If you want to hash an nsAString or nsACString, use the HashString functions - * in nsHashKeys.h. - */ - -#ifndef mozilla_HashFunctions_h -#define mozilla_HashFunctions_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Char16.h" -#include "mozilla/MathAlgorithms.h" -#include "mozilla/Types.h" - -#include - -#ifdef __cplusplus -namespace mozilla { - -/** - * The golden ratio as a 32-bit fixed-point value. - */ -static const uint32_t kGoldenRatioU32 = 0x9E3779B9U; - -inline uint32_t -RotateBitsLeft32(uint32_t aValue, uint8_t aBits) -{ - MOZ_ASSERT(aBits < 32); - return (aValue << aBits) | (aValue >> (32 - aBits)); -} - -namespace detail { - -inline uint32_t -AddU32ToHash(uint32_t aHash, uint32_t aValue) -{ - /* - * This is the meat of all our hash routines. This hash function is not - * particularly sophisticated, but it seems to work well for our mostly - * plain-text inputs. Implementation notes follow. - * - * Our use of the golden ratio here is arbitrary; we could pick almost any - * number which: - * - * * is odd (because otherwise, all our hash values will be even) - * - * * has a reasonably-even mix of 1's and 0's (consider the extreme case - * where we multiply by 0x3 or 0xeffffff -- this will not produce good - * mixing across all bits of the hash). - * - * The rotation length of 5 is also arbitrary, although an odd number is again - * preferable so our hash explores the whole universe of possible rotations. - * - * Finally, we multiply by the golden ratio *after* xor'ing, not before. - * Otherwise, if |aHash| is 0 (as it often is for the beginning of a - * message), the expression - * - * (kGoldenRatioU32 * RotateBitsLeft(aHash, 5)) |xor| aValue - * - * evaluates to |aValue|. - * - * (Number-theoretic aside: Because any odd number |m| is relatively prime to - * our modulus (2^32), the list - * - * [x * m (mod 2^32) for 0 <= x < 2^32] - * - * has no duplicate elements. This means that multiplying by |m| does not - * cause us to skip any possible hash values. - * - * It's also nice if |m| has large-ish order mod 2^32 -- that is, if the - * smallest k such that m^k == 1 (mod 2^32) is large -- so we can safely - * multiply our hash value by |m| a few times without negating the - * multiplicative effect. Our golden ratio constant has order 2^29, which is - * more than enough for our purposes.) - */ - return kGoldenRatioU32 * (RotateBitsLeft32(aHash, 5) ^ aValue); -} - -/** - * AddUintptrToHash takes sizeof(uintptr_t) as a template parameter. - */ -template -inline uint32_t -AddUintptrToHash(uint32_t aHash, uintptr_t aValue); - -template<> -inline uint32_t -AddUintptrToHash<4>(uint32_t aHash, uintptr_t aValue) -{ - return AddU32ToHash(aHash, static_cast(aValue)); -} - -template<> -inline uint32_t -AddUintptrToHash<8>(uint32_t aHash, uintptr_t aValue) -{ - /* - * The static cast to uint64_t below is necessary because this function - * sometimes gets compiled on 32-bit platforms (yes, even though it's a - * template and we never call this particular override in a 32-bit build). If - * we do aValue >> 32 on a 32-bit machine, we're shifting a 32-bit uintptr_t - * right 32 bits, and the compiler throws an error. - */ - uint32_t v1 = static_cast(aValue); - uint32_t v2 = static_cast(static_cast(aValue) >> 32); - return AddU32ToHash(AddU32ToHash(aHash, v1), v2); -} - -} /* namespace detail */ - -/** - * AddToHash takes a hash and some values and returns a new hash based on the - * inputs. - * - * Currently, we support hashing uint32_t's, values which we can implicitly - * convert to uint32_t, data pointers, and function pointers. - */ -template -MOZ_MUST_USE inline uint32_t -AddToHash(uint32_t aHash, A aA) -{ - /* - * Try to convert |A| to uint32_t implicitly. If this works, great. If not, - * we'll error out. - */ - return detail::AddU32ToHash(aHash, aA); -} - -template -MOZ_MUST_USE inline uint32_t -AddToHash(uint32_t aHash, A* aA) -{ - /* - * You might think this function should just take a void*. But then we'd only - * catch data pointers and couldn't handle function pointers. - */ - - static_assert(sizeof(aA) == sizeof(uintptr_t), "Strange pointer!"); - - return detail::AddUintptrToHash(aHash, uintptr_t(aA)); -} - -template<> -MOZ_MUST_USE inline uint32_t -AddToHash(uint32_t aHash, uintptr_t aA) -{ - return detail::AddUintptrToHash(aHash, aA); -} - -template -MOZ_MUST_USE uint32_t -AddToHash(uint32_t aHash, A aArg, Args... aArgs) -{ - return AddToHash(AddToHash(aHash, aArg), aArgs...); -} - -/** - * The HashGeneric class of functions let you hash one or more values. - * - * If you want to hash together two values x and y, calling HashGeneric(x, y) is - * much better than calling AddToHash(x, y), because AddToHash(x, y) assumes - * that x has already been hashed. - */ -template -MOZ_MUST_USE inline uint32_t -HashGeneric(Args... aArgs) -{ - return AddToHash(0, aArgs...); -} - -namespace detail { - -template -uint32_t -HashUntilZero(const T* aStr) -{ - uint32_t hash = 0; - for (T c; (c = *aStr); aStr++) { - hash = AddToHash(hash, c); - } - return hash; -} - -template -uint32_t -HashKnownLength(const T* aStr, size_t aLength) -{ - uint32_t hash = 0; - for (size_t i = 0; i < aLength; i++) { - hash = AddToHash(hash, aStr[i]); - } - return hash; -} - -} /* namespace detail */ - -/** - * The HashString overloads below do just what you'd expect. - * - * If you have the string's length, you might as well call the overload which - * includes the length. It may be marginally faster. - */ -MOZ_MUST_USE inline uint32_t -HashString(const char* aStr) -{ - return detail::HashUntilZero(reinterpret_cast(aStr)); -} - -MOZ_MUST_USE inline uint32_t -HashString(const char* aStr, size_t aLength) -{ - return detail::HashKnownLength(reinterpret_cast(aStr), aLength); -} - -MOZ_MUST_USE -inline uint32_t -HashString(const unsigned char* aStr, size_t aLength) -{ - return detail::HashKnownLength(aStr, aLength); -} - -MOZ_MUST_USE inline uint32_t -HashString(const char16_t* aStr) -{ - return detail::HashUntilZero(aStr); -} - -MOZ_MUST_USE inline uint32_t -HashString(const char16_t* aStr, size_t aLength) -{ - return detail::HashKnownLength(aStr, aLength); -} - -/* - * On Windows, wchar_t is not the same as char16_t, even though it's - * the same width! - */ -#ifdef WIN32 -MOZ_MUST_USE inline uint32_t -HashString(const wchar_t* aStr) -{ - return detail::HashUntilZero(aStr); -} - -MOZ_MUST_USE inline uint32_t -HashString(const wchar_t* aStr, size_t aLength) -{ - return detail::HashKnownLength(aStr, aLength); -} -#endif - -/** - * Hash some number of bytes. - * - * This hash walks word-by-word, rather than byte-by-byte, so you won't get the - * same result out of HashBytes as you would out of HashString. - */ -MOZ_MUST_USE extern MFBT_API uint32_t -HashBytes(const void* bytes, size_t aLength); - -/** - * A pseudorandom function mapping 32-bit integers to 32-bit integers. - * - * This is for when you're feeding private data (like pointer values or credit - * card numbers) to a non-crypto hash function (like HashBytes) and then using - * the hash code for something that untrusted parties could observe (like a JS - * Map). Plug in a HashCodeScrambler before that last step to avoid leaking the - * private data. - * - * By itself, this does not prevent hash-flooding DoS attacks, because an - * attacker can still generate many values with exactly equal hash codes by - * attacking the non-crypto hash function alone. Equal hash codes will, of - * course, still be equal however much you scramble them. - * - * The algorithm is SipHash-1-3. See . - */ -class HashCodeScrambler -{ - struct SipHasher; - - uint64_t mK0, mK1; - -public: - /** Creates a new scrambler with the given 128-bit key. */ - constexpr HashCodeScrambler(uint64_t aK0, uint64_t aK1) : mK0(aK0), mK1(aK1) {} - - /** - * Scramble a hash code. Always produces the same result for the same - * combination of key and hash code. - */ - uint32_t scramble(uint32_t aHashCode) const - { - SipHasher hasher(mK0, mK1); - return uint32_t(hasher.sipHash(aHashCode)); - } - -private: - struct SipHasher - { - SipHasher(uint64_t aK0, uint64_t aK1) - { - // 1. Initialization. - mV0 = aK0 ^ UINT64_C(0x736f6d6570736575); - mV1 = aK1 ^ UINT64_C(0x646f72616e646f6d); - mV2 = aK0 ^ UINT64_C(0x6c7967656e657261); - mV3 = aK1 ^ UINT64_C(0x7465646279746573); - } - - uint64_t sipHash(uint64_t aM) - { - // 2. Compression. - mV3 ^= aM; - sipRound(); - mV0 ^= aM; - - // 3. Finalization. - mV2 ^= 0xff; - for (int i = 0; i < 3; i++) - sipRound(); - return mV0 ^ mV1 ^ mV2 ^ mV3; - } - - void sipRound() - { - mV0 += mV1; - mV1 = RotateLeft(mV1, 13); - mV1 ^= mV0; - mV0 = RotateLeft(mV0, 32); - mV2 += mV3; - mV3 = RotateLeft(mV3, 16); - mV3 ^= mV2; - mV0 += mV3; - mV3 = RotateLeft(mV3, 21); - mV3 ^= mV0; - mV2 += mV1; - mV1 = RotateLeft(mV1, 17); - mV1 ^= mV2; - mV2 = RotateLeft(mV2, 32); - } - - uint64_t mV0, mV1, mV2, mV3; - }; -}; - -} /* namespace mozilla */ -#endif /* __cplusplus */ - -#endif /* mozilla_HashFunctions_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/IndexSequence.h b/android/armeabi-v7a/include/spidermonkey/mozilla/IndexSequence.h deleted file mode 100644 index 1ccace02..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/IndexSequence.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A utility for expanding a tuple into a variadic argument list. - * Based on std::index_sequence. */ - -/** - * Example usage: - * - * Problem: - * - * You have a variadic function Foo: - * - * template void Foo(Args...); - * - * And a variadic function Bar, which contains a tuple: - * - * template - * void Bar() { - * // ... - * Tuple t; - * } - * - * And inside Bar, you want to call Foo with the elements of the tuple as - * arguments to Foo. - * - * You want to write: - * - * Foo(Get<0>(t), Get<1>(t), ..., Get(t)) - * - * but you can't literally write that, because N is different for different - * instantiations of Bar. - * - * Solution: - * - * Write a helper function which takes the tuple, and an index sequence - * containing indices corresponding to the tuple indices. - * - * template - * void Helper(const Tuple& t, IndexSequence) - * { - * Foo(Get(t)...); - * } - * - * Assuming 'Indices...' are 0, 1, ..., N - 1, where N is the size of the - * tuple, pack expansion will expand the pack 'Get(t)...' to - * 'Get<0>(t), Get<1>(t), ..., Get(t)'. - * - * Finally, call the helper, creating the index sequence to pass in like so: - * - * template - * void Bar() { - * // ... - * Tuple t; - * Helper(t, typename IndexSequenceFor::Type()); - * } - */ - -#ifndef mozilla_IndexSequence_h -#define mozilla_IndexSequence_h - -#include "mozilla/Attributes.h" - -#include - -namespace mozilla { - -/** - * Represents a compile-time sequence of integer indices. - */ -template -struct IndexSequence -{ - static constexpr size_t Size() { return sizeof...(Indices); } -}; - -namespace detail { - -// Helpers used by MakeIndexSequence. - -template -struct IndexTuple -{ - typedef IndexTuple Next; -}; - -// Builds IndexTuple<0, 1, ..., N - 1>. -template -struct BuildIndexTuple -{ - typedef typename BuildIndexTuple::Type::Next Type; -}; - -template<> -struct BuildIndexTuple<0> -{ - typedef IndexTuple<> Type; -}; - -template -struct MakeIndexSequenceImpl; - -template -struct MakeIndexSequenceImpl> -{ - typedef IndexSequence Type; -}; - -} // namespace detail - -/** - * A utility for building an IndexSequence of consecutive indices. - * MakeIndexSequence::Type evaluates to IndexSequence<0, 1, .., N - 1>. - * Note: unlike std::make_index_sequence, this is not an alias template - * to work around bugs in MSVC 2013. - */ -template -struct MakeIndexSequence -{ - typedef typename detail::MakeIndexSequenceImpl::Type>::Type Type; -}; - -/** - * A utility for building an IndexSequence of consecutive indices - * corresponding to a variadic argument list. - * IndexSequenceFor evaluates to IndexSequence<0, 1, ..., N - 1> - * where N is the number of types in Types. - * Note: unlike std::index_sequence_for, this is not an alias template - * to work around bugs in MSVC 2013. - */ -template -struct IndexSequenceFor -{ - typedef typename MakeIndexSequence::Type Type; -}; - -} // namespace mozilla - -#endif /* mozilla_IndexSequence_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/IntegerPrintfMacros.h b/android/armeabi-v7a/include/spidermonkey/mozilla/IntegerPrintfMacros.h deleted file mode 100644 index c534a0ba..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/IntegerPrintfMacros.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implements the C99 interface. */ - -#ifndef mozilla_IntegerPrintfMacros_h_ -#define mozilla_IntegerPrintfMacros_h_ - -/* - * These macros should not be used with the NSPR printf-like functions or their - * users, e.g. mozilla/Logging.h. If you need to use NSPR's facilities, see the - * comment on supported formats at the top of nsprpub/pr/include/prprf.h. - */ - -/* - * scanf is a footgun: if the input number exceeds the bounds of the target - * type, behavior is undefined (in the compiler sense: that is, this code - * could overwrite your hard drive with zeroes): - * - * uint8_t u; - * sscanf("256", "%" SCNu8, &u); // BAD - * - * For this reason, *never* use the SCN* macros provided by this header! - */ - -#include - -/* - * Fix up Android's broken [u]intptr_t inttype macros. Android's PRI*PTR - * macros are defined as "ld", but sizeof(long) is 8 and sizeof(intptr_t) - * is 4 on 32-bit Android. TestTypeTraits.cpp asserts that these new macro - * definitions match the actual type sizes seen at compile time. - */ -#if defined(ANDROID) && !defined(__LP64__) -# undef PRIdPTR /* intptr_t */ -# define PRIdPTR "d" /* intptr_t */ -# undef PRIiPTR /* intptr_t */ -# define PRIiPTR "i" /* intptr_t */ -# undef PRIoPTR /* uintptr_t */ -# define PRIoPTR "o" /* uintptr_t */ -# undef PRIuPTR /* uintptr_t */ -# define PRIuPTR "u" /* uintptr_t */ -# undef PRIxPTR /* uintptr_t */ -# define PRIxPTR "x" /* uintptr_t */ -# undef PRIXPTR /* uintptr_t */ -# define PRIXPTR "X" /* uintptr_t */ -#endif - -#endif /* mozilla_IntegerPrintfMacros_h_ */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/IntegerRange.h b/android/armeabi-v7a/include/spidermonkey/mozilla/IntegerRange.h deleted file mode 100644 index 8d5d2e4d..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/IntegerRange.h +++ /dev/null @@ -1,181 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Iterator over ranges of integers */ - -#ifndef mozilla_IntegerRange_h -#define mozilla_IntegerRange_h - -#include "mozilla/Assertions.h" -#include "mozilla/ReverseIterator.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -namespace detail { - -template -class IntegerIterator -{ -public: - template - explicit IntegerIterator(IntType aCurrent) - : mCurrent(aCurrent) { } - - template - explicit IntegerIterator(const IntegerIterator& aOther) - : mCurrent(aOther.mCurrent) { } - - IntTypeT operator*() const { return mCurrent; } - - /* Increment and decrement operators */ - - IntegerIterator& operator++() { ++mCurrent; return *this; } - IntegerIterator& operator--() { --mCurrent; return *this; } - IntegerIterator operator++(int) { auto ret = *this; ++mCurrent; return ret; } - IntegerIterator operator--(int) { auto ret = *this; --mCurrent; return ret; } - - /* Comparison operators */ - - template - friend bool operator==(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - template - friend bool operator!=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - template - friend bool operator<(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - template - friend bool operator<=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - template - friend bool operator>(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - template - friend bool operator>=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - -private: - IntTypeT mCurrent; -}; - -template -bool operator==(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent == aIter2.mCurrent; -} - -template -bool operator!=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent != aIter2.mCurrent; -} - -template -bool operator<(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent < aIter2.mCurrent; -} - -template -bool operator<=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent <= aIter2.mCurrent; -} - -template -bool operator>(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent > aIter2.mCurrent; -} - -template -bool operator>=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent >= aIter2.mCurrent; -} - -template -class IntegerRange -{ -public: - typedef IntegerIterator iterator; - typedef IntegerIterator const_iterator; - typedef ReverseIterator> reverse_iterator; - typedef ReverseIterator> const_reverse_iterator; - - template - explicit IntegerRange(IntType aEnd) - : mBegin(0), mEnd(aEnd) { } - - template - IntegerRange(IntType1 aBegin, IntType2 aEnd) - : mBegin(aBegin), mEnd(aEnd) { } - - iterator begin() const { return iterator(mBegin); } - const_iterator cbegin() const { return begin(); } - iterator end() const { return iterator(mEnd); } - const_iterator cend() const { return end(); } - reverse_iterator rbegin() const { return reverse_iterator(mEnd); } - const_reverse_iterator crbegin() const { return rbegin(); } - reverse_iterator rend() const { return reverse_iterator(mBegin); } - const_reverse_iterator crend() const { return rend(); } - -private: - IntTypeT mBegin; - IntTypeT mEnd; -}; - -template::value> -struct GeqZero -{ - static bool check(T t) { - return t >= 0; - } -}; - -template -struct GeqZero -{ - static bool check(T t) { - return true; - } -}; - -} // namespace detail - -template -detail::IntegerRange -MakeRange(IntType aEnd) -{ - static_assert(IsIntegral::value, "value must be integral"); - MOZ_ASSERT(detail::GeqZero::check(aEnd), - "Should never have negative value here"); - return detail::IntegerRange(aEnd); -} - -template -detail::IntegerRange -MakeRange(IntType1 aBegin, IntType2 aEnd) -{ - static_assert(IsIntegral::value && IsIntegral::value, - "values must both be integral"); - static_assert(IsSigned::value == IsSigned::value, - "signed/unsigned mismatch"); - MOZ_ASSERT(aEnd >= aBegin, "End value should be larger than begin value"); - return detail::IntegerRange(aBegin, aEnd); -} - -} // namespace mozilla - -#endif // mozilla_IntegerRange_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/IntegerTypeTraits.h b/android/armeabi-v7a/include/spidermonkey/mozilla/IntegerTypeTraits.h deleted file mode 100644 index 6144d208..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/IntegerTypeTraits.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Helpers to manipulate integer types that don't fit in TypeTraits.h */ - -#ifndef mozilla_IntegerTypeTraits_h -#define mozilla_IntegerTypeTraits_h - -#include "mozilla/TypeTraits.h" -#include - -namespace mozilla { - -namespace detail { - -/** - * StdintTypeForSizeAndSignedness returns the stdint integer type - * of given size (can be 1, 2, 4 or 8) and given signedness - * (false means unsigned, true means signed). - */ -template -struct StdintTypeForSizeAndSignedness; - -template<> -struct StdintTypeForSizeAndSignedness<1, true> -{ - typedef int8_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<1, false> -{ - typedef uint8_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<2, true> -{ - typedef int16_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<2, false> -{ - typedef uint16_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<4, true> -{ - typedef int32_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<4, false> -{ - typedef uint32_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<8, true> -{ - typedef int64_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<8, false> -{ - typedef uint64_t Type; -}; - -} // namespace detail - -template -struct UnsignedStdintTypeForSize - : detail::StdintTypeForSizeAndSignedness -{}; - -template -struct SignedStdintTypeForSize - : detail::StdintTypeForSizeAndSignedness -{}; - -template -struct PositionOfSignBit -{ - static_assert(IsIntegral::value, - "PositionOfSignBit is only for integral types"); - // 8 here should be CHAR_BIT from limits.h, but the world has moved on. - static const size_t value = 8 * sizeof(IntegerType) - 1; -}; - -/** - * MinValue returns the minimum value of the given integer type as a - * compile-time constant, which std::numeric_limits::min() - * cannot do in c++98. - */ -template -struct MinValue -{ -private: - static_assert(IsIntegral::value, - "MinValue is only for integral types"); - - typedef typename MakeUnsigned::Type UnsignedIntegerType; - static const size_t PosOfSignBit = PositionOfSignBit::value; - -public: - // Bitwise ops may return a larger type, that's why we cast explicitly. - // In C++, left bit shifts on signed values is undefined by the standard - // unless the shifted value is representable. - // Notice that signed-to-unsigned conversions are always well-defined in - // the standard as the value congruent to 2**n, as expected. By contrast, - // unsigned-to-signed is only well-defined if the value is representable. - static const IntegerType value = - IsSigned::value - ? IntegerType(UnsignedIntegerType(1) << PosOfSignBit) - : IntegerType(0); -}; - -/** - * MaxValue returns the maximum value of the given integer type as a - * compile-time constant, which std::numeric_limits::max() - * cannot do in c++98. - */ -template -struct MaxValue -{ - static_assert(IsIntegral::value, - "MaxValue is only for integral types"); - - // Tricksy, but covered by the CheckedInt unit test. - // Relies on the type of MinValue::value - // being IntegerType. - static const IntegerType value = ~MinValue::value; -}; - -} // namespace mozilla - -#endif // mozilla_IntegerTypeTraits_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/JSONWriter.h b/android/armeabi-v7a/include/spidermonkey/mozilla/JSONWriter.h deleted file mode 100644 index 7d44dc7f..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/JSONWriter.h +++ /dev/null @@ -1,460 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A JSON pretty-printer class. */ - -// A typical JSON-writing library requires you to first build up a data -// structure that represents a JSON object and then serialize it (to file, or -// somewhere else). This approach makes for a clean API, but building the data -// structure takes up memory. Sometimes that isn't desirable, such as when the -// JSON data is produced for memory reporting. -// -// The JSONWriter class instead allows JSON data to be written out -// incrementally without building up large data structures. -// -// The API is slightly uglier than you would see in a typical JSON-writing -// library, but still fairly easy to use. It's possible to generate invalid -// JSON with JSONWriter, but typically the most basic testing will identify any -// such problems. -// -// Similarly, there are no RAII facilities for automatically closing objects -// and arrays. These would be nice if you are generating all your code within -// nested functions, but in other cases you'd have to maintain an explicit -// stack of RAII objects and manually unwind it, which is no better than just -// calling "end" functions. Furthermore, the consequences of forgetting to -// close an object or array are obvious and, again, will be identified via -// basic testing, unlike other cases where RAII is typically used (e.g. smart -// pointers) and the consequences of defects are more subtle. -// -// Importantly, the class does solve the two hard problems of JSON -// pretty-printing, which are (a) correctly escaping strings, and (b) adding -// appropriate indentation and commas between items. -// -// By default, every property is placed on its own line. However, it is -// possible to request that objects and arrays be placed entirely on a single -// line, which can reduce output size significantly in some cases. -// -// Strings used (for property names and string property values) are |const -// char*| throughout, and can be ASCII or UTF-8. -// -// EXAMPLE -// ------- -// Assume that |MyWriteFunc| is a class that implements |JSONWriteFunc|. The -// following code: -// -// JSONWriter w(MakeUnique()); -// w.Start(); -// { -// w.NullProperty("null"); -// w.BoolProperty("bool", true); -// w.IntProperty("int", 1); -// w.StartArrayProperty("array"); -// { -// w.StringElement("string"); -// w.StartObjectElement(); -// { -// w.DoubleProperty("double", 3.4); -// w.StartArrayProperty("single-line array", w.SingleLineStyle); -// { -// w.IntElement(1); -// w.StartObjectElement(); // SingleLineStyle is inherited from -// w.EndObjectElement(); // above for this collection -// } -// w.EndArray(); -// } -// w.EndObjectElement(); -// } -// w.EndArrayProperty(); -// } -// w.End(); -// -// will produce pretty-printed output for the following JSON object: -// -// { -// "null": null, -// "bool": true, -// "int": 1, -// "array": [ -// "string", -// { -// "double": 3.4, -// "single-line array": [1, {}] -// } -// ] -// } -// -// The nesting in the example code is obviously optional, but can aid -// readability. - -#ifndef mozilla_JSONWriter_h -#define mozilla_JSONWriter_h - -#include "mozilla/double-conversion.h" -#include "mozilla/IntegerPrintfMacros.h" -#include "mozilla/PodOperations.h" -#include "mozilla/Sprintf.h" -#include "mozilla/UniquePtr.h" -#include "mozilla/Vector.h" - -#include - -namespace mozilla { - -// A quasi-functor for JSONWriter. We don't use a true functor because that -// requires templatizing JSONWriter, and the templatization seeps to lots of -// places we don't want it to. -class JSONWriteFunc -{ -public: - virtual void Write(const char* aStr) = 0; - virtual ~JSONWriteFunc() {} -}; - -// Ideally this would be within |EscapedString| but when compiling with GCC -// on Linux that caused link errors, whereas this formulation didn't. -namespace detail { -extern MFBT_DATA const char gTwoCharEscapes[256]; -} // namespace detail - -class JSONWriter -{ - // From http://www.ietf.org/rfc/rfc4627.txt: - // - // "All Unicode characters may be placed within the quotation marks except - // for the characters that must be escaped: quotation mark, reverse - // solidus, and the control characters (U+0000 through U+001F)." - // - // This implementation uses two-char escape sequences where possible, namely: - // - // \", \\, \b, \f, \n, \r, \t - // - // All control characters not in the above list are represented with a - // six-char escape sequence, e.g. '\u000b' (a.k.a. '\v'). - // - class EscapedString - { - // Only one of |mUnownedStr| and |mOwnedStr| are ever non-null. |mIsOwned| - // indicates which one is in use. They're not within a union because that - // wouldn't work with UniquePtr. - bool mIsOwned; - const char* mUnownedStr; - UniquePtr mOwnedStr; - - void SanityCheck() const - { - MOZ_ASSERT_IF( mIsOwned, mOwnedStr.get() && !mUnownedStr); - MOZ_ASSERT_IF(!mIsOwned, !mOwnedStr.get() && mUnownedStr); - } - - static char hexDigitToAsciiChar(uint8_t u) - { - u = u & 0xf; - return u < 10 ? '0' + u : 'a' + (u - 10); - } - - public: - explicit EscapedString(const char* aStr) - : mUnownedStr(nullptr) - , mOwnedStr(nullptr) - { - const char* p; - - // First, see if we need to modify the string. - size_t nExtra = 0; - p = aStr; - while (true) { - uint8_t u = *p; // ensure it can't be interpreted as negative - if (u == 0) { - break; - } - if (detail::gTwoCharEscapes[u]) { - nExtra += 1; - } else if (u <= 0x1f) { - nExtra += 5; - } - p++; - } - - if (nExtra == 0) { - // No escapes needed. Easy. - mIsOwned = false; - mUnownedStr = aStr; - return; - } - - // Escapes are needed. We'll create a new string. - mIsOwned = true; - size_t len = (p - aStr) + nExtra; - mOwnedStr = MakeUnique(len + 1); - - p = aStr; - size_t i = 0; - - while (true) { - uint8_t u = *p; // ensure it can't be interpreted as negative - if (u == 0) { - mOwnedStr[i] = 0; - break; - } - if (detail::gTwoCharEscapes[u]) { - mOwnedStr[i++] = '\\'; - mOwnedStr[i++] = detail::gTwoCharEscapes[u]; - } else if (u <= 0x1f) { - mOwnedStr[i++] = '\\'; - mOwnedStr[i++] = 'u'; - mOwnedStr[i++] = '0'; - mOwnedStr[i++] = '0'; - mOwnedStr[i++] = hexDigitToAsciiChar((u & 0x00f0) >> 4); - mOwnedStr[i++] = hexDigitToAsciiChar(u & 0x000f); - } else { - mOwnedStr[i++] = u; - } - p++; - } - } - - ~EscapedString() - { - SanityCheck(); - } - - const char* get() const - { - SanityCheck(); - return mIsOwned ? mOwnedStr.get() : mUnownedStr; - } - }; - -public: - // Collections (objects and arrays) are printed in a multi-line style by - // default. This can be changed to a single-line style if SingleLineStyle is - // specified. If a collection is printed in single-line style, every nested - // collection within it is also printed in single-line style, even if - // multi-line style is requested. - enum CollectionStyle { - MultiLineStyle, // the default - SingleLineStyle - }; - -protected: - const UniquePtr mWriter; - Vector mNeedComma; // do we need a comma at depth N? - Vector mNeedNewlines; // do we need newlines at depth N? - size_t mDepth; // the current nesting depth - - void Indent() - { - for (size_t i = 0; i < mDepth; i++) { - mWriter->Write(" "); - } - } - - // Adds whatever is necessary (maybe a comma, and then a newline and - // whitespace) to separate an item (property or element) from what's come - // before. - void Separator() - { - if (mNeedComma[mDepth]) { - mWriter->Write(","); - } - if (mDepth > 0 && mNeedNewlines[mDepth]) { - mWriter->Write("\n"); - Indent(); - } else if (mNeedComma[mDepth]) { - mWriter->Write(" "); - } - } - - void PropertyNameAndColon(const char* aName) - { - EscapedString escapedName(aName); - mWriter->Write("\""); - mWriter->Write(escapedName.get()); - mWriter->Write("\": "); - } - - void Scalar(const char* aMaybePropertyName, const char* aStringValue) - { - Separator(); - if (aMaybePropertyName) { - PropertyNameAndColon(aMaybePropertyName); - } - mWriter->Write(aStringValue); - mNeedComma[mDepth] = true; - } - - void QuotedScalar(const char* aMaybePropertyName, const char* aStringValue) - { - Separator(); - if (aMaybePropertyName) { - PropertyNameAndColon(aMaybePropertyName); - } - mWriter->Write("\""); - mWriter->Write(aStringValue); - mWriter->Write("\""); - mNeedComma[mDepth] = true; - } - - void NewVectorEntries() - { - // If these tiny allocations OOM we might as well just crash because we - // must be in serious memory trouble. - MOZ_RELEASE_ASSERT(mNeedComma.resizeUninitialized(mDepth + 1)); - MOZ_RELEASE_ASSERT(mNeedNewlines.resizeUninitialized(mDepth + 1)); - mNeedComma[mDepth] = false; - mNeedNewlines[mDepth] = true; - } - - void StartCollection(const char* aMaybePropertyName, const char* aStartChar, - CollectionStyle aStyle = MultiLineStyle) - { - Separator(); - if (aMaybePropertyName) { - mWriter->Write("\""); - mWriter->Write(aMaybePropertyName); - mWriter->Write("\": "); - } - mWriter->Write(aStartChar); - mNeedComma[mDepth] = true; - mDepth++; - NewVectorEntries(); - mNeedNewlines[mDepth] = - mNeedNewlines[mDepth - 1] && aStyle == MultiLineStyle; - } - - // Adds the whitespace and closing char necessary to end a collection. - void EndCollection(const char* aEndChar) - { - if (mNeedNewlines[mDepth]) { - mWriter->Write("\n"); - mDepth--; - Indent(); - } else { - mDepth--; - } - mWriter->Write(aEndChar); - } - -public: - explicit JSONWriter(UniquePtr aWriter) - : mWriter(Move(aWriter)) - , mNeedComma() - , mNeedNewlines() - , mDepth(0) - { - NewVectorEntries(); - } - - // Returns the JSONWriteFunc passed in at creation, for temporary use. The - // JSONWriter object still owns the JSONWriteFunc. - JSONWriteFunc* WriteFunc() const { return mWriter.get(); } - - // For all the following functions, the "Prints:" comment indicates what the - // basic output looks like. However, it doesn't indicate the whitespace and - // trailing commas, which are automatically added as required. - // - // All property names and string properties are escaped as necessary. - - // Prints: { - void Start(CollectionStyle aStyle = MultiLineStyle) - { - StartCollection(nullptr, "{", aStyle); - } - - // Prints: } - void End() { EndCollection("}\n"); } - - // Prints: "": null - void NullProperty(const char* aName) - { - Scalar(aName, "null"); - } - - // Prints: null - void NullElement() { NullProperty(nullptr); } - - // Prints: "": - void BoolProperty(const char* aName, bool aBool) - { - Scalar(aName, aBool ? "true" : "false"); - } - - // Prints: - void BoolElement(bool aBool) { BoolProperty(nullptr, aBool); } - - // Prints: "": - void IntProperty(const char* aName, int64_t aInt) - { - char buf[64]; - SprintfLiteral(buf, "%" PRId64, aInt); - Scalar(aName, buf); - } - - // Prints: - void IntElement(int64_t aInt) { IntProperty(nullptr, aInt); } - - // Prints: "": - void DoubleProperty(const char* aName, double aDouble) - { - static const size_t buflen = 64; - char buf[buflen]; - const double_conversion::DoubleToStringConverter &converter = - double_conversion::DoubleToStringConverter::EcmaScriptConverter(); - double_conversion::StringBuilder builder(buf, buflen); - converter.ToShortest(aDouble, &builder); - Scalar(aName, builder.Finalize()); - } - - // Prints: - void DoubleElement(double aDouble) { DoubleProperty(nullptr, aDouble); } - - // Prints: "": "" - void StringProperty(const char* aName, const char* aStr) - { - EscapedString escapedStr(aStr); - QuotedScalar(aName, escapedStr.get()); - } - - // Prints: "" - void StringElement(const char* aStr) { StringProperty(nullptr, aStr); } - - // Prints: "": [ - void StartArrayProperty(const char* aName, - CollectionStyle aStyle = MultiLineStyle) - { - StartCollection(aName, "[", aStyle); - } - - // Prints: [ - void StartArrayElement(CollectionStyle aStyle = MultiLineStyle) - { - StartArrayProperty(nullptr, aStyle); - } - - // Prints: ] - void EndArray() { EndCollection("]"); } - - // Prints: "": { - void StartObjectProperty(const char* aName, - CollectionStyle aStyle = MultiLineStyle) - { - StartCollection(aName, "{", aStyle); - } - - // Prints: { - void StartObjectElement(CollectionStyle aStyle = MultiLineStyle) - { - StartObjectProperty(nullptr, aStyle); - } - - // Prints: } - void EndObject() { EndCollection("}"); } -}; - -} // namespace mozilla - -#endif /* mozilla_JSONWriter_h */ - diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Likely.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Likely.h deleted file mode 100644 index 4f216092..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Likely.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * MOZ_LIKELY and MOZ_UNLIKELY macros to hint to the compiler how a - * boolean predicate should be branch-predicted. - */ - -#ifndef mozilla_Likely_h -#define mozilla_Likely_h - -#if defined(__clang__) || defined(__GNUC__) -# define MOZ_LIKELY(x) (__builtin_expect(!!(x), 1)) -# define MOZ_UNLIKELY(x) (__builtin_expect(!!(x), 0)) -#else -# define MOZ_LIKELY(x) (!!(x)) -# define MOZ_UNLIKELY(x) (!!(x)) -#endif - -#endif /* mozilla_Likely_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/LinkedList.h b/android/armeabi-v7a/include/spidermonkey/mozilla/LinkedList.h deleted file mode 100644 index 6e14aa16..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/LinkedList.h +++ /dev/null @@ -1,659 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A type-safe doubly-linked list class. */ - -/* - * The classes LinkedList and LinkedListElement together form a - * convenient, type-safe doubly-linked list implementation. - * - * The class T which will be inserted into the linked list must inherit from - * LinkedListElement. A given object may be in only one linked list at a - * time. - * - * A LinkedListElement automatically removes itself from the list upon - * destruction, and a LinkedList will fatally assert in debug builds if it's - * non-empty when it's destructed. - * - * For example, you might use LinkedList in a simple observer list class as - * follows. - * - * class Observer : public LinkedListElement - * { - * public: - * void observe(char* aTopic) { ... } - * }; - * - * class ObserverContainer - * { - * private: - * LinkedList list; - * - * public: - * void addObserver(Observer* aObserver) - * { - * // Will assert if |aObserver| is part of another list. - * list.insertBack(aObserver); - * } - * - * void removeObserver(Observer* aObserver) - * { - * // Will assert if |aObserver| is not part of some list. - * aObserver.remove(); - * // Or, will assert if |aObserver| is not part of |list| specifically. - * // aObserver.removeFrom(list); - * } - * - * void notifyObservers(char* aTopic) - * { - * for (Observer* o = list.getFirst(); o != nullptr; o = o->getNext()) { - * o->observe(aTopic); - * } - * } - * }; - * - * Additionally, the class AutoCleanLinkedList is a LinkedList that will - * remove and delete each element still within itself upon destruction. Note - * that because each element is deleted, elements must have been allocated - * using |new|. - */ - -#ifndef mozilla_LinkedList_h -#define mozilla_LinkedList_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" -#include "mozilla/RefPtr.h" - -#ifdef __cplusplus - -namespace mozilla { - -template -class LinkedListElement; - -namespace detail { - -/** - * LinkedList supports refcounted elements using this adapter class. Clients - * using LinkedList> will get a data structure that holds a strong - * reference to T as long as T is in the list. - */ -template -struct LinkedListElementTraits -{ - typedef T* RawType; - typedef const T* ConstRawType; - typedef T* ClientType; - typedef const T* ConstClientType; - - // These static methods are called when an element is added to or removed from - // a linked list. It can be used to keep track ownership in lists that are - // supposed to own their elements. If elements are transferred from one list - // to another, no enter or exit calls happen since the elements still belong - // to a list. - static void enterList(LinkedListElement* elt) {} - static void exitList(LinkedListElement* elt) {} -}; - -template -struct LinkedListElementTraits> -{ - typedef T* RawType; - typedef const T* ConstRawType; - typedef RefPtr ClientType; - typedef RefPtr ConstClientType; - - static void enterList(LinkedListElement>* elt) { elt->asT()->AddRef(); } - static void exitList(LinkedListElement>* elt) { elt->asT()->Release(); } -}; - -} /* namespace detail */ - -template -class LinkedList; - -template -class LinkedListElement -{ - typedef typename detail::LinkedListElementTraits Traits; - typedef typename Traits::RawType RawType; - typedef typename Traits::ConstRawType ConstRawType; - typedef typename Traits::ClientType ClientType; - typedef typename Traits::ConstClientType ConstClientType; - - /* - * It's convenient that we return nullptr when getNext() or getPrevious() - * hits the end of the list, but doing so costs an extra word of storage in - * each linked list node (to keep track of whether |this| is the sentinel - * node) and a branch on this value in getNext/getPrevious. - * - * We could get rid of the extra word of storage by shoving the "is - * sentinel" bit into one of the pointers, although this would, of course, - * have performance implications of its own. - * - * But the goal here isn't to win an award for the fastest or slimmest - * linked list; rather, we want a *convenient* linked list. So we won't - * waste time guessing which micro-optimization strategy is best. - * - * - * Speaking of unnecessary work, it's worth addressing here why we wrote - * mozilla::LinkedList in the first place, instead of using stl::list. - * - * The key difference between mozilla::LinkedList and stl::list is that - * mozilla::LinkedList stores the mPrev/mNext pointers in the object itself, - * while stl::list stores the mPrev/mNext pointers in a list element which - * itself points to the object being stored. - * - * mozilla::LinkedList's approach makes it harder to store an object in more - * than one list. But the upside is that you can call next() / prev() / - * remove() directly on the object. With stl::list, you'd need to store a - * pointer to its iterator in the object in order to accomplish this. Not - * only would this waste space, but you'd have to remember to update that - * pointer every time you added or removed the object from a list. - * - * In-place, constant-time removal is a killer feature of doubly-linked - * lists, and supporting this painlessly was a key design criterion. - */ - -private: - LinkedListElement* mNext; - LinkedListElement* mPrev; - const bool mIsSentinel; - -public: - LinkedListElement() - : mNext(this), - mPrev(this), - mIsSentinel(false) - { } - - /* - * Moves |aOther| into |*this|. If |aOther| is already in a list, then - * |aOther| is removed from the list and replaced by |*this|. - */ - LinkedListElement(LinkedListElement&& aOther) - : mIsSentinel(aOther.mIsSentinel) - { - adjustLinkForMove(Move(aOther)); - } - - LinkedListElement& operator=(LinkedListElement&& aOther) - { - MOZ_ASSERT(mIsSentinel == aOther.mIsSentinel, "Mismatch NodeKind!"); - MOZ_ASSERT(!isInList(), - "Assigning to an element in a list messes up that list!"); - adjustLinkForMove(Move(aOther)); - return *this; - } - - ~LinkedListElement() - { - if (!mIsSentinel && isInList()) { - remove(); - } - } - - /* - * Get the next element in the list, or nullptr if this is the last element - * in the list. - */ - RawType getNext() { return mNext->asT(); } - ConstRawType getNext() const { return mNext->asT(); } - - /* - * Get the previous element in the list, or nullptr if this is the first - * element in the list. - */ - RawType getPrevious() { return mPrev->asT(); } - ConstRawType getPrevious() const { return mPrev->asT(); } - - /* - * Insert aElem after this element in the list. |this| must be part of a - * linked list when you call setNext(); otherwise, this method will assert. - */ - void setNext(RawType aElem) - { - MOZ_ASSERT(isInList()); - setNextUnsafe(aElem); - } - - /* - * Insert aElem before this element in the list. |this| must be part of a - * linked list when you call setPrevious(); otherwise, this method will - * assert. - */ - void setPrevious(RawType aElem) - { - MOZ_ASSERT(isInList()); - setPreviousUnsafe(aElem); - } - - /* - * Remove this element from the list which contains it. If this element is - * not currently part of a linked list, this method asserts. - */ - void remove() - { - MOZ_ASSERT(isInList()); - - mPrev->mNext = mNext; - mNext->mPrev = mPrev; - mNext = this; - mPrev = this; - - Traits::exitList(this); - } - - /* - * Remove this element from the list containing it. Returns a pointer to the - * element that follows this element (before it was removed). This method - * asserts if the element does not belong to a list. - */ - ClientType removeAndGetNext() - { - ClientType r = getNext(); - remove(); - return r; - } - - /* - * Remove this element from the list containing it. Returns a pointer to the - * previous element in the containing list (before the removal). This method - * asserts if the element does not belong to a list. - */ - ClientType removeAndGetPrevious() - { - ClientType r = getPrevious(); - remove(); - return r; - } - - /* - * Identical to remove(), but also asserts in debug builds that this element - * is in aList. - */ - void removeFrom(const LinkedList& aList) - { - aList.assertContains(asT()); - remove(); - } - - /* - * Return true if |this| part is of a linked list, and false otherwise. - */ - bool isInList() const - { - MOZ_ASSERT((mNext == this) == (mPrev == this)); - return mNext != this; - } - -private: - friend class LinkedList; - friend struct detail::LinkedListElementTraits; - - enum class NodeKind { - Normal, - Sentinel - }; - - explicit LinkedListElement(NodeKind nodeKind) - : mNext(this), - mPrev(this), - mIsSentinel(nodeKind == NodeKind::Sentinel) - { } - - /* - * Return |this| cast to T* if we're a normal node, or return nullptr if - * we're a sentinel node. - */ - RawType asT() - { - return mIsSentinel ? nullptr : static_cast(this); - } - ConstRawType asT() const - { - return mIsSentinel ? nullptr : static_cast(this); - } - - /* - * Insert aElem after this element, but don't check that this element is in - * the list. This is called by LinkedList::insertFront(). - */ - void setNextUnsafe(RawType aElem) - { - LinkedListElement *listElem = static_cast(aElem); - MOZ_ASSERT(!listElem->isInList()); - - listElem->mNext = this->mNext; - listElem->mPrev = this; - this->mNext->mPrev = listElem; - this->mNext = listElem; - - Traits::enterList(aElem); - } - - /* - * Insert aElem before this element, but don't check that this element is in - * the list. This is called by LinkedList::insertBack(). - */ - void setPreviousUnsafe(RawType aElem) - { - LinkedListElement* listElem = static_cast*>(aElem); - MOZ_ASSERT(!listElem->isInList()); - - listElem->mNext = this; - listElem->mPrev = this->mPrev; - this->mPrev->mNext = listElem; - this->mPrev = listElem; - - Traits::enterList(aElem); - } - - /* - * Adjust mNext and mPrev for implementing move constructor and move - * assignment. - */ - void adjustLinkForMove(LinkedListElement&& aOther) - { - if (!aOther.isInList()) { - mNext = this; - mPrev = this; - return; - } - - if (!mIsSentinel) { - Traits::enterList(this); - } - - MOZ_ASSERT(aOther.mNext->mPrev == &aOther); - MOZ_ASSERT(aOther.mPrev->mNext == &aOther); - - /* - * Initialize |this| with |aOther|'s mPrev/mNext pointers, and adjust those - * element to point to this one. - */ - mNext = aOther.mNext; - mPrev = aOther.mPrev; - - mNext->mPrev = this; - mPrev->mNext = this; - - /* - * Adjust |aOther| so it doesn't think it's in a list. This makes it - * safely destructable. - */ - aOther.mNext = &aOther; - aOther.mPrev = &aOther; - - if (!mIsSentinel) { - Traits::exitList(&aOther); - } - } - - LinkedListElement& operator=(const LinkedListElement& aOther) = delete; - LinkedListElement(const LinkedListElement& aOther) = delete; -}; - -template -class LinkedList -{ -private: - typedef typename detail::LinkedListElementTraits Traits; - typedef typename Traits::RawType RawType; - typedef typename Traits::ConstRawType ConstRawType; - typedef typename Traits::ClientType ClientType; - typedef typename Traits::ConstClientType ConstClientType; - - LinkedListElement sentinel; - -public: - class Iterator { - RawType mCurrent; - - public: - explicit Iterator(RawType aCurrent) : mCurrent(aCurrent) {} - - RawType operator *() const { - return mCurrent; - } - - const Iterator& operator++() { - mCurrent = mCurrent->getNext(); - return *this; - } - - bool operator!=(Iterator& aOther) const { - return mCurrent != aOther.mCurrent; - } - }; - - LinkedList() : sentinel(LinkedListElement::NodeKind::Sentinel) { } - - LinkedList(LinkedList&& aOther) - : sentinel(mozilla::Move(aOther.sentinel)) - { } - - LinkedList& operator=(LinkedList&& aOther) - { - MOZ_ASSERT(isEmpty(), "Assigning to a non-empty list leaks elements in that list!"); - sentinel = mozilla::Move(aOther.sentinel); - return *this; - } - - ~LinkedList() { - MOZ_ASSERT(isEmpty(), - "failing this assertion means this LinkedList's creator is " - "buggy: it should have removed all this list's elements before " - "the list's destruction"); - } - - /* - * Add aElem to the front of the list. - */ - void insertFront(RawType aElem) - { - /* Bypass setNext()'s this->isInList() assertion. */ - sentinel.setNextUnsafe(aElem); - } - - /* - * Add aElem to the back of the list. - */ - void insertBack(RawType aElem) - { - sentinel.setPreviousUnsafe(aElem); - } - - /* - * Get the first element of the list, or nullptr if the list is empty. - */ - RawType getFirst() { return sentinel.getNext(); } - ConstRawType getFirst() const { return sentinel.getNext(); } - - /* - * Get the last element of the list, or nullptr if the list is empty. - */ - RawType getLast() { return sentinel.getPrevious(); } - ConstRawType getLast() const { return sentinel.getPrevious(); } - - /* - * Get and remove the first element of the list. If the list is empty, - * return nullptr. - */ - ClientType popFirst() - { - ClientType ret = sentinel.getNext(); - if (ret) { - static_cast*>(RawType(ret))->remove(); - } - return ret; - } - - /* - * Get and remove the last element of the list. If the list is empty, - * return nullptr. - */ - ClientType popLast() - { - ClientType ret = sentinel.getPrevious(); - if (ret) { - static_cast*>(RawType(ret))->remove(); - } - return ret; - } - - /* - * Return true if the list is empty, or false otherwise. - */ - bool isEmpty() const - { - return !sentinel.isInList(); - } - - /* - * Remove all the elements from the list. - * - * This runs in time linear to the list's length, because we have to mark - * each element as not in the list. - */ - void clear() - { - while (popFirst()) { - continue; - } - } - - /* - * Allow range-based iteration: - * - * for (MyElementType* elt : myList) { ... } - */ - Iterator begin() { - return Iterator(getFirst()); - } - Iterator end() { - return Iterator(nullptr); - } - - /* - * Measures the memory consumption of the list excluding |this|. Note that - * it only measures the list elements themselves. If the list elements - * contain pointers to other memory blocks, those blocks must be measured - * separately during a subsequent iteration over the list. - */ - size_t sizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const - { - size_t n = 0; - for (const T* t = getFirst(); t; t = t->getNext()) { - n += aMallocSizeOf(t); - } - return n; - } - - /* - * Like sizeOfExcludingThis(), but measures |this| as well. - */ - size_t sizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const - { - return aMallocSizeOf(this) + sizeOfExcludingThis(aMallocSizeOf); - } - - /* - * In a debug build, make sure that the list is sane (no cycles, consistent - * mNext/mPrev pointers, only one sentinel). Has no effect in release builds. - */ - void debugAssertIsSane() const - { -#ifdef DEBUG - const LinkedListElement* slow; - const LinkedListElement* fast1; - const LinkedListElement* fast2; - - /* - * Check for cycles in the forward singly-linked list using the - * tortoise/hare algorithm. - */ - for (slow = sentinel.mNext, - fast1 = sentinel.mNext->mNext, - fast2 = sentinel.mNext->mNext->mNext; - slow != &sentinel && fast1 != &sentinel && fast2 != &sentinel; - slow = slow->mNext, fast1 = fast2->mNext, fast2 = fast1->mNext) { - MOZ_ASSERT(slow != fast1); - MOZ_ASSERT(slow != fast2); - } - - /* Check for cycles in the backward singly-linked list. */ - for (slow = sentinel.mPrev, - fast1 = sentinel.mPrev->mPrev, - fast2 = sentinel.mPrev->mPrev->mPrev; - slow != &sentinel && fast1 != &sentinel && fast2 != &sentinel; - slow = slow->mPrev, fast1 = fast2->mPrev, fast2 = fast1->mPrev) { - MOZ_ASSERT(slow != fast1); - MOZ_ASSERT(slow != fast2); - } - - /* - * Check that |sentinel| is the only node in the list with - * mIsSentinel == true. - */ - for (const LinkedListElement* elem = sentinel.mNext; - elem != &sentinel; - elem = elem->mNext) { - MOZ_ASSERT(!elem->mIsSentinel); - } - - /* Check that the mNext/mPrev pointers match up. */ - const LinkedListElement* prev = &sentinel; - const LinkedListElement* cur = sentinel.mNext; - do { - MOZ_ASSERT(cur->mPrev == prev); - MOZ_ASSERT(prev->mNext == cur); - - prev = cur; - cur = cur->mNext; - } while (cur != &sentinel); -#endif /* ifdef DEBUG */ - } - -private: - friend class LinkedListElement; - - void assertContains(const RawType aValue) const - { -#ifdef DEBUG - for (ConstRawType elem = getFirst(); elem; elem = elem->getNext()) { - if (elem == aValue) { - return; - } - } - MOZ_CRASH("element wasn't found in this list!"); -#endif - } - - LinkedList& operator=(const LinkedList& aOther) = delete; - LinkedList(const LinkedList& aOther) = delete; -}; - -template -class AutoCleanLinkedList : public LinkedList -{ -public: - ~AutoCleanLinkedList() - { - while (T* element = this->popFirst()) { - delete element; - } - } -}; - -} /* namespace mozilla */ - -#endif /* __cplusplus */ - -#endif /* mozilla_LinkedList_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/LinuxSignal.h b/android/armeabi-v7a/include/spidermonkey/mozilla/LinuxSignal.h deleted file mode 100644 index 83c2bf81..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/LinuxSignal.h +++ /dev/null @@ -1,45 +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/. */ - -#ifndef mozilla_LinuxSignal_h -#define mozilla_LinuxSignal_h - -namespace mozilla { - -#if defined(__arm__) - -// Some (old) Linux kernels on ARM have a bug where a signal handler -// can be called without clearing the IT bits in CPSR first. The result -// is that the first few instructions of the handler could be skipped, -// ultimately resulting in crashes. To workaround this bug, the handler -// on ARM is a trampoline that starts with enough NOP instructions, so -// that even if the IT bits are not cleared, only the NOP instructions -// will be skipped over. - -template -__attribute__((naked)) void -SignalTrampoline(int aSignal, siginfo_t* aInfo, void* aContext) -{ - asm volatile ( - "nop; nop; nop; nop" - : : : "memory"); - - asm volatile ( - "b %0" - : - : "X"(H) - : "memory"); -} - -# define MOZ_SIGNAL_TRAMPOLINE(h) (mozilla::SignalTrampoline) - -#else // __arm__ - -# define MOZ_SIGNAL_TRAMPOLINE(h) (h) - -#endif // __arm__ - -} // namespace mozilla - -#endif // mozilla_LinuxSignal_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/MacroArgs.h b/android/armeabi-v7a/include/spidermonkey/mozilla/MacroArgs.h deleted file mode 100644 index 52ed1e82..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/MacroArgs.h +++ /dev/null @@ -1,109 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Implements various macros meant to ease the use of variadic macros. - */ - -#ifndef mozilla_MacroArgs_h -#define mozilla_MacroArgs_h - -// Concatenates pre-processor tokens in a way that can be used with __LINE__. -#define MOZ_CONCAT2(x, y) x ## y -#define MOZ_CONCAT(x, y) MOZ_CONCAT2(x, y) - -/* - * MOZ_PASTE_PREFIX_AND_ARG_COUNT(aPrefix, ...) counts the number of variadic - * arguments and prefixes it with |aPrefix|. For example: - * - * MOZ_PASTE_PREFIX_AND_ARG_COUNT(, foo, 42) expands to 2 - * MOZ_PASTE_PREFIX_AND_ARG_COUNT(A, foo, 42, bar) expands to A3 - * - * You must pass in between 1 and 50 (inclusive) variadic arguments, past - * |aPrefix|. It is not legal to do - * - * MOZ_PASTE_PREFIX_AND_ARG_COUNT(prefix) - * - * (that is, pass in 0 variadic arguments). To ensure that a compile-time - * error occurs when these constraints are violated, use the - * MOZ_STATIC_ASSERT_VALID_ARG_COUNT macro with the same variaidc arguments - * wherever this macro is used. - * - * Passing (__VA_ARGS__, ) rather than simply calling - * MOZ_MACROARGS_ARG_COUNT_HELPER2(__VA_ARGS__, ) very - * carefully tiptoes around a MSVC bug where it improperly expands __VA_ARGS__ - * as a single token in argument lists. For details, see: - * - * http://connect.microsoft.com/VisualStudio/feedback/details/380090/variadic-macro-replacement - * http://cplusplus.co.il/2010/07/17/variadic-macro-to-count-number-of-arguments/#comment-644 - */ -#define MOZ_PASTE_PREFIX_AND_ARG_COUNT(aPrefix, ...) \ - MOZ_MACROARGS_ARG_COUNT_HELPER((__VA_ARGS__, \ - aPrefix##50, aPrefix##49, aPrefix##48, aPrefix##47, aPrefix##46, \ - aPrefix##45, aPrefix##44, aPrefix##43, aPrefix##42, aPrefix##41, \ - aPrefix##40, aPrefix##39, aPrefix##38, aPrefix##37, aPrefix##36, \ - aPrefix##35, aPrefix##34, aPrefix##33, aPrefix##32, aPrefix##31, \ - aPrefix##30, aPrefix##29, aPrefix##28, aPrefix##27, aPrefix##26, \ - aPrefix##25, aPrefix##24, aPrefix##23, aPrefix##22, aPrefix##21, \ - aPrefix##20, aPrefix##19, aPrefix##18, aPrefix##17, aPrefix##16, \ - aPrefix##15, aPrefix##14, aPrefix##13, aPrefix##12, aPrefix##11, \ - aPrefix##10, aPrefix##9, aPrefix##8, aPrefix##7, aPrefix##6, \ - aPrefix##5, aPrefix##4, aPrefix##3, aPrefix##2, aPrefix##1, aPrefix##0)) - -#define MOZ_MACROARGS_ARG_COUNT_HELPER(aArgs) \ - MOZ_MACROARGS_ARG_COUNT_HELPER2 aArgs - -#define MOZ_MACROARGS_ARG_COUNT_HELPER2( \ - a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, \ - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, \ - a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, \ - a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, \ - a41, a42, a43, a44, a45, a46, a47, a48, a49, a50, \ - a51, ...) a51 - -/* - * MOZ_STATIC_ASSERT_VALID_ARG_COUNT ensures that a compile-time error occurs - * when the argument count constraints of MOZ_PASTE_PREFIX_AND_ARG_COUNT are - * violated. Use this macro wherever MOZ_PASTE_PREFIX_AND_ARG_COUNT is used - * and pass it the same variadic arguments. - * - * This macro employs a few dirty tricks to function. To detect the zero - * argument case, |(__VA_ARGS__)| is stringified, sizeof-ed, and compared to - * what it should be in the absence of arguments. - * - * Detecting too many arguments is a little trickier. With a valid argument - * count and a prefix of 1, MOZ_PASTE_PREFIX_AND_ARG_COUNT expands to e.g. 14. - * With a prefix of 0.0, it expands to e.g. 0.04. If there are too many - * arguments, it expands to the first argument over the limit. If this - * exceeding argument is a number, the assertion will fail as there is no - * number than can simultaneously be both > 10 and == 0. If the exceeding - * argument is not a number, a compile-time error should still occur due to - * the operations performed on it. - */ -#define MOZ_MACROARGS_STRINGIFY_HELPER(x) #x -#define MOZ_STATIC_ASSERT_VALID_ARG_COUNT(...) \ - static_assert( \ - sizeof(MOZ_MACROARGS_STRINGIFY_HELPER((__VA_ARGS__))) != sizeof("()") && \ - (MOZ_PASTE_PREFIX_AND_ARG_COUNT(1, __VA_ARGS__)) > 10 && \ - (int)(MOZ_PASTE_PREFIX_AND_ARG_COUNT(0.0, __VA_ARGS__)) == 0, \ - "MOZ_STATIC_ASSERT_VALID_ARG_COUNT requires 1 to 50 arguments") /* ; */ - -/* - * MOZ_ARGS_AFTER_N expands to its arguments excluding the first |N| - * arguments. For example: - * - * MOZ_ARGS_AFTER_2(a, b, c, d) expands to: c, d - */ -#define MOZ_ARGS_AFTER_1(a1, ...) __VA_ARGS__ -#define MOZ_ARGS_AFTER_2(a1, a2, ...) __VA_ARGS__ - -/* - * MOZ_ARG_N expands to its |N|th argument. - */ -#define MOZ_ARG_1(a1, ...) a1 -#define MOZ_ARG_2(a1, a2, ...) a2 - -#endif /* mozilla_MacroArgs_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/MacroForEach.h b/android/armeabi-v7a/include/spidermonkey/mozilla/MacroForEach.h deleted file mode 100644 index 7c0e3cfb..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/MacroForEach.h +++ /dev/null @@ -1,158 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Implements a higher-order macro for iteratively calling another macro with - * fixed leading arguments, plus a trailing element picked from a second list - * of arguments. - */ - -#ifndef mozilla_MacroForEach_h -#define mozilla_MacroForEach_h - -#include "mozilla/MacroArgs.h" - -/* - * MOZ_FOR_EACH(aMacro, aFixedArgs, aArgs) expands to N calls to the macro - * |aMacro| where N is equal the number of items in the list |aArgs|. The - * arguments for each |aMacro| call are composed of *all* arguments in the list - * |aFixedArgs| as well as a single argument in the list |aArgs|. For example: - * - * #define MACRO_A(x) x + - * int a = MOZ_FOR_EACH(MACRO_A, (), (1, 2, 3)) 0; - * // Expands to: MACRO_A(1) MACRO_A(2) MACRO_A(3) 0; - * // And further to: 1 + 2 + 3 + 0; - * - * #define MACRO_B(k, x) (k + x) + - * int b = MOZ_FOR_EACH(MACRO_B, (5,), (1, 2)) 0; - * // Expands to: MACRO_B(5, 1) MACRO_B(5, 2) 0; - * - * #define MACRO_C(k1, k2, x) (k1 + k2 + x) + - * int c = MOZ_FOR_EACH(MACRO_C, (5, 8,), (1, 2)) 0; - * // Expands to: MACRO_B(5, 8, 1) MACRO_B(5, 8, 2) 0; - * - * If the |aFixedArgs| list is not empty, a trailing comma must be included. - * - * The |aArgs| list must be not be empty and may be up to 50 items long. Use - * MOZ_STATIC_ASSERT_VALID_ARG_COUNT to ensure that violating this constraint - * results in a compile-time error. - */ -#define MOZ_FOR_EACH_EXPAND_HELPER(...) __VA_ARGS__ -#define MOZ_FOR_EACH_GLUE(a, b) a b -#define MOZ_FOR_EACH(aMacro, aFixedArgs, aArgs) \ - MOZ_FOR_EACH_GLUE( \ - MOZ_PASTE_PREFIX_AND_ARG_COUNT(MOZ_FOR_EACH_, \ - MOZ_FOR_EACH_EXPAND_HELPER aArgs), \ - (aMacro, aFixedArgs, aArgs)) - -#define MOZ_FOR_EACH_HELPER_GLUE(a, b) a b -#define MOZ_FOR_EACH_HELPER(aMacro, aFixedArgs, aArgs) \ - MOZ_FOR_EACH_HELPER_GLUE( \ - aMacro, \ - (MOZ_FOR_EACH_EXPAND_HELPER aFixedArgs MOZ_ARG_1 aArgs)) - -#define MOZ_FOR_EACH_1(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) -#define MOZ_FOR_EACH_2(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_1(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_3(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_2(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_4(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_3(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_5(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_4(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_6(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_5(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_7(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_6(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_8(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_7(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_9(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_8(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_10(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_9(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_11(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_10(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_12(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_11(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_13(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_12(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_14(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_13(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_15(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_14(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_16(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_15(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_17(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_16(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_18(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_17(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_19(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_18(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_20(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_19(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_21(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_20(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_22(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_21(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_23(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_22(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_24(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_23(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_25(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_24(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_26(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_25(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_27(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_26(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_28(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_27(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_29(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_28(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_30(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_29(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_31(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_30(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_32(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_31(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_33(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_32(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_34(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_33(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_35(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_34(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_36(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_35(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_37(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_36(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_38(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_37(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_39(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_38(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_40(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_39(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_41(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_40(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_42(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_41(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_43(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_42(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_44(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_43(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_45(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_44(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_46(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_45(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_47(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_46(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_48(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_47(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_49(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_48(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_50(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_49(m, fa, (MOZ_ARGS_AFTER_1 a)) - -#endif /* mozilla_MacroForEach_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/MathAlgorithms.h b/android/armeabi-v7a/include/spidermonkey/mozilla/MathAlgorithms.h deleted file mode 100644 index 4db6de49..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/MathAlgorithms.h +++ /dev/null @@ -1,547 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* mfbt maths algorithms. */ - -#ifndef mozilla_MathAlgorithms_h -#define mozilla_MathAlgorithms_h - -#include "mozilla/Assertions.h" -#include "mozilla/TypeTraits.h" - -#include -#include -#include - -namespace mozilla { - -// Greatest Common Divisor -template -MOZ_ALWAYS_INLINE IntegerType -EuclidGCD(IntegerType aA, IntegerType aB) -{ - // Euclid's algorithm; O(N) in the worst case. (There are better - // ways, but we don't need them for the current use of this algo.) - MOZ_ASSERT(aA > IntegerType(0)); - MOZ_ASSERT(aB > IntegerType(0)); - - while (aA != aB) { - if (aA > aB) { - aA = aA - aB; - } else { - aB = aB - aA; - } - } - - return aA; -} - -// Least Common Multiple -template -MOZ_ALWAYS_INLINE IntegerType -EuclidLCM(IntegerType aA, IntegerType aB) -{ - // Divide first to reduce overflow risk. - return (aA / EuclidGCD(aA, aB)) * aB; -} - -namespace detail { - -template -struct AllowDeprecatedAbsFixed : FalseType {}; - -template<> struct AllowDeprecatedAbsFixed : TrueType {}; -template<> struct AllowDeprecatedAbsFixed : TrueType {}; - -template -struct AllowDeprecatedAbs : AllowDeprecatedAbsFixed {}; - -template<> struct AllowDeprecatedAbs : TrueType {}; -template<> struct AllowDeprecatedAbs : TrueType {}; - -} // namespace detail - -// DO NOT USE DeprecatedAbs. It exists only until its callers can be converted -// to Abs below, and it will be removed when all callers have been changed. -template -inline typename mozilla::EnableIf::value, T>::Type -DeprecatedAbs(const T aValue) -{ - // The absolute value of the smallest possible value of a signed-integer type - // won't fit in that type (on twos-complement systems -- and we're blithely - // assuming we're on such systems, for the non- types listed above), - // so assert that the input isn't that value. - // - // This is the case if: the value is non-negative; or if adding one (giving a - // value in the range [-maxvalue, 0]), then negating (giving a value in the - // range [0, maxvalue]), doesn't produce maxvalue (because in twos-complement, - // (minvalue + 1) == -maxvalue). - MOZ_ASSERT(aValue >= 0 || - -(aValue + 1) != T((1ULL << (CHAR_BIT * sizeof(T) - 1)) - 1), - "You can't negate the smallest possible negative integer!"); - return aValue >= 0 ? aValue : -aValue; -} - -namespace detail { - -// For now mozilla::Abs only takes intN_T, the signed natural types, and -// float/double/long double. Feel free to add overloads for other standard, -// signed types if you need them. - -template -struct AbsReturnTypeFixed; - -template<> struct AbsReturnTypeFixed { typedef uint8_t Type; }; -template<> struct AbsReturnTypeFixed { typedef uint16_t Type; }; -template<> struct AbsReturnTypeFixed { typedef uint32_t Type; }; -template<> struct AbsReturnTypeFixed { typedef uint64_t Type; }; - -template -struct AbsReturnType : AbsReturnTypeFixed {}; - -template<> struct AbsReturnType : - EnableIf {}; -template<> struct AbsReturnType { typedef unsigned char Type; }; -template<> struct AbsReturnType { typedef unsigned short Type; }; -template<> struct AbsReturnType { typedef unsigned int Type; }; -template<> struct AbsReturnType { typedef unsigned long Type; }; -template<> struct AbsReturnType { typedef unsigned long long Type; }; -template<> struct AbsReturnType { typedef float Type; }; -template<> struct AbsReturnType { typedef double Type; }; -template<> struct AbsReturnType { typedef long double Type; }; - -} // namespace detail - -template -inline typename detail::AbsReturnType::Type -Abs(const T aValue) -{ - typedef typename detail::AbsReturnType::Type ReturnType; - return aValue >= 0 ? ReturnType(aValue) : ~ReturnType(aValue) + 1; -} - -template<> -inline float -Abs(const float aFloat) -{ - return std::fabs(aFloat); -} - -template<> -inline double -Abs(const double aDouble) -{ - return std::fabs(aDouble); -} - -template<> -inline long double -Abs(const long double aLongDouble) -{ - return std::fabs(aLongDouble); -} - -} // namespace mozilla - -#if defined(_MSC_VER) && \ - (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) -# define MOZ_BITSCAN_WINDOWS - -# include -# pragma intrinsic(_BitScanForward, _BitScanReverse) - -# if defined(_M_AMD64) || defined(_M_X64) -# define MOZ_BITSCAN_WINDOWS64 -# pragma intrinsic(_BitScanForward64, _BitScanReverse64) -# endif - -#endif - -namespace mozilla { - -namespace detail { - -#if defined(MOZ_BITSCAN_WINDOWS) - -inline uint_fast8_t -CountLeadingZeroes32(uint32_t aValue) -{ - unsigned long index; - if (!_BitScanReverse(&index, static_cast(aValue))) - return 32; - return uint_fast8_t(31 - index); -} - - -inline uint_fast8_t -CountTrailingZeroes32(uint32_t aValue) -{ - unsigned long index; - if (!_BitScanForward(&index, static_cast(aValue))) - return 32; - return uint_fast8_t(index); -} - -inline uint_fast8_t -CountPopulation32(uint32_t aValue) -{ - uint32_t x = aValue - ((aValue >> 1) & 0x55555555); - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - return (((x + (x >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24; -} -inline uint_fast8_t -CountPopulation64(uint64_t aValue) -{ - return uint_fast8_t(CountPopulation32(aValue & 0xffffffff) + - CountPopulation32(aValue >> 32)); -} - -inline uint_fast8_t -CountLeadingZeroes64(uint64_t aValue) -{ -#if defined(MOZ_BITSCAN_WINDOWS64) - unsigned long index; - if (!_BitScanReverse64(&index, static_cast(aValue))) - return 64; - return uint_fast8_t(63 - index); -#else - uint32_t hi = uint32_t(aValue >> 32); - if (hi != 0) { - return CountLeadingZeroes32(hi); - } - return 32u + CountLeadingZeroes32(uint32_t(aValue)); -#endif -} - -inline uint_fast8_t -CountTrailingZeroes64(uint64_t aValue) -{ -#if defined(MOZ_BITSCAN_WINDOWS64) - unsigned long index; - if (!_BitScanForward64(&index, static_cast(aValue))) - return 64; - return uint_fast8_t(index); -#else - uint32_t lo = uint32_t(aValue); - if (lo != 0) { - return CountTrailingZeroes32(lo); - } - return 32u + CountTrailingZeroes32(uint32_t(aValue >> 32)); -#endif -} - -# ifdef MOZ_HAVE_BITSCAN64 -# undef MOZ_HAVE_BITSCAN64 -# endif - -#elif defined(__clang__) || defined(__GNUC__) - -# if defined(__clang__) -# if !__has_builtin(__builtin_ctz) || !__has_builtin(__builtin_clz) -# error "A clang providing __builtin_c[lt]z is required to build" -# endif -# else - // gcc has had __builtin_clz and friends since 3.4: no need to check. -# endif - -inline uint_fast8_t -CountLeadingZeroes32(uint32_t aValue) -{ - return __builtin_clz(aValue); -} - -inline uint_fast8_t -CountTrailingZeroes32(uint32_t aValue) -{ - return __builtin_ctz(aValue); -} - -inline uint_fast8_t -CountPopulation32(uint32_t aValue) -{ - return __builtin_popcount(aValue); -} - -inline uint_fast8_t -CountPopulation64(uint64_t aValue) -{ - return __builtin_popcountll(aValue); -} - -inline uint_fast8_t -CountLeadingZeroes64(uint64_t aValue) -{ - return __builtin_clzll(aValue); -} - -inline uint_fast8_t -CountTrailingZeroes64(uint64_t aValue) -{ - return __builtin_ctzll(aValue); -} - -#else -# error "Implement these!" -inline uint_fast8_t CountLeadingZeroes32(uint32_t aValue) = delete; -inline uint_fast8_t CountTrailingZeroes32(uint32_t aValue) = delete; -inline uint_fast8_t CountPopulation32(uint32_t aValue) = delete; -inline uint_fast8_t CountPopulation64(uint64_t aValue) = delete; -inline uint_fast8_t CountLeadingZeroes64(uint64_t aValue) = delete; -inline uint_fast8_t CountTrailingZeroes64(uint64_t aValue) = delete; -#endif - -} // namespace detail - -/** - * Compute the number of high-order zero bits in the NON-ZERO number |aValue|. - * That is, looking at the bitwise representation of the number, with the - * highest- valued bits at the start, return the number of zeroes before the - * first one is observed. - * - * CountLeadingZeroes32(0xF0FF1000) is 0; - * CountLeadingZeroes32(0x7F8F0001) is 1; - * CountLeadingZeroes32(0x3FFF0100) is 2; - * CountLeadingZeroes32(0x1FF50010) is 3; and so on. - */ -inline uint_fast8_t -CountLeadingZeroes32(uint32_t aValue) -{ - MOZ_ASSERT(aValue != 0); - return detail::CountLeadingZeroes32(aValue); -} - -/** - * Compute the number of low-order zero bits in the NON-ZERO number |aValue|. - * That is, looking at the bitwise representation of the number, with the - * lowest- valued bits at the start, return the number of zeroes before the - * first one is observed. - * - * CountTrailingZeroes32(0x0100FFFF) is 0; - * CountTrailingZeroes32(0x7000FFFE) is 1; - * CountTrailingZeroes32(0x0080FFFC) is 2; - * CountTrailingZeroes32(0x0080FFF8) is 3; and so on. - */ -inline uint_fast8_t -CountTrailingZeroes32(uint32_t aValue) -{ - MOZ_ASSERT(aValue != 0); - return detail::CountTrailingZeroes32(aValue); -} - -/** - * Compute the number of one bits in the number |aValue|, - */ -inline uint_fast8_t -CountPopulation32(uint32_t aValue) -{ - return detail::CountPopulation32(aValue); -} - -/** Analogous to CountPopulation32, but for 64-bit numbers */ -inline uint_fast8_t -CountPopulation64(uint64_t aValue) -{ - return detail::CountPopulation64(aValue); -} - -/** Analogous to CountLeadingZeroes32, but for 64-bit numbers. */ -inline uint_fast8_t -CountLeadingZeroes64(uint64_t aValue) -{ - MOZ_ASSERT(aValue != 0); - return detail::CountLeadingZeroes64(aValue); -} - -/** Analogous to CountTrailingZeroes32, but for 64-bit numbers. */ -inline uint_fast8_t -CountTrailingZeroes64(uint64_t aValue) -{ - MOZ_ASSERT(aValue != 0); - return detail::CountTrailingZeroes64(aValue); -} - -namespace detail { - -template -class CeilingLog2; - -template -class CeilingLog2 -{ -public: - static uint_fast8_t compute(const T aValue) - { - // Check for <= 1 to avoid the == 0 undefined case. - return aValue <= 1 ? 0u : 32u - CountLeadingZeroes32(aValue - 1); - } -}; - -template -class CeilingLog2 -{ -public: - static uint_fast8_t compute(const T aValue) - { - // Check for <= 1 to avoid the == 0 undefined case. - return aValue <= 1 ? 0u : 64u - CountLeadingZeroes64(aValue - 1); - } -}; - -} // namespace detail - -/** - * Compute the log of the least power of 2 greater than or equal to |aValue|. - * - * CeilingLog2(0..1) is 0; - * CeilingLog2(2) is 1; - * CeilingLog2(3..4) is 2; - * CeilingLog2(5..8) is 3; - * CeilingLog2(9..16) is 4; and so on. - */ -template -inline uint_fast8_t -CeilingLog2(const T aValue) -{ - return detail::CeilingLog2::compute(aValue); -} - -/** A CeilingLog2 variant that accepts only size_t. */ -inline uint_fast8_t -CeilingLog2Size(size_t aValue) -{ - return CeilingLog2(aValue); -} - -namespace detail { - -template -class FloorLog2; - -template -class FloorLog2 -{ -public: - static uint_fast8_t compute(const T aValue) - { - return 31u - CountLeadingZeroes32(aValue | 1); - } -}; - -template -class FloorLog2 -{ -public: - static uint_fast8_t compute(const T aValue) - { - return 63u - CountLeadingZeroes64(aValue | 1); - } -}; - -} // namespace detail - -/** - * Compute the log of the greatest power of 2 less than or equal to |aValue|. - * - * FloorLog2(0..1) is 0; - * FloorLog2(2..3) is 1; - * FloorLog2(4..7) is 2; - * FloorLog2(8..15) is 3; and so on. - */ -template -inline uint_fast8_t -FloorLog2(const T aValue) -{ - return detail::FloorLog2::compute(aValue); -} - -/** A FloorLog2 variant that accepts only size_t. */ -inline uint_fast8_t -FloorLog2Size(size_t aValue) -{ - return FloorLog2(aValue); -} - -/* - * Compute the smallest power of 2 greater than or equal to |x|. |x| must not - * be so great that the computed value would overflow |size_t|. - */ -inline size_t -RoundUpPow2(size_t aValue) -{ - MOZ_ASSERT(aValue <= (size_t(1) << (sizeof(size_t) * CHAR_BIT - 1)), - "can't round up -- will overflow!"); - return size_t(1) << CeilingLog2(aValue); -} - -/** - * Rotates the bits of the given value left by the amount of the shift width. - */ -template -inline T -RotateLeft(const T aValue, uint_fast8_t aShift) -{ - MOZ_ASSERT(aShift < sizeof(T) * CHAR_BIT, "Shift value is too large!"); - MOZ_ASSERT(aShift > 0, - "Rotation by value length is undefined behavior, but compilers " - "do not currently fold a test into the rotate instruction. " - "Please remove this restriction when compilers optimize the " - "zero case (http://blog.regehr.org/archives/1063)."); - static_assert(IsUnsigned::value, "Rotates require unsigned values"); - return (aValue << aShift) | (aValue >> (sizeof(T) * CHAR_BIT - aShift)); -} - -/** - * Rotates the bits of the given value right by the amount of the shift width. - */ -template -inline T -RotateRight(const T aValue, uint_fast8_t aShift) -{ - MOZ_ASSERT(aShift < sizeof(T) * CHAR_BIT, "Shift value is too large!"); - MOZ_ASSERT(aShift > 0, - "Rotation by value length is undefined behavior, but compilers " - "do not currently fold a test into the rotate instruction. " - "Please remove this restriction when compilers optimize the " - "zero case (http://blog.regehr.org/archives/1063)."); - static_assert(IsUnsigned::value, "Rotates require unsigned values"); - return (aValue >> aShift) | (aValue << (sizeof(T) * CHAR_BIT - aShift)); -} - -/** - * Returns true if |x| is a power of two. - * Zero is not an integer power of two. (-Inf is not an integer) - */ -template -constexpr bool -IsPowerOfTwo(T x) -{ - static_assert(IsUnsigned::value, - "IsPowerOfTwo requires unsigned values"); - return x && (x & (x - 1)) == 0; -} - -template -inline T -Clamp(const T aValue, const T aMin, const T aMax) -{ - static_assert(IsIntegral::value, - "Clamp accepts only integral types, so that it doesn't have" - " to distinguish differently-signed zeroes (which users may" - " or may not care to distinguish, likely at a perf cost) or" - " to decide how to clamp NaN or a range with a NaN" - " endpoint."); - MOZ_ASSERT(aMin <= aMax); - - if (aValue <= aMin) - return aMin; - if (aValue >= aMax) - return aMax; - return aValue; -} - -} /* namespace mozilla */ - -#endif /* mozilla_MathAlgorithms_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Maybe.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Maybe.h deleted file mode 100644 index 2a601ac4..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Maybe.h +++ /dev/null @@ -1,551 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A class for optional values and in-place lazy construction. */ - -#ifndef mozilla_Maybe_h -#define mozilla_Maybe_h - -#include "mozilla/Alignment.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -#include // for placement new -#include - -namespace mozilla { - -struct Nothing { }; - -/* - * Maybe is a container class which contains either zero or one elements. It - * serves two roles. It can represent values which are *semantically* optional, - * augmenting a type with an explicit 'Nothing' value. In this role, it provides - * methods that make it easy to work with values that may be missing, along with - * equality and comparison operators so that Maybe values can be stored in - * containers. Maybe values can be constructed conveniently in expressions using - * type inference, as follows: - * - * void doSomething(Maybe aFoo) { - * if (aFoo) // Make sure that aFoo contains a value... - * aFoo->takeAction(); // and then use |aFoo->| to access it. - * } // |*aFoo| also works! - * - * doSomething(Nothing()); // Passes a Maybe containing no value. - * doSomething(Some(Foo(100))); // Passes a Maybe containing |Foo(100)|. - * - * You'll note that it's important to check whether a Maybe contains a value - * before using it, using conversion to bool, |isSome()|, or |isNothing()|. You - * can avoid these checks, and sometimes write more readable code, using - * |valueOr()|, |ptrOr()|, and |refOr()|, which allow you to retrieve the value - * in the Maybe and provide a default for the 'Nothing' case. You can also use - * |apply()| to call a function only if the Maybe holds a value, and |map()| to - * transform the value in the Maybe, returning another Maybe with a possibly - * different type. - * - * Maybe's other role is to support lazily constructing objects without using - * dynamic storage. A Maybe directly contains storage for a value, but it's - * empty by default. |emplace()|, as mentioned above, can be used to construct a - * value in Maybe's storage. The value a Maybe contains can be destroyed by - * calling |reset()|; this will happen automatically if a Maybe is destroyed - * while holding a value. - * - * It's a common idiom in C++ to use a pointer as a 'Maybe' type, with a null - * value meaning 'Nothing' and any other value meaning 'Some'. You can convert - * from such a pointer to a Maybe value using 'ToMaybe()'. - * - * Maybe is inspired by similar types in the standard library of many other - * languages (e.g. Haskell's Maybe and Rust's Option). In the C++ world it's - * very similar to std::optional, which was proposed for C++14 and originated in - * Boost. The most important differences between Maybe and std::optional are: - * - * - std::optional may be compared with T. We deliberately forbid that. - * - std::optional allows in-place construction without a separate call to - * |emplace()| by using a dummy |in_place_t| value to tag the appropriate - * constructor. - * - std::optional has |valueOr()|, equivalent to Maybe's |valueOr()|, but - * lacks corresponding methods for |refOr()| and |ptrOr()|. - * - std::optional lacks |map()| and |apply()|, making it less suitable for - * functional-style code. - * - std::optional lacks many convenience functions that Maybe has. Most - * unfortunately, it lacks equivalents of the type-inferred constructor - * functions |Some()| and |Nothing()|. - * - * N.B. GCC has missed optimizations with Maybe in the past and may generate - * extra branches/loads/stores. Use with caution on hot paths; it's not known - * whether or not this is still a problem. - */ -template -class Maybe -{ - bool mIsSome; - AlignedStorage2 mStorage; - -public: - typedef T ValueType; - - Maybe() : mIsSome(false) { } - ~Maybe() { reset(); } - - MOZ_IMPLICIT Maybe(Nothing) : mIsSome(false) { } - - Maybe(const Maybe& aOther) - : mIsSome(false) - { - if (aOther.mIsSome) { - emplace(*aOther); - } - } - - /** - * Maybe can be copy-constructed from a Maybe if U* and T* are - * compatible, or from Maybe. - */ - template::value && - (std::is_same::value || - (std::is_pointer::value && - std::is_base_of::type, - typename std::remove_pointer::type>::value))>::type> - MOZ_IMPLICIT - Maybe(const Maybe& aOther) - : mIsSome(false) - { - if (aOther.isSome()) { - emplace(*aOther); - } - } - - Maybe(Maybe&& aOther) - : mIsSome(false) - { - if (aOther.mIsSome) { - emplace(Move(*aOther)); - aOther.reset(); - } - } - - /** - * Maybe can be move-constructed from a Maybe if U* and T* are - * compatible, or from Maybe. - */ - template::value && - (std::is_same::value || - (std::is_pointer::value && - std::is_base_of::type, - typename std::remove_pointer::type>::value))>::type> - MOZ_IMPLICIT - Maybe(Maybe&& aOther) - : mIsSome(false) - { - if (aOther.isSome()) { - emplace(Move(*aOther)); - aOther.reset(); - } - } - - Maybe& operator=(const Maybe& aOther) - { - if (&aOther != this) { - if (aOther.mIsSome) { - if (mIsSome) { - // XXX(seth): The correct code for this branch, below, can't be used - // due to a bug in Visual Studio 2010. See bug 1052940. - /* - ref() = aOther.ref(); - */ - reset(); - emplace(*aOther); - } else { - emplace(*aOther); - } - } else { - reset(); - } - } - return *this; - } - - Maybe& operator=(Maybe&& aOther) - { - MOZ_ASSERT(this != &aOther, "Self-moves are prohibited"); - - if (aOther.mIsSome) { - if (mIsSome) { - ref() = Move(aOther.ref()); - } else { - emplace(Move(*aOther)); - } - aOther.reset(); - } else { - reset(); - } - - return *this; - } - - /* Methods that check whether this Maybe contains a value */ - explicit operator bool() const { return isSome(); } - bool isSome() const { return mIsSome; } - bool isNothing() const { return !mIsSome; } - - /* Returns the contents of this Maybe by value. Unsafe unless |isSome()|. */ - T value() const - { - MOZ_ASSERT(mIsSome); - return ref(); - } - - /* - * Returns the contents of this Maybe by value. If |isNothing()|, returns - * the default value provided. - */ - template - T valueOr(V&& aDefault) const - { - if (isSome()) { - return ref(); - } - return Forward(aDefault); - } - - /* - * Returns the contents of this Maybe by value. If |isNothing()|, returns - * the value returned from the function or functor provided. - */ - template - T valueOrFrom(F&& aFunc) const - { - if (isSome()) { - return ref(); - } - return aFunc(); - } - - /* Returns the contents of this Maybe by pointer. Unsafe unless |isSome()|. */ - T* ptr() - { - MOZ_ASSERT(mIsSome); - return &ref(); - } - - const T* ptr() const - { - MOZ_ASSERT(mIsSome); - return &ref(); - } - - /* - * Returns the contents of this Maybe by pointer. If |isNothing()|, - * returns the default value provided. - */ - T* ptrOr(T* aDefault) - { - if (isSome()) { - return ptr(); - } - return aDefault; - } - - const T* ptrOr(const T* aDefault) const - { - if (isSome()) { - return ptr(); - } - return aDefault; - } - - /* - * Returns the contents of this Maybe by pointer. If |isNothing()|, - * returns the value returned from the function or functor provided. - */ - template - T* ptrOrFrom(F&& aFunc) - { - if (isSome()) { - return ptr(); - } - return aFunc(); - } - - template - const T* ptrOrFrom(F&& aFunc) const - { - if (isSome()) { - return ptr(); - } - return aFunc(); - } - - T* operator->() - { - MOZ_ASSERT(mIsSome); - return ptr(); - } - - const T* operator->() const - { - MOZ_ASSERT(mIsSome); - return ptr(); - } - - /* Returns the contents of this Maybe by ref. Unsafe unless |isSome()|. */ - T& ref() - { - MOZ_ASSERT(mIsSome); - return *mStorage.addr(); - } - - const T& ref() const - { - MOZ_ASSERT(mIsSome); - return *mStorage.addr(); - } - - /* - * Returns the contents of this Maybe by ref. If |isNothing()|, returns - * the default value provided. - */ - T& refOr(T& aDefault) - { - if (isSome()) { - return ref(); - } - return aDefault; - } - - const T& refOr(const T& aDefault) const - { - if (isSome()) { - return ref(); - } - return aDefault; - } - - /* - * Returns the contents of this Maybe by ref. If |isNothing()|, returns the - * value returned from the function or functor provided. - */ - template - T& refOrFrom(F&& aFunc) - { - if (isSome()) { - return ref(); - } - return aFunc(); - } - - template - const T& refOrFrom(F&& aFunc) const - { - if (isSome()) { - return ref(); - } - return aFunc(); - } - - T& operator*() - { - MOZ_ASSERT(mIsSome); - return ref(); - } - - const T& operator*() const - { - MOZ_ASSERT(mIsSome); - return ref(); - } - - /* If |isSome()|, runs the provided function or functor on the contents of - * this Maybe. */ - template - Maybe& apply(Func aFunc) - { - if (isSome()) { - aFunc(ref()); - } - return *this; - } - - template - const Maybe& apply(Func aFunc) const - { - if (isSome()) { - aFunc(ref()); - } - return *this; - } - - /* - * If |isSome()|, runs the provided function and returns the result wrapped - * in a Maybe. If |isNothing()|, returns an empty Maybe value. - */ - template - auto map(Func aFunc) -> Maybe>().ref()))> - { - using ReturnType = decltype(aFunc(ref())); - if (isSome()) { - Maybe val; - val.emplace(aFunc(ref())); - return val; - } - return Maybe(); - } - - template - auto map(Func aFunc) const -> Maybe>().ref()))> - { - using ReturnType = decltype(aFunc(ref())); - if (isSome()) { - Maybe val; - val.emplace(aFunc(ref())); - return val; - } - return Maybe(); - } - - /* If |isSome()|, empties this Maybe and destroys its contents. */ - void reset() - { - if (isSome()) { - ref().T::~T(); - mIsSome = false; - } - } - - /* - * Constructs a T value in-place in this empty Maybe's storage. The - * arguments to |emplace()| are the parameters to T's constructor. - */ - template - void emplace(Args&&... aArgs) - { - MOZ_ASSERT(!mIsSome); - ::new (mStorage.addr()) T(Forward(aArgs)...); - mIsSome = true; - } -}; - -/* - * Some() creates a Maybe value containing the provided T value. If T has a - * move constructor, it's used to make this as efficient as possible. - * - * Some() selects the type of Maybe it returns by removing any const, volatile, - * or reference qualifiers from the type of the value you pass to it. This gives - * it more intuitive behavior when used in expressions, but it also means that - * if you need to construct a Maybe value that holds a const, volatile, or - * reference value, you need to use emplace() instead. - */ -template -Maybe::Type>::Type> -Some(T&& aValue) -{ - typedef typename RemoveCV::Type>::Type U; - Maybe value; - value.emplace(Forward(aValue)); - return value; -} - -template -Maybe::Type>::Type> -ToMaybe(T* aPtr) -{ - if (aPtr) { - return Some(*aPtr); - } - return Nothing(); -} - -/* - * Two Maybe values are equal if - * - both are Nothing, or - * - both are Some, and the values they contain are equal. - */ -template bool -operator==(const Maybe& aLHS, const Maybe& aRHS) -{ - if (aLHS.isNothing() != aRHS.isNothing()) { - return false; - } - return aLHS.isNothing() || *aLHS == *aRHS; -} - -template bool -operator!=(const Maybe& aLHS, const Maybe& aRHS) -{ - return !(aLHS == aRHS); -} - -/* - * We support comparison to Nothing to allow reasonable expressions like: - * if (maybeValue == Nothing()) { ... } - */ -template bool -operator==(const Maybe& aLHS, const Nothing& aRHS) -{ - return aLHS.isNothing(); -} - -template bool -operator!=(const Maybe& aLHS, const Nothing& aRHS) -{ - return !(aLHS == aRHS); -} - -template bool -operator==(const Nothing& aLHS, const Maybe& aRHS) -{ - return aRHS.isNothing(); -} - -template bool -operator!=(const Nothing& aLHS, const Maybe& aRHS) -{ - return !(aLHS == aRHS); -} - -/* - * Maybe values are ordered in the same way T values are ordered, except that - * Nothing comes before anything else. - */ -template bool -operator<(const Maybe& aLHS, const Maybe& aRHS) -{ - if (aLHS.isNothing()) { - return aRHS.isSome(); - } - if (aRHS.isNothing()) { - return false; - } - return *aLHS < *aRHS; -} - -template bool -operator>(const Maybe& aLHS, const Maybe& aRHS) -{ - return !(aLHS < aRHS || aLHS == aRHS); -} - -template bool -operator<=(const Maybe& aLHS, const Maybe& aRHS) -{ - return aLHS < aRHS || aLHS == aRHS; -} - -template bool -operator>=(const Maybe& aLHS, const Maybe& aRHS) -{ - return !(aLHS < aRHS); -} - -} // namespace mozilla - -#endif /* mozilla_Maybe_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/MaybeOneOf.h b/android/armeabi-v7a/include/spidermonkey/mozilla/MaybeOneOf.h deleted file mode 100644 index 9c38ff8b..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/MaybeOneOf.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_MaybeOneOf_h -#define mozilla_MaybeOneOf_h - -#include "mozilla/Alignment.h" -#include "mozilla/Assertions.h" -#include "mozilla/Move.h" -#include "mozilla/TemplateLib.h" - -#include // For placement new - -namespace mozilla { - -/* - * MaybeOneOf is like Maybe, but it supports constructing either T1 - * or T2. When a MaybeOneOf is constructed, it is |empty()|, i.e., - * no value has been constructed and no destructor will be called when the - * MaybeOneOf is destroyed. Upon calling |construct()| or - * |construct()|, a T1 or T2 object will be constructed with the given - * arguments and that object will be destroyed when the owning MaybeOneOf is - * destroyed. - */ -template -class MaybeOneOf -{ - AlignedStorage::value> storage; - - enum State { None, SomeT1, SomeT2 } state; - template struct Type2State {}; - - template - T& as() - { - MOZ_ASSERT(state == Type2State::result); - return *(T*)storage.addr(); - } - - template - const T& as() const - { - MOZ_ASSERT(state == Type2State::result); - return *(T*)storage.addr(); - } - -public: - MaybeOneOf() : state(None) {} - ~MaybeOneOf() { destroyIfConstructed(); } - - MaybeOneOf(MaybeOneOf&& rhs) - : state(None) - { - if (!rhs.empty()) { - if (rhs.constructed()) { - construct(Move(rhs.as())); - rhs.as().~T1(); - } else { - construct(Move(rhs.as())); - rhs.as().~T2(); - } - rhs.state = None; - } - } - - MaybeOneOf &operator=(MaybeOneOf&& rhs) - { - MOZ_ASSERT(this != &rhs, "Self-move is prohibited"); - this->~MaybeOneOf(); - new(this) MaybeOneOf(Move(rhs)); - return *this; - } - - bool empty() const { return state == None; } - - template - bool constructed() const { return state == Type2State::result; } - - template - void construct(Args&&... aArgs) - { - MOZ_ASSERT(state == None); - state = Type2State::result; - ::new (storage.addr()) T(Forward(aArgs)...); - } - - template - T& ref() - { - return as(); - } - - template - const T& ref() const - { - return as(); - } - - void destroy() - { - MOZ_ASSERT(state == SomeT1 || state == SomeT2); - if (state == SomeT1) { - as().~T1(); - } else if (state == SomeT2) { - as().~T2(); - } - state = None; - } - - void destroyIfConstructed() - { - if (!empty()) { - destroy(); - } - } - -private: - MaybeOneOf(const MaybeOneOf& aOther) = delete; - const MaybeOneOf& operator=(const MaybeOneOf& aOther) = delete; -}; - -template -template -struct MaybeOneOf::Type2State -{ - typedef MaybeOneOf Enclosing; - static const typename Enclosing::State result = Enclosing::SomeT1; -}; - -template -template -struct MaybeOneOf::Type2State -{ - typedef MaybeOneOf Enclosing; - static const typename Enclosing::State result = Enclosing::SomeT2; -}; - -} // namespace mozilla - -#endif /* mozilla_MaybeOneOf_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/MemoryChecking.h b/android/armeabi-v7a/include/spidermonkey/mozilla/MemoryChecking.h deleted file mode 100644 index ff42d7f1..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/MemoryChecking.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Provides a common interface to the ASan (AddressSanitizer) and Valgrind - * functions used to mark memory in certain ways. In detail, the following - * three macros are provided: - * - * MOZ_MAKE_MEM_NOACCESS - Mark memory as unsafe to access (e.g. freed) - * MOZ_MAKE_MEM_UNDEFINED - Mark memory as accessible, with content undefined - * MOZ_MAKE_MEM_DEFINED - Mark memory as accessible, with content defined - * - * With Valgrind in use, these directly map to the three respective Valgrind - * macros. With ASan in use, the NOACCESS macro maps to poisoning the memory, - * while the UNDEFINED/DEFINED macros unpoison memory. - * - * With no memory checker available, all macros expand to the empty statement. - */ - -#ifndef mozilla_MemoryChecking_h -#define mozilla_MemoryChecking_h - -#if defined(MOZ_VALGRIND) -#include "valgrind/memcheck.h" -#endif - -#if defined(MOZ_ASAN) || defined(MOZ_VALGRIND) -#define MOZ_HAVE_MEM_CHECKS 1 -#endif - -#if defined(MOZ_ASAN) -#include - -#include "mozilla/Attributes.h" -#include "mozilla/Types.h" - -#ifdef _MSC_VER -// In clang-cl based ASAN, we link against the memory poisoning functions -// statically. -#define MOZ_ASAN_VISIBILITY -#else -#define MOZ_ASAN_VISIBILITY MOZ_EXPORT -#endif - -extern "C" { -/* These definitions are usually provided through the - * sanitizer/asan_interface.h header installed by ASan. - */ -void MOZ_ASAN_VISIBILITY -__asan_poison_memory_region(void const volatile *addr, size_t size); -void MOZ_ASAN_VISIBILITY -__asan_unpoison_memory_region(void const volatile *addr, size_t size); - -#define MOZ_MAKE_MEM_NOACCESS(addr, size) \ - __asan_poison_memory_region((addr), (size)) - -#define MOZ_MAKE_MEM_UNDEFINED(addr, size) \ - __asan_unpoison_memory_region((addr), (size)) - -#define MOZ_MAKE_MEM_DEFINED(addr, size) \ - __asan_unpoison_memory_region((addr), (size)) - -/* - * These definitions are usually provided through the - * sanitizer/lsan_interface.h header installed by LSan. - */ -void MOZ_EXPORT -__lsan_ignore_object(const void *p); - -} -#elif defined(MOZ_MSAN) -#include - -#include "mozilla/Types.h" - -extern "C" { -/* These definitions are usually provided through the - * sanitizer/msan_interface.h header installed by MSan. - */ -void MOZ_EXPORT -__msan_poison(void const volatile *addr, size_t size); -void MOZ_EXPORT -__msan_unpoison(void const volatile *addr, size_t size); - -#define MOZ_MAKE_MEM_NOACCESS(addr, size) \ - __msan_poison((addr), (size)) - -#define MOZ_MAKE_MEM_UNDEFINED(addr, size) \ - __msan_poison((addr), (size)) - -#define MOZ_MAKE_MEM_DEFINED(addr, size) \ - __msan_unpoison((addr), (size)) -} -#elif defined(MOZ_VALGRIND) -#define MOZ_MAKE_MEM_NOACCESS(addr, size) \ - VALGRIND_MAKE_MEM_NOACCESS((addr), (size)) - -#define MOZ_MAKE_MEM_UNDEFINED(addr, size) \ - VALGRIND_MAKE_MEM_UNDEFINED((addr), (size)) - -#define MOZ_MAKE_MEM_DEFINED(addr, size) \ - VALGRIND_MAKE_MEM_DEFINED((addr), (size)) -#else - -#define MOZ_MAKE_MEM_NOACCESS(addr, size) do {} while (0) -#define MOZ_MAKE_MEM_UNDEFINED(addr, size) do {} while (0) -#define MOZ_MAKE_MEM_DEFINED(addr, size) do {} while (0) - -#endif - -/* - * MOZ_LSAN_INTENTIONAL_LEAK(X) is a macro to tell LeakSanitizer that X - * points to a value that will intentionally never be deallocated during - * the execution of the process. - * - * Additional uses of this macro should be reviewed by people - * conversant in leak-checking and/or MFBT peers. - */ -#if defined(MOZ_ASAN) -# define MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(X) __lsan_ignore_object(X) -#else -# define MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(X) /* nothing */ -#endif // defined(MOZ_ASAN) - - -#endif /* mozilla_MemoryChecking_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/MemoryReporting.h b/android/armeabi-v7a/include/spidermonkey/mozilla/MemoryReporting.h deleted file mode 100644 index d2340ecf..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/MemoryReporting.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Memory reporting infrastructure. */ - -#ifndef mozilla_MemoryReporting_h -#define mozilla_MemoryReporting_h - -#include - -#ifdef __cplusplus - -namespace mozilla { - -/* - * This is for functions that are like malloc_usable_size. Such functions are - * used for measuring the size of data structures. - */ -typedef size_t (*MallocSizeOf)(const void* p); - -} /* namespace mozilla */ - -#endif /* __cplusplus */ - -typedef size_t (*MozMallocSizeOf)(const void* p); - -#endif /* mozilla_MemoryReporting_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Move.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Move.h deleted file mode 100644 index f6d0bfc1..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Move.h +++ /dev/null @@ -1,238 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* C++11-style, but C++98-usable, "move references" implementation. */ - -#ifndef mozilla_Move_h -#define mozilla_Move_h - -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -/* - * "Move" References - * - * Some types can be copied much more efficiently if we know the original's - * value need not be preserved --- that is, if we are doing a "move", not a - * "copy". For example, if we have: - * - * Vector u; - * Vector v(u); - * - * the constructor for v must apply a copy constructor to each element of u --- - * taking time linear in the length of u. However, if we know we will not need u - * any more once v has been initialized, then we could initialize v very - * efficiently simply by stealing u's dynamically allocated buffer and giving it - * to v --- a constant-time operation, regardless of the size of u. - * - * Moves often appear in container implementations. For example, when we append - * to a vector, we may need to resize its buffer. This entails moving each of - * its extant elements from the old, smaller buffer to the new, larger buffer. - * But once the elements have been migrated, we're just going to throw away the - * old buffer; we don't care if they still have their values. So if the vector's - * element type can implement "move" more efficiently than "copy", the vector - * resizing should by all means use a "move" operation. Hash tables should also - * use moves when resizing their internal array as entries are added and - * removed. - * - * The details of the optimization, and whether it's worth applying, vary - * from one type to the next: copying an 'int' is as cheap as moving it, so - * there's no benefit in distinguishing 'int' moves from copies. And while - * some constructor calls for complex types are moves, many really have to - * be copies, and can't be optimized this way. So we need: - * - * 1) a way for a type (like Vector) to announce that it can be moved more - * efficiently than it can be copied, and provide an implementation of that - * move operation; and - * - * 2) a way for a particular invocation of a copy constructor to say that it's - * really a move, not a copy, and that the value of the original isn't - * important afterwards (although it must still be safe to destroy). - * - * If a constructor has a single argument of type 'T&&' (an 'rvalue reference - * to T'), that indicates that it is a 'move constructor'. That's 1). It should - * move, not copy, its argument into the object being constructed. It may leave - * the original in any safely-destructible state. - * - * If a constructor's argument is an rvalue, as in 'C(f(x))' or 'C(x + y)', as - * opposed to an lvalue, as in 'C(x)', then overload resolution will prefer the - * move constructor, if there is one. The 'mozilla::Move' function, defined in - * this file, is an identity function you can use in a constructor invocation to - * make any argument into an rvalue, like this: C(Move(x)). That's 2). (You - * could use any function that works, but 'Move' indicates your intention - * clearly.) - * - * Where we might define a copy constructor for a class C like this: - * - * C(const C& rhs) { ... copy rhs to this ... } - * - * we would declare a move constructor like this: - * - * C(C&& rhs) { .. move rhs to this ... } - * - * And where we might perform a copy like this: - * - * C c2(c1); - * - * we would perform a move like this: - * - * C c2(Move(c1)); - * - * Note that 'T&&' implicitly converts to 'T&'. So you can pass a 'T&&' to an - * ordinary copy constructor for a type that doesn't support a special move - * constructor, and you'll just get a copy. This means that templates can use - * Move whenever they know they won't use the original value any more, even if - * they're not sure whether the type at hand has a specialized move constructor. - * If it doesn't, the 'T&&' will just convert to a 'T&', and the ordinary copy - * constructor will apply. - * - * A class with a move constructor can also provide a move assignment operator. - * A generic definition would run this's destructor, and then apply the move - * constructor to *this's memory. A typical definition: - * - * C& operator=(C&& rhs) { - * MOZ_ASSERT(&rhs != this, "self-moves are prohibited"); - * this->~C(); - * new(this) C(Move(rhs)); - * return *this; - * } - * - * With that in place, one can write move assignments like this: - * - * c2 = Move(c1); - * - * This destroys c2, moves c1's value to c2, and leaves c1 in an undefined but - * destructible state. - * - * As we say, a move must leave the original in a "destructible" state. The - * original's destructor will still be called, so if a move doesn't - * actually steal all its resources, that's fine. We require only that the - * move destination must take on the original's value; and that destructing - * the original must not break the move destination. - * - * (Opinions differ on whether move assignment operators should deal with move - * assignment of an object onto itself. It seems wise to either handle that - * case, or assert that it does not occur.) - * - * Forwarding: - * - * Sometimes we want copy construction or assignment if we're passed an ordinary - * value, but move construction if passed an rvalue reference. For example, if - * our constructor takes two arguments and either could usefully be a move, it - * seems silly to write out all four combinations: - * - * C::C(X& x, Y& y) : x(x), y(y) { } - * C::C(X& x, Y&& y) : x(x), y(Move(y)) { } - * C::C(X&& x, Y& y) : x(Move(x)), y(y) { } - * C::C(X&& x, Y&& y) : x(Move(x)), y(Move(y)) { } - * - * To avoid this, C++11 has tweaks to make it possible to write what you mean. - * The four constructor overloads above can be written as one constructor - * template like so[0]: - * - * template - * C::C(XArg&& x, YArg&& y) : x(Forward(x)), y(Forward(y)) { } - * - * ("'Don't Repeat Yourself'? What's that?") - * - * This takes advantage of two new rules in C++11: - * - * - First, when a function template takes an argument that is an rvalue - * reference to a template argument (like 'XArg&& x' and 'YArg&& y' above), - * then when the argument is applied to an lvalue, the template argument - * resolves to 'T&'; and when it is applied to an rvalue, the template - * argument resolves to 'T'. Thus, in a call to C::C like: - * - * X foo(int); - * Y yy; - * - * C(foo(5), yy) - * - * XArg would resolve to 'X', and YArg would resolve to 'Y&'. - * - * - Second, Whereas C++ used to forbid references to references, C++11 defines - * 'collapsing rules': 'T& &', 'T&& &', and 'T& &&' (that is, any combination - * involving an lvalue reference) now collapse to simply 'T&'; and 'T&& &&' - * collapses to 'T&&'. - * - * Thus, in the call above, 'XArg&&' is 'X&&'; and 'YArg&&' is 'Y& &&', which - * collapses to 'Y&'. Because the arguments are declared as rvalue references - * to template arguments, the lvalue-ness "shines through" where present. - * - * Then, the 'Forward' function --- you must invoke 'Forward' with its type - * argument --- returns an lvalue reference or an rvalue reference to its - * argument, depending on what T is. In our unified constructor definition, that - * means that we'll invoke either the copy or move constructors for x and y, - * depending on what we gave C's constructor. In our call, we'll move 'foo()' - * into 'x', but copy 'yy' into 'y'. - * - * This header file defines Move and Forward in the mozilla namespace. It's up - * to individual containers to annotate moves as such, by calling Move; and it's - * up to individual types to define move constructors and assignment operators - * when valuable. - * - * (C++11 says that the header file should define 'std::move' and - * 'std::forward', which are just like our 'Move' and 'Forward'; but those - * definitions aren't available in that header on all our platforms, so we - * define them ourselves here.) - * - * 0. This pattern is known as "perfect forwarding". Interestingly, it is not - * actually perfect, and it can't forward all possible argument expressions! - * There is a C++11 issue: you can't form a reference to a bit-field. As a - * workaround, assign the bit-field to a local variable and use that: - * - * // C is as above - * struct S { int x : 1; } s; - * C(s.x, 0); // BAD: s.x is a reference to a bit-field, can't form those - * int tmp = s.x; - * C(tmp, 0); // OK: tmp not a bit-field - */ - -/** - * Identical to std::Move(); this is necessary until our stlport supports - * std::move(). - */ -template -inline typename RemoveReference::Type&& -Move(T&& aX) -{ - return static_cast::Type&&>(aX); -} - -/** - * These two overloads are identical to std::forward(); they are necessary until - * our stlport supports std::forward(). - */ -template -inline T&& -Forward(typename RemoveReference::Type& aX) -{ - return static_cast(aX); -} - -template -inline T&& -Forward(typename RemoveReference::Type&& aX) -{ - static_assert(!IsLvalueReference::value, - "misuse of Forward detected! try the other overload"); - return static_cast(aX); -} - -/** Swap |aX| and |aY| using move-construction if possible. */ -template -inline void -Swap(T& aX, T& aY) -{ - T tmp(Move(aX)); - aX = Move(aY); - aY = Move(tmp); -} - -} // namespace mozilla - -#endif /* mozilla_Move_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/NotNull.h b/android/armeabi-v7a/include/spidermonkey/mozilla/NotNull.h deleted file mode 100644 index 0c3c333e..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/NotNull.h +++ /dev/null @@ -1,209 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_NotNull_h -#define mozilla_NotNull_h - -// It's often unclear if a particular pointer, be it raw (T*) or smart -// (RefPtr, nsCOMPtr, etc.) can be null. This leads to missing null -// checks (which can cause crashes) and unnecessary null checks (which clutter -// the code). -// -// C++ has a built-in alternative that avoids these problems: references. This -// module defines another alternative, NotNull, which can be used in cases -// where references are not suitable. -// -// In the comments below we use the word "handle" to cover all varieties of -// pointers and references. -// -// References -// ---------- -// References are always non-null. (You can do |T& r = *p;| where |p| is null, -// but that's undefined behaviour. C++ doesn't provide any built-in, ironclad -// guarantee of non-nullness.) -// -// A reference works well when you need a temporary handle to an existing -// single object, e.g. for passing a handle to a function, or as a local handle -// within another object. (In Rust parlance, this is a "borrow".) -// -// A reference is less appropriate in the following cases. -// -// - As a primary handle to an object. E.g. code such as this is possible but -// strange: |T& t = *new T(); ...; delete &t;| -// -// - As a handle to an array. It's common for |T*| to refer to either a single -// |T| or an array of |T|, but |T&| cannot refer to an array of |T| because -// you can't index off a reference (at least, not without first converting it -// to a pointer). -// -// - When the handle identity is meaningful, e.g. if you have a hashtable of -// handles, because you have to use |&| on the reference to convert it to a -// pointer. -// -// - Some people don't like using non-const references as function parameters, -// because it is not clear at the call site that the argument might be -// modified. -// -// - When you need "smart" behaviour. E.g. we lack reference equivalents to -// RefPtr and nsCOMPtr. -// -// - When interfacing with code that uses pointers a lot, sometimes using a -// reference just feels like an odd fit. -// -// Furthermore, a reference is impossible in the following cases. -// -// - When the handle is rebound to another object. References don't allow this. -// -// - When the handle has type |void|. |void&| is not allowed. -// -// NotNull is an alternative that can be used in any of the above cases except -// for the last one, where the handle type is |void|. See below. - -#include "mozilla/Assertions.h" - -namespace mozilla { - -// NotNull can be used to wrap a "base" pointer (raw or smart) to indicate it -// is not null. Some examples: -// -// - NotNull -// - NotNull> -// - NotNull> -// -// NotNull has the following notable properties. -// -// - It has zero space overhead. -// -// - It must be initialized explicitly. There is no default initialization. -// -// - It auto-converts to the base pointer type. -// -// - It does not auto-convert from a base pointer. Implicit conversion from a -// less-constrained type (e.g. T*) to a more-constrained type (e.g. -// NotNull) is dangerous. Creation and assignment from a base pointer can -// only be done with WrapNotNull(), which makes them impossible to overlook, -// both when writing and reading code. -// -// - When initialized (or assigned) it is checked, and if it is null we abort. -// This guarantees that it cannot be null. -// -// - |operator bool()| is deleted. This means you cannot check a NotNull in a -// boolean context, which eliminates the possibility of unnecessary null -// checks. -// -// NotNull currently doesn't work with UniquePtr. See -// https://github.com/Microsoft/GSL/issues/89 for some discussion. -// -template -class NotNull -{ - template friend NotNull WrapNotNull(U aBasePtr); - - T mBasePtr; - - // This constructor is only used by WrapNotNull(). - template - explicit NotNull(U aBasePtr) : mBasePtr(aBasePtr) {} - -public: - // Disallow default construction. - NotNull() = delete; - - // Construct/assign from another NotNull with a compatible base pointer type. - template - MOZ_IMPLICIT NotNull(const NotNull& aOther) : mBasePtr(aOther.get()) {} - - // Default copy/move construction and assignment. - NotNull(const NotNull&) = default; - NotNull& operator=(const NotNull&) = default; - NotNull(NotNull&&) = default; - NotNull& operator=(NotNull&&) = default; - - // Disallow null checks, which are unnecessary for this type. - explicit operator bool() const = delete; - - // Explicit conversion to a base pointer. Use only to resolve ambiguity or to - // get a castable pointer. - const T& get() const { return mBasePtr; } - - // Implicit conversion to a base pointer. Preferable to get(). - operator const T&() const { return get(); } - - // Dereference operators. - const T& operator->() const { return get(); } - decltype(*mBasePtr) operator*() const { return *mBasePtr; } -}; - -template -NotNull -WrapNotNull(const T aBasePtr) -{ - NotNull notNull(aBasePtr); - MOZ_RELEASE_ASSERT(aBasePtr); - return notNull; -} - -// Compare two NotNulls. -template -inline bool -operator==(const NotNull& aLhs, const NotNull& aRhs) -{ - return aLhs.get() == aRhs.get(); -} -template -inline bool -operator!=(const NotNull& aLhs, const NotNull& aRhs) -{ - return aLhs.get() != aRhs.get(); -} - -// Compare a NotNull to a base pointer. -template -inline bool -operator==(const NotNull& aLhs, const U& aRhs) -{ - return aLhs.get() == aRhs; -} -template -inline bool -operator!=(const NotNull& aLhs, const U& aRhs) -{ - return aLhs.get() != aRhs; -} - -// Compare a base pointer to a NotNull. -template -inline bool -operator==(const T& aLhs, const NotNull& aRhs) -{ - return aLhs == aRhs.get(); -} -template -inline bool -operator!=(const T& aLhs, const NotNull& aRhs) -{ - return aLhs != aRhs.get(); -} - -// Disallow comparing a NotNull to a nullptr. -template -bool -operator==(const NotNull&, decltype(nullptr)) = delete; -template -bool -operator!=(const NotNull&, decltype(nullptr)) = delete; - -// Disallow comparing a nullptr to a NotNull. -template -bool -operator==(decltype(nullptr), const NotNull&) = delete; -template -bool -operator!=(decltype(nullptr), const NotNull&) = delete; - -} // namespace mozilla - -#endif /* mozilla_NotNull_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/NullPtr.h b/android/armeabi-v7a/include/spidermonkey/mozilla/NullPtr.h deleted file mode 100644 index d2248f4b..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/NullPtr.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implements a mozilla::IsNullPointer type trait. */ - -#ifndef mozilla_NullPtr_h -#define mozilla_NullPtr_h - -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -/** - * IsNullPointer::value is true iff T is decltype(nullptr). - * - * Ideally this would be in TypeTraits.h, but C++11 omitted std::is_null_pointer - * (fixed in C++14), so in the interests of easing a switch to , - * this trait lives elsewhere. - */ -template -struct IsNullPointer : FalseType {}; - -template<> -struct IsNullPointer : TrueType {}; - -} // namespace mozilla - -#endif /* mozilla_NullPtr_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Opaque.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Opaque.h deleted file mode 100644 index d7239ee7..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Opaque.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* An opaque integral type supporting only comparison operators. */ - -#ifndef mozilla_Opaque_h -#define mozilla_Opaque_h - -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -/** - * Opaque is a replacement for integral T in cases where only comparisons - * must be supported, and it's desirable to prevent accidental dependency on - * exact values. - */ -template -class Opaque final -{ - static_assert(mozilla::IsIntegral::value, - "mozilla::Opaque only supports integral types"); - - T mValue; - -public: - Opaque() {} - explicit Opaque(T aValue) : mValue(aValue) {} - - bool operator==(const Opaque& aOther) const { - return mValue == aOther.mValue; - } - - bool operator!=(const Opaque& aOther) const { - return !(*this == aOther); - } -}; - -} // namespace mozilla - -#endif /* mozilla_Opaque_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/OperatorNewExtensions.h b/android/armeabi-v7a/include/spidermonkey/mozilla/OperatorNewExtensions.h deleted file mode 100644 index 52fd88a6..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/OperatorNewExtensions.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A version of |operator new| that eschews mandatory null-checks. */ - -#ifndef mozilla_OperatorNewExtensions_h -#define mozilla_OperatorNewExtensions_h - -#include "mozilla/Assertions.h" - -// Credit goes to WebKit for this implementation, cf. -// https://bugs.webkit.org/show_bug.cgi?id=74676 -namespace mozilla { -enum NotNullTag { - KnownNotNull, -}; -} // namespace mozilla - -/* - * The logic here is a little subtle. [expr.new] states that if the allocation - * function being called returns null, then object initialization must not be - * done, and the entirety of the new expression must return null. Non-throwing - * (noexcept) functions are defined to return null to indicate failure. The - * standard placement operator new is defined in such a way, and so it requires - * a null check, even when that null check would be extraneous. Functions - * declared without such a specification are defined to throw std::bad_alloc if - * they fail, and return a non-null pointer otherwise. We compile without - * exceptions, so any placement new overload we define that doesn't declare - * itself as noexcept must therefore avoid generating a null check. Below is - * just such an overload. - * - * You might think that MOZ_NONNULL might perform the same function, but - * MOZ_NONNULL isn't supported on all of our compilers, and even when it is - * supported, doesn't work on all the versions we support. And even keeping - * those limitations in mind, we can't put MOZ_NONNULL on the global, - * standardized placement new function in any event. - * - * We deliberately don't add MOZ_NONNULL(3) to tag |p| as non-null, to benefit - * hypothetical static analyzers. Doing so makes |MOZ_ASSERT(p)|'s internal - * test vacuous, and some compilers warn about such vacuous tests. - */ -inline void* -operator new(size_t, mozilla::NotNullTag, void* p) -{ - MOZ_ASSERT(p); - return p; -} - -#endif // mozilla_OperatorNewExtensions_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Pair.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Pair.h deleted file mode 100644 index ad7b86a2..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Pair.h +++ /dev/null @@ -1,219 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A class holding a pair of objects that tries to conserve storage space. */ - -#ifndef mozilla_Pair_h -#define mozilla_Pair_h - -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -namespace detail { - -enum StorageType { AsBase, AsMember }; - -// Optimize storage using the Empty Base Optimization -- that empty base classes -// don't take up space -- to optimize size when one or the other class is -// stateless and can be used as a base class. -// -// The extra conditions on storage for B are necessary so that PairHelper won't -// ambiguously inherit from either A or B, such that one or the other base class -// would be inaccessible. -template::value ? detail::AsBase : detail::AsMember, - detail::StorageType = - IsEmpty::value && !IsBaseOf::value && !IsBaseOf::value - ? detail::AsBase - : detail::AsMember> -struct PairHelper; - -template -struct PairHelper -{ -protected: - template - PairHelper(AArg&& aA, BArg&& aB) - : mFirstA(Forward(aA)), - mSecondB(Forward(aB)) - {} - - A& first() { return mFirstA; } - const A& first() const { return mFirstA; } - B& second() { return mSecondB; } - const B& second() const { return mSecondB; } - - void swap(PairHelper& aOther) - { - Swap(mFirstA, aOther.mFirstA); - Swap(mSecondB, aOther.mSecondB); - } - -private: - A mFirstA; - B mSecondB; -}; - -template -struct PairHelper : private B -{ -protected: - template - PairHelper(AArg&& aA, BArg&& aB) - : B(Forward(aB)), - mFirstA(Forward(aA)) - {} - - A& first() { return mFirstA; } - const A& first() const { return mFirstA; } - B& second() { return *this; } - const B& second() const { return *this; } - - void swap(PairHelper& aOther) - { - Swap(mFirstA, aOther.mFirstA); - Swap(static_cast(*this), static_cast(aOther)); - } - -private: - A mFirstA; -}; - -template -struct PairHelper : private A -{ -protected: - template - PairHelper(AArg&& aA, BArg&& aB) - : A(Forward(aA)), - mSecondB(Forward(aB)) - {} - - A& first() { return *this; } - const A& first() const { return *this; } - B& second() { return mSecondB; } - const B& second() const { return mSecondB; } - - void swap(PairHelper& aOther) - { - Swap(static_cast(*this), static_cast(aOther)); - Swap(mSecondB, aOther.mSecondB); - } - -private: - B mSecondB; -}; - -template -struct PairHelper : private A, private B -{ -protected: - template - PairHelper(AArg&& aA, BArg&& aB) - : A(Forward(aA)), - B(Forward(aB)) - {} - - A& first() { return static_cast(*this); } - const A& first() const { return static_cast(*this); } - B& second() { return static_cast(*this); } - const B& second() const { return static_cast(*this); } - - void swap(PairHelper& aOther) - { - Swap(static_cast(*this), static_cast(aOther)); - Swap(static_cast(*this), static_cast(aOther)); - } -}; - -} // namespace detail - -/** - * Pair is the logical concatenation of an instance of A with an instance B. - * Space is conserved when possible. Neither A nor B may be a final class. - * - * It's typically clearer to have individual A and B member fields. Except if - * you want the space-conserving qualities of Pair, you're probably better off - * not using this! - * - * No guarantees are provided about the memory layout of A and B, the order of - * initialization or destruction of A and B, and so on. (This is approximately - * required to optimize space usage.) The first/second names are merely - * conceptual! - */ -template -struct Pair - : private detail::PairHelper -{ - typedef typename detail::PairHelper Base; - -public: - template - Pair(AArg&& aA, BArg&& aB) - : Base(Forward(aA), Forward(aB)) - {} - - Pair(Pair&& aOther) - : Base(Move(aOther.first()), Move(aOther.second())) - { } - - Pair(const Pair& aOther) = default; - - Pair& operator=(Pair&& aOther) - { - MOZ_ASSERT(this != &aOther, "Self-moves are prohibited"); - - first() = Move(aOther.first()); - second() = Move(aOther.second()); - - return *this; - } - - Pair& operator=(const Pair& aOther) = default; - - /** The A instance. */ - using Base::first; - /** The B instance. */ - using Base::second; - - /** Swap this pair with another pair. */ - void swap(Pair& aOther) { Base::swap(aOther); } -}; - -template -void -Swap(Pair& aX, Pair& aY) -{ - aX.swap(aY); -} - -/** - * MakePair allows you to construct a Pair instance using type inference. A call - * like this: - * - * MakePair(Foo(), Bar()) - * - * will return a Pair. - */ -template -Pair::Type>::Type, - typename RemoveCV::Type>::Type> -MakePair(A&& aA, B&& aB) -{ - return - Pair::Type>::Type, - typename RemoveCV::Type>::Type>( - Forward(aA), - Forward(aB)); -} - -} // namespace mozilla - -#endif /* mozilla_Pair_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/PodOperations.h b/android/armeabi-v7a/include/spidermonkey/mozilla/PodOperations.h deleted file mode 100644 index e6f4df21..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/PodOperations.h +++ /dev/null @@ -1,196 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Operations for zeroing POD types, arrays, and so on. - * - * These operations are preferable to memset, memcmp, and the like because they - * don't require remembering to multiply by sizeof(T), array lengths, and so on - * everywhere. - */ - -#ifndef mozilla_PodOperations_h -#define mozilla_PodOperations_h - -#include "mozilla/Array.h" -#include "mozilla/ArrayUtils.h" -#include "mozilla/Attributes.h" - -#include -#include - -namespace mozilla { - -/** Set the contents of |aT| to 0. */ -template -static MOZ_ALWAYS_INLINE void -PodZero(T* aT) -{ - memset(aT, 0, sizeof(T)); -} - -/** Set the contents of |aNElem| elements starting at |aT| to 0. */ -template -static MOZ_ALWAYS_INLINE void -PodZero(T* aT, size_t aNElem) -{ - /* - * This function is often called with 'aNElem' small; we use an inline loop - * instead of calling 'memset' with a non-constant length. The compiler - * should inline the memset call with constant size, though. - */ - for (T* end = aT + aNElem; aT < end; aT++) { - memset(aT, 0, sizeof(T)); - } -} - -/* - * Arrays implicitly convert to pointers to their first element, which is - * dangerous when combined with the above PodZero definitions. Adding an - * overload for arrays is ambiguous, so we need another identifier. The - * ambiguous overload is left to catch mistaken uses of PodZero; if you get a - * compile error involving PodZero and array types, use PodArrayZero instead. - */ -template -static void PodZero(T (&aT)[N]) = delete; -template -static void PodZero(T (&aT)[N], size_t aNElem) = delete; - -/** Set the contents of the array |aT| to zero. */ -template -static MOZ_ALWAYS_INLINE void -PodArrayZero(T (&aT)[N]) -{ - memset(aT, 0, N * sizeof(T)); -} - -template -static MOZ_ALWAYS_INLINE void -PodArrayZero(Array& aArr) -{ - memset(&aArr[0], 0, N * sizeof(T)); -} - -/** - * Assign |*aSrc| to |*aDst|. The locations must not be the same and must not - * overlap. - */ -template -static MOZ_ALWAYS_INLINE void -PodAssign(T* aDst, const T* aSrc) -{ - MOZ_ASSERT(aDst + 1 <= aSrc || aSrc + 1 <= aDst, - "destination and source must not overlap"); - memcpy(reinterpret_cast(aDst), reinterpret_cast(aSrc), - sizeof(T)); -} - -/** - * Copy |aNElem| T elements from |aSrc| to |aDst|. The two memory ranges must - * not overlap! - */ -template -static MOZ_ALWAYS_INLINE void -PodCopy(T* aDst, const T* aSrc, size_t aNElem) -{ - MOZ_ASSERT(aDst + aNElem <= aSrc || aSrc + aNElem <= aDst, - "destination and source must not overlap"); - if (aNElem < 128) { - /* - * Avoid using operator= in this loop, as it may have been - * intentionally deleted by the POD type. - */ - for (const T* srcend = aSrc + aNElem; aSrc < srcend; aSrc++, aDst++) { - PodAssign(aDst, aSrc); - } - } else { - memcpy(aDst, aSrc, aNElem * sizeof(T)); - } -} - -template -static MOZ_ALWAYS_INLINE void -PodCopy(volatile T* aDst, const volatile T* aSrc, size_t aNElem) -{ - MOZ_ASSERT(aDst + aNElem <= aSrc || aSrc + aNElem <= aDst, - "destination and source must not overlap"); - - /* - * Volatile |aDst| requires extra work, because it's undefined behavior to - * modify volatile objects using the mem* functions. Just write out the - * loops manually, using operator= rather than memcpy for the same reason, - * and let the compiler optimize to the extent it can. - */ - for (const volatile T* srcend = aSrc + aNElem; - aSrc < srcend; - aSrc++, aDst++) { - *aDst = *aSrc; - } -} - -/* - * Copy the contents of the array |aSrc| into the array |aDst|, both of size N. - * The arrays must not overlap! - */ -template -static MOZ_ALWAYS_INLINE void -PodArrayCopy(T (&aDst)[N], const T (&aSrc)[N]) -{ - PodCopy(aDst, aSrc, N); -} - -/** - * Copy the memory for |aNElem| T elements from |aSrc| to |aDst|. If the two - * memory ranges overlap, then the effect is as if the |aNElem| elements are - * first copied from |aSrc| to a temporary array, and then from the temporary - * array to |aDst|. - */ -template -static MOZ_ALWAYS_INLINE void -PodMove(T* aDst, const T* aSrc, size_t aNElem) -{ - MOZ_ASSERT(aNElem <= SIZE_MAX / sizeof(T), - "trying to move an impossible number of elements"); - memmove(aDst, aSrc, aNElem * sizeof(T)); -} - -/** - * Determine whether the |len| elements at |one| are memory-identical to the - * |len| elements at |two|. - */ -template -static MOZ_ALWAYS_INLINE bool -PodEqual(const T* one, const T* two, size_t len) -{ - if (len < 128) { - const T* p1end = one + len; - const T* p1 = one; - const T* p2 = two; - for (; p1 < p1end; p1++, p2++) { - if (*p1 != *p2) { - return false; - } - } - return true; - } - - return !memcmp(one, two, len * sizeof(T)); -} - -/* - * Determine whether the |N| elements at |one| are memory-identical to the - * |N| elements at |two|. - */ -template -static MOZ_ALWAYS_INLINE bool -PodEqual(const T (&one)[N], const T (&two)[N]) -{ - return PodEqual(one, two, N); -} - -} // namespace mozilla - -#endif /* mozilla_PodOperations_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Poison.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Poison.h deleted file mode 100644 index aae56765..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Poison.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * A poison value that can be used to fill a memory space with - * an address that leads to a safe crash when dereferenced. - */ - -#ifndef mozilla_Poison_h -#define mozilla_Poison_h - -#include "mozilla/Assertions.h" -#include "mozilla/Types.h" - -#include - -MOZ_BEGIN_EXTERN_C - -extern MFBT_DATA uintptr_t gMozillaPoisonValue; - -/** - * @return the poison value. - */ -inline uintptr_t mozPoisonValue() -{ - return gMozillaPoisonValue; -} - -/** - * Overwrite the memory block of aSize bytes at aPtr with the poison value. - * aPtr MUST be aligned at a sizeof(uintptr_t) boundary. - * Only an even number of sizeof(uintptr_t) bytes are overwritten, the last - * few bytes (if any) is not overwritten. - */ -inline void mozWritePoison(void* aPtr, size_t aSize) -{ - const uintptr_t POISON = mozPoisonValue(); - char* p = (char*)aPtr; - char* limit = p + aSize; - MOZ_ASSERT((uintptr_t)aPtr % sizeof(uintptr_t) == 0, "bad alignment"); - MOZ_ASSERT(aSize >= sizeof(uintptr_t), "poisoning this object has no effect"); - for (; p < limit; p += sizeof(uintptr_t)) { - *((uintptr_t*)p) = POISON; - } -} - -/** - * Initialize the poison value. - * This should only be called once. - */ -extern MFBT_API void mozPoisonValueInit(); - -/* Values annotated by CrashReporter */ -extern MFBT_DATA uintptr_t gMozillaPoisonBase; -extern MFBT_DATA uintptr_t gMozillaPoisonSize; - -MOZ_END_EXTERN_C - -#if defined(__cplusplus) - -namespace mozilla { - -/** - * This class is designed to cause crashes when various kinds of memory - * corruption are observed. For instance, let's say we have a class C where we - * suspect out-of-bounds writes to some members. We can insert a member of type - * Poison near the members we suspect are being corrupted by out-of-bounds - * writes. Or perhaps we have a class K we suspect is subject to use-after-free - * violations, in which case it doesn't particularly matter where in the class - * we add the member of type Poison. - * - * In either case, we then insert calls to Check() throughout the code. Doing - * so enables us to narrow down the location where the corruption is occurring. - * A pleasant side-effect of these additional Check() calls is that crash - * signatures may become more regular, as crashes will ideally occur - * consolidated at the point of a Check(), rather than scattered about at - * various uses of the corrupted memory. - */ -class CorruptionCanary { -public: - CorruptionCanary() { - mValue = kCanarySet; - } - - ~CorruptionCanary() { - Check(); - mValue = mozPoisonValue(); - } - - void Check() const { - if (mValue != kCanarySet) { - MOZ_CRASH("Canary check failed, check lifetime"); - } - } - -private: - static const uintptr_t kCanarySet = 0x0f0b0f0b; - uintptr_t mValue; -}; - -} // mozilla - -#endif - -#endif /* mozilla_Poison_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Range.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Range.h deleted file mode 100644 index 47d91bb0..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Range.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_Range_h -#define mozilla_Range_h - -#include "mozilla/RangedPtr.h" -#include "mozilla/TypeTraits.h" - -#include - -namespace mozilla { - -// Range is a tuple containing a pointer and a length. -template -class Range -{ - const RangedPtr mStart; - const RangedPtr mEnd; - -public: - Range() : mStart(nullptr, 0), mEnd(nullptr, 0) {} - Range(T* aPtr, size_t aLength) - : mStart(aPtr, aPtr, aPtr + aLength), - mEnd(aPtr + aLength, aPtr, aPtr + aLength) - {} - Range(const RangedPtr& aStart, const RangedPtr& aEnd) - : mStart(aStart.get(), aStart.get(), aEnd.get()), - mEnd(aEnd.get(), aStart.get(), aEnd.get()) - { - // Only accept two RangedPtrs within the same range. - aStart.checkIdenticalRange(aEnd); - MOZ_ASSERT(aStart <= aEnd); - } - - template::value, - int>::Type> - MOZ_IMPLICIT Range(const Range& aOther) - : mStart(aOther.mStart), - mEnd(aOther.mEnd) - {} - - RangedPtr begin() const { return mStart; } - RangedPtr end() const { return mEnd; } - size_t length() const { return mEnd - mStart; } - - T& operator[](size_t aOffset) const { return mStart[aOffset]; } - - explicit operator bool() const { return mStart != nullptr; } -}; - -} // namespace mozilla - -#endif /* mozilla_Range_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/RangedArray.h b/android/armeabi-v7a/include/spidermonkey/mozilla/RangedArray.h deleted file mode 100644 index afe6267f..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/RangedArray.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * A compile-time constant-length array, with bounds-checking assertions -- but - * unlike mozilla::Array, with indexes biased by a constant. - * - * Thus where mozilla::Array is a three-element array indexed by [0, 3), - * mozilla::RangedArray is a three-element array indexed by [8, 11). - */ - -#ifndef mozilla_RangedArray_h -#define mozilla_RangedArray_h - -#include "mozilla/Array.h" - -namespace mozilla { - -template -class RangedArray -{ -private: - typedef Array ArrayType; - ArrayType mArr; - -public: - T& operator[](size_t aIndex) - { - MOZ_ASSERT(aIndex == MinIndex || aIndex > MinIndex); - return mArr[aIndex - MinIndex]; - } - - const T& operator[](size_t aIndex) const - { - MOZ_ASSERT(aIndex == MinIndex || aIndex > MinIndex); - return mArr[aIndex - MinIndex]; - } - - typedef typename ArrayType::iterator iterator; - typedef typename ArrayType::const_iterator const_iterator; - typedef typename ArrayType::reverse_iterator reverse_iterator; - typedef typename ArrayType::const_reverse_iterator const_reverse_iterator; - - // Methods for range-based for loops. - iterator begin() { return mArr.begin(); } - const_iterator begin() const { return mArr.begin(); } - const_iterator cbegin() const { return mArr.cbegin(); } - iterator end() { return mArr.end(); } - const_iterator end() const { return mArr.end(); } - const_iterator cend() const { return mArr.cend(); } - - // Methods for reverse iterating. - reverse_iterator rbegin() { return mArr.rbegin(); } - const_reverse_iterator rbegin() const { return mArr.rbegin(); } - const_reverse_iterator crbegin() const { return mArr.crbegin(); } - reverse_iterator rend() { return mArr.rend(); } - const_reverse_iterator rend() const { return mArr.rend(); } - const_reverse_iterator crend() const { return mArr.crend(); } -}; - -} // namespace mozilla - -#endif // mozilla_RangedArray_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/RangedPtr.h b/android/armeabi-v7a/include/spidermonkey/mozilla/RangedPtr.h deleted file mode 100644 index a07c1f4f..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/RangedPtr.h +++ /dev/null @@ -1,292 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Implements a smart pointer asserted to remain within a range specified at - * construction. - */ - -#ifndef mozilla_RangedPtr_h -#define mozilla_RangedPtr_h - -#include "mozilla/ArrayUtils.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -#include - -namespace mozilla { - -/* - * RangedPtr is a smart pointer restricted to an address range specified at - * creation. The pointer (and any smart pointers derived from it) must remain - * within the range [start, end] (inclusive of end to facilitate use as - * sentinels). Dereferencing or indexing into the pointer (or pointers derived - * from it) must remain within the range [start, end). All the standard pointer - * operators are defined on it; in debug builds these operations assert that the - * range specified at construction is respected. - * - * In theory passing a smart pointer instance as an argument can be slightly - * slower than passing a T* (due to ABI requirements for passing structs versus - * passing pointers), if the method being called isn't inlined. If you are in - * extremely performance-critical code, you may want to be careful using this - * smart pointer as an argument type. - * - * RangedPtr intentionally does not implicitly convert to T*. Use get() to - * explicitly convert to T*. Keep in mind that the raw pointer of course won't - * implement bounds checking in debug builds. - */ -template -class RangedPtr -{ - T* mPtr; - -#ifdef DEBUG - T* const mRangeStart; - T* const mRangeEnd; -#endif - - void checkSanity() - { - MOZ_ASSERT(mRangeStart <= mPtr); - MOZ_ASSERT(mPtr <= mRangeEnd); - } - - /* Creates a new pointer for |aPtr|, restricted to this pointer's range. */ - RangedPtr create(T* aPtr) const - { -#ifdef DEBUG - return RangedPtr(aPtr, mRangeStart, mRangeEnd); -#else - return RangedPtr(aPtr, nullptr, size_t(0)); -#endif - } - - uintptr_t asUintptr() const { return reinterpret_cast(mPtr); } - -public: - RangedPtr(T* aPtr, T* aStart, T* aEnd) - : mPtr(aPtr) -#ifdef DEBUG - , mRangeStart(aStart), mRangeEnd(aEnd) -#endif - { - MOZ_ASSERT(mRangeStart <= mRangeEnd); - checkSanity(); - } - RangedPtr(T* aPtr, T* aStart, size_t aLength) - : mPtr(aPtr) -#ifdef DEBUG - , mRangeStart(aStart), mRangeEnd(aStart + aLength) -#endif - { - MOZ_ASSERT(aLength <= size_t(-1) / sizeof(T)); - MOZ_ASSERT(reinterpret_cast(mRangeStart) + aLength * sizeof(T) >= - reinterpret_cast(mRangeStart)); - checkSanity(); - } - - /* Equivalent to RangedPtr(aPtr, aPtr, aLength). */ - RangedPtr(T* aPtr, size_t aLength) - : mPtr(aPtr) -#ifdef DEBUG - , mRangeStart(aPtr), mRangeEnd(aPtr + aLength) -#endif - { - MOZ_ASSERT(aLength <= size_t(-1) / sizeof(T)); - MOZ_ASSERT(reinterpret_cast(mRangeStart) + aLength * sizeof(T) >= - reinterpret_cast(mRangeStart)); - checkSanity(); - } - - /* Equivalent to RangedPtr(aArr, aArr, N). */ - template - explicit RangedPtr(T (&aArr)[N]) - : mPtr(aArr) -#ifdef DEBUG - , mRangeStart(aArr), mRangeEnd(aArr + N) -#endif - { - checkSanity(); - } - - T* get() const { return mPtr; } - - explicit operator bool() const { return mPtr != nullptr; } - - void checkIdenticalRange(const RangedPtr& aOther) const - { - MOZ_ASSERT(mRangeStart == aOther.mRangeStart); - MOZ_ASSERT(mRangeEnd == aOther.mRangeEnd); - } - - /* - * You can only assign one RangedPtr into another if the two pointers have - * the same valid range: - * - * char arr1[] = "hi"; - * char arr2[] = "bye"; - * RangedPtr p1(arr1, 2); - * p1 = RangedPtr(arr1 + 1, arr1, arr1 + 2); // works - * p1 = RangedPtr(arr2, 3); // asserts - */ - RangedPtr& operator=(const RangedPtr& aOther) - { - checkIdenticalRange(aOther); - mPtr = aOther.mPtr; - checkSanity(); - return *this; - } - - RangedPtr operator+(size_t aInc) const - { - MOZ_ASSERT(aInc <= size_t(-1) / sizeof(T)); - MOZ_ASSERT(asUintptr() + aInc * sizeof(T) >= asUintptr()); - return create(mPtr + aInc); - } - - RangedPtr operator-(size_t aDec) const - { - MOZ_ASSERT(aDec <= size_t(-1) / sizeof(T)); - MOZ_ASSERT(asUintptr() - aDec * sizeof(T) <= asUintptr()); - return create(mPtr - aDec); - } - - /* - * You can assign a raw pointer into a RangedPtr if the raw pointer is - * within the range specified at creation. - */ - template - RangedPtr& operator=(U* aPtr) - { - *this = create(aPtr); - return *this; - } - - template - RangedPtr& operator=(const RangedPtr& aPtr) - { - MOZ_ASSERT(mRangeStart <= aPtr.mPtr); - MOZ_ASSERT(aPtr.mPtr <= mRangeEnd); - mPtr = aPtr.mPtr; - checkSanity(); - return *this; - } - - RangedPtr& operator++() - { - return (*this += 1); - } - - RangedPtr operator++(int) - { - RangedPtr rcp = *this; - ++*this; - return rcp; - } - - RangedPtr& operator--() - { - return (*this -= 1); - } - - RangedPtr operator--(int) - { - RangedPtr rcp = *this; - --*this; - return rcp; - } - - RangedPtr& operator+=(size_t aInc) - { - *this = *this + aInc; - return *this; - } - - RangedPtr& operator-=(size_t aDec) - { - *this = *this - aDec; - return *this; - } - - T& operator[](int aIndex) const - { - MOZ_ASSERT(size_t(aIndex > 0 ? aIndex : -aIndex) <= size_t(-1) / sizeof(T)); - return *create(mPtr + aIndex); - } - - T& operator*() const - { - MOZ_ASSERT(mPtr >= mRangeStart); - MOZ_ASSERT(mPtr < mRangeEnd); - return *mPtr; - } - - T* operator->() const - { - MOZ_ASSERT(mPtr >= mRangeStart); - MOZ_ASSERT(mPtr < mRangeEnd); - return mPtr; - } - - template - bool operator==(const RangedPtr& aOther) const - { - return mPtr == aOther.mPtr; - } - template - bool operator!=(const RangedPtr& aOther) const - { - return !(*this == aOther); - } - - template - bool operator==(const U* u) const - { - return mPtr == u; - } - template - bool operator!=(const U* u) const - { - return !(*this == u); - } - - template - bool operator<(const RangedPtr& aOther) const - { - return mPtr < aOther.mPtr; - } - template - bool operator<=(const RangedPtr& aOther) const - { - return mPtr <= aOther.mPtr; - } - - template - bool operator>(const RangedPtr& aOther) const - { - return mPtr > aOther.mPtr; - } - template - bool operator>=(const RangedPtr& aOther) const - { - return mPtr >= aOther.mPtr; - } - - size_t operator-(const RangedPtr& aOther) const - { - MOZ_ASSERT(mPtr >= aOther.mPtr); - return PointerRangeSize(aOther.mPtr, mPtr); - } - -private: - RangedPtr() = delete; - T* operator&() = delete; -}; - -} /* namespace mozilla */ - -#endif /* mozilla_RangedPtr_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/ReentrancyGuard.h b/android/armeabi-v7a/include/spidermonkey/mozilla/ReentrancyGuard.h deleted file mode 100644 index 9963974e..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/ReentrancyGuard.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Small helper class for asserting uses of a class are non-reentrant. */ - -#ifndef mozilla_ReentrancyGuard_h -#define mozilla_ReentrancyGuard_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/GuardObjects.h" - -namespace mozilla { - -/* Useful for implementing containers that assert non-reentrancy */ -class MOZ_RAII ReentrancyGuard -{ - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -#ifdef DEBUG - bool& mEntered; -#endif - -public: - template -#ifdef DEBUG - explicit ReentrancyGuard(T& aObj - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mEntered(aObj.mEntered) -#else - explicit ReentrancyGuard(T& - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) -#endif - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; -#ifdef DEBUG - MOZ_ASSERT(!mEntered); - mEntered = true; -#endif - } - ~ReentrancyGuard() - { -#ifdef DEBUG - mEntered = false; -#endif - } - -private: - ReentrancyGuard(const ReentrancyGuard&) = delete; - void operator=(const ReentrancyGuard&) = delete; -}; - -} // namespace mozilla - -#endif /* mozilla_ReentrancyGuard_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/RefCountType.h b/android/armeabi-v7a/include/spidermonkey/mozilla/RefCountType.h deleted file mode 100644 index e95a22a0..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/RefCountType.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_RefCountType_h -#define mozilla_RefCountType_h - -#include - -/** - * MozRefCountType is Mozilla's reference count type. - * - * We use the same type to represent the refcount of RefCounted objects - * as well, in order to be able to use the leak detection facilities - * that are implemented by XPCOM. - * - * Note that this type is not in the mozilla namespace so that it is - * usable for both C and C++ code. - */ -typedef uintptr_t MozRefCountType; - -/* - * This is the return type for AddRef() and Release() in nsISupports. - * IUnknown of COM returns an unsigned long from equivalent functions. - * - * The following ifdef exists to maintain binary compatibility with - * IUnknown, the base interface in Microsoft COM. - */ -#ifdef XP_WIN -typedef unsigned long MozExternalRefCountType; -#else -typedef uint32_t MozExternalRefCountType; -#endif - -#endif diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/RefCounted.h b/android/armeabi-v7a/include/spidermonkey/mozilla/RefCounted.h deleted file mode 100644 index ae05f1e0..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/RefCounted.h +++ /dev/null @@ -1,210 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* CRTP refcounting templates. Do not use unless you are an Expert. */ - -#ifndef mozilla_RefCounted_h -#define mozilla_RefCounted_h - -#include "mozilla/AlreadyAddRefed.h" -#include "mozilla/Assertions.h" -#include "mozilla/Atomics.h" -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" -#include "mozilla/RefCountType.h" -#include "mozilla/TypeTraits.h" - -#if defined(MOZILLA_INTERNAL_API) -#include "nsXPCOM.h" -#endif - -#if defined(MOZILLA_INTERNAL_API) && \ - (defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING)) -#define MOZ_REFCOUNTED_LEAK_CHECKING -#endif - -namespace mozilla { - -/** - * RefCounted is a sort of a "mixin" for a class T. RefCounted - * manages, well, refcounting for T, and because RefCounted is - * parameterized on T, RefCounted can call T's destructor directly. - * This means T doesn't need to have a virtual dtor and so doesn't - * need a vtable. - * - * RefCounted is created with refcount == 0. Newly-allocated - * RefCounted must immediately be assigned to a RefPtr to make the - * refcount > 0. It's an error to allocate and free a bare - * RefCounted, i.e. outside of the RefPtr machinery. Attempts to - * do so will abort DEBUG builds. - * - * Live RefCounted have refcount > 0. The lifetime (refcounts) of - * live RefCounted are controlled by RefPtr and - * RefPtr. Upon a transition from refcounted==1 - * to 0, the RefCounted "dies" and is destroyed. The "destroyed" - * state is represented in DEBUG builds by refcount==0xffffdead. This - * state distinguishes use-before-ref (refcount==0) from - * use-after-destroy (refcount==0xffffdead). - * - * Note that when deriving from RefCounted or AtomicRefCounted, you - * should add MOZ_DECLARE_REFCOUNTED_TYPENAME(ClassName) to the public - * section of your class, where ClassName is the name of your class. - */ -namespace detail { -const MozRefCountType DEAD = 0xffffdead; - -// When building code that gets compiled into Gecko, try to use the -// trace-refcount leak logging facilities. -#ifdef MOZ_REFCOUNTED_LEAK_CHECKING -class RefCountLogger -{ -public: - static void logAddRef(const void* aPointer, MozRefCountType aRefCount, - const char* aTypeName, uint32_t aInstanceSize) - { - MOZ_ASSERT(aRefCount != DEAD); - NS_LogAddRef(const_cast(aPointer), aRefCount, aTypeName, - aInstanceSize); - } - - static void logRelease(const void* aPointer, MozRefCountType aRefCount, - const char* aTypeName) - { - MOZ_ASSERT(aRefCount != DEAD); - NS_LogRelease(const_cast(aPointer), aRefCount, aTypeName); - } -}; -#endif - -// This is used WeakPtr.h as well as this file. -enum RefCountAtomicity -{ - AtomicRefCount, - NonAtomicRefCount -}; - -template -class RefCounted -{ -protected: - RefCounted() : mRefCnt(0) {} - ~RefCounted() { MOZ_ASSERT(mRefCnt == detail::DEAD); } - -public: - // Compatibility with nsRefPtr. - void AddRef() const - { - // Note: this method must be thread safe for AtomicRefCounted. - MOZ_ASSERT(int32_t(mRefCnt) >= 0); -#ifndef MOZ_REFCOUNTED_LEAK_CHECKING - ++mRefCnt; -#else - const char* type = static_cast(this)->typeName(); - uint32_t size = static_cast(this)->typeSize(); - const void* ptr = static_cast(this); - MozRefCountType cnt = ++mRefCnt; - detail::RefCountLogger::logAddRef(ptr, cnt, type, size); -#endif - } - - void Release() const - { - // Note: this method must be thread safe for AtomicRefCounted. - MOZ_ASSERT(int32_t(mRefCnt) > 0); -#ifndef MOZ_REFCOUNTED_LEAK_CHECKING - MozRefCountType cnt = --mRefCnt; -#else - const char* type = static_cast(this)->typeName(); - const void* ptr = static_cast(this); - MozRefCountType cnt = --mRefCnt; - // Note: it's not safe to touch |this| after decrementing the refcount, - // except for below. - detail::RefCountLogger::logRelease(ptr, cnt, type); -#endif - if (0 == cnt) { - // Because we have atomically decremented the refcount above, only - // one thread can get a 0 count here, so as long as we can assume that - // everything else in the system is accessing this object through - // RefPtrs, it's safe to access |this| here. -#ifdef DEBUG - mRefCnt = detail::DEAD; -#endif - delete static_cast(this); - } - } - - // Compatibility with wtf::RefPtr. - void ref() { AddRef(); } - void deref() { Release(); } - MozRefCountType refCount() const { return mRefCnt; } - bool hasOneRef() const - { - MOZ_ASSERT(mRefCnt > 0); - return mRefCnt == 1; - } - -private: - mutable typename Conditional, - MozRefCountType>::Type mRefCnt; -}; - -#ifdef MOZ_REFCOUNTED_LEAK_CHECKING -// Passing override for the optional argument marks the typeName and -// typeSize functions defined by this macro as overrides. -#define MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(T, ...) \ - virtual const char* typeName() const __VA_ARGS__ { return #T; } \ - virtual size_t typeSize() const __VA_ARGS__ { return sizeof(*this); } -#else -#define MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(T, ...) -#endif - -// Note that this macro is expanded unconditionally because it declares only -// two small inline functions which will hopefully get eliminated by the linker -// in non-leak-checking builds. -#define MOZ_DECLARE_REFCOUNTED_TYPENAME(T) \ - const char* typeName() const { return #T; } \ - size_t typeSize() const { return sizeof(*this); } - -} // namespace detail - -template -class RefCounted : public detail::RefCounted -{ -public: - ~RefCounted() - { - static_assert(IsBaseOf::value, - "T must derive from RefCounted"); - } -}; - -namespace external { - -/** - * AtomicRefCounted is like RefCounted, with an atomically updated - * reference counter. - * - * NOTE: Please do not use this class, use NS_INLINE_DECL_THREADSAFE_REFCOUNTING - * instead. - */ -template -class AtomicRefCounted : - public mozilla::detail::RefCounted -{ -public: - ~AtomicRefCounted() - { - static_assert(IsBaseOf::value, - "T must derive from AtomicRefCounted"); - } -}; - -} // namespace external - -} // namespace mozilla - -#endif // mozilla_RefCounted_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/RefPtr.h b/android/armeabi-v7a/include/spidermonkey/mozilla/RefPtr.h deleted file mode 100644 index bfa8f6e0..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/RefPtr.h +++ /dev/null @@ -1,656 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_RefPtr_h -#define mozilla_RefPtr_h - -#include "mozilla/AlreadyAddRefed.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -/*****************************************************************************/ - -// template class RefPtrGetterAddRefs; - -class nsCOMPtr_helper; - -namespace mozilla { -template class OwningNonNull; -template class StaticRefPtr; - -// Traditionally, RefPtr supports automatic refcounting of any pointer type -// with AddRef() and Release() methods that follow the traditional semantics. -// -// This traits class can be specialized to operate on other pointer types. For -// example, we specialize this trait for opaque FFI types that represent -// refcounted objects in Rust. -// -// Given the use of ConstRemovingRefPtrTraits below, U should not be a const- -// qualified type. -template -struct RefPtrTraits -{ - static void AddRef(U* aPtr) { - aPtr->AddRef(); - } - static void Release(U* aPtr) { - aPtr->Release(); - } -}; - -} // namespace mozilla - -template -class RefPtr -{ -private: - void - assign_with_AddRef(T* aRawPtr) - { - if (aRawPtr) { - ConstRemovingRefPtrTraits::AddRef(aRawPtr); - } - assign_assuming_AddRef(aRawPtr); - } - - void - assign_assuming_AddRef(T* aNewPtr) - { - T* oldPtr = mRawPtr; - mRawPtr = aNewPtr; - if (oldPtr) { - ConstRemovingRefPtrTraits::Release(oldPtr); - } - } - -private: - T* MOZ_OWNING_REF mRawPtr; - -public: - typedef T element_type; - - ~RefPtr() - { - if (mRawPtr) { - ConstRemovingRefPtrTraits::Release(mRawPtr); - } - } - - // Constructors - - RefPtr() - : mRawPtr(nullptr) - // default constructor - { - } - - RefPtr(const RefPtr& aSmartPtr) - : mRawPtr(aSmartPtr.mRawPtr) - // copy-constructor - { - if (mRawPtr) { - ConstRemovingRefPtrTraits::AddRef(mRawPtr); - } - } - - RefPtr(RefPtr&& aRefPtr) - : mRawPtr(aRefPtr.mRawPtr) - { - aRefPtr.mRawPtr = nullptr; - } - - // construct from a raw pointer (of the right type) - - MOZ_IMPLICIT RefPtr(T* aRawPtr) - : mRawPtr(aRawPtr) - { - if (mRawPtr) { - ConstRemovingRefPtrTraits::AddRef(mRawPtr); - } - } - - MOZ_IMPLICIT RefPtr(decltype(nullptr)) - : mRawPtr(nullptr) - { - } - - template - MOZ_IMPLICIT RefPtr(already_AddRefed& aSmartPtr) - : mRawPtr(aSmartPtr.take()) - // construct from |already_AddRefed| - { - } - - template - MOZ_IMPLICIT RefPtr(already_AddRefed&& aSmartPtr) - : mRawPtr(aSmartPtr.take()) - // construct from |otherRefPtr.forget()| - { - } - - template - MOZ_IMPLICIT RefPtr(const RefPtr& aSmartPtr) - : mRawPtr(aSmartPtr.get()) - // copy-construct from a smart pointer with a related pointer type - { - if (mRawPtr) { - ConstRemovingRefPtrTraits::AddRef(mRawPtr); - } - } - - template - MOZ_IMPLICIT RefPtr(RefPtr&& aSmartPtr) - : mRawPtr(aSmartPtr.forget().take()) - // construct from |Move(RefPtr)|. - { - } - - MOZ_IMPLICIT RefPtr(const nsCOMPtr_helper& aHelper); - - // Defined in OwningNonNull.h - template - MOZ_IMPLICIT RefPtr(const mozilla::OwningNonNull& aOther); - - // Defined in StaticPtr.h - template - MOZ_IMPLICIT RefPtr(const mozilla::StaticRefPtr& aOther); - - // Assignment operators - - RefPtr& - operator=(decltype(nullptr)) - { - assign_assuming_AddRef(nullptr); - return *this; - } - - RefPtr& - operator=(const RefPtr& aRhs) - // copy assignment operator - { - assign_with_AddRef(aRhs.mRawPtr); - return *this; - } - - template - RefPtr& - operator=(const RefPtr& aRhs) - // assign from an RefPtr of a related pointer type - { - assign_with_AddRef(aRhs.get()); - return *this; - } - - RefPtr& - operator=(T* aRhs) - // assign from a raw pointer (of the right type) - { - assign_with_AddRef(aRhs); - return *this; - } - - template - RefPtr& - operator=(already_AddRefed& aRhs) - // assign from |already_AddRefed| - { - assign_assuming_AddRef(aRhs.take()); - return *this; - } - - template - RefPtr& - operator=(already_AddRefed && aRhs) - // assign from |otherRefPtr.forget()| - { - assign_assuming_AddRef(aRhs.take()); - return *this; - } - - RefPtr& operator=(const nsCOMPtr_helper& aHelper); - - RefPtr& - operator=(RefPtr && aRefPtr) - { - assign_assuming_AddRef(aRefPtr.mRawPtr); - aRefPtr.mRawPtr = nullptr; - return *this; - } - - // Defined in OwningNonNull.h - template - RefPtr& - operator=(const mozilla::OwningNonNull& aOther); - - // Defined in StaticPtr.h - template - RefPtr& - operator=(const mozilla::StaticRefPtr& aOther); - - // Other pointer operators - - void - swap(RefPtr& aRhs) - // ...exchange ownership with |aRhs|; can save a pair of refcount operations - { - T* temp = aRhs.mRawPtr; - aRhs.mRawPtr = mRawPtr; - mRawPtr = temp; - } - - void - swap(T*& aRhs) - // ...exchange ownership with |aRhs|; can save a pair of refcount operations - { - T* temp = aRhs; - aRhs = mRawPtr; - mRawPtr = temp; - } - - already_AddRefed - forget() - // return the value of mRawPtr and null out mRawPtr. Useful for - // already_AddRefed return values. - { - T* temp = nullptr; - swap(temp); - return already_AddRefed(temp); - } - - template - void - forget(I** aRhs) - // Set the target of aRhs to the value of mRawPtr and null out mRawPtr. - // Useful to avoid unnecessary AddRef/Release pairs with "out" - // parameters where aRhs bay be a T** or an I** where I is a base class - // of T. - { - MOZ_ASSERT(aRhs, "Null pointer passed to forget!"); - *aRhs = mRawPtr; - mRawPtr = nullptr; - } - - T* - get() const - /* - Prefer the implicit conversion provided automatically by |operator T*() const|. - Use |get()| to resolve ambiguity or to get a castable pointer. - */ - { - return const_cast(mRawPtr); - } - - operator T*() const -#ifdef MOZ_HAVE_REF_QUALIFIERS - & -#endif - /* - ...makes an |RefPtr| act like its underlying raw pointer type whenever it - is used in a context where a raw pointer is expected. It is this operator - that makes an |RefPtr| substitutable for a raw pointer. - - Prefer the implicit use of this operator to calling |get()|, except where - necessary to resolve ambiguity. - */ - { - return get(); - } - -#ifdef MOZ_HAVE_REF_QUALIFIERS - // Don't allow implicit conversion of temporary RefPtr to raw pointer, - // because the refcount might be one and the pointer will immediately become - // invalid. - operator T*() const && = delete; - - // These are needed to avoid the deleted operator above. XXX Why is operator! - // needed separately? Shouldn't the compiler prefer using the non-deleted - // operator bool instead of the deleted operator T*? - explicit operator bool() const { return !!mRawPtr; } - bool operator!() const { return !mRawPtr; } -#endif - - T* - operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN - { - MOZ_ASSERT(mRawPtr != nullptr, - "You can't dereference a NULL RefPtr with operator->()."); - return get(); - } - - template - class Proxy - { - typedef R (T::*member_function)(Args...); - T* mRawPtr; - member_function mFunction; - public: - Proxy(T* aRawPtr, member_function aFunction) - : mRawPtr(aRawPtr), - mFunction(aFunction) - { - } - template - R operator()(ActualArgs&&... aArgs) - { - return ((*mRawPtr).*mFunction)(mozilla::Forward(aArgs)...); - } - }; - - template - Proxy operator->*(R (T::*aFptr)(Args...)) const - { - MOZ_ASSERT(mRawPtr != nullptr, - "You can't dereference a NULL RefPtr with operator->*()."); - return Proxy(get(), aFptr); - } - - RefPtr* - get_address() - // This is not intended to be used by clients. See |address_of| - // below. - { - return this; - } - - const RefPtr* - get_address() const - // This is not intended to be used by clients. See |address_of| - // below. - { - return this; - } - -public: - T& - operator*() const - { - MOZ_ASSERT(mRawPtr != nullptr, - "You can't dereference a NULL RefPtr with operator*()."); - return *get(); - } - - T** - StartAssignment() - { - assign_assuming_AddRef(nullptr); - return reinterpret_cast(&mRawPtr); - } -private: - // This helper class makes |RefPtr| possible by casting away - // the constness from the pointer when calling AddRef() and Release(). - // - // This is necessary because AddRef() and Release() implementations can't - // generally expected to be const themselves (without heavy use of |mutable| - // and |const_cast| in their own implementations). - // - // This should be sound because while |RefPtr| provides a - // const view of an object, the object itself should not be const (it - // would have to be allocated as |new const T| or similar to be const). - template - struct ConstRemovingRefPtrTraits - { - static void AddRef(U* aPtr) { - mozilla::RefPtrTraits::AddRef(aPtr); - } - static void Release(U* aPtr) { - mozilla::RefPtrTraits::Release(aPtr); - } - }; - template - struct ConstRemovingRefPtrTraits - { - static void AddRef(const U* aPtr) { - mozilla::RefPtrTraits::AddRef(const_cast(aPtr)); - } - static void Release(const U* aPtr) { - mozilla::RefPtrTraits::Release(const_cast(aPtr)); - } - }; -}; - -class nsCycleCollectionTraversalCallback; -template -void -CycleCollectionNoteChild(nsCycleCollectionTraversalCallback& aCallback, - T* aChild, const char* aName, uint32_t aFlags); - -template -inline void -ImplCycleCollectionUnlink(RefPtr& aField) -{ - aField = nullptr; -} - -template -inline void -ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, - RefPtr& aField, - const char* aName, - uint32_t aFlags = 0) -{ - CycleCollectionNoteChild(aCallback, aField.get(), aName, aFlags); -} - -template -inline RefPtr* -address_of(RefPtr& aPtr) -{ - return aPtr.get_address(); -} - -template -inline const RefPtr* -address_of(const RefPtr& aPtr) -{ - return aPtr.get_address(); -} - -template -class RefPtrGetterAddRefs -/* - ... - - This class is designed to be used for anonymous temporary objects in the - argument list of calls that return COM interface pointers, e.g., - - RefPtr fooP; - ...->GetAddRefedPointer(getter_AddRefs(fooP)) - - DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_AddRefs()| instead. - - When initialized with a |RefPtr|, as in the example above, it returns - a |void**|, a |T**|, or an |nsISupports**| as needed, that the - outer call (|GetAddRefedPointer| in this case) can fill in. - - This type should be a nested class inside |RefPtr|. -*/ -{ -public: - explicit - RefPtrGetterAddRefs(RefPtr& aSmartPtr) - : mTargetSmartPtr(aSmartPtr) - { - // nothing else to do - } - - operator void**() - { - return reinterpret_cast(mTargetSmartPtr.StartAssignment()); - } - - operator T**() - { - return mTargetSmartPtr.StartAssignment(); - } - - T*& - operator*() - { - return *(mTargetSmartPtr.StartAssignment()); - } - -private: - RefPtr& mTargetSmartPtr; -}; - -template -inline RefPtrGetterAddRefs -getter_AddRefs(RefPtr& aSmartPtr) -/* - Used around a |RefPtr| when - ...makes the class |RefPtrGetterAddRefs| invisible. -*/ -{ - return RefPtrGetterAddRefs(aSmartPtr); -} - - -// Comparing two |RefPtr|s - -template -inline bool -operator==(const RefPtr& aLhs, const RefPtr& aRhs) -{ - return static_cast(aLhs.get()) == static_cast(aRhs.get()); -} - - -template -inline bool -operator!=(const RefPtr& aLhs, const RefPtr& aRhs) -{ - return static_cast(aLhs.get()) != static_cast(aRhs.get()); -} - - -// Comparing an |RefPtr| to a raw pointer - -template -inline bool -operator==(const RefPtr& aLhs, const U* aRhs) -{ - return static_cast(aLhs.get()) == static_cast(aRhs); -} - -template -inline bool -operator==(const U* aLhs, const RefPtr& aRhs) -{ - return static_cast(aLhs) == static_cast(aRhs.get()); -} - -template -inline bool -operator!=(const RefPtr& aLhs, const U* aRhs) -{ - return static_cast(aLhs.get()) != static_cast(aRhs); -} - -template -inline bool -operator!=(const U* aLhs, const RefPtr& aRhs) -{ - return static_cast(aLhs) != static_cast(aRhs.get()); -} - -template -inline bool -operator==(const RefPtr& aLhs, U* aRhs) -{ - return static_cast(aLhs.get()) == const_cast(aRhs); -} - -template -inline bool -operator==(U* aLhs, const RefPtr& aRhs) -{ - return const_cast(aLhs) == static_cast(aRhs.get()); -} - -template -inline bool -operator!=(const RefPtr& aLhs, U* aRhs) -{ - return static_cast(aLhs.get()) != const_cast(aRhs); -} - -template -inline bool -operator!=(U* aLhs, const RefPtr& aRhs) -{ - return const_cast(aLhs) != static_cast(aRhs.get()); -} - -// Comparing an |RefPtr| to |nullptr| - -template -inline bool -operator==(const RefPtr& aLhs, decltype(nullptr)) -{ - return aLhs.get() == nullptr; -} - -template -inline bool -operator==(decltype(nullptr), const RefPtr& aRhs) -{ - return nullptr == aRhs.get(); -} - -template -inline bool -operator!=(const RefPtr& aLhs, decltype(nullptr)) -{ - return aLhs.get() != nullptr; -} - -template -inline bool -operator!=(decltype(nullptr), const RefPtr& aRhs) -{ - return nullptr != aRhs.get(); -} - -/*****************************************************************************/ - -template -inline already_AddRefed -do_AddRef(T* aObj) -{ - RefPtr ref(aObj); - return ref.forget(); -} - -template -inline already_AddRefed -do_AddRef(const RefPtr& aObj) -{ - RefPtr ref(aObj); - return ref.forget(); -} - -namespace mozilla { - -/** - * Helper function to be able to conveniently write things like: - * - * already_AddRefed - * f(...) - * { - * return MakeAndAddRef(...); - * } - */ -template -already_AddRefed -MakeAndAddRef(Args&&... aArgs) -{ - RefPtr p(new T(Forward(aArgs)...)); - return p.forget(); -} - -} // namespace mozilla - -#endif /* mozilla_RefPtr_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/ReverseIterator.h b/android/armeabi-v7a/include/spidermonkey/mozilla/ReverseIterator.h deleted file mode 100644 index 49c2e279..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/ReverseIterator.h +++ /dev/null @@ -1,168 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* An iterator that acts like another iterator, but iterating in - * the negative direction. (Note that not all iterators can iterate - * in the negative direction.) */ - -#ifndef mozilla_ReverseIterator_h -#define mozilla_ReverseIterator_h - -#include "mozilla/Attributes.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -template -class ReverseIterator -{ -public: - template - explicit ReverseIterator(Iterator aIter) - : mCurrent(aIter) { } - - template - MOZ_IMPLICIT ReverseIterator(const ReverseIterator& aOther) - : mCurrent(aOther.mCurrent) { } - - decltype(*DeclVal()) operator*() const - { - IteratorT tmp = mCurrent; - return *--tmp; - } - - /* Increments and decrements operators */ - - ReverseIterator& operator++() { --mCurrent; return *this; } - ReverseIterator& operator--() { ++mCurrent; return *this; } - ReverseIterator operator++(int) { auto ret = *this; mCurrent--; return ret; } - ReverseIterator operator--(int) { auto ret = *this; mCurrent++; return ret; } - - /* Comparison operators */ - - template - friend bool operator==(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - template - friend bool operator!=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - template - friend bool operator<(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - template - friend bool operator<=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - template - friend bool operator>(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - template - friend bool operator>=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - -private: - IteratorT mCurrent; -}; - -template -bool -operator==(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent == aIter2.mCurrent; -} - -template -bool -operator!=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent != aIter2.mCurrent; -} - -template -bool -operator<(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent > aIter2.mCurrent; -} - -template -bool -operator<=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent >= aIter2.mCurrent; -} - -template -bool -operator>(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent < aIter2.mCurrent; -} - -template -bool -operator>=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent <= aIter2.mCurrent; -} - -namespace detail { - -template -class IteratorRange -{ -public: - typedef IteratorT iterator; - typedef IteratorT const_iterator; - typedef ReverseIterator reverse_iterator; - typedef ReverseIterator const_reverse_iterator; - - template - MOZ_IMPLICIT IteratorRange(Iterator1 aIterBegin, Iterator2 aIterEnd) - : mIterBegin(aIterBegin), mIterEnd(aIterEnd) { } - - template - MOZ_IMPLICIT IteratorRange(const IteratorRange& aOther) - : mIterBegin(aOther.mIterBegin), mIterEnd(aOther.mIterEnd) { } - - iterator begin() const { return mIterBegin; } - const_iterator cbegin() const { return begin(); } - iterator end() const { return mIterEnd; } - const_iterator cend() const { return end(); } - reverse_iterator rbegin() const { return reverse_iterator(mIterEnd); } - const_reverse_iterator crbegin() const { return rbegin(); } - reverse_iterator rend() const { return reverse_iterator(mIterBegin); } - const_reverse_iterator crend() const { return rend(); } - -private: - IteratorT mIterBegin; - IteratorT mIterEnd; -}; - -} // namespace detail - -template -detail::IteratorRange -Reversed(Range& aRange) -{ - return {aRange.rbegin(), aRange.rend()}; -} - -template -detail::IteratorRange -Reversed(const Range& aRange) -{ - return {aRange.rbegin(), aRange.rend()}; -} - -} // namespace mozilla - -#endif // mozilla_ReverseIterator_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/RollingMean.h b/android/armeabi-v7a/include/spidermonkey/mozilla/RollingMean.h deleted file mode 100644 index 8cc3148e..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/RollingMean.h +++ /dev/null @@ -1,115 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A set abstraction for enumeration values. */ - -#ifndef mozilla_RollingMean_h_ -#define mozilla_RollingMean_h_ - -#include "mozilla/Assertions.h" -#include "mozilla/TypeTraits.h" -#include "mozilla/Vector.h" - -#include - -namespace mozilla { - -/** - * RollingMean calculates a rolling mean of the values it is given. It - * accumulates the total as values are added and removed. The second type - * argument S specifies the type of the total. This may need to be a bigger - * type in order to maintain that the sum of all values in the average doesn't - * exceed the maximum input value. - * - * WARNING: Float types are not supported due to rounding errors. - */ -template -class RollingMean -{ -private: - size_t mInsertIndex; - size_t mMaxValues; - Vector mValues; - S mTotal; - -public: - static_assert(!IsFloatingPoint::value, - "floating-point types are unsupported due to rounding " - "errors"); - - explicit RollingMean(size_t aMaxValues) - : mInsertIndex(0), - mMaxValues(aMaxValues), - mTotal(0) - { - MOZ_ASSERT(aMaxValues > 0); - } - - RollingMean& operator=(RollingMean&& aOther) - { - MOZ_ASSERT(this != &aOther, "self-assignment is forbidden"); - this->~RollingMean(); - new(this) RollingMean(aOther.mMaxValues); - mInsertIndex = aOther.mInsertIndex; - mTotal = aOther.mTotal; - mValues.swap(aOther.mValues); - return *this; - } - - /** - * Insert a value into the rolling mean. - */ - bool insert(T aValue) - { - MOZ_ASSERT(mValues.length() <= mMaxValues); - - if (mValues.length() == mMaxValues) { - mTotal = mTotal - mValues[mInsertIndex] + aValue; - mValues[mInsertIndex] = aValue; - } else { - if (!mValues.append(aValue)) { - return false; - } - mTotal = mTotal + aValue; - } - - mInsertIndex = (mInsertIndex + 1) % mMaxValues; - return true; - } - - /** - * Calculate the rolling mean. - */ - T mean() - { - MOZ_ASSERT(!empty()); - return T(mTotal / int64_t(mValues.length())); - } - - bool empty() - { - return mValues.empty(); - } - - /** - * Remove all values from the rolling mean. - */ - void clear() - { - mValues.clear(); - mInsertIndex = 0; - mTotal = T(0); - } - - size_t maxValues() - { - return mMaxValues; - } -}; - -} // namespace mozilla - -#endif // mozilla_RollingMean_h_ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/SHA1.h b/android/armeabi-v7a/include/spidermonkey/mozilla/SHA1.h deleted file mode 100644 index ddccaa67..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/SHA1.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Simple class for computing SHA1. */ - -#ifndef mozilla_SHA1_h -#define mozilla_SHA1_h - -#include "mozilla/Types.h" - -#include -#include - -namespace mozilla { - -/** - * This class computes the SHA1 hash of a byte sequence, or of the concatenation - * of multiple sequences. For example, computing the SHA1 of two sequences of - * bytes could be done as follows: - * - * void SHA1(const uint8_t* buf1, uint32_t size1, - * const uint8_t* buf2, uint32_t size2, - * SHA1Sum::Hash& hash) - * { - * SHA1Sum s; - * s.update(buf1, size1); - * s.update(buf2, size2); - * s.finish(hash); - * } - * - * The finish method may only be called once and cannot be followed by calls - * to update. - */ -class SHA1Sum -{ - union - { - uint32_t mW[16]; /* input buffer */ - uint8_t mB[64]; - } mU; - uint64_t mSize; /* count of hashed bytes. */ - unsigned mH[22]; /* 5 state variables, 16 tmp values, 1 extra */ - bool mDone; - -public: - MFBT_API SHA1Sum(); - - static const size_t kHashSize = 20; - typedef uint8_t Hash[kHashSize]; - - /* Add len bytes of dataIn to the data sequence being hashed. */ - MFBT_API void update(const void* aData, uint32_t aLength); - - /* Compute the final hash of all data into hashOut. */ - MFBT_API void finish(SHA1Sum::Hash& aHashOut); -}; - -} /* namespace mozilla */ - -#endif /* mozilla_SHA1_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Saturate.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Saturate.h deleted file mode 100644 index b79364d2..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Saturate.h +++ /dev/null @@ -1,288 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Provides saturation arithmetics for scalar types. */ - -#ifndef mozilla_Saturate_h -#define mozilla_Saturate_h - -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -#include - -namespace mozilla { -namespace detail { - -/** - * |SaturateOp| wraps scalar values for saturation arithmetics. Usage: - * - * uint32_t value = 1; - * - * ++SaturateOp(value); // value is 2 - * --SaturateOp(value); // value is 1 - * --SaturateOp(value); // value is 0 - * --SaturateOp(value); // value is still 0 - * - * Please add new operators when required. - * - * |SaturateOp| will saturate at the minimum and maximum values of - * type T. If you need other bounds, implement a clamped-type class and - * specialize the type traits accordingly. - */ -template -class SaturateOp -{ -public: - explicit SaturateOp(T& aValue) - : mValue(aValue) - { - // We should actually check for |std::is_scalar::value| to be - // true, but this type trait is not available everywhere. Relax - // this assertion if you want to use floating point values as well. - static_assert(IsIntegral::value, - "Integral type required in instantiation"); - } - - // Add and subtract operators - - T operator+(const T& aRhs) const - { - return T(mValue) += aRhs; - } - - T operator-(const T& aRhs) const - { - return T(mValue) -= aRhs; - } - - // Compound operators - - const T& operator+=(const T& aRhs) const - { - const T min = std::numeric_limits::min(); - const T max = std::numeric_limits::max(); - - if (aRhs > static_cast(0)) { - mValue = (max - aRhs) < mValue ? max : mValue + aRhs; - } else { - mValue = (min - aRhs) > mValue ? min : mValue + aRhs; - } - return mValue; - } - - const T& operator-=(const T& aRhs) const - { - const T min = std::numeric_limits::min(); - const T max = std::numeric_limits::max(); - - if (aRhs > static_cast(0)) { - mValue = (min + aRhs) > mValue ? min : mValue - aRhs; - } else { - mValue = (max + aRhs) < mValue ? max : mValue - aRhs; - } - return mValue; - } - - // Increment and decrement operators - - const T& operator++() const // prefix - { - return operator+=(static_cast(1)); - } - - T operator++(int) const // postfix - { - const T value(mValue); - operator++(); - return value; - } - - const T& operator--() const // prefix - { - return operator-=(static_cast(1)); - } - - T operator--(int) const // postfix - { - const T value(mValue); - operator--(); - return value; - } - -private: - SaturateOp(const SaturateOp&) = delete; - SaturateOp(SaturateOp&&) = delete; - SaturateOp& operator=(const SaturateOp&) = delete; - SaturateOp& operator=(SaturateOp&&) = delete; - - T& mValue; -}; - -/** - * |Saturate| is a value type for saturation arithmetics. It's - * build on top of |SaturateOp|. - */ -template -class Saturate -{ -public: - Saturate() = default; - MOZ_IMPLICIT Saturate(const Saturate&) = default; - - MOZ_IMPLICIT Saturate(Saturate&& aValue) - { - mValue = Move(aValue.mValue); - } - - explicit Saturate(const T& aValue) - : mValue(aValue) - { } - - const T& value() const - { - return mValue; - } - - // Compare operators - - bool operator==(const Saturate& aRhs) const - { - return mValue == aRhs.mValue; - } - - bool operator!=(const Saturate& aRhs) const - { - return !operator==(aRhs); - } - - bool operator==(const T& aRhs) const - { - return mValue == aRhs; - } - - bool operator!=(const T& aRhs) const - { - return !operator==(aRhs); - } - - // Assignment operators - - Saturate& operator=(const Saturate&) = default; - - Saturate& operator=(Saturate&& aRhs) - { - mValue = Move(aRhs.mValue); - return *this; - } - - // Add and subtract operators - - Saturate operator+(const Saturate& aRhs) const - { - Saturate lhs(mValue); - return lhs += aRhs.mValue; - } - - Saturate operator+(const T& aRhs) const - { - Saturate lhs(mValue); - return lhs += aRhs; - } - - Saturate operator-(const Saturate& aRhs) const - { - Saturate lhs(mValue); - return lhs -= aRhs.mValue; - } - - Saturate operator-(const T& aRhs) const - { - Saturate lhs(mValue); - return lhs -= aRhs; - } - - // Compound operators - - Saturate& operator+=(const Saturate& aRhs) - { - SaturateOp(mValue) += aRhs.mValue; - return *this; - } - - Saturate& operator+=(const T& aRhs) - { - SaturateOp(mValue) += aRhs; - return *this; - } - - Saturate& operator-=(const Saturate& aRhs) - { - SaturateOp(mValue) -= aRhs.mValue; - return *this; - } - - Saturate& operator-=(const T& aRhs) - { - SaturateOp(mValue) -= aRhs; - return *this; - } - - // Increment and decrement operators - - Saturate& operator++() // prefix - { - ++SaturateOp(mValue); - return *this; - } - - Saturate operator++(int) // postfix - { - return Saturate(SaturateOp(mValue)++); - } - - Saturate& operator--() // prefix - { - --SaturateOp(mValue); - return *this; - } - - Saturate operator--(int) // postfix - { - return Saturate(SaturateOp(mValue)--); - } - -private: - T mValue; -}; - -} // namespace detail - -typedef detail::Saturate SaturateInt8; -typedef detail::Saturate SaturateInt16; -typedef detail::Saturate SaturateInt32; -typedef detail::Saturate SaturateUint8; -typedef detail::Saturate SaturateUint16; -typedef detail::Saturate SaturateUint32; - -} // namespace mozilla - -template -bool -operator==(LhsT aLhs, const mozilla::detail::Saturate& aRhs) -{ - return aRhs.operator==(static_cast(aLhs)); -} - -template -bool -operator!=(LhsT aLhs, const mozilla::detail::Saturate& aRhs) -{ - return !(aLhs == aRhs); -} - -#endif // mozilla_Saturate_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/ScopeExit.h b/android/armeabi-v7a/include/spidermonkey/mozilla/ScopeExit.h deleted file mode 100644 index 7aff82d8..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/ScopeExit.h +++ /dev/null @@ -1,135 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* RAII class for executing arbitrary actions at scope end. */ - -#ifndef mozilla_ScopeExit_h -#define mozilla_ScopeExit_h - -/* - * See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4189.pdf for a - * standards-track version of this. - * - * Error handling can be complex when various actions need to be performed that - * need to be undone if an error occurs midway. This can be handled with a - * collection of boolean state variables and gotos, which can get clunky and - * error-prone: - * - * { - * if (!a.setup()) - * goto fail; - * isASetup = true; - * - * if (!b.setup()) - * goto fail; - * isBSetup = true; - * - * ... - * return true; - * - * fail: - * if (isASetup) - * a.teardown(); - * if (isBSetup) - * b.teardown(); - * return false; - * } - * - * ScopeExit is a mechanism to simplify this pattern by keeping an RAII guard - * class that will perform the teardown on destruction, unless released. So the - * above would become: - * - * { - * if (!a.setup()) { - * return false; - * } - * auto guardA = MakeScopeExit([&] { - * a.teardown(); - * }); - * - * if (!b.setup()) { - * return false; - * } - * auto guardB = MakeScopeExit([&] { - * b.teardown(); - * }); - * - * ... - * guardA.release(); - * guardB.release(); - * return true; - * } - * - * This header provides: - * - * - |ScopeExit| - a container for a cleanup call, automically called at the - * end of the scope; - * - |MakeScopeExit| - a convenience function for constructing a |ScopeExit| - * with a given cleanup routine, commonly used with a lambda function. - * - * Note that the RAII classes defined in this header do _not_ perform any form - * of reference-counting or garbage-collection. These classes have exactly two - * behaviors: - * - * - if |release()| has not been called, the cleanup is always performed at - * the end of the scope; - * - if |release()| has been called, nothing will happen at the end of the - * scope. - */ - -#include "mozilla/GuardObjects.h" -#include "mozilla/Move.h" - -namespace mozilla { - -template -class MOZ_STACK_CLASS ScopeExit { - ExitFunction mExitFunction; - bool mExecuteOnDestruction; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - -public: - explicit ScopeExit(ExitFunction&& cleanup - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mExitFunction(cleanup) - , mExecuteOnDestruction(true) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - ScopeExit(ScopeExit&& rhs) - : mExitFunction(mozilla::Move(rhs.mExitFunction)) - , mExecuteOnDestruction(rhs.mExecuteOnDestruction) - { - rhs.release(); - } - - ~ScopeExit() { - if (mExecuteOnDestruction) { - mExitFunction(); - } - } - - void release() { - mExecuteOnDestruction = false; - } - -private: - explicit ScopeExit(const ScopeExit&) = delete; - ScopeExit& operator=(const ScopeExit&) = delete; - ScopeExit& operator=(ScopeExit&&) = delete; -}; - -template -ScopeExit -MakeScopeExit(ExitFunction&& exitFunction) -{ - return ScopeExit(mozilla::Move(exitFunction)); -} - -} /* namespace mozilla */ - -#endif /* mozilla_ScopeExit_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Scoped.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Scoped.h deleted file mode 100644 index c935434a..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Scoped.h +++ /dev/null @@ -1,255 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* DEPRECATED: Use UniquePtr.h instead. */ - -#ifndef mozilla_Scoped_h -#define mozilla_Scoped_h - -/* - * DEPRECATED: Use UniquePtr.h instead. - * - * Resource Acquisition Is Initialization is a programming idiom used - * to write robust code that is able to deallocate resources properly, - * even in presence of execution errors or exceptions that need to be - * propagated. The Scoped* classes defined via the |SCOPED_TEMPLATE| - * and |MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLTE| macros perform the - * deallocation of the resource they hold once program execution - * reaches the end of the scope for which they have been defined. - * These macros have been used to automatically close file - * descriptors/file handles when reaching the end of the scope, - * graphics contexts, etc. - * - * The general scenario for RAII classes created by the above macros - * is the following: - * - * ScopedClass foo(create_value()); - * // ... In this scope, |foo| is defined. Use |foo.get()| or |foo.rwget()| - * to access the value. - * // ... In case of |return| or |throw|, |foo| is deallocated automatically. - * // ... If |foo| needs to be returned or stored, use |foo.forget()| - * - * Note that the RAII classes defined in this header do _not_ perform any form - * of reference-counting or garbage-collection. These classes have exactly two - * behaviors: - * - * - if |forget()| has not been called, the resource is always deallocated at - * the end of the scope; - * - if |forget()| has been called, any control on the resource is unbound - * and the resource is not deallocated by the class. - */ - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/GuardObjects.h" -#include "mozilla/Move.h" - -namespace mozilla { - -/* - * Scoped is a helper to create RAII wrappers - * Type argument |Traits| is expected to have the following structure: - * - * struct Traits - * { - * // Define the type of the value stored in the wrapper - * typedef value_type type; - * // Returns the value corresponding to the uninitialized or freed state - * const static type empty(); - * // Release resources corresponding to the wrapped value - * // This function is responsible for not releasing an |empty| value - * const static void release(type); - * } - */ -template -class MOZ_NON_TEMPORARY_CLASS Scoped -{ -public: - typedef typename Traits::type Resource; - - explicit Scoped(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) - : mValue(Traits::empty()) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - explicit Scoped(const Resource& aValue - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mValue(aValue) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - /* Move constructor. */ - Scoped(Scoped&& aOther - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mValue(Move(aOther.mValue)) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - aOther.mValue = Traits::empty(); - } - - ~Scoped() { Traits::release(mValue); } - - // Constant getter - operator const Resource&() const { return mValue; } - const Resource& operator->() const { return mValue; } - const Resource& get() const { return mValue; } - // Non-constant getter. - Resource& rwget() { return mValue; } - - /* - * Forget the resource. - * - * Once |forget| has been called, the |Scoped| is neutralized, i.e. it will - * have no effect at destruction (unless it is reset to another resource by - * |operator=|). - * - * @return The original resource. - */ - Resource forget() - { - Resource tmp = mValue; - mValue = Traits::empty(); - return tmp; - } - - /* - * Perform immediate clean-up of this |Scoped|. - * - * If this |Scoped| is currently empty, this method has no effect. - */ - void dispose() - { - Traits::release(mValue); - mValue = Traits::empty(); - } - - bool operator==(const Resource& aOther) const { return mValue == aOther; } - - /* - * Replace the resource with another resource. - * - * Calling |operator=| has the side-effect of triggering clean-up. If you do - * not want to trigger clean-up, you should first invoke |forget|. - * - * @return this - */ - Scoped& operator=(const Resource& aOther) { return reset(aOther); } - - Scoped& reset(const Resource& aOther) - { - Traits::release(mValue); - mValue = aOther; - return *this; - } - - /* Move assignment operator. */ - Scoped& operator=(Scoped&& aRhs) - { - MOZ_ASSERT(&aRhs != this, "self-move-assignment not allowed"); - this->~Scoped(); - new(this) Scoped(Move(aRhs)); - return *this; - } - -private: - explicit Scoped(const Scoped& aValue) = delete; - Scoped& operator=(const Scoped& aValue) = delete; - -private: - Resource mValue; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -/* - * SCOPED_TEMPLATE defines a templated class derived from Scoped - * This allows to implement templates such as ScopedFreePtr. - * - * @param name The name of the class to define. - * @param Traits A struct implementing clean-up. See the implementations - * for more details. - */ -#define SCOPED_TEMPLATE(name, Traits) \ -template \ -struct MOZ_NON_TEMPORARY_CLASS name : public mozilla::Scoped > \ -{ \ - typedef mozilla::Scoped > Super; \ - typedef typename Super::Resource Resource; \ - name& operator=(Resource aRhs) \ - { \ - Super::operator=(aRhs); \ - return *this; \ - } \ - name& operator=(name&& aRhs) \ - { \ - Super::operator=(Move(aRhs)); \ - return *this; \ - } \ - explicit name(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) \ - : Super(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT) \ - {} \ - explicit name(Resource aRhs \ - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \ - : Super(aRhs \ - MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \ - {} \ - name(name&& aRhs \ - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \ - : Super(Move(aRhs) \ - MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \ - {} \ -private: \ - explicit name(name&) = delete; \ - name& operator=(name&) = delete; \ -}; - -/* - * MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE makes it easy to create scoped - * pointers for types with custom deleters; just overload - * TypeSpecificDelete(T*) in the same namespace as T to call the deleter for - * type T. - * - * @param name The name of the class to define. - * @param Type A struct implementing clean-up. See the implementations - * for more details. - * *param Deleter The function that is used to delete/destroy/free a - * non-null value of Type*. - * - * Example: - * - * MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRFileDesc, PRFileDesc, \ - * PR_Close) - * ... - * { - * ScopedPRFileDesc file(PR_OpenFile(...)); - * ... - * } // file is closed with PR_Close here - */ -#define MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(name, Type, Deleter) \ -template <> inline void TypeSpecificDelete(Type* aValue) { Deleter(aValue); } \ -typedef ::mozilla::TypeSpecificScopedPointer name; - -template void TypeSpecificDelete(T* aValue); - -template -struct TypeSpecificScopedPointerTraits -{ - typedef T* type; - static type empty() { return nullptr; } - static void release(type aValue) - { - if (aValue) { - TypeSpecificDelete(aValue); - } - } -}; - -SCOPED_TEMPLATE(TypeSpecificScopedPointer, TypeSpecificScopedPointerTraits) - -} /* namespace mozilla */ - -#endif /* mozilla_Scoped_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/SegmentedVector.h b/android/armeabi-v7a/include/spidermonkey/mozilla/SegmentedVector.h deleted file mode 100644 index 1bf60e46..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/SegmentedVector.h +++ /dev/null @@ -1,339 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -// A simple segmented vector class. -// -// This class should be used in preference to mozilla::Vector or nsTArray when -// you are simply gathering items in order to later iterate over them. -// -// - In the case where you don't know the final size in advance, using -// SegmentedVector avoids the need to repeatedly allocate increasingly large -// buffers and copy the data into them. -// -// - In the case where you know the final size in advance and so can set the -// capacity appropriately, using SegmentedVector still avoids the need for -// large allocations (which can trigger OOMs). - -#ifndef mozilla_SegmentedVector_h -#define mozilla_SegmentedVector_h - -#include "mozilla/Alignment.h" -#include "mozilla/AllocPolicy.h" -#include "mozilla/Array.h" -#include "mozilla/LinkedList.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -#include // for placement new - -namespace mozilla { - -// |IdealSegmentSize| specifies how big each segment will be in bytes (or as -// close as is possible). Use the following guidelines to choose a size. -// -// - It should be a power-of-two, to avoid slop. -// -// - It should not be too small, so that segment allocations are infrequent, -// and so that per-segment bookkeeping overhead is low. Typically each -// segment should be able to hold hundreds of elements, at least. -// -// - It should not be too large, so that OOMs are unlikely when allocating -// segments, and so that not too much space is wasted when the final segment -// is not full. -// -// The ideal size depends on how the SegmentedVector is used and the size of -// |T|, but reasonable sizes include 1024, 4096 (the default), 8192, and 16384. -// -template -class SegmentedVector : private AllocPolicy -{ - template - struct SegmentImpl - : public mozilla::LinkedListElement> - { - SegmentImpl() : mLength(0) {} - - ~SegmentImpl() - { - for (uint32_t i = 0; i < mLength; i++) { - (*this)[i].~T(); - } - } - - uint32_t Length() const { return mLength; } - - T* Elems() { return reinterpret_cast(&mStorage.mBuf); } - - T& operator[](size_t aIndex) - { - MOZ_ASSERT(aIndex < mLength); - return Elems()[aIndex]; - } - - const T& operator[](size_t aIndex) const - { - MOZ_ASSERT(aIndex < mLength); - return Elems()[aIndex]; - } - - template - void Append(U&& aU) - { - MOZ_ASSERT(mLength < SegmentCapacity); - // Pre-increment mLength so that the bounds-check in operator[] passes. - mLength++; - T* elem = &(*this)[mLength - 1]; - new (elem) T(mozilla::Forward(aU)); - } - - void PopLast() - { - MOZ_ASSERT(mLength > 0); - (*this)[mLength - 1].~T(); - mLength--; - } - - uint32_t mLength; - - // The union ensures that the elements are appropriately aligned. - union Storage - { - char mBuf[sizeof(T) * SegmentCapacity]; - mozilla::AlignedElem mAlign; - } mStorage; - - static_assert(MOZ_ALIGNOF(T) == MOZ_ALIGNOF(Storage), - "SegmentedVector provides incorrect alignment"); - }; - - // See how many we elements we can fit in a segment of IdealSegmentSize. If - // IdealSegmentSize is too small, it'll be just one. The +1 is because - // kSingleElementSegmentSize already accounts for one element. - static const size_t kSingleElementSegmentSize = sizeof(SegmentImpl<1>); - static const size_t kSegmentCapacity = - kSingleElementSegmentSize <= IdealSegmentSize - ? (IdealSegmentSize - kSingleElementSegmentSize) / sizeof(T) + 1 - : 1; - - typedef SegmentImpl Segment; - -public: - // The |aIdealSegmentSize| is only for sanity checking. If it's specified, we - // check that the actual segment size is as close as possible to it. This - // serves as a sanity check for SegmentedVectorCapacity's capacity - // computation. - explicit SegmentedVector(size_t aIdealSegmentSize = 0) - { - // The difference between the actual segment size and the ideal segment - // size should be less than the size of a single element... unless the - // ideal size was too small, in which case the capacity should be one. - MOZ_ASSERT_IF( - aIdealSegmentSize != 0, - (sizeof(Segment) > aIdealSegmentSize && kSegmentCapacity == 1) || - aIdealSegmentSize - sizeof(Segment) < sizeof(T)); - } - - ~SegmentedVector() { Clear(); } - - bool IsEmpty() const { return !mSegments.getFirst(); } - - // Note that this is O(n) rather than O(1), but the constant factor is very - // small because it only has to do one addition per segment. - size_t Length() const - { - size_t n = 0; - for (auto segment = mSegments.getFirst(); - segment; - segment = segment->getNext()) { - n += segment->Length(); - } - return n; - } - - // Returns false if the allocation failed. (If you are using an infallible - // allocation policy, use InfallibleAppend() instead.) - template - MOZ_MUST_USE bool Append(U&& aU) - { - Segment* last = mSegments.getLast(); - if (!last || last->Length() == kSegmentCapacity) { - last = this->template pod_malloc(1); - if (!last) { - return false; - } - new (last) Segment(); - mSegments.insertBack(last); - } - last->Append(mozilla::Forward(aU)); - return true; - } - - // You should probably only use this instead of Append() if you are using an - // infallible allocation policy. It will crash if the allocation fails. - template - void InfallibleAppend(U&& aU) - { - bool ok = Append(mozilla::Forward(aU)); - MOZ_RELEASE_ASSERT(ok); - } - - void Clear() - { - Segment* segment; - while ((segment = mSegments.popFirst())) { - segment->~Segment(); - this->free_(segment); - } - } - - T& GetLast() - { - MOZ_ASSERT(!IsEmpty()); - Segment* last = mSegments.getLast(); - return (*last)[last->Length() - 1]; - } - - const T& GetLast() const - { - MOZ_ASSERT(!IsEmpty()); - Segment* last = mSegments.getLast(); - return (*last)[last->Length() - 1]; - } - - void PopLast() - { - MOZ_ASSERT(!IsEmpty()); - Segment* last = mSegments.getLast(); - last->PopLast(); - if (!last->Length()) { - mSegments.popLast(); - last->~Segment(); - this->free_(last); - } - } - - // Equivalent to calling |PopLast| |aNumElements| times, but potentially - // more efficient. - void PopLastN(uint32_t aNumElements) - { - MOZ_ASSERT(aNumElements <= Length()); - - Segment* last; - - // Pop full segments for as long as we can. Note that this loop - // cleanly handles the case when the initial last segment is not - // full and we are popping more elements than said segment contains. - do { - last = mSegments.getLast(); - - // The list is empty. We're all done. - if (!last) { - return; - } - - // Check to see if the list contains too many elements. Handle - // that in the epilogue. - uint32_t segmentLen = last->Length(); - if (segmentLen > aNumElements) { - break; - } - - // Destroying the segment destroys all elements contained therein. - mSegments.popLast(); - last->~Segment(); - this->free_(last); - - MOZ_ASSERT(aNumElements >= segmentLen); - aNumElements -= segmentLen; - if (aNumElements == 0) { - return; - } - } while (true); - - // Handle the case where the last segment contains more elements - // than we want to pop. - MOZ_ASSERT(last); - MOZ_ASSERT(last == mSegments.getLast()); - MOZ_ASSERT(aNumElements != 0); - MOZ_ASSERT(aNumElements < last->Length()); - for (uint32_t i = 0; i < aNumElements; ++i) { - last->PopLast(); - } - MOZ_ASSERT(last->Length() != 0); - } - - // Use this class to iterate over a SegmentedVector, like so: - // - // for (auto iter = v.Iter(); !iter.Done(); iter.Next()) { - // MyElem& elem = iter.Get(); - // f(elem); - // } - // - class IterImpl - { - friend class SegmentedVector; - - Segment* mSegment; - size_t mIndex; - - explicit IterImpl(SegmentedVector* aVector) - : mSegment(aVector->mSegments.getFirst()) - , mIndex(0) - {} - - public: - bool Done() const { return !mSegment; } - - T& Get() - { - MOZ_ASSERT(!Done()); - return (*mSegment)[mIndex]; - } - - const T& Get() const - { - MOZ_ASSERT(!Done()); - return (*mSegment)[mIndex]; - } - - void Next() - { - MOZ_ASSERT(!Done()); - mIndex++; - if (mIndex == mSegment->Length()) { - mSegment = mSegment->getNext(); - mIndex = 0; - } - } - }; - - IterImpl Iter() { return IterImpl(this); } - - // Measure the memory consumption of the vector excluding |this|. Note that - // it only measures the vector itself. If the vector elements contain - // pointers to other memory blocks, those blocks must be measured separately - // during a subsequent iteration over the vector. - size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const - { - return mSegments.sizeOfExcludingThis(aMallocSizeOf); - } - - // Like sizeOfExcludingThis(), but measures |this| as well. - size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const - { - return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); - } - -private: - mozilla::LinkedList mSegments; -}; - -} // namespace mozilla - -#endif /* mozilla_SegmentedVector_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/SizePrintfMacros.h b/android/armeabi-v7a/include/spidermonkey/mozilla/SizePrintfMacros.h deleted file mode 100644 index ec55c62c..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/SizePrintfMacros.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implements (nonstandard) PRI{ouxX}SIZE format macros for size_t types. */ - -#ifndef mozilla_SizePrintfMacros_h_ -#define mozilla_SizePrintfMacros_h_ - -/* - * MSVC's libc does not support C99's %z format length modifier for size_t - * types. Instead, we use Microsoft's nonstandard %I modifier for size_t, which - * is unsigned __int32 on 32-bit platforms and unsigned __int64 on 64-bit - * platforms: - * - * http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx - */ - -#if defined(XP_WIN) -# define PRIoSIZE "Io" -# define PRIuSIZE "Iu" -# define PRIxSIZE "Ix" -# define PRIXSIZE "IX" -#else -# define PRIoSIZE "zo" -# define PRIuSIZE "zu" -# define PRIxSIZE "zx" -# define PRIXSIZE "zX" -#endif - -#endif /* mozilla_SizePrintfMacros_h_ */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/SplayTree.h b/android/armeabi-v7a/include/spidermonkey/mozilla/SplayTree.h deleted file mode 100644 index 2b3b838b..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/SplayTree.h +++ /dev/null @@ -1,330 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/** - * A sorted tree with optimal access times, where recently-accessed elements - * are faster to access again. - */ - -#ifndef mozilla_SplayTree_h -#define mozilla_SplayTree_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -namespace mozilla { - -template -class SplayTree; - -template -class SplayTreeNode -{ -public: - template - friend class SplayTree; - - SplayTreeNode() - : mLeft(nullptr) - , mRight(nullptr) - , mParent(nullptr) - {} - -private: - T* mLeft; - T* mRight; - T* mParent; -}; - - -/** - * Class which represents a splay tree. - * Splay trees are balanced binary search trees for which search, insert and - * remove are all amortized O(log n), but where accessing a node makes it - * faster to access that node in the future. - * - * T indicates the type of tree elements, Comparator must have a static - * compare(const T&, const T&) method ordering the elements. The compare - * method must be free from side effects. - */ -template -class SplayTree -{ - T* mRoot; - -public: - constexpr SplayTree() - : mRoot(nullptr) - {} - - bool empty() const - { - return !mRoot; - } - - T* find(const T& aValue) - { - if (empty()) { - return nullptr; - } - - T* last = lookup(aValue); - splay(last); - return Comparator::compare(aValue, *last) == 0 ? last : nullptr; - } - - void insert(T* aValue) - { - MOZ_ASSERT(!find(*aValue), "Duplicate elements are not allowed."); - - if (!mRoot) { - mRoot = aValue; - return; - } - T* last = lookup(*aValue); - int cmp = Comparator::compare(*aValue, *last); - - finishInsertion(last, cmp, aValue); - return; - } - - T* findOrInsert(const T& aValue); - - T* remove(const T& aValue) - { - T* last = lookup(aValue); - MOZ_ASSERT(last, "This tree must contain the element being removed."); - MOZ_ASSERT(Comparator::compare(aValue, *last) == 0); - - // Splay the tree so that the item to remove is the root. - splay(last); - MOZ_ASSERT(last == mRoot); - - // Find another node which can be swapped in for the root: either the - // rightmost child of the root's left, or the leftmost child of the - // root's right. - T* swap; - T* swapChild; - if (mRoot->mLeft) { - swap = mRoot->mLeft; - while (swap->mRight) { - swap = swap->mRight; - } - swapChild = swap->mLeft; - } else if (mRoot->mRight) { - swap = mRoot->mRight; - while (swap->mLeft) { - swap = swap->mLeft; - } - swapChild = swap->mRight; - } else { - T* result = mRoot; - mRoot = nullptr; - return result; - } - - // The selected node has at most one child, in swapChild. Detach it - // from the subtree by replacing it with that child. - if (swap == swap->mParent->mLeft) { - swap->mParent->mLeft = swapChild; - } else { - swap->mParent->mRight = swapChild; - } - if (swapChild) { - swapChild->mParent = swap->mParent; - } - - // Make the selected node the new root. - mRoot = swap; - mRoot->mParent = nullptr; - mRoot->mLeft = last->mLeft; - mRoot->mRight = last->mRight; - if (mRoot->mLeft) { - mRoot->mLeft->mParent = mRoot; - } - if (mRoot->mRight) { - mRoot->mRight->mParent = mRoot; - } - - return last; - } - - T* removeMin() - { - MOZ_ASSERT(mRoot, "No min to remove!"); - - T* min = mRoot; - while (min->mLeft) { - min = min->mLeft; - } - return remove(*min); - } - - // For testing purposes only. - void checkCoherency() - { - checkCoherency(mRoot, nullptr); - } - -private: - /** - * Returns the node in this comparing equal to |aValue|, or a node just - * greater or just less than |aValue| if there is no such node. - */ - T* lookup(const T& aValue) - { - MOZ_ASSERT(!empty()); - - T* node = mRoot; - T* parent; - do { - parent = node; - int c = Comparator::compare(aValue, *node); - if (c == 0) { - return node; - } else if (c < 0) { - node = node->mLeft; - } else { - node = node->mRight; - } - } while (node); - return parent; - } - - void finishInsertion(T* aLast, int32_t aCmp, T* aNew) - { - MOZ_ASSERT(aCmp, "Nodes shouldn't be equal!"); - - T** parentPointer = (aCmp < 0) ? &aLast->mLeft : &aLast->mRight; - MOZ_ASSERT(!*parentPointer); - *parentPointer = aNew; - aNew->mParent = aLast; - - splay(aNew); - } - - /** - * Rotate the tree until |node| is at the root of the tree. Performing - * the rotations in this fashion preserves the amortized balancing of - * the tree. - */ - void splay(T* aNode) - { - MOZ_ASSERT(aNode); - - while (aNode != mRoot) { - T* parent = aNode->mParent; - if (parent == mRoot) { - // Zig rotation. - rotate(aNode); - MOZ_ASSERT(aNode == mRoot); - return; - } - T* grandparent = parent->mParent; - if ((parent->mLeft == aNode) == (grandparent->mLeft == parent)) { - // Zig-zig rotation. - rotate(parent); - rotate(aNode); - } else { - // Zig-zag rotation. - rotate(aNode); - rotate(aNode); - } - } - } - - void rotate(T* aNode) - { - // Rearrange nodes so that aNode becomes the parent of its current - // parent, while preserving the sortedness of the tree. - T* parent = aNode->mParent; - if (parent->mLeft == aNode) { - // x y - // y c ==> a x - // a b b c - parent->mLeft = aNode->mRight; - if (aNode->mRight) { - aNode->mRight->mParent = parent; - } - aNode->mRight = parent; - } else { - MOZ_ASSERT(parent->mRight == aNode); - // x y - // a y ==> x c - // b c a b - parent->mRight = aNode->mLeft; - if (aNode->mLeft) { - aNode->mLeft->mParent = parent; - } - aNode->mLeft = parent; - } - aNode->mParent = parent->mParent; - parent->mParent = aNode; - if (T* grandparent = aNode->mParent) { - if (grandparent->mLeft == parent) { - grandparent->mLeft = aNode; - } else { - grandparent->mRight = aNode; - } - } else { - mRoot = aNode; - } - } - - T* checkCoherency(T* aNode, T* aMinimum) - { - if (mRoot) { - MOZ_RELEASE_ASSERT(!mRoot->mParent); - } - if (!aNode) { - MOZ_RELEASE_ASSERT(!mRoot); - return nullptr; - } - if (!aNode->mParent) { - MOZ_RELEASE_ASSERT(aNode == mRoot); - } - if (aMinimum) { - MOZ_RELEASE_ASSERT(Comparator::compare(*aMinimum, *aNode) < 0); - } - if (aNode->mLeft) { - MOZ_RELEASE_ASSERT(aNode->mLeft->mParent == aNode); - T* leftMaximum = checkCoherency(aNode->mLeft, aMinimum); - MOZ_RELEASE_ASSERT(Comparator::compare(*leftMaximum, *aNode) < 0); - } - if (aNode->mRight) { - MOZ_RELEASE_ASSERT(aNode->mRight->mParent == aNode); - return checkCoherency(aNode->mRight, aNode); - } - return aNode; - } - - SplayTree(const SplayTree&) = delete; - void operator=(const SplayTree&) = delete; -}; - -template -T* -SplayTree::findOrInsert(const T& aValue) -{ - if (!mRoot) { - mRoot = new T(aValue); - return mRoot; - } - - T* last = lookup(aValue); - int cmp = Comparator::compare(aValue, *last); - if (!cmp) { - return last; - } - - T* t = new T(aValue); - finishInsertion(last, cmp, t); - return t; -} - -} /* namespace mozilla */ - -#endif /* mozilla_SplayTree_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Sprintf.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Sprintf.h deleted file mode 100644 index e0be271e..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Sprintf.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Provides a safer sprintf for printing to fixed-size character arrays. */ - -#ifndef mozilla_Sprintf_h_ -#define mozilla_Sprintf_h_ - -#include -#include - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -#ifdef __cplusplus - -template -int VsprintfLiteral(char (&buffer)[N], const char* format, va_list args) -{ - MOZ_ASSERT(format != buffer); - int result = vsnprintf(buffer, N, format, args); - buffer[N - 1] = '\0'; - return result; -} - -template -MOZ_FORMAT_PRINTF(2, 3) -int SprintfLiteral(char (&buffer)[N], const char* format, ...) -{ - va_list args; - va_start(args, format); - int result = VsprintfLiteral(buffer, format, args); - va_end(args); - return result; -} - -#endif -#endif /* mozilla_Sprintf_h_ */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/StackWalk.h b/android/armeabi-v7a/include/spidermonkey/mozilla/StackWalk.h deleted file mode 100644 index 534c0bd8..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/StackWalk.h +++ /dev/null @@ -1,163 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* API for getting a stack trace of the C/C++ stack on the current thread */ - -#ifndef mozilla_StackWalk_h -#define mozilla_StackWalk_h - -/* WARNING: This file is intended to be included from C or C++ files. */ - -#include "mozilla/Types.h" -#include - -/** - * The callback for MozStackWalk. - * - * @param aFrameNumber The frame number (starts at 1, not 0). - * @param aPC The program counter value. - * @param aSP The best approximation possible of what the stack - * pointer will be pointing to when the execution returns - * to executing that at aPC. If no approximation can - * be made it will be nullptr. - * @param aClosure Extra data passed in via MozStackWalk(). - */ -typedef void -(*MozWalkStackCallback)(uint32_t aFrameNumber, void* aPC, void* aSP, - void* aClosure); - -/** - * Call aCallback for the C/C++ stack frames on the current thread, from - * the caller of MozStackWalk to main (or above). - * - * @param aCallback Callback function, called once per frame. - * @param aSkipFrames Number of initial frames to skip. 0 means that - * the first callback will be for the caller of - * MozStackWalk. - * @param aMaxFrames Maximum number of frames to trace. 0 means no limit. - * @param aClosure Caller-supplied data passed through to aCallback. - * @param aThread The thread for which the stack is to be retrieved. - * Passing null causes us to walk the stack of the - * current thread. On Windows, this is a thread HANDLE. - * It is currently not supported on any other platform. - * @param aPlatformData Platform specific data that can help in walking the - * stack, this should be nullptr unless you really know - * what you're doing! This needs to be a pointer to a - * CONTEXT on Windows and should not be passed on other - * platforms. - * - * May skip some stack frames due to compiler optimizations or code - * generation. - * - */ -MFBT_API bool -MozStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames, - uint32_t aMaxFrames, void* aClosure, uintptr_t aThread, - void* aPlatformData); - -typedef struct -{ - /* - * The name of the shared library or executable containing an - * address and the address's offset within that library, or empty - * string and zero if unknown. - */ - char library[256]; - ptrdiff_t loffset; - /* - * The name of the file name and line number of the code - * corresponding to the address, or empty string and zero if - * unknown. - */ - char filename[256]; - unsigned long lineno; - /* - * The name of the function containing an address and the address's - * offset within that function, or empty string and zero if unknown. - */ - char function[256]; - ptrdiff_t foffset; -} MozCodeAddressDetails; - -/** - * For a given pointer to code, fill in the pieces of information used - * when printing a stack trace. - * - * @param aPC The code address. - * @param aDetails A structure to be filled in with the result. - */ -MFBT_API bool -MozDescribeCodeAddress(void* aPC, MozCodeAddressDetails* aDetails); - -/** - * Format the information about a code address in a format suitable for - * stack traces on the current platform. When available, this string - * should contain the function name, source file, and line number. When - * these are not available, library and offset should be reported, if - * possible. - * - * Note that this output is parsed by several scripts including the fix*.py and - * make-tree.pl scripts in tools/rb/. It should only be change with care, and - * in conjunction with those scripts. - * - * @param aBuffer A string to be filled in with the description. - * The string will always be null-terminated. - * @param aBufferSize The size, in bytes, of aBuffer, including - * room for the terminating null. If the information - * to be printed would be larger than aBuffer, it - * will be truncated so that aBuffer[aBufferSize-1] - * is the terminating null. - * @param aFrameNumber The frame number. - * @param aPC The code address. - * @param aFunction The function name. Possibly null or the empty string. - * @param aLibrary The library name. Possibly null or the empty string. - * @param aLOffset The library offset. - * @param aFileName The filename. Possibly null or the empty string. - * @param aLineNo The line number. Possibly zero. - */ -MFBT_API void -MozFormatCodeAddress(char* aBuffer, uint32_t aBufferSize, uint32_t aFrameNumber, - const void* aPC, const char* aFunction, - const char* aLibrary, ptrdiff_t aLOffset, - const char* aFileName, uint32_t aLineNo); - -/** - * Format the information about a code address in the same fashion as - * MozFormatCodeAddress. - * - * @param aBuffer A string to be filled in with the description. - * The string will always be null-terminated. - * @param aBufferSize The size, in bytes, of aBuffer, including - * room for the terminating null. If the information - * to be printed would be larger than aBuffer, it - * will be truncated so that aBuffer[aBufferSize-1] - * is the terminating null. - * @param aFrameNumber The frame number. - * @param aPC The code address. - * @param aDetails The value filled in by MozDescribeCodeAddress(aPC). - */ -MFBT_API void -MozFormatCodeAddressDetails(char* aBuffer, uint32_t aBufferSize, - uint32_t aFrameNumber, void* aPC, - const MozCodeAddressDetails* aDetails); - -namespace mozilla { - -MFBT_API bool -FramePointerStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames, - uint32_t aMaxFrames, void* aClosure, void** aBp, - void* aStackEnd); - -} // namespace mozilla - -/** - * Initialize the critical sections for this platform so that we can - * abort stack walks when needed. - */ -MFBT_API void -StackWalkInitCriticalAddress(void); - -#endif diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/StaticAnalysisFunctions.h b/android/armeabi-v7a/include/spidermonkey/mozilla/StaticAnalysisFunctions.h deleted file mode 100644 index a06809dc..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/StaticAnalysisFunctions.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_StaticAnalysisFunctions_h -#define mozilla_StaticAnalysisFunctions_h - -#ifndef __cplusplus -#ifndef bool -#include -#endif -#endif -/* - * Functions that are used as markers in Gecko code for static analysis. Their - * purpose is to have different AST nodes generated during compile time and to - * match them based on different checkers implemented in build/clang-plugin - */ - -#ifdef MOZ_CLANG_PLUGIN - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * MOZ_AssertAssignmentTest - used in MOZ_ASSERT in order to test the possible - * presence of assignment instead of logical comparisons. - * - * Example: - * MOZ_ASSERT(retVal = true); - */ -static MOZ_ALWAYS_INLINE bool MOZ_AssertAssignmentTest(bool exprResult) { - return exprResult; -} - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#define MOZ_CHECK_ASSERT_ASSIGNMENT(expr) MOZ_AssertAssignmentTest(!!(expr)) - -#else - -#define MOZ_CHECK_ASSERT_ASSIGNMENT(expr) (!!(expr)) - -#endif /* MOZ_CLANG_PLUGIN */ -#endif /* StaticAnalysisFunctions_h */ \ No newline at end of file diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/TaggedAnonymousMemory.h b/android/armeabi-v7a/include/spidermonkey/mozilla/TaggedAnonymousMemory.h deleted file mode 100644 index d26b06df..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/TaggedAnonymousMemory.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -// Some Linux kernels -- specifically, newer versions of Android and -// some B2G devices -- have a feature for assigning names to ranges of -// anonymous memory (i.e., memory that doesn't have a "name" in the -// form of an underlying mapped file). These names are reported in -// /proc//smaps alongside system-level memory usage information -// such as Proportional Set Size (memory usage adjusted for sharing -// between processes), which allows reporting this information at a -// finer granularity than would otherwise be possible (e.g., -// separating malloc() heap from JS heap). -// -// Existing memory can be tagged with MozTagAnonymousMemory(); it will -// tag the range of complete pages containing the given interval, so -// the results may be inexact if the range isn't page-aligned. -// MozTaggedAnonymousMmap() can be used like mmap() with an extra -// parameter, and will tag the returned memory if the mapping was -// successful (and if it was in fact anonymous). -// -// NOTE: The pointer given as the "tag" argument MUST remain valid as -// long as the mapping exists. The referenced string is read when -// /proc//smaps or /proc//maps is read, not when the tag is -// established, so freeing it or changing its contents will have -// unexpected results. Using a static string is probably best. -// -// Also note that this header can be used by both C and C++ code. - -#ifndef mozilla_TaggedAnonymousMemory_h -#define mozilla_TaggedAnonymousMemory_h - -#ifndef XP_WIN - -#include -#include - -#include "mozilla/Types.h" - -#ifdef ANDROID - -#ifdef __cplusplus -extern "C" { -#endif - -MFBT_API void -MozTagAnonymousMemory(const void* aPtr, size_t aLength, const char* aTag); - -MFBT_API void* -MozTaggedAnonymousMmap(void* aAddr, size_t aLength, int aProt, int aFlags, - int aFd, off_t aOffset, const char* aTag); - -MFBT_API int -MozTaggedMemoryIsSupported(void); - -#ifdef __cplusplus -} // extern "C" -#endif - -#else // ANDROID - -static inline void -MozTagAnonymousMemory(const void* aPtr, size_t aLength, const char* aTag) -{ -} - -static inline void* -MozTaggedAnonymousMmap(void* aAddr, size_t aLength, int aProt, int aFlags, - int aFd, off_t aOffset, const char* aTag) -{ - return mmap(aAddr, aLength, aProt, aFlags, aFd, aOffset); -} - -static inline int -MozTaggedMemoryIsSupported(void) -{ - return 0; -} - -#endif // ANDROID - -#endif // !XP_WIN - -#endif // mozilla_TaggedAnonymousMemory_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/TemplateLib.h b/android/armeabi-v7a/include/spidermonkey/mozilla/TemplateLib.h deleted file mode 100644 index 6286452d..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/TemplateLib.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Reusable template meta-functions on types and compile-time values. Meta- - * functions are placed inside the 'tl' namespace to avoid conflict with non- - * meta functions of the same name (e.g., mozilla::tl::FloorLog2 vs. - * mozilla::FloorLog2). - * - * When constexpr support becomes universal, we should probably use that instead - * of some of these templates, for simplicity. - */ - -#ifndef mozilla_TemplateLib_h -#define mozilla_TemplateLib_h - -#include -#include - -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -namespace tl { - -/** Compute min/max. */ -template -struct Min -{ - static const size_t value = I < J ? I : J; -}; -template -struct Max -{ - static const size_t value = I > J ? I : J; -}; - -/** Compute floor(log2(i)). */ -template -struct FloorLog2 -{ - static const size_t value = 1 + FloorLog2::value; -}; -template<> struct FloorLog2<0> { /* Error */ }; -template<> struct FloorLog2<1> { static const size_t value = 0; }; - -/** Compute ceiling(log2(i)). */ -template -struct CeilingLog2 -{ - static const size_t value = FloorLog2<2 * I - 1>::value; -}; - -/** Round up to the nearest power of 2. */ -template -struct RoundUpPow2 -{ - static const size_t value = size_t(1) << CeilingLog2::value; -}; -template<> -struct RoundUpPow2<0> -{ - static const size_t value = 1; -}; - -/** Compute the number of bits in the given unsigned type. */ -template -struct BitSize -{ - static const size_t value = sizeof(T) * CHAR_BIT; -}; - -/** - * Produce an N-bit mask, where N <= BitSize::value. Handle the - * language-undefined edge case when N = BitSize::value. - */ -template -struct NBitMask -{ - // Assert the precondition. On success this evaluates to 0. Otherwise it - // triggers divide-by-zero at compile time: a guaranteed compile error in - // C++11, and usually one in C++98. Add this value to |value| to assure - // its computation. - static const size_t checkPrecondition = - 0 / size_t(N < BitSize::value); - static const size_t value = (size_t(1) << N) - 1 + checkPrecondition; -}; -template<> -struct NBitMask::value> -{ - static const size_t value = size_t(-1); -}; - -/** - * For the unsigned integral type size_t, compute a mask M for N such that - * for all X, !(X & M) implies X * N will not overflow (w.r.t size_t) - */ -template -struct MulOverflowMask -{ - static const size_t value = - ~NBitMask::value - CeilingLog2::value>::value; -}; -template<> struct MulOverflowMask<0> { /* Error */ }; -template<> struct MulOverflowMask<1> { static const size_t value = 0; }; - -/** - * And computes the logical 'and' of its argument booleans. - * - * Examples: - * mozilla::t1::And::value is true. - * mozilla::t1::And::value is false. - * mozilla::t1::And<>::value is true. - */ - -template -struct And; - -template<> -struct And<> : public TrueType { }; - -template -struct And - : public Conditional, FalseType>::Type { }; - -} // namespace tl - -} // namespace mozilla - -#endif /* mozilla_TemplateLib_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/ThreadLocal.h b/android/armeabi-v7a/include/spidermonkey/mozilla/ThreadLocal.h deleted file mode 100644 index 880e6773..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/ThreadLocal.h +++ /dev/null @@ -1,222 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Cross-platform lightweight thread local data wrappers. */ - -#ifndef mozilla_ThreadLocal_h -#define mozilla_ThreadLocal_h - -#if defined(XP_WIN) -// This file will get included in any file that wants to add a profiler mark. -// In order to not bring together we could include windef.h and -// winbase.h which are sufficient to get the prototypes for the Tls* functions. -// # include -// # include -// Unfortunately, even including these headers causes us to add a bunch of ugly -// stuff to our namespace e.g #define CreateEvent CreateEventW -extern "C" { -__declspec(dllimport) void* __stdcall TlsGetValue(unsigned long); -__declspec(dllimport) int __stdcall TlsSetValue(unsigned long, void*); -__declspec(dllimport) unsigned long __stdcall TlsAlloc(); -} -#else -# include -# include -#endif - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -// sig_safe_t denotes an atomic type which can be read or stored in a single -// instruction. This means that data of this type is safe to be manipulated -// from a signal handler, or other similar asynchronous execution contexts. -#if defined(XP_WIN) -typedef unsigned long sig_safe_t; -#else -typedef sig_atomic_t sig_safe_t; -#endif - -namespace detail { - -#if defined(HAVE_THREAD_TLS_KEYWORD) -#define MOZ_HAS_THREAD_LOCAL -#endif - -/* - * Thread Local Storage helpers. - * - * Usage: - * - * Do not directly instantiate this class. Instead, use the - * MOZ_THREAD_LOCAL macro to declare or define instances. The macro - * takes a type name as its argument. - * - * Declare like this: - * extern MOZ_THREAD_LOCAL(int) tlsInt; - * Define like this: - * MOZ_THREAD_LOCAL(int) tlsInt; - * or: - * static MOZ_THREAD_LOCAL(int) tlsInt; - * - * Only static-storage-duration (e.g. global variables, or static class members) - * objects of this class should be instantiated. This class relies on - * zero-initialization, which is implicit for static-storage-duration objects. - * It doesn't have a custom default constructor, to avoid static initializers. - * - * API usage: - * - * // Create a TLS item. - * // - * // Note that init() should be invoked before the first use of set() - * // or get(). It is ok to call it multiple times. This must be - * // called in a way that avoids possible races with other threads. - * MOZ_THREAD_LOCAL(int) tlsKey; - * if (!tlsKey.init()) { - * // deal with the error - * } - * - * // Set the TLS value - * tlsKey.set(123); - * - * // Get the TLS value - * int value = tlsKey.get(); - */ -template -class ThreadLocal -{ -#ifndef MOZ_HAS_THREAD_LOCAL -#if defined(XP_WIN) - typedef unsigned long key_t; -#else - typedef pthread_key_t key_t; -#endif - - // Integral types narrower than void* must be extended to avoid - // warnings from valgrind on some platforms. This helper type - // achieves that without penalizing the common case of ThreadLocals - // instantiated using a pointer type. - template - struct Helper - { - typedef uintptr_t Type; - }; - - template - struct Helper - { - typedef S *Type; - }; -#endif - - bool initialized() const { -#ifdef MOZ_HAS_THREAD_LOCAL - return true; -#else - return mInited; -#endif - } - -public: - // __thread does not allow non-trivial constructors, but we can - // instead rely on zero-initialization. -#ifndef MOZ_HAS_THREAD_LOCAL - ThreadLocal() - : mKey(0), mInited(false) - {} -#endif - - MOZ_MUST_USE inline bool init(); - - inline T get() const; - - inline void set(const T aValue); - -private: -#ifdef MOZ_HAS_THREAD_LOCAL - T mValue; -#else - key_t mKey; - bool mInited; -#endif -}; - -template -inline bool -ThreadLocal::init() -{ - static_assert(mozilla::IsPointer::value || mozilla::IsIntegral::value, - "mozilla::ThreadLocal must be used with a pointer or " - "integral type"); - static_assert(sizeof(T) <= sizeof(void*), - "mozilla::ThreadLocal can't be used for types larger than " - "a pointer"); - -#ifdef MOZ_HAS_THREAD_LOCAL - return true; -#else - if (!initialized()) { -#ifdef XP_WIN - mKey = TlsAlloc(); - mInited = mKey != 0xFFFFFFFFUL; // TLS_OUT_OF_INDEXES -#else - mInited = !pthread_key_create(&mKey, nullptr); -#endif - } - return mInited; -#endif -} - -template -inline T -ThreadLocal::get() const -{ -#ifdef MOZ_HAS_THREAD_LOCAL - return mValue; -#else - MOZ_ASSERT(initialized()); - void* h; -#ifdef XP_WIN - h = TlsGetValue(mKey); -#else - h = pthread_getspecific(mKey); -#endif - return static_cast(reinterpret_cast::Type>(h)); -#endif -} - -template -inline void -ThreadLocal::set(const T aValue) -{ -#ifdef MOZ_HAS_THREAD_LOCAL - mValue = aValue; -#else - MOZ_ASSERT(initialized()); - void* h = reinterpret_cast(static_cast::Type>(aValue)); -#ifdef XP_WIN - bool succeeded = TlsSetValue(mKey, h); -#else - bool succeeded = !pthread_setspecific(mKey, h); -#endif - if (!succeeded) { - MOZ_CRASH(); - } -#endif -} - -#ifdef MOZ_HAS_THREAD_LOCAL -#define MOZ_THREAD_LOCAL(TYPE) __thread mozilla::detail::ThreadLocal -#else -#define MOZ_THREAD_LOCAL(TYPE) mozilla::detail::ThreadLocal -#endif - -} // namespace detail -} // namespace mozilla - -#endif /* mozilla_ThreadLocal_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/TimeStamp.h b/android/armeabi-v7a/include/spidermonkey/mozilla/TimeStamp.h deleted file mode 100644 index a1a0eb36..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/TimeStamp.h +++ /dev/null @@ -1,609 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_TimeStamp_h -#define mozilla_TimeStamp_h - -#include -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/FloatingPoint.h" -#include "mozilla/TypeTraits.h" -#include "mozilla/Types.h" - -namespace IPC { -template struct ParamTraits; -} // namespace IPC - -#ifdef XP_WIN -// defines TimeStampValue as a complex value keeping both -// GetTickCount and QueryPerformanceCounter values -#include "TimeStamp_windows.h" -#endif - -namespace mozilla { - -#ifndef XP_WIN -typedef uint64_t TimeStampValue; -#endif - -class TimeStamp; - -/** - * Platform-specific implementation details of BaseTimeDuration. - */ -class BaseTimeDurationPlatformUtils -{ -public: - static MFBT_API double ToSeconds(int64_t aTicks); - static MFBT_API double ToSecondsSigDigits(int64_t aTicks); - static MFBT_API int64_t TicksFromMilliseconds(double aMilliseconds); - static MFBT_API int64_t ResolutionInTicks(); -}; - -/** - * Instances of this class represent the length of an interval of time. - * Negative durations are allowed, meaning the end is before the start. - * - * Internally the duration is stored as a int64_t in units of - * PR_TicksPerSecond() when building with NSPR interval timers, or a - * system-dependent unit when building with system clocks. The - * system-dependent unit must be constant, otherwise the semantics of - * this class would be broken. - * - * The ValueCalculator template parameter determines how arithmetic - * operations are performed on the integer count of ticks (mValue). - */ -template -class BaseTimeDuration -{ -public: - // The default duration is 0. - constexpr BaseTimeDuration() : mValue(0) {} - // Allow construction using '0' as the initial value, for readability, - // but no other numbers (so we don't have any implicit unit conversions). - struct _SomethingVeryRandomHere; - MOZ_IMPLICIT BaseTimeDuration(_SomethingVeryRandomHere* aZero) : mValue(0) - { - MOZ_ASSERT(!aZero, "Who's playing funny games here?"); - } - // Default copy-constructor and assignment are OK - - // Converting copy-constructor and assignment operator - template - explicit BaseTimeDuration(const BaseTimeDuration& aOther) - : mValue(aOther.mValue) - { } - - template - BaseTimeDuration& operator=(const BaseTimeDuration& aOther) - { - mValue = aOther.mValue; - return *this; - } - - double ToSeconds() const - { - if (mValue == INT64_MAX) { - return PositiveInfinity(); - } - if (mValue == INT64_MIN) { - return NegativeInfinity(); - } - return BaseTimeDurationPlatformUtils::ToSeconds(mValue); - } - // Return a duration value that includes digits of time we think to - // be significant. This method should be used when displaying a - // time to humans. - double ToSecondsSigDigits() const - { - if (mValue == INT64_MAX) { - return PositiveInfinity(); - } - if (mValue == INT64_MIN) { - return NegativeInfinity(); - } - return BaseTimeDurationPlatformUtils::ToSecondsSigDigits(mValue); - } - double ToMilliseconds() const { return ToSeconds() * 1000.0; } - double ToMicroseconds() const { return ToMilliseconds() * 1000.0; } - - // Using a double here is safe enough; with 53 bits we can represent - // durations up to over 280,000 years exactly. If the units of - // mValue do not allow us to represent durations of that length, - // long durations are clamped to the max/min representable value - // instead of overflowing. - static inline BaseTimeDuration FromSeconds(double aSeconds) - { - return FromMilliseconds(aSeconds * 1000.0); - } - static BaseTimeDuration FromMilliseconds(double aMilliseconds) - { - if (aMilliseconds == PositiveInfinity()) { - return Forever(); - } - if (aMilliseconds == NegativeInfinity()) { - return FromTicks(INT64_MIN); - } - return FromTicks( - BaseTimeDurationPlatformUtils::TicksFromMilliseconds(aMilliseconds)); - } - static inline BaseTimeDuration FromMicroseconds(double aMicroseconds) - { - return FromMilliseconds(aMicroseconds / 1000.0); - } - - static BaseTimeDuration Forever() - { - return FromTicks(INT64_MAX); - } - - BaseTimeDuration operator+(const BaseTimeDuration& aOther) const - { - return FromTicks(ValueCalculator::Add(mValue, aOther.mValue)); - } - BaseTimeDuration operator-(const BaseTimeDuration& aOther) const - { - return FromTicks(ValueCalculator::Subtract(mValue, aOther.mValue)); - } - BaseTimeDuration& operator+=(const BaseTimeDuration& aOther) - { - mValue = ValueCalculator::Add(mValue, aOther.mValue); - return *this; - } - BaseTimeDuration& operator-=(const BaseTimeDuration& aOther) - { - mValue = ValueCalculator::Subtract(mValue, aOther.mValue); - return *this; - } - BaseTimeDuration operator-() const - { - // We don't just use FromTicks(ValueCalculator::Subtract(0, mValue)) - // since that won't give the correct result for -TimeDuration::Forever(). - int64_t ticks; - if (mValue == INT64_MAX) { - ticks = INT64_MIN; - } else if (mValue == INT64_MIN) { - ticks = INT64_MAX; - } else { - ticks = -mValue; - } - - return FromTicks(ticks); - } - -private: - // Block double multiplier (slower, imprecise if long duration) - Bug 853398. - // If required, use MultDouble explicitly and with care. - BaseTimeDuration operator*(const double aMultiplier) const = delete; - - // Block double divisor (for the same reason, and because dividing by - // fractional values would otherwise invoke the int64_t variant, and rounding - // the passed argument can then cause divide-by-zero) - Bug 1147491. - BaseTimeDuration operator/(const double aDivisor) const = delete; - -public: - BaseTimeDuration MultDouble(double aMultiplier) const - { - return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); - } - BaseTimeDuration operator*(const int32_t aMultiplier) const - { - return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); - } - BaseTimeDuration operator*(const uint32_t aMultiplier) const - { - return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); - } - BaseTimeDuration operator*(const int64_t aMultiplier) const - { - return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); - } - BaseTimeDuration operator*(const uint64_t aMultiplier) const - { - if (aMultiplier > INT64_MAX) { - return Forever(); - } - return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); - } - BaseTimeDuration operator/(const int64_t aDivisor) const - { - MOZ_ASSERT(aDivisor != 0, "Division by zero"); - return FromTicks(ValueCalculator::Divide(mValue, aDivisor)); - } - double operator/(const BaseTimeDuration& aOther) const - { -#ifndef MOZ_B2G - // Bug 1066388 - This fails on B2G ICS Emulator - MOZ_ASSERT(aOther.mValue != 0, "Division by zero"); -#endif - return ValueCalculator::DivideDouble(mValue, aOther.mValue); - } - BaseTimeDuration operator%(const BaseTimeDuration& aOther) const - { - MOZ_ASSERT(aOther.mValue != 0, "Division by zero"); - return FromTicks(ValueCalculator::Modulo(mValue, aOther.mValue)); - } - - template - bool operator<(const BaseTimeDuration& aOther) const - { - return mValue < aOther.mValue; - } - template - bool operator<=(const BaseTimeDuration& aOther) const - { - return mValue <= aOther.mValue; - } - template - bool operator>=(const BaseTimeDuration& aOther) const - { - return mValue >= aOther.mValue; - } - template - bool operator>(const BaseTimeDuration& aOther) const - { - return mValue > aOther.mValue; - } - template - bool operator==(const BaseTimeDuration& aOther) const - { - return mValue == aOther.mValue; - } - template - bool operator!=(const BaseTimeDuration& aOther) const - { - return mValue != aOther.mValue; - } - bool IsZero() const - { - return mValue == 0; - } - explicit operator bool() const - { - return mValue != 0; - } - - // Return a best guess at the system's current timing resolution, - // which might be variable. BaseTimeDurations below this order of - // magnitude are meaningless, and those at the same order of - // magnitude or just above are suspect. - static BaseTimeDuration Resolution() { - return FromTicks(BaseTimeDurationPlatformUtils::ResolutionInTicks()); - } - - // We could define additional operators here: - // -- convert to/from other time units - // -- scale duration by a float - // but let's do that on demand. - // Comparing durations for equality will only lead to bugs on - // platforms with high-resolution timers. - -private: - friend class TimeStamp; - friend struct IPC::ParamTraits>; - template - friend class BaseTimeDuration; - - static BaseTimeDuration FromTicks(int64_t aTicks) - { - BaseTimeDuration t; - t.mValue = aTicks; - return t; - } - - static BaseTimeDuration FromTicks(double aTicks) - { - // NOTE: this MUST be a >= test, because int64_t(double(INT64_MAX)) - // overflows and gives INT64_MIN. - if (aTicks >= double(INT64_MAX)) { - return FromTicks(INT64_MAX); - } - - // This MUST be a <= test. - if (aTicks <= double(INT64_MIN)) { - return FromTicks(INT64_MIN); - } - - return FromTicks(int64_t(aTicks)); - } - - // Duration, result is implementation-specific difference of two TimeStamps - int64_t mValue; -}; - -/** - * Perform arithmetic operations on the value of a BaseTimeDuration without - * doing strict checks on the range of values. - */ -class TimeDurationValueCalculator -{ -public: - static int64_t Add(int64_t aA, int64_t aB) { return aA + aB; } - static int64_t Subtract(int64_t aA, int64_t aB) { return aA - aB; } - - template - static int64_t Multiply(int64_t aA, T aB) - { - static_assert(IsIntegral::value, - "Using integer multiplication routine with non-integer type." - " Further specialization required"); - return aA * static_cast(aB); - } - - static int64_t Divide(int64_t aA, int64_t aB) { return aA / aB; } - static double DivideDouble(int64_t aA, int64_t aB) - { - return static_cast(aA) / aB; - } - static int64_t Modulo(int64_t aA, int64_t aB) { return aA % aB; } -}; - -template <> -inline int64_t -TimeDurationValueCalculator::Multiply(int64_t aA, double aB) -{ - return static_cast(aA * aB); -} - -/** - * Specialization of BaseTimeDuration that uses TimeDurationValueCalculator for - * arithmetic on the mValue member. - * - * Use this class for time durations that are *not* expected to hold values of - * Forever (or the negative equivalent) or when such time duration are *not* - * expected to be used in arithmetic operations. - */ -typedef BaseTimeDuration TimeDuration; - -/** - * Instances of this class represent moments in time, or a special - * "null" moment. We do not use the non-monotonic system clock or - * local time, since they can be reset, causing apparent backward - * travel in time, which can confuse algorithms. Instead we measure - * elapsed time according to the system. This time can never go - * backwards (i.e. it never wraps around, at least not in less than - * five million years of system elapsed time). It might not advance - * while the system is sleeping. If TimeStamp::SetNow() is not called - * at all for hours or days, we might not notice the passage of some - * of that time. - * - * We deliberately do not expose a way to convert TimeStamps to some - * particular unit. All you can do is compute a difference between two - * TimeStamps to get a TimeDuration. You can also add a TimeDuration - * to a TimeStamp to get a new TimeStamp. You can't do something - * meaningless like add two TimeStamps. - * - * Internally this is implemented as either a wrapper around - * - high-resolution, monotonic, system clocks if they exist on this - * platform - * - PRIntervalTime otherwise. We detect wraparounds of - * PRIntervalTime and work around them. - * - * This class is similar to C++11's time_point, however it is - * explicitly nullable and provides an IsNull() method. time_point - * is initialized to the clock's epoch and provides a - * time_since_epoch() method that functions similiarly. i.e. - * t.IsNull() is equivalent to t.time_since_epoch() == decltype(t)::duration::zero(); - */ -class TimeStamp -{ -public: - /** - * Initialize to the "null" moment - */ - constexpr TimeStamp() : mValue(0) {} - // Default copy-constructor and assignment are OK - - /** - * The system timestamps are the same as the TimeStamp - * retrieved by mozilla::TimeStamp. Since we need this for - * vsync timestamps, we enable the creation of mozilla::TimeStamps - * on platforms that support vsync aligned refresh drivers / compositors - * Verified true as of Jan 31, 2015: B2G and OS X - * False on Windows 7 - * UNTESTED ON OTHER PLATFORMS - */ -#if defined(MOZ_WIDGET_GONK) || defined(XP_DARWIN) - static TimeStamp FromSystemTime(int64_t aSystemTime) - { - static_assert(sizeof(aSystemTime) == sizeof(TimeStampValue), - "System timestamp should be same units as TimeStampValue"); - return TimeStamp(aSystemTime); - } -#endif - - /** - * Return true if this is the "null" moment - */ - bool IsNull() const { return mValue == 0; } - - /** - * Return true if this is not the "null" moment, may be used in tests, e.g.: - * |if (timestamp) { ... }| - */ - explicit operator bool() const - { - return mValue != 0; - } - - /** - * Return a timestamp reflecting the current elapsed system time. This - * is monotonically increasing (i.e., does not decrease) over the - * lifetime of this process' XPCOM session. - * - * Now() is trying to ensure the best possible precision on each platform, - * at least one millisecond. - * - * NowLoRes() has been introduced to workaround performance problems of - * QueryPerformanceCounter on the Windows platform. NowLoRes() is giving - * lower precision, usually 15.6 ms, but with very good performance benefit. - * Use it for measurements of longer times, like >200ms timeouts. - */ - static TimeStamp Now() { return Now(true); } - static TimeStamp NowLoRes() { return Now(false); } - - /** - * Return a timestamp representing the time when the current process was - * created which will be comparable with other timestamps taken with this - * class. If the actual process creation time is detected to be inconsistent - * the @a aIsInconsistent parameter will be set to true, the returned - * timestamp however will still be valid though inaccurate. - * - * @param aIsInconsistent Set to true if an inconsistency was detected in the - * process creation time - * @returns A timestamp representing the time when the process was created, - * this timestamp is always valid even when errors are reported - */ - static MFBT_API TimeStamp ProcessCreation(bool& aIsInconsistent); - - /** - * Records a process restart. After this call ProcessCreation() will return - * the time when the browser was restarted instead of the actual time when - * the process was created. - */ - static MFBT_API void RecordProcessRestart(); - - /** - * Compute the difference between two timestamps. Both must be non-null. - */ - TimeDuration operator-(const TimeStamp& aOther) const - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value"); - static_assert(-INT64_MAX > INT64_MIN, "int64_t sanity check"); - int64_t ticks = int64_t(mValue - aOther.mValue); - // Check for overflow. - if (mValue > aOther.mValue) { - if (ticks < 0) { - ticks = INT64_MAX; - } - } else { - if (ticks > 0) { - ticks = INT64_MIN; - } - } - return TimeDuration::FromTicks(ticks); - } - - TimeStamp operator+(const TimeDuration& aOther) const - { - TimeStamp result = *this; - result += aOther; - return result; - } - TimeStamp operator-(const TimeDuration& aOther) const - { - TimeStamp result = *this; - result -= aOther; - return result; - } - TimeStamp& operator+=(const TimeDuration& aOther) - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - TimeStampValue value = mValue + aOther.mValue; - // Check for underflow. - // (We don't check for overflow because it's not obvious what the error - // behavior should be in that case.) - if (aOther.mValue < 0 && value > mValue) { - value = 0; - } - mValue = value; - return *this; - } - TimeStamp& operator-=(const TimeDuration& aOther) - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - TimeStampValue value = mValue - aOther.mValue; - // Check for underflow. - // (We don't check for overflow because it's not obvious what the error - // behavior should be in that case.) - if (aOther.mValue > 0 && value > mValue) { - value = 0; - } - mValue = value; - return *this; - } - - bool operator<(const TimeStamp& aOther) const - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value"); - return mValue < aOther.mValue; - } - bool operator<=(const TimeStamp& aOther) const - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value"); - return mValue <= aOther.mValue; - } - bool operator>=(const TimeStamp& aOther) const - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value"); - return mValue >= aOther.mValue; - } - bool operator>(const TimeStamp& aOther) const - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value"); - return mValue > aOther.mValue; - } - bool operator==(const TimeStamp& aOther) const - { - return IsNull() - ? aOther.IsNull() - : !aOther.IsNull() && mValue == aOther.mValue; - } - bool operator!=(const TimeStamp& aOther) const - { - return !(*this == aOther); - } - - // Comparing TimeStamps for equality should be discouraged. Adding - // two TimeStamps, or scaling TimeStamps, is nonsense and must never - // be allowed. - - static MFBT_API void Startup(); - static MFBT_API void Shutdown(); - -private: - friend struct IPC::ParamTraits; - friend void StartupTimelineRecordExternal(int, uint64_t); - - MOZ_IMPLICIT TimeStamp(TimeStampValue aValue) : mValue(aValue) {} - - static MFBT_API TimeStamp Now(bool aHighResolution); - - /** - * Computes the uptime of the current process in microseconds. The result - * is platform-dependent and needs to be checked against existing timestamps - * for consistency. - * - * @returns The number of microseconds since the calling process was started - * or 0 if an error was encountered while computing the uptime - */ - static MFBT_API uint64_t ComputeProcessUptime(); - - /** - * When built with PRIntervalTime, a value of 0 means this instance - * is "null". Otherwise, the low 32 bits represent a PRIntervalTime, - * and the high 32 bits represent a counter of the number of - * rollovers of PRIntervalTime that we've seen. This counter starts - * at 1 to avoid a real time colliding with the "null" value. - * - * PR_INTERVAL_MAX is set at 100,000 ticks per second. So the minimum - * time to wrap around is about 2^64/100000 seconds, i.e. about - * 5,849,424 years. - * - * When using a system clock, a value is system dependent. - */ - TimeStampValue mValue; -}; - -} // namespace mozilla - -#endif /* mozilla_TimeStamp_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/ToString.h b/android/armeabi-v7a/include/spidermonkey/mozilla/ToString.h deleted file mode 100644 index f11cad5c..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/ToString.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Utilities for converting an object to a string representation. */ - -#ifndef mozilla_ToString_h -#define mozilla_ToString_h - -#include -#include - -namespace mozilla { - -/** - * A convenience function for converting an object to a string representation. - * Supports any object which can be streamed to an std::ostream. - */ -template -std::string -ToString(const T& aValue) -{ - std::ostringstream stream; - stream << aValue; - return stream.str(); -} - -} // namespace mozilla - -#endif /* mozilla_ToString_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Tuple.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Tuple.h deleted file mode 100644 index a7f9bee6..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Tuple.h +++ /dev/null @@ -1,461 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A variadic tuple class. */ - -#ifndef mozilla_Tuple_h -#define mozilla_Tuple_h - -#include "mozilla/Move.h" -#include "mozilla/Pair.h" -#include "mozilla/TemplateLib.h" -#include "mozilla/TypeTraits.h" - -#include -#include - -namespace mozilla { - -namespace detail { - -/* - * A helper class that allows passing around multiple variadic argument lists - * by grouping them. - */ -template -struct Group; - -/* - * CheckConvertibility checks whether each type in a source pack of types - * is convertible to the corresponding type in a target pack of types. - * - * It is intended to be invoked like this: - * CheckConvertibility, Group> - * 'Group' is used to separate types in the two packs (otherwise if we just - * wrote 'CheckConvertibility -struct CheckConvertibilityImpl; - -template -struct CheckConvertibilityImpl - : FalseType {}; - -template -struct CheckConvertibilityImpl, Group, true> - : IntegralConstant::value...>::value> { }; - -template -struct CheckConvertibility; - -template -struct CheckConvertibility, Group> - : CheckConvertibilityImpl, Group, - sizeof...(SourceTypes) == sizeof...(TargetTypes)> { }; - -/* - * TupleImpl is a helper class used to implement mozilla::Tuple. - * It represents one node in a recursive inheritance hierarchy. - * 'Index' is the 0-based index of the tuple element stored in this node; - * 'Elements...' are the types of the elements stored in this node and its - * base classes. - * - * Example: - * Tuple inherits from - * TupleImpl<0, int, float, char>, which stores the 'int' and inherits from - * TupleImpl<1, float, char>, which stores the 'float' and inherits from - * TupleImpl<2, char>, which stores the 'char' and inherits from - * TupleImpl<3>, which stores nothing and terminates the recursion. - * - * The purpose of the 'Index' parameter is to allow efficient index-based - * access to a tuple element: given a tuple, and an index 'I' that we wish to - * access, we can cast the tuple to the base which stores the I'th element - * by performing template argument deduction against 'TupleImpl', - * where 'I' is specified explicitly and 'E...' is deduced (this is what the - * non-member 'Get(t)' function does). - * - * This implementation strategy is borrowed from libstdc++'s std::tuple - * implementation. - */ -template -struct TupleImpl; - -/* - * The base case of the inheritance recursion (and also the implementation - * of an empty tuple). - */ -template -struct TupleImpl { - bool operator==(const TupleImpl& aOther) const - { - return true; - } -}; - -/* - * One node of the recursive inheritance hierarchy. It stores the element at - * index 'Index' of a tuple, of type 'HeadT', and inherits from the nodes - * that store the remaining elements, of types 'TailT...'. - */ -template -struct TupleImpl - : public TupleImpl -{ - typedef TupleImpl Base; - - // Accessors for the head and the tail. - // These are static, because the intended usage is for the caller to, - // given a tuple, obtain the type B of the base class which stores the - // element of interest, and then call B::Head(tuple) to access it. - // (Tail() is mostly for internal use, but is exposed for consistency.) - static HeadT& Head(TupleImpl& aTuple) { return aTuple.mHead; } - static const HeadT& Head(const TupleImpl& aTuple) { return aTuple.mHead; } - static Base& Tail(TupleImpl& aTuple) { return aTuple; } - static const Base& Tail(const TupleImpl& aTuple) { return aTuple; } - - TupleImpl() : Base(), mHead() { } - - // Construct from const references to the elements. - explicit TupleImpl(const HeadT& aHead, const TailT&... aTail) - : Base(aTail...), mHead(aHead) { } - - // Construct from objects that are convertible to the elements. - // This constructor is enabled only when the argument types are actually - // convertible to the element types, otherwise it could become a better - // match for certain invocations than the copy constructor. - template , - Group>::value>::Type> - explicit TupleImpl(OtherHeadT&& aHead, OtherTailT&&... aTail) - : Base(Forward(aTail)...), mHead(Forward(aHead)) { } - - // Copy and move constructors. - // We'd like to use '= default' to implement these, but MSVC 2013's support - // for '= default' is incomplete and this doesn't work. - TupleImpl(const TupleImpl& aOther) - : Base(Tail(aOther)) - , mHead(Head(aOther)) {} - TupleImpl(TupleImpl&& aOther) - : Base(Move(Tail(aOther))) - , mHead(Forward(Head(aOther))) {} - - // Assign from a tuple whose elements are convertible to the elements - // of this tuple. - template ::Type> - TupleImpl& operator=(const TupleImpl& aOther) - { - typedef TupleImpl OtherT; - Head(*this) = OtherT::Head(aOther); - Tail(*this) = OtherT::Tail(aOther); - return *this; - } - template ::Type> - TupleImpl& operator=(TupleImpl&& aOther) - { - typedef TupleImpl OtherT; - Head(*this) = Move(OtherT::Head(aOther)); - Tail(*this) = Move(OtherT::Tail(aOther)); - return *this; - } - - // Copy and move assignment operators. - TupleImpl& operator=(const TupleImpl& aOther) - { - Head(*this) = Head(aOther); - Tail(*this) = Tail(aOther); - return *this; - } - TupleImpl& operator=(TupleImpl&& aOther) - { - Head(*this) = Move(Head(aOther)); - Tail(*this) = Move(Tail(aOther)); - return *this; - } - bool operator==(const TupleImpl& aOther) const - { - return Head(*this) == Head(aOther) && Tail(*this) == Tail(aOther); - } -private: - HeadT mHead; // The element stored at this index in the tuple. -}; - -} // namespace detail - -/** - * Tuple is a class that stores zero or more objects, whose types are specified - * as template parameters. It can be thought of as a generalization of Pair, - * (which can be thought of as a 2-tuple). - * - * Tuple allows index-based access to its elements (with the index having to be - * known at compile time) via the non-member function 'Get(tuple)'. - */ -template -class Tuple : public detail::TupleImpl<0, Elements...> -{ - typedef detail::TupleImpl<0, Elements...> Impl; -public: - // The constructors and assignment operators here are simple wrappers - // around those in TupleImpl. - - Tuple() : Impl() { } - explicit Tuple(const Elements&... aElements) : Impl(aElements...) { } - // Here, we can't just use 'typename... OtherElements' because MSVC will give - // a warning "C4520: multiple default constructors specified" (even if no one - // actually instantiates the constructor with an empty parameter pack - - // that's probably a bug) and we compile with warnings-as-errors. - template , - detail::Group>::value>::Type> - explicit Tuple(OtherHead&& aHead, OtherTail&&... aTail) - : Impl(Forward(aHead), Forward(aTail)...) { } - Tuple(const Tuple& aOther) : Impl(aOther) { } - Tuple(Tuple&& aOther) : Impl(Move(aOther)) { } - - template ::Type> - Tuple& operator=(const Tuple& aOther) - { - static_cast(*this) = aOther; - return *this; - } - template ::Type> - Tuple& operator=(Tuple&& aOther) - { - static_cast(*this) = Move(aOther); - return *this; - } - Tuple& operator=(const Tuple& aOther) - { - static_cast(*this) = aOther; - return *this; - } - Tuple& operator=(Tuple&& aOther) - { - static_cast(*this) = Move(aOther); - return *this; - } - bool operator==(const Tuple& aOther) const - { - return static_cast(*this) == static_cast(aOther); - } -}; - -/** - * Specialization of Tuple for two elements. - * This is created to support construction and assignment from a Pair or std::pair. - */ -template -class Tuple : public detail::TupleImpl<0, A, B> -{ - typedef detail::TupleImpl<0, A, B> Impl; - -public: - // The constructors and assignment operators here are simple wrappers - // around those in TupleImpl. - - Tuple() : Impl() { } - explicit Tuple(const A& aA, const B& aB) : Impl(aA, aB) { } - template , - detail::Group>::value>::Type> - explicit Tuple(AArg&& aA, BArg&& aB) - : Impl(Forward(aA), Forward(aB)) { } - Tuple(const Tuple& aOther) : Impl(aOther) { } - Tuple(Tuple&& aOther) : Impl(Move(aOther)) { } - explicit Tuple(const Pair& aOther) - : Impl(aOther.first(), aOther.second()) { } - explicit Tuple(Pair&& aOther) : Impl(Forward(aOther.first()), - Forward(aOther.second())) { } - explicit Tuple(const std::pair& aOther) - : Impl(aOther.first, aOther.second) { } - explicit Tuple(std::pair&& aOther) : Impl(Forward(aOther.first), - Forward(aOther.second)) { } - - template - Tuple& operator=(const Tuple& aOther) - { - static_cast(*this) = aOther; - return *this; - } - template - Tuple& operator=(Tuple&& aOther) - { - static_cast(*this) = Move(aOther); - return *this; - } - Tuple& operator=(const Tuple& aOther) - { - static_cast(*this) = aOther; - return *this; - } - Tuple& operator=(Tuple&& aOther) - { - static_cast(*this) = Move(aOther); - return *this; - } - template - Tuple& operator=(const Pair& aOther) - { - Impl::Head(*this) = aOther.first(); - Impl::Tail(*this).Head(*this) = aOther.second(); - return *this; - } - template - Tuple& operator=(Pair&& aOther) - { - Impl::Head(*this) = Forward(aOther.first()); - Impl::Tail(*this).Head(*this) = Forward(aOther.second()); - return *this; - } - template - Tuple& operator=(const std::pair& aOther) - { - Impl::Head(*this) = aOther.first; - Impl::Tail(*this).Head(*this) = aOther.second; - return *this; - } - template - Tuple& operator=(std::pair&& aOther) - { - Impl::Head(*this) = Forward(aOther.first); - Impl::Tail(*this).Head(*this) = Forward(aOther.second); - return *this; - } -}; - -/** - * Specialization of Tuple for zero arguments. - * This is necessary because if the primary template were instantiated with - * an empty parameter pack, the 'Tuple(Elements...)' constructors would - * become illegal overloads of the default constructor. - */ -template <> -class Tuple<> {}; - -namespace detail { - -/* - * Helper functions for implementing Get(tuple). - * These functions take a TupleImpl, with Index being - * explicitly specified, and Elements being deduced. By passing a Tuple - * object as argument, template argument deduction will do its magic and - * cast the tuple to the base class which stores the element at Index. - */ - -// Const reference version. -template -auto TupleGetHelper(TupleImpl& aTuple) - -> decltype(TupleImpl::Head(aTuple)) -{ - return TupleImpl::Head(aTuple); -} - -// Non-const reference version. -template -auto TupleGetHelper(const TupleImpl& aTuple) - -> decltype(TupleImpl::Head(aTuple)) -{ - return TupleImpl::Head(aTuple); -} - -} // namespace detail - -/** - * Index-based access to an element of a tuple. - * The syntax is Get(tuple). The index is zero-based. - * - * Example: - * - * Tuple t; - * ... - * float f = Get<1>(t); - */ - -// Non-const reference version. -template -auto Get(Tuple& aTuple) - -> decltype(detail::TupleGetHelper(aTuple)) -{ - return detail::TupleGetHelper(aTuple); -} - -// Const reference version. -template -auto Get(const Tuple& aTuple) - -> decltype(detail::TupleGetHelper(aTuple)) -{ - return detail::TupleGetHelper(aTuple); -} - -// Rvalue reference version. -template -auto Get(Tuple&& aTuple) - -> decltype(Move(mozilla::Get(aTuple))) -{ - // We need a 'mozilla::' qualification here to avoid - // name lookup only finding the current function. - return Move(mozilla::Get(aTuple)); -} - -/** - * A convenience function for constructing a tuple out of a sequence of - * values without specifying the type of the tuple. - * The type of the tuple is deduced from the types of its elements. - * - * Example: - * - * auto tuple = MakeTuple(42, 0.5f, 'c'); // has type Tuple - */ -template -inline Tuple::Type...> -MakeTuple(Elements&&... aElements) -{ - return Tuple::Type...>(Forward(aElements)...); -} - -/** - * A convenience function for constructing a tuple of references to a - * sequence of variables. Since assignments to the elements of the tuple - * "go through" to the referenced variables, this can be used to "unpack" - * a tuple into individual variables. - * - * Example: - * - * int i; - * float f; - * char c; - * Tie(i, f, c) = FunctionThatReturnsATuple(); - */ -template -inline Tuple -Tie(Elements&... aVariables) -{ - return Tuple(aVariables...); -} - -} // namespace mozilla - -#endif /* mozilla_Tuple_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/TypeTraits.h b/android/armeabi-v7a/include/spidermonkey/mozilla/TypeTraits.h deleted file mode 100644 index 084f608c..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/TypeTraits.h +++ /dev/null @@ -1,1262 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Template-based metaprogramming and type-testing facilities. */ - -#ifndef mozilla_TypeTraits_h -#define mozilla_TypeTraits_h - -#include "mozilla/Types.h" - -/* - * These traits are approximate copies of the traits and semantics from C++11's - * header. Don't add traits not in that header! When all - * platforms provide that header, we can convert all users and remove this one. - */ - -#include - -namespace mozilla { - -/* Forward declarations. */ - -template struct RemoveCV; -template struct AddRvalueReference; - -/* 20.2.4 Function template declval [declval] */ - -/** - * DeclVal simplifies the definition of expressions which occur as unevaluated - * operands. It converts T to a reference type, making it possible to use in - * decltype expressions even if T does not have a default constructor, e.g.: - * decltype(DeclVal().foo()) - */ -template -typename AddRvalueReference::Type DeclVal(); - -/* 20.9.3 Helper classes [meta.help] */ - -/** - * Helper class used as a base for various type traits, exposed publicly - * because exposes it as well. - */ -template -struct IntegralConstant -{ - static const T value = Value; - typedef T ValueType; - typedef IntegralConstant Type; -}; - -/** Convenient aliases. */ -typedef IntegralConstant TrueType; -typedef IntegralConstant FalseType; - -/* 20.9.4 Unary type traits [meta.unary] */ - -/* 20.9.4.1 Primary type categories [meta.unary.cat] */ - -namespace detail { - -template -struct IsVoidHelper : FalseType {}; - -template<> -struct IsVoidHelper : TrueType {}; - -} // namespace detail - -/** - * IsVoid determines whether a type is void. - * - * mozilla::IsVoid::value is false; - * mozilla::IsVoid::value is true; - * mozilla::IsVoid::value is false; - * mozilla::IsVoid::value is true. - */ -template -struct IsVoid : detail::IsVoidHelper::Type> {}; - -namespace detail { - -template -struct IsIntegralHelper : FalseType {}; - -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; - -} /* namespace detail */ - -/** - * IsIntegral determines whether a type is an integral type. - * - * mozilla::IsIntegral::value is true; - * mozilla::IsIntegral::value is true; - * mozilla::IsIntegral::value is true; - * mozilla::IsIntegral::value is false; - * mozilla::IsIntegral::value is false; - */ -template -struct IsIntegral : detail::IsIntegralHelper::Type> -{}; - -template -struct IsSame; - -namespace detail { - -template -struct IsFloatingPointHelper - : IntegralConstant::value || - IsSame::value || - IsSame::value> -{}; - -} // namespace detail - -/** - * IsFloatingPoint determines whether a type is a floating point type (float, - * double, long double). - * - * mozilla::IsFloatingPoint::value is false; - * mozilla::IsFloatingPoint::value is true; - * mozilla::IsFloatingPoint::value is true; - * mozilla::IsFloatingPoint::value is false. - */ -template -struct IsFloatingPoint - : detail::IsFloatingPointHelper::Type> -{}; - -namespace detail { - -template -struct IsArrayHelper : FalseType {}; - -template -struct IsArrayHelper : TrueType {}; - -template -struct IsArrayHelper : TrueType {}; - -} // namespace detail - -/** - * IsArray determines whether a type is an array type, of known or unknown - * length. - * - * mozilla::IsArray::value is false; - * mozilla::IsArray::value is true; - * mozilla::IsArray::value is true. - */ -template -struct IsArray : detail::IsArrayHelper::Type> -{}; - -namespace detail { - -template -struct IsFunPtr; - -template -struct IsFunPtr - : public FalseType -{}; - -template -struct IsFunPtr - : public TrueType -{}; - -}; // namespace detail - -/** - * IsFunction determines whether a type is a function type. Function pointers - * don't qualify here--only the type of an actual function symbol. We do not - * correctly handle varags function types because of a bug in MSVC. - * - * Given the function: - * void f(int) {} - * - * mozilla::IsFunction is true; - * mozilla::IsFunction is false; - * mozilla::IsFunction is true. - */ -template -struct IsFunction - : public detail::IsFunPtr::Type *> -{}; - -namespace detail { - -template -struct IsPointerHelper : FalseType {}; - -template -struct IsPointerHelper : TrueType {}; - -} // namespace detail - -/** - * IsPointer determines whether a type is a possibly-CV-qualified pointer type - * (but not a pointer-to-member type). - * - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is false; - * mozilla::IsPointer::value is false. - * mozilla::IsPointer::value is false - */ -template -struct IsPointer : detail::IsPointerHelper::Type> -{}; - -/** - * IsLvalueReference determines whether a type is an lvalue reference. - * - * mozilla::IsLvalueReference::value is false; - * mozilla::IsLvalueReference::value is false; - * mozilla::IsLvalueReference::value is false; - * mozilla::IsLvalueReference::value is false; - * mozilla::IsLvalueReference::value is false; - * mozilla::IsLvalueReference::value is true; - * mozilla::IsLvalueReference::value is false. - */ -template -struct IsLvalueReference : FalseType {}; - -template -struct IsLvalueReference : TrueType {}; - -/** - * IsRvalueReference determines whether a type is an rvalue reference. - * - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is true. - */ -template -struct IsRvalueReference : FalseType {}; - -template -struct IsRvalueReference : TrueType {}; - -namespace detail { - -// __is_enum is a supported extension across all of our supported compilers. -template -struct IsEnumHelper - : IntegralConstant -{}; - -} // namespace detail - -/** - * IsEnum determines whether a type is an enum type. - * - * mozilla::IsEnum::value is true; - * mozilla::IsEnum::value is false; - * mozilla::IsEnum::value is false; - */ -template -struct IsEnum - : detail::IsEnumHelper::Type> -{}; - -namespace detail { - -// __is_class is a supported extension across all of our supported compilers: -// http://llvm.org/releases/3.0/docs/ClangReleaseNotes.html -// http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Type-Traits.html#Type-Traits -// http://msdn.microsoft.com/en-us/library/ms177194%28v=vs.100%29.aspx -template -struct IsClassHelper - : IntegralConstant -{}; - -} // namespace detail - -/** - * IsClass determines whether a type is a class type (but not a union). - * - * struct S {}; - * union U {}; - * mozilla::IsClass::value is false; - * mozilla::IsClass::value is true; - * mozilla::IsClass::value is false; - */ -template -struct IsClass - : detail::IsClassHelper::Type> -{}; - -/* 20.9.4.2 Composite type traits [meta.unary.comp] */ - -/** - * IsReference determines whether a type is an lvalue or rvalue reference. - * - * mozilla::IsReference::value is false; - * mozilla::IsReference::value is false; - * mozilla::IsReference::value is true; - * mozilla::IsReference::value is false; - * mozilla::IsReference::value is true; - * mozilla::IsReference::value is false; - * mozilla::IsReference::value is false; - * mozilla::IsReference::value is true; - * mozilla::IsReference::value is true; - * mozilla::IsReference::value is true. - */ -template -struct IsReference - : IntegralConstant::value || IsRvalueReference::value> -{}; - -/** - * IsArithmetic determines whether a type is arithmetic. A type is arithmetic - * iff it is an integral type or a floating point type. - * - * mozilla::IsArithmetic::value is true; - * mozilla::IsArithmetic::value is true; - * mozilla::IsArithmetic::value is false. - */ -template -struct IsArithmetic - : IntegralConstant::value || IsFloatingPoint::value> -{}; - -namespace detail { - -template -struct IsMemberPointerHelper : FalseType {}; - -template -struct IsMemberPointerHelper : TrueType {}; - -} // namespace detail - -/** - * IsMemberPointer determines whether a type is pointer to non-static member - * object or a pointer to non-static member function. - * - * mozilla::IsMemberPointer::value is true - * mozilla::IsMemberPointer::value is false - */ -template -struct IsMemberPointer - : detail::IsMemberPointerHelper::Type> -{}; - -/** - * IsScalar determines whether a type is a scalar type. - * - * mozilla::IsScalar::value is true - * mozilla::IsScalar::value is true - * mozilla::IsScalar::value is false - */ -template -struct IsScalar - : IntegralConstant::value || IsEnum::value || - IsPointer::value || IsMemberPointer::value> -{}; - -/* 20.9.4.3 Type properties [meta.unary.prop] */ - -/** - * IsConst determines whether a type is const or not. - * - * mozilla::IsConst::value is false; - * mozilla::IsConst::value is true; - * mozilla::IsConst::value is false. - */ -template -struct IsConst : FalseType {}; - -template -struct IsConst : TrueType {}; - -/** - * IsVolatile determines whether a type is volatile or not. - * - * mozilla::IsVolatile::value is false; - * mozilla::IsVolatile::value is true; - * mozilla::IsVolatile::value is false. - */ -template -struct IsVolatile : FalseType {}; - -template -struct IsVolatile : TrueType {}; - -/** - * Traits class for identifying POD types. Until C++11 there's no automatic - * way to detect PODs, so for the moment this is done manually. Users may - * define specializations of this class that inherit from mozilla::TrueType and - * mozilla::FalseType (or equivalently mozilla::IntegralConstant, or conveniently from mozilla::IsPod for composite types) as needed to - * ensure correct IsPod behavior. - */ -template -struct IsPod : public FalseType {}; - -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template struct IsPod : TrueType {}; - -namespace detail { - -// __is_empty is a supported extension across all of our supported compilers: -// http://llvm.org/releases/3.0/docs/ClangReleaseNotes.html -// http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Type-Traits.html#Type-Traits -// http://msdn.microsoft.com/en-us/library/ms177194%28v=vs.100%29.aspx -template -struct IsEmptyHelper - : IntegralConstant::value && __is_empty(T)> -{}; - -} // namespace detail - -/** - * IsEmpty determines whether a type is a class (but not a union) that is empty. - * - * A class is empty iff it and all its base classes have no non-static data - * members (except bit-fields of length 0) and no virtual member functions, and - * no base class is empty or a virtual base class. - * - * Intuitively, empty classes don't have any data that has to be stored in - * instances of those classes. (The size of the class must still be non-zero, - * because distinct array elements of any type must have different addresses. - * However, if the Empty Base Optimization is implemented by the compiler [most - * compilers implement it, and in certain cases C++11 requires it], the size of - * a class inheriting from an empty |Base| class need not be inflated by - * |sizeof(Base)|.) And intuitively, non-empty classes have data members and/or - * vtable pointers that must be stored in each instance for proper behavior. - * - * static_assert(!mozilla::IsEmpty::value, "not a class => not empty"); - * union U1 { int x; }; - * static_assert(!mozilla::IsEmpty::value, "not a class => not empty"); - * struct E1 {}; - * struct E2 { int : 0 }; - * struct E3 : E1 {}; - * struct E4 : E2 {}; - * static_assert(mozilla::IsEmpty::value && - * mozilla::IsEmpty::value && - * mozilla::IsEmpty::value && - * mozilla::IsEmpty::value, - * "all empty"); - * union U2 { E1 e1; }; - * static_assert(!mozilla::IsEmpty::value, "not a class => not empty"); - * struct NE1 { int x; }; - * struct NE2 : virtual E1 {}; - * struct NE3 : E2 { virtual ~NE3() {} }; - * struct NE4 { virtual void f() {} }; - * static_assert(!mozilla::IsEmpty::value && - * !mozilla::IsEmpty::value && - * !mozilla::IsEmpty::value && - * !mozilla::IsEmpty::value, - * "all empty"); - */ -template -struct IsEmpty : detail::IsEmptyHelper::Type> -{}; - - -namespace detail { - -template::value, - bool = IsIntegral::value, - typename NoCV = typename RemoveCV::Type> -struct IsSignedHelper; - -// Floating point is signed. -template -struct IsSignedHelper : TrueType {}; - -// Integral is conditionally signed. -template -struct IsSignedHelper - : IntegralConstant -{}; - -// Non-floating point, non-integral is not signed. -template -struct IsSignedHelper : FalseType {}; - -} // namespace detail - -/** - * IsSigned determines whether a type is a signed arithmetic type. |char| is - * considered a signed type if it has the same representation as |signed char|. - * - * mozilla::IsSigned::value is true; - * mozilla::IsSigned::value is false; - * mozilla::IsSigned::value is false; - * mozilla::IsSigned::value is true. - */ -template -struct IsSigned : detail::IsSignedHelper {}; - -namespace detail { - -template::value, - bool = IsIntegral::value, - typename NoCV = typename RemoveCV::Type> -struct IsUnsignedHelper; - -// Floating point is not unsigned. -template -struct IsUnsignedHelper : FalseType {}; - -// Integral is conditionally unsigned. -template -struct IsUnsignedHelper - : IntegralConstant::value || bool(NoCV(1) < NoCV(-1)))> -{}; - -// Non-floating point, non-integral is not unsigned. -template -struct IsUnsignedHelper : FalseType {}; - -} // namespace detail - -/** - * IsUnsigned determines whether a type is an unsigned arithmetic type. - * - * mozilla::IsUnsigned::value is false; - * mozilla::IsUnsigned::value is true; - * mozilla::IsUnsigned::value is true; - * mozilla::IsUnsigned::value is false. - */ -template -struct IsUnsigned : detail::IsUnsignedHelper {}; - -namespace detail { - -struct DoIsDestructibleImpl -{ - template().~T())> - static TrueType test(int); - template - static FalseType test(...); -}; - -template -struct IsDestructibleImpl : public DoIsDestructibleImpl -{ - typedef decltype(test(0)) Type; -}; - -} // namespace detail - -template -struct IsDestructible : public detail::IsDestructibleImpl::Type {}; - -/* 20.9.5 Type property queries [meta.unary.prop.query] */ - -/* 20.9.6 Relationships between types [meta.rel] */ - -/** - * IsSame tests whether two types are the same type. - * - * mozilla::IsSame::value is true; - * mozilla::IsSame::value is true; - * mozilla::IsSame::value is false; - * mozilla::IsSame::value is true; - * mozilla::IsSame::value is false; - * mozilla::IsSame::value is true. - */ -template -struct IsSame : FalseType {}; - -template -struct IsSame : TrueType {}; - -namespace detail { - -#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) - -template -struct BaseOfTester : IntegralConstant {}; - -#else - -// The trickery used to implement IsBaseOf here makes it possible to use it for -// the cases of private and multiple inheritance. This code was inspired by the -// sample code here: -// -// http://stackoverflow.com/questions/2910979/how-is-base-of-works -template -struct BaseOfHelper -{ -public: - operator Base*() const; - operator Derived*(); -}; - -template -struct BaseOfTester -{ -private: - template - static char test(Derived*, T); - static int test(Base*, int); - -public: - static const bool value = - sizeof(test(BaseOfHelper(), int())) == sizeof(char); -}; - -template -struct BaseOfTester -{ -private: - template - static char test(Derived*, T); - static int test(Base*, int); - -public: - static const bool value = - sizeof(test(BaseOfHelper(), int())) == sizeof(char); -}; - -template -struct BaseOfTester : FalseType {}; - -template -struct BaseOfTester : TrueType {}; - -template -struct BaseOfTester : TrueType {}; - -#endif - -} /* namespace detail */ - -/* - * IsBaseOf allows to know whether a given class is derived from another. - * - * Consider the following class definitions: - * - * class A {}; - * class B : public A {}; - * class C {}; - * - * mozilla::IsBaseOf::value is true; - * mozilla::IsBaseOf::value is false; - */ -template -struct IsBaseOf - : IntegralConstant::value> -{}; - -namespace detail { - -template -struct ConvertibleTester -{ -private: - template - static char test_helper(To1); - - template - static decltype(test_helper(DeclVal())) test(int); - - template - static int test(...); - -public: - static const bool value = - sizeof(test(0)) == sizeof(char); -}; - -} // namespace detail - -/** - * IsConvertible determines whether a value of type From will implicitly convert - * to a value of type To. For example: - * - * struct A {}; - * struct B : public A {}; - * struct C {}; - * - * mozilla::IsConvertible::value is true; - * mozilla::IsConvertible::value is true; - * mozilla::IsConvertible::value is true; - * mozilla::IsConvertible::value is true; - * mozilla::IsConvertible::value is false; - * mozilla::IsConvertible::value is false; - * mozilla::IsConvertible::value is false; - * mozilla::IsConvertible::value is false. - * - * For obscure reasons, you can't use IsConvertible when the types being tested - * are related through private inheritance, and you'll get a compile error if - * you try. Just don't do it! - * - * Note - we need special handling for void, which ConvertibleTester doesn't - * handle. The void handling here doesn't handle const/volatile void correctly, - * which could be easily fixed if the need arises. - */ -template -struct IsConvertible - : IntegralConstant::value> -{}; - -template -struct IsConvertible - : IntegralConstant::value> -{}; - -template -struct IsConvertible - : IntegralConstant::value> -{}; - -template<> -struct IsConvertible - : TrueType -{}; - -/* 20.9.7 Transformations between types [meta.trans] */ - -/* 20.9.7.1 Const-volatile modifications [meta.trans.cv] */ - -/** - * RemoveConst removes top-level const qualifications on a type. - * - * mozilla::RemoveConst::Type is int; - * mozilla::RemoveConst::Type is int; - * mozilla::RemoveConst::Type is const int*; - * mozilla::RemoveConst::Type is int*. - */ -template -struct RemoveConst -{ - typedef T Type; -}; - -template -struct RemoveConst -{ - typedef T Type; -}; - -/** - * RemoveVolatile removes top-level volatile qualifications on a type. - * - * mozilla::RemoveVolatile::Type is int; - * mozilla::RemoveVolatile::Type is int; - * mozilla::RemoveVolatile::Type is volatile int*; - * mozilla::RemoveVolatile::Type is int*. - */ -template -struct RemoveVolatile -{ - typedef T Type; -}; - -template -struct RemoveVolatile -{ - typedef T Type; -}; - -/** - * RemoveCV removes top-level const and volatile qualifications on a type. - * - * mozilla::RemoveCV::Type is int; - * mozilla::RemoveCV::Type is int; - * mozilla::RemoveCV::Type is int; - * mozilla::RemoveCV::Type is int*. - */ -template -struct RemoveCV -{ - typedef typename RemoveConst::Type>::Type Type; -}; - -/* 20.9.7.2 Reference modifications [meta.trans.ref] */ - -/** - * Converts reference types to the underlying types. - * - * mozilla::RemoveReference::Type is T; - * mozilla::RemoveReference::Type is T; - * mozilla::RemoveReference::Type is T; - */ - -template -struct RemoveReference -{ - typedef T Type; -}; - -template -struct RemoveReference -{ - typedef T Type; -}; - -template -struct RemoveReference -{ - typedef T Type; -}; - -template -struct Conditional; - -namespace detail { - -enum Voidness { TIsVoid, TIsNotVoid }; - -template::value ? TIsVoid : TIsNotVoid> -struct AddLvalueReferenceHelper; - -template -struct AddLvalueReferenceHelper -{ - typedef void Type; -}; - -template -struct AddLvalueReferenceHelper -{ - typedef T& Type; -}; - -} // namespace detail - -/** - * AddLvalueReference adds an lvalue & reference to T if one isn't already - * present. (Note: adding an lvalue reference to an rvalue && reference in - * essence replaces the && with a &&, per C+11 reference collapsing rules. For - * example, int&& would become int&.) - * - * The final computed type will only *not* be an lvalue reference if T is void. - * - * mozilla::AddLvalueReference::Type is int&; - * mozilla::AddLvalueRference::Type is volatile int&; - * mozilla::AddLvalueReference::Type is void*&; - * mozilla::AddLvalueReference::Type is void; - * mozilla::AddLvalueReference::Type is struct S&. - */ -template -struct AddLvalueReference - : detail::AddLvalueReferenceHelper -{}; - -namespace detail { - -template::value ? TIsVoid : TIsNotVoid> -struct AddRvalueReferenceHelper; - -template -struct AddRvalueReferenceHelper -{ - typedef void Type; -}; - -template -struct AddRvalueReferenceHelper -{ - typedef T&& Type; -}; - -} // namespace detail - -/** - * AddRvalueReference adds an rvalue && reference to T if one isn't already - * present. (Note: adding an rvalue reference to an lvalue & reference in - * essence keeps the &, per C+11 reference collapsing rules. For example, - * int& would remain int&.) - * - * The final computed type will only *not* be a reference if T is void. - * - * mozilla::AddRvalueReference::Type is int&&; - * mozilla::AddRvalueRference::Type is volatile int&; - * mozilla::AddRvalueRference::Type is const int&&; - * mozilla::AddRvalueReference::Type is void*&&; - * mozilla::AddRvalueReference::Type is void; - * mozilla::AddRvalueReference::Type is struct S&. - */ -template -struct AddRvalueReference - : detail::AddRvalueReferenceHelper -{}; - -/* 20.9.7.3 Sign modifications [meta.trans.sign] */ - -template -struct EnableIf; - -namespace detail { - -template -struct WithC : Conditional -{}; - -template -struct WithV : Conditional -{}; - - -template -struct WithCV : WithC::Type> -{}; - -template -struct CorrespondingSigned; - -template<> -struct CorrespondingSigned { typedef signed char Type; }; -template<> -struct CorrespondingSigned { typedef signed char Type; }; -template<> -struct CorrespondingSigned { typedef short Type; }; -template<> -struct CorrespondingSigned { typedef int Type; }; -template<> -struct CorrespondingSigned { typedef long Type; }; -template<> -struct CorrespondingSigned { typedef long long Type; }; - -template::Type, - bool IsSignedIntegerType = IsSigned::value && - !IsSame::value> -struct MakeSigned; - -template -struct MakeSigned -{ - typedef T Type; -}; - -template -struct MakeSigned - : WithCV::value, IsVolatile::value, - typename CorrespondingSigned::Type> -{}; - -} // namespace detail - -/** - * MakeSigned produces the corresponding signed integer type for a given - * integral type T, with the const/volatile qualifiers of T. T must be a - * possibly-const/volatile-qualified integral type that isn't bool. - * - * If T is already a signed integer type (not including char!), then T is - * produced. - * - * Otherwise, if T is an unsigned integer type, the signed variety of T, with - * T's const/volatile qualifiers, is produced. - * - * Otherwise, the integral type of the same size as T, with the lowest rank, - * with T's const/volatile qualifiers, is produced. (This basically only acts - * to produce signed char when T = char.) - * - * mozilla::MakeSigned::Type is signed long; - * mozilla::MakeSigned::Type is volatile int; - * mozilla::MakeSigned::Type is const signed short; - * mozilla::MakeSigned::Type is const signed char; - * mozilla::MakeSigned is an error; - * mozilla::MakeSigned is an error. - */ -template -struct MakeSigned - : EnableIf::value && - !IsSame::Type>::value, - typename detail::MakeSigned - >::Type -{}; - -namespace detail { - -template -struct CorrespondingUnsigned; - -template<> -struct CorrespondingUnsigned { typedef unsigned char Type; }; -template<> -struct CorrespondingUnsigned { typedef unsigned char Type; }; -template<> -struct CorrespondingUnsigned { typedef unsigned short Type; }; -template<> -struct CorrespondingUnsigned { typedef unsigned int Type; }; -template<> -struct CorrespondingUnsigned { typedef unsigned long Type; }; -template<> -struct CorrespondingUnsigned { typedef unsigned long long Type; }; - - -template::Type, - bool IsUnsignedIntegerType = IsUnsigned::value && - !IsSame::value> -struct MakeUnsigned; - -template -struct MakeUnsigned -{ - typedef T Type; -}; - -template -struct MakeUnsigned - : WithCV::value, IsVolatile::value, - typename CorrespondingUnsigned::Type> -{}; - -} // namespace detail - -/** - * MakeUnsigned produces the corresponding unsigned integer type for a given - * integral type T, with the const/volatile qualifiers of T. T must be a - * possibly-const/volatile-qualified integral type that isn't bool. - * - * If T is already an unsigned integer type (not including char!), then T is - * produced. - * - * Otherwise, if T is an signed integer type, the unsigned variety of T, with - * T's const/volatile qualifiers, is produced. - * - * Otherwise, the unsigned integral type of the same size as T, with the lowest - * rank, with T's const/volatile qualifiers, is produced. (This basically only - * acts to produce unsigned char when T = char.) - * - * mozilla::MakeUnsigned::Type is unsigned long; - * mozilla::MakeUnsigned::Type is volatile unsigned int; - * mozilla::MakeUnsigned::Type is const unsigned short; - * mozilla::MakeUnsigned::Type is const unsigned char; - * mozilla::MakeUnsigned is an error; - * mozilla::MakeUnsigned is an error. - */ -template -struct MakeUnsigned - : EnableIf::value && - !IsSame::Type>::value, - typename detail::MakeUnsigned - >::Type -{}; - -/* 20.9.7.4 Array modifications [meta.trans.arr] */ - -/** - * RemoveExtent produces either the type of the elements of the array T, or T - * itself. - * - * mozilla::RemoveExtent::Type is int; - * mozilla::RemoveExtent::Type is const int; - * mozilla::RemoveExtent::Type is volatile int; - * mozilla::RemoveExtent::Type is long[17]. - */ -template -struct RemoveExtent -{ - typedef T Type; -}; - -template -struct RemoveExtent -{ - typedef T Type; -}; - -template -struct RemoveExtent -{ - typedef T Type; -}; - -/* 20.9.7.5 Pointer modifications [meta.trans.ptr] */ - -namespace detail { - -template -struct RemovePointerHelper -{ - typedef T Type; -}; - -template -struct RemovePointerHelper -{ - typedef Pointee Type; -}; - -} // namespace detail - -/** - * Produces the pointed-to type if a pointer is provided, else returns the input - * type. Note that this does not dereference pointer-to-member pointers. - * - * struct S { bool m; void f(); }; - * mozilla::RemovePointer::Type is int; - * mozilla::RemovePointer::Type is int; - * mozilla::RemovePointer::Type is int; - * mozilla::RemovePointer::Type is int; - * mozilla::RemovePointer::Type is const long; - * mozilla::RemovePointer::Type is void; - * mozilla::RemovePointer::Type is void (S::*)(); - * mozilla::RemovePointer::Type is void(); - * mozilla::RemovePointer::Type is bool S::*. - */ -template -struct RemovePointer - : detail::RemovePointerHelper::Type> -{}; - -/** - * Converts T& to T*. Otherwise returns T* given T. Note that C++17 wants - * std::add_pointer to work differently for function types. We don't implement - * that behavior here. - * - * mozilla::AddPointer is int*; - * mozilla::AddPointer is int**; - * mozilla::AddPointer is int*; - * mozilla::AddPointer is int** const. - */ -template -struct AddPointer -{ - typedef typename RemoveReference::Type* Type; -}; - -/* 20.9.7.6 Other transformations [meta.trans.other] */ - -/** - * EnableIf is a struct containing a typedef of T if and only if B is true. - * - * mozilla::EnableIf::Type is int; - * mozilla::EnableIf::Type is a compile-time error. - * - * Use this template to implement SFINAE-style (Substitution Failure Is not An - * Error) requirements. For example, you might use it to impose a restriction - * on a template parameter: - * - * template - * class PodVector // vector optimized to store POD (memcpy-able) types - * { - * EnableIf::value, T>::Type* vector; - * size_t length; - * ... - * }; - */ -template -struct EnableIf -{}; - -template -struct EnableIf -{ - typedef T Type; -}; - -/** - * Conditional selects a class between two, depending on a given boolean value. - * - * mozilla::Conditional::Type is A; - * mozilla::Conditional::Type is B; - */ -template -struct Conditional -{ - typedef A Type; -}; - -template -struct Conditional -{ - typedef B Type; -}; - -namespace detail { - -template::value, - bool IsFunction = IsFunction::value> -struct DecaySelector; - -template -struct DecaySelector -{ - typedef typename RemoveCV::Type Type; -}; - -template -struct DecaySelector -{ - typedef typename RemoveExtent::Type* Type; -}; - -template -struct DecaySelector -{ - typedef typename AddPointer::Type Type; -}; - -}; // namespace detail - -/** - * Strips const/volatile off a type and decays it from an lvalue to an - * rvalue. So function types are converted to function pointers, arrays to - * pointers, and references are removed. - * - * mozilla::Decay::Type is int - * mozilla::Decay::Type is int - * mozilla::Decay::Type is int - * mozilla::Decay::Type is int - * mozilla::Decay::Type is int* - * mozilla::Decay::Type is int(*)(int) - */ -template -class Decay - : public detail::DecaySelector::Type> -{ -}; - -} /* namespace mozilla */ - -#endif /* mozilla_TypeTraits_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/TypedEnumBits.h b/android/armeabi-v7a/include/spidermonkey/mozilla/TypedEnumBits.h deleted file mode 100644 index 5ee6315c..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/TypedEnumBits.h +++ /dev/null @@ -1,156 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS allows using a typed enum as bit flags. - */ - -#ifndef mozilla_TypedEnumBits_h -#define mozilla_TypedEnumBits_h - -#include "mozilla/Attributes.h" -#include "mozilla/IntegerTypeTraits.h" - -namespace mozilla { - -/* - * The problem that CastableTypedEnumResult aims to solve is that - * typed enums are not convertible to bool, and there is no way to make them - * be, yet user code wants to be able to write - * - * if (myFlags & Flags::SOME_PARTICULAR_FLAG) (1) - * - * There are different approaches to solving this. Most of them require - * adapting user code. For example, we could implement operator! and have - * the user write - * - * if (!!(myFlags & Flags::SOME_PARTICULAR_FLAG)) (2) - * - * Or we could supply a IsNonZero() or Any() function returning whether - * an enum value is nonzero, and have the user write - * - * if (Any(Flags & Flags::SOME_PARTICULAR_FLAG)) (3) - * - * But instead, we choose to preserve the original user syntax (1) as it - * is inherently more readable, and to ease porting existing code to typed - * enums. We achieve this by having operator& and other binary bitwise - * operators have as return type a class, CastableTypedEnumResult, - * that wraps a typed enum but adds bool convertibility. - */ -template -class CastableTypedEnumResult -{ -private: - const E mValue; - -public: - explicit constexpr CastableTypedEnumResult(E aValue) - : mValue(aValue) - {} - - constexpr operator E() const { return mValue; } - - template - explicit constexpr - operator DestinationType() const { return DestinationType(mValue); } - - constexpr bool operator !() const { return !bool(mValue); } -}; - -#define MOZ_CASTABLETYPEDENUMRESULT_BINOP(Op, OtherType, ReturnType) \ -template \ -constexpr ReturnType \ -operator Op(const OtherType& aE, const CastableTypedEnumResult& aR) \ -{ \ - return ReturnType(aE Op OtherType(aR)); \ -} \ -template \ -constexpr ReturnType \ -operator Op(const CastableTypedEnumResult& aR, const OtherType& aE) \ -{ \ - return ReturnType(OtherType(aR) Op aE); \ -} \ -template \ -constexpr ReturnType \ -operator Op(const CastableTypedEnumResult& aR1, \ - const CastableTypedEnumResult& aR2) \ -{ \ - return ReturnType(OtherType(aR1) Op OtherType(aR2)); \ -} - -MOZ_CASTABLETYPEDENUMRESULT_BINOP(|, E, CastableTypedEnumResult) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(&, E, CastableTypedEnumResult) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(^, E, CastableTypedEnumResult) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(==, E, bool) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(!=, E, bool) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(||, bool, bool) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(&&, bool, bool) - -template -constexpr CastableTypedEnumResult -operator ~(const CastableTypedEnumResult& aR) -{ - return CastableTypedEnumResult(~(E(aR))); -} - -#define MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(Op) \ -template \ -E& \ -operator Op(E& aR1, \ - const CastableTypedEnumResult& aR2) \ -{ \ - return aR1 Op E(aR2); \ -} - -MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(&=) -MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(|=) -MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(^=) - -#undef MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP - -#undef MOZ_CASTABLETYPEDENUMRESULT_BINOP - -namespace detail { -template -struct UnsignedIntegerTypeForEnum - : UnsignedStdintTypeForSize -{}; -} // namespace detail - -} // namespace mozilla - -#define MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, Op) \ - inline constexpr mozilla::CastableTypedEnumResult \ - operator Op(Name a, Name b) \ - { \ - typedef mozilla::CastableTypedEnumResult Result; \ - typedef mozilla::detail::UnsignedIntegerTypeForEnum::Type U; \ - return Result(Name(U(a) Op U(b))); \ - } \ - \ - inline Name& \ - operator Op##=(Name& a, Name b) \ - { \ - return a = a Op b; \ - } - -/** - * MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS generates standard bitwise operators - * for the given enum type. Use this to enable using an enum type as bit-field. - */ -#define MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Name) \ - MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, |) \ - MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, &) \ - MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, ^) \ - inline constexpr mozilla::CastableTypedEnumResult \ - operator~(Name a) \ - { \ - typedef mozilla::CastableTypedEnumResult Result; \ - typedef mozilla::detail::UnsignedIntegerTypeForEnum::Type U; \ - return Result(Name(~(U(a)))); \ - } - -#endif // mozilla_TypedEnumBits_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Types.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Types.h deleted file mode 100644 index e7e18abb..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Types.h +++ /dev/null @@ -1,134 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* mfbt foundational types and macros. */ - -#ifndef mozilla_Types_h -#define mozilla_Types_h - -/* - * This header must be valid C and C++, includable by code embedding either - * SpiderMonkey or Gecko. - */ - -/* Expose all types and size_t. */ -#include -#include - -/* Implement compiler and linker macros needed for APIs. */ - -/* - * MOZ_EXPORT is used to declare and define a symbol or type which is externally - * visible to users of the current library. It encapsulates various decorations - * needed to properly export the method's symbol. - * - * api.h: - * extern MOZ_EXPORT int MeaningOfLife(void); - * extern MOZ_EXPORT int LuggageCombination; - * - * api.c: - * int MeaningOfLife(void) { return 42; } - * int LuggageCombination = 12345; - * - * If you are merely sharing a method across files, just use plain |extern|. - * These macros are designed for use by library interfaces -- not for normal - * methods or data used cross-file. - */ -#if defined(WIN32) -# define MOZ_EXPORT __declspec(dllexport) -#else /* Unix */ -# ifdef HAVE_VISIBILITY_ATTRIBUTE -# define MOZ_EXPORT __attribute__((visibility("default"))) -# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) -# define MOZ_EXPORT __global -# else -# define MOZ_EXPORT /* nothing */ -# endif -#endif - - -/* - * Whereas implementers use MOZ_EXPORT to declare and define library symbols, - * users use MOZ_IMPORT_API and MOZ_IMPORT_DATA to access them. Most often the - * implementer of the library will expose an API macro which expands to either - * the export or import version of the macro, depending upon the compilation - * mode. - */ -#ifdef _WIN32 -# if defined(__MWERKS__) -# define MOZ_IMPORT_API /* nothing */ -# else -# define MOZ_IMPORT_API __declspec(dllimport) -# endif -#else -# define MOZ_IMPORT_API MOZ_EXPORT -#endif - -#if defined(_WIN32) && !defined(__MWERKS__) -# define MOZ_IMPORT_DATA __declspec(dllimport) -#else -# define MOZ_IMPORT_DATA MOZ_EXPORT -#endif - -/* - * Consistent with the above comment, the MFBT_API and MFBT_DATA macros expose - * export mfbt declarations when building mfbt, and they expose import mfbt - * declarations when using mfbt. - */ -#if defined(IMPL_MFBT) -# define MFBT_API MOZ_EXPORT -# define MFBT_DATA MOZ_EXPORT -#else - /* - * On linux mozglue is linked in the program and we link libxul.so with - * -z,defs. Normally that causes the linker to reject undefined references in - * libxul.so, but as a loophole it allows undefined references to weak - * symbols. We add the weak attribute to the import version of the MFBT API - * macros to exploit this. - */ -# if defined(MOZ_GLUE_IN_PROGRAM) -# define MFBT_API __attribute__((weak)) MOZ_IMPORT_API -# define MFBT_DATA __attribute__((weak)) MOZ_IMPORT_DATA -# else -# define MFBT_API MOZ_IMPORT_API -# define MFBT_DATA MOZ_IMPORT_DATA -# endif -#endif - -/* - * C symbols in C++ code must be declared immediately within |extern "C"| - * blocks. However, in C code, they need not be declared specially. This - * difference is abstracted behind the MOZ_BEGIN_EXTERN_C and MOZ_END_EXTERN_C - * macros, so that the user need not know whether he is being used in C or C++ - * code. - * - * MOZ_BEGIN_EXTERN_C - * - * extern MOZ_EXPORT int MostRandomNumber(void); - * ...other declarations... - * - * MOZ_END_EXTERN_C - * - * This said, it is preferable to just use |extern "C"| in C++ header files for - * its greater clarity. - */ -#ifdef __cplusplus -# define MOZ_BEGIN_EXTERN_C extern "C" { -# define MOZ_END_EXTERN_C } -#else -# define MOZ_BEGIN_EXTERN_C -# define MOZ_END_EXTERN_C -#endif - -/* - * GCC's typeof is available when decltype is not. - */ -#if defined(__GNUC__) && defined(__cplusplus) && \ - !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L -# define decltype __typeof__ -#endif - -#endif /* mozilla_Types_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/UniquePtr.h b/android/armeabi-v7a/include/spidermonkey/mozilla/UniquePtr.h deleted file mode 100644 index 7e1035bc..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/UniquePtr.h +++ /dev/null @@ -1,697 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Smart pointer managing sole ownership of a resource. */ - -#ifndef mozilla_UniquePtr_h -#define mozilla_UniquePtr_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Compiler.h" -#include "mozilla/Move.h" -#include "mozilla/Pair.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -template class DefaultDelete; -template> class UniquePtr; - -} // namespace mozilla - -namespace mozilla { - -namespace detail { - -struct HasPointerTypeHelper -{ - template static double Test(...); - template static char Test(typename U::pointer* = 0); -}; - -template -class HasPointerType : public IntegralConstant(0)) == 1> -{ -}; - -template ::value> -struct PointerTypeImpl -{ - typedef typename D::pointer Type; -}; - -template -struct PointerTypeImpl -{ - typedef T* Type; -}; - -template -struct PointerType -{ - typedef typename PointerTypeImpl::Type>::Type Type; -}; - -} // namespace detail - -/** - * UniquePtr is a smart pointer that wholly owns a resource. Ownership may be - * transferred out of a UniquePtr through explicit action, but otherwise the - * resource is destroyed when the UniquePtr is destroyed. - * - * UniquePtr is similar to C++98's std::auto_ptr, but it improves upon auto_ptr - * in one crucial way: it's impossible to copy a UniquePtr. Copying an auto_ptr - * obviously *can't* copy ownership of its singly-owned resource. So what - * happens if you try to copy one? Bizarrely, ownership is implicitly - * *transferred*, preserving single ownership but breaking code that assumes a - * copy of an object is identical to the original. (This is why auto_ptr is - * prohibited in STL containers.) - * - * UniquePtr solves this problem by being *movable* rather than copyable. - * Instead of passing a |UniquePtr u| directly to the constructor or assignment - * operator, you pass |Move(u)|. In doing so you indicate that you're *moving* - * ownership out of |u|, into the target of the construction/assignment. After - * the transfer completes, |u| contains |nullptr| and may be safely destroyed. - * This preserves single ownership but also allows UniquePtr to be moved by - * algorithms that have been made move-safe. (Note: if |u| is instead a - * temporary expression, don't use |Move()|: just pass the expression, because - * it's already move-ready. For more information see Move.h.) - * - * UniquePtr is also better than std::auto_ptr in that the deletion operation is - * customizable. An optional second template parameter specifies a class that - * (through its operator()(T*)) implements the desired deletion policy. If no - * policy is specified, mozilla::DefaultDelete is used -- which will either - * |delete| or |delete[]| the resource, depending whether the resource is an - * array. Custom deletion policies ideally should be empty classes (no member - * fields, no member fields in base classes, no virtual methods/inheritance), - * because then UniquePtr can be just as efficient as a raw pointer. - * - * Use of UniquePtr proceeds like so: - * - * UniquePtr g1; // initializes to nullptr - * g1.reset(new int); // switch resources using reset() - * g1 = nullptr; // clears g1, deletes the int - * - * UniquePtr g2(new int); // owns that int - * int* p = g2.release(); // g2 leaks its int -- still requires deletion - * delete p; // now freed - * - * struct S { int x; S(int x) : x(x) {} }; - * UniquePtr g3, g4(new S(5)); - * g3 = Move(g4); // g3 owns the S, g4 cleared - * S* p = g3.get(); // g3 still owns |p| - * assert(g3->x == 5); // operator-> works (if .get() != nullptr) - * assert((*g3).x == 5); // also operator* (again, if not cleared) - * Swap(g3, g4); // g4 now owns the S, g3 cleared - * g3.swap(g4); // g3 now owns the S, g4 cleared - * UniquePtr g5(Move(g3)); // g5 owns the S, g3 cleared - * g5.reset(); // deletes the S, g5 cleared - * - * struct FreePolicy { void operator()(void* p) { free(p); } }; - * UniquePtr g6(static_cast(malloc(sizeof(int)))); - * int* ptr = g6.get(); - * g6 = nullptr; // calls free(ptr) - * - * Now, carefully note a few things you *can't* do: - * - * UniquePtr b1; - * b1 = new int; // BAD: can only assign another UniquePtr - * int* ptr = b1; // BAD: no auto-conversion to pointer, use get() - * - * UniquePtr b2(b1); // BAD: can't copy a UniquePtr - * UniquePtr b3 = b1; // BAD: can't copy-assign a UniquePtr - * - * (Note that changing a UniquePtr to store a direct |new| expression is - * permitted, but usually you should use MakeUnique, defined at the end of this - * header.) - * - * A few miscellaneous notes: - * - * UniquePtr, when not instantiated for an array type, can be move-constructed - * and move-assigned, not only from itself but from "derived" UniquePtr - * instantiations where U converts to T and E converts to D. If you want to use - * this, you're going to have to specify a deletion policy for both UniquePtr - * instantations, and T pretty much has to have a virtual destructor. In other - * words, this doesn't work: - * - * struct Base { virtual ~Base() {} }; - * struct Derived : Base {}; - * - * UniquePtr b1; - * // BAD: DefaultDelete and DefaultDelete don't interconvert - * UniquePtr d1(Move(b)); - * - * UniquePtr b2; - * UniquePtr> d2(Move(b2)); // okay - * - * UniquePtr is specialized for array types. Specializing with an array type - * creates a smart-pointer version of that array -- not a pointer to such an - * array. - * - * UniquePtr arr(new int[5]); - * arr[0] = 4; - * - * What else is different? Deletion of course uses |delete[]|. An operator[] - * is provided. Functionality that doesn't make sense for arrays is removed. - * The constructors and mutating methods only accept array pointers (not T*, U* - * that converts to T*, or UniquePtr or UniquePtr) or |nullptr|. - * - * It's perfectly okay for a function to return a UniquePtr. This transfers - * the UniquePtr's sole ownership of the data, to the fresh UniquePtr created - * in the calling function, that will then solely own that data. Such functions - * can return a local variable UniquePtr, |nullptr|, |UniquePtr(ptr)| where - * |ptr| is a |T*|, or a UniquePtr |Move()|'d from elsewhere. - * - * UniquePtr will commonly be a member of a class, with lifetime equivalent to - * that of that class. If you want to expose the related resource, you could - * expose a raw pointer via |get()|, but ownership of a raw pointer is - * inherently unclear. So it's better to expose a |const UniquePtr&| instead. - * This prohibits mutation but still allows use of |get()| when needed (but - * operator-> is preferred). Of course, you can only use this smart pointer as - * long as the enclosing class instance remains live -- no different than if you - * exposed the |get()| raw pointer. - * - * To pass a UniquePtr-managed resource as a pointer, use a |const UniquePtr&| - * argument. To specify an inout parameter (where the method may or may not - * take ownership of the resource, or reset it), or to specify an out parameter - * (where simply returning a |UniquePtr| isn't possible), use a |UniquePtr&| - * argument. To unconditionally transfer ownership of a UniquePtr - * into a method, use a |UniquePtr| argument. To conditionally transfer - * ownership of a resource into a method, should the method want it, use a - * |UniquePtr&&| argument. - */ -template -class UniquePtr -{ -public: - typedef T ElementType; - typedef D DeleterType; - typedef typename detail::PointerType::Type Pointer; - -private: - Pair mTuple; - - Pointer& ptr() { return mTuple.first(); } - const Pointer& ptr() const { return mTuple.first(); } - - DeleterType& del() { return mTuple.second(); } - const DeleterType& del() const { return mTuple.second(); } - -public: - /** - * Construct a UniquePtr containing |nullptr|. - */ - constexpr UniquePtr() - : mTuple(static_cast(nullptr), DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - /** - * Construct a UniquePtr containing |aPtr|. - */ - explicit UniquePtr(Pointer aPtr) - : mTuple(aPtr, DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - UniquePtr(Pointer aPtr, - typename Conditional::value, - D, - const D&>::Type aD1) - : mTuple(aPtr, aD1) - {} - - // If you encounter an error with MSVC10 about RemoveReference below, along - // the lines that "more than one partial specialization matches the template - // argument list": don't use UniquePtr! Ideally - // you should make deletion use the same function every time, using a - // deleter policy: - // - // // BAD, won't compile with MSVC10, deleter doesn't need to be a - // // variable at all - // typedef void (&FreeSignature)(void*); - // UniquePtr ptr((int*) malloc(sizeof(int)), free); - // - // // GOOD, compiles with MSVC10, deletion behavior statically known and - // // optimizable - // struct DeleteByFreeing - // { - // void operator()(void* aPtr) { free(aPtr); } - // }; - // - // If deletion really, truly, must be a variable: you might be able to work - // around this with a deleter class that contains the function reference. - // But this workaround is untried and untested, because variable deletion - // behavior really isn't something you should use. - UniquePtr(Pointer aPtr, - typename RemoveReference::Type&& aD2) - : mTuple(aPtr, Move(aD2)) - { - static_assert(!IsReference::value, - "rvalue deleter can't be stored by reference"); - } - - UniquePtr(UniquePtr&& aOther) - : mTuple(aOther.release(), Forward(aOther.get_deleter())) - {} - - MOZ_IMPLICIT - UniquePtr(decltype(nullptr)) - : mTuple(nullptr, DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - template - MOZ_IMPLICIT - UniquePtr(UniquePtr&& aOther, - typename EnableIf::Pointer, - Pointer>::value && - !IsArray::value && - (IsReference::value - ? IsSame::value - : IsConvertible::value), - int>::Type aDummy = 0) - : mTuple(aOther.release(), Forward(aOther.get_deleter())) - { - } - - ~UniquePtr() { reset(nullptr); } - - UniquePtr& operator=(UniquePtr&& aOther) - { - reset(aOther.release()); - get_deleter() = Forward(aOther.get_deleter()); - return *this; - } - - template - UniquePtr& operator=(UniquePtr&& aOther) - { - static_assert(IsConvertible::Pointer, - Pointer>::value, - "incompatible UniquePtr pointees"); - static_assert(!IsArray::value, - "can't assign from UniquePtr holding an array"); - - reset(aOther.release()); - get_deleter() = Forward(aOther.get_deleter()); - return *this; - } - - UniquePtr& operator=(decltype(nullptr)) - { - reset(nullptr); - return *this; - } - - T& operator*() const { return *get(); } - Pointer operator->() const - { - MOZ_ASSERT(get(), "dereferencing a UniquePtr containing nullptr"); - return get(); - } - - explicit operator bool() const { return get() != nullptr; } - - Pointer get() const { return ptr(); } - - DeleterType& get_deleter() { return del(); } - const DeleterType& get_deleter() const { return del(); } - - MOZ_MUST_USE Pointer release() - { - Pointer p = ptr(); - ptr() = nullptr; - return p; - } - - void reset(Pointer aPtr = Pointer()) - { - Pointer old = ptr(); - ptr() = aPtr; - if (old != nullptr) { - get_deleter()(old); - } - } - - void swap(UniquePtr& aOther) - { - mTuple.swap(aOther.mTuple); - } - - UniquePtr(const UniquePtr& aOther) = delete; // construct using Move()! - void operator=(const UniquePtr& aOther) = delete; // assign using Move()! -}; - -// In case you didn't read the comment by the main definition (you should!): the -// UniquePtr specialization exists to manage array pointers. It deletes -// such pointers using delete[], it will reject construction and modification -// attempts using U* or U[]. Otherwise it works like the normal UniquePtr. -template -class UniquePtr -{ -public: - typedef T* Pointer; - typedef T ElementType; - typedef D DeleterType; - -private: - Pair mTuple; - -public: - /** - * Construct a UniquePtr containing nullptr. - */ - constexpr UniquePtr() - : mTuple(static_cast(nullptr), DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - /** - * Construct a UniquePtr containing |aPtr|. - */ - explicit UniquePtr(Pointer aPtr) - : mTuple(aPtr, DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - // delete[] knows how to handle *only* an array of a single class type. For - // delete[] to work correctly, it must know the size of each element, the - // fields and base classes of each element requiring destruction, and so on. - // So forbid all overloads which would end up invoking delete[] on a pointer - // of the wrong type. - template - UniquePtr(U&& aU, - typename EnableIf::value && - IsConvertible::value, - int>::Type aDummy = 0) - = delete; - - UniquePtr(Pointer aPtr, - typename Conditional::value, - D, - const D&>::Type aD1) - : mTuple(aPtr, aD1) - {} - - // If you encounter an error with MSVC10 about RemoveReference below, along - // the lines that "more than one partial specialization matches the template - // argument list": don't use UniquePtr! See the - // comment by this constructor in the non-T[] specialization above. - UniquePtr(Pointer aPtr, - typename RemoveReference::Type&& aD2) - : mTuple(aPtr, Move(aD2)) - { - static_assert(!IsReference::value, - "rvalue deleter can't be stored by reference"); - } - - // Forbidden for the same reasons as stated above. - template - UniquePtr(U&& aU, V&& aV, - typename EnableIf::value && - IsConvertible::value, - int>::Type aDummy = 0) - = delete; - - UniquePtr(UniquePtr&& aOther) - : mTuple(aOther.release(), Forward(aOther.get_deleter())) - {} - - MOZ_IMPLICIT - UniquePtr(decltype(nullptr)) - : mTuple(nullptr, DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - ~UniquePtr() { reset(nullptr); } - - UniquePtr& operator=(UniquePtr&& aOther) - { - reset(aOther.release()); - get_deleter() = Forward(aOther.get_deleter()); - return *this; - } - - UniquePtr& operator=(decltype(nullptr)) - { - reset(); - return *this; - } - - explicit operator bool() const { return get() != nullptr; } - - T& operator[](decltype(sizeof(int)) aIndex) const { return get()[aIndex]; } - Pointer get() const { return mTuple.first(); } - - DeleterType& get_deleter() { return mTuple.second(); } - const DeleterType& get_deleter() const { return mTuple.second(); } - - MOZ_MUST_USE Pointer release() - { - Pointer p = mTuple.first(); - mTuple.first() = nullptr; - return p; - } - - void reset(Pointer aPtr = Pointer()) - { - Pointer old = mTuple.first(); - mTuple.first() = aPtr; - if (old != nullptr) { - mTuple.second()(old); - } - } - - void reset(decltype(nullptr)) - { - Pointer old = mTuple.first(); - mTuple.first() = nullptr; - if (old != nullptr) { - mTuple.second()(old); - } - } - - template - void reset(U) = delete; - - void swap(UniquePtr& aOther) { mTuple.swap(aOther.mTuple); } - - UniquePtr(const UniquePtr& aOther) = delete; // construct using Move()! - void operator=(const UniquePtr& aOther) = delete; // assign using Move()! -}; - -/** - * A default deletion policy using plain old operator delete. - * - * Note that this type can be specialized, but authors should beware of the risk - * that the specialization may at some point cease to match (either because it - * gets moved to a different compilation unit or the signature changes). If the - * non-specialized (|delete|-based) version compiles for that type but does the - * wrong thing, bad things could happen. - * - * This is a non-issue for types which are always incomplete (i.e. opaque handle - * types), since |delete|-ing such a type will always trigger a compilation - * error. - */ -template -class DefaultDelete -{ -public: - constexpr DefaultDelete() {} - - template - MOZ_IMPLICIT DefaultDelete(const DefaultDelete& aOther, - typename EnableIf::value, - int>::Type aDummy = 0) - {} - - void operator()(T* aPtr) const - { - static_assert(sizeof(T) > 0, "T must be complete"); - delete aPtr; - } -}; - -/** A default deletion policy using operator delete[]. */ -template -class DefaultDelete -{ -public: - constexpr DefaultDelete() {} - - void operator()(T* aPtr) const - { - static_assert(sizeof(T) > 0, "T must be complete"); - delete[] aPtr; - } - - template - void operator()(U* aPtr) const = delete; -}; - -template -void -Swap(UniquePtr& aX, UniquePtr& aY) -{ - aX.swap(aY); -} - -template -bool -operator==(const UniquePtr& aX, const UniquePtr& aY) -{ - return aX.get() == aY.get(); -} - -template -bool -operator!=(const UniquePtr& aX, const UniquePtr& aY) -{ - return aX.get() != aY.get(); -} - -template -bool -operator==(const UniquePtr& aX, decltype(nullptr)) -{ - return !aX; -} - -template -bool -operator==(decltype(nullptr), const UniquePtr& aX) -{ - return !aX; -} - -template -bool -operator!=(const UniquePtr& aX, decltype(nullptr)) -{ - return bool(aX); -} - -template -bool -operator!=(decltype(nullptr), const UniquePtr& aX) -{ - return bool(aX); -} - -// No operator<, operator>, operator<=, operator>= for now because simplicity. - -namespace detail { - -template -struct UniqueSelector -{ - typedef UniquePtr SingleObject; -}; - -template -struct UniqueSelector -{ - typedef UniquePtr UnknownBound; -}; - -template -struct UniqueSelector -{ - typedef UniquePtr KnownBound; -}; - -} // namespace detail - -/** - * MakeUnique is a helper function for allocating new'd objects and arrays, - * returning a UniquePtr containing the resulting pointer. The semantics of - * MakeUnique(...) are as follows. - * - * If Type is an array T[n]: - * Disallowed, deleted, no overload for you! - * If Type is an array T[]: - * MakeUnique(size_t) is the only valid overload. The pointer returned - * is as if by |new T[n]()|, which value-initializes each element. (If T - * isn't a class type, this will zero each element. If T is a class type, - * then roughly speaking, each element will be constructed using its default - * constructor. See C++11 [dcl.init]p7 for the full gory details.) - * If Type is non-array T: - * The arguments passed to MakeUnique(...) are forwarded into a - * |new T(...)| call, initializing the T as would happen if executing - * |T(...)|. - * - * There are various benefits to using MakeUnique instead of |new| expressions. - * - * First, MakeUnique eliminates use of |new| from code entirely. If objects are - * only created through UniquePtr, then (assuming all explicit release() calls - * are safe, including transitively, and no type-safety casting funniness) - * correctly maintained ownership of the UniquePtr guarantees no leaks are - * possible. (This pays off best if a class is only ever created through a - * factory method on the class, using a private constructor.) - * - * Second, initializing a UniquePtr using a |new| expression requires repeating - * the name of the new'd type, whereas MakeUnique in concert with the |auto| - * keyword names it only once: - * - * UniquePtr ptr1(new char()); // repetitive - * auto ptr2 = MakeUnique(); // shorter - * - * Of course this assumes the reader understands the operation MakeUnique - * performs. In the long run this is probably a reasonable assumption. In the - * short run you'll have to use your judgment about what readers can be expected - * to know, or to quickly look up. - * - * Third, a call to MakeUnique can be assigned directly to a UniquePtr. In - * contrast you can't assign a pointer into a UniquePtr without using the - * cumbersome reset(). - * - * UniquePtr p; - * p = new char; // ERROR - * p.reset(new char); // works, but fugly - * p = MakeUnique(); // preferred - * - * (And third, although not relevant to Mozilla: MakeUnique is exception-safe. - * An exception thrown after |new T| succeeds will leak that memory, unless the - * pointer is assigned to an object that will manage its ownership. UniquePtr - * ably serves this function.) - */ - -template -typename detail::UniqueSelector::SingleObject -MakeUnique(Args&&... aArgs) -{ - return UniquePtr(new T(Forward(aArgs)...)); -} - -template -typename detail::UniqueSelector::UnknownBound -MakeUnique(decltype(sizeof(int)) aN) -{ - typedef typename RemoveExtent::Type ArrayType; - return UniquePtr(new ArrayType[aN]()); -} - -template -typename detail::UniqueSelector::KnownBound -MakeUnique(Args&&... aArgs) = delete; - -} // namespace mozilla - -#endif /* mozilla_UniquePtr_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/UniquePtrExtensions.h b/android/armeabi-v7a/include/spidermonkey/mozilla/UniquePtrExtensions.h deleted file mode 100644 index d94f33ee..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/UniquePtrExtensions.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Useful extensions to UniquePtr. */ - -#ifndef mozilla_UniquePtrExtensions_h -#define mozilla_UniquePtrExtensions_h - -#include "mozilla/fallible.h" -#include "mozilla/UniquePtr.h" - -namespace mozilla { - -/** - * MakeUniqueFallible works exactly like MakeUnique, except that the memory - * allocation performed is done fallibly, i.e. it can return nullptr. - */ -template -typename detail::UniqueSelector::SingleObject -MakeUniqueFallible(Args&&... aArgs) -{ - return UniquePtr(new (fallible) T(Forward(aArgs)...)); -} - -template -typename detail::UniqueSelector::UnknownBound -MakeUniqueFallible(decltype(sizeof(int)) aN) -{ - typedef typename RemoveExtent::Type ArrayType; - return UniquePtr(new (fallible) ArrayType[aN]()); -} - -template -typename detail::UniqueSelector::KnownBound -MakeUniqueFallible(Args&&... aArgs) = delete; - -namespace detail { - -template -struct FreePolicy -{ - void operator()(const void* ptr) { - free(const_cast(ptr)); - } -}; - -} // namespace detail - -template -using UniqueFreePtr = UniquePtr>; - -} // namespace mozilla - -#endif // mozilla_UniquePtrExtensions_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Unused.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Unused.h deleted file mode 100644 index e693e32a..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Unused.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_unused_h -#define mozilla_unused_h - -#include "mozilla/Types.h" - -#ifdef __cplusplus - -namespace mozilla { - -// -// Suppress GCC warnings about unused return values with -// Unused << SomeFuncDeclaredWarnUnusedReturnValue(); -// -struct unused_t -{ - template - inline void - operator<<(const T& /*unused*/) const {} -}; - -extern MFBT_DATA const unused_t Unused; - -} // namespace mozilla - -#endif // __cplusplus - -// An alternative to mozilla::Unused for use in (a) C code and (b) code where -// linking with unused.o is difficult. -#define MOZ_UNUSED(expr) \ - do { if (expr) { (void)0; } } while (0) - -#endif // mozilla_unused_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Variant.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Variant.h deleted file mode 100644 index 8a33286e..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Variant.h +++ /dev/null @@ -1,625 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A template class for tagged unions. */ - -#include -#include - -#include "mozilla/Alignment.h" -#include "mozilla/Assertions.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -#ifndef mozilla_Variant_h -#define mozilla_Variant_h - -namespace mozilla { - -template -class Variant; - -namespace detail { - -// MaxSizeOf computes the maximum sizeof(T) for each T in Ts. - -template -struct MaxSizeOf -{ - static const size_t size = sizeof(T) > MaxSizeOf::size - ? sizeof(T) - : MaxSizeOf::size; -}; - -template -struct MaxSizeOf -{ - static const size_t size = sizeof(T); -}; - -// The `IsVariant` helper is used in conjunction with static_assert and -// `mozilla::EnableIf` to catch passing non-variant types to `Variant::is()` -// and friends at compile time, rather than at runtime. It ensures that the -// given type `Needle` is one of the types in the set of types `Haystack`. - -template -struct IsVariant; - -template -struct IsVariant -{ - static const bool value = false; -}; - -template -struct IsVariant -{ - static const bool value = true; -}; - -template -struct IsVariant : public IsVariant { }; - -/// SelectVariantTypeHelper is used in the implementation of SelectVariantType. -template -struct SelectVariantTypeHelper; - -template -struct SelectVariantTypeHelper -{ }; - -template -struct SelectVariantTypeHelper -{ - typedef T Type; -}; - -template -struct SelectVariantTypeHelper -{ - typedef const T Type; -}; - -template -struct SelectVariantTypeHelper -{ - typedef const T& Type; -}; - -template -struct SelectVariantTypeHelper -{ - typedef T&& Type; -}; - -template -struct SelectVariantTypeHelper - : public SelectVariantTypeHelper -{ }; - -/** - * SelectVariantType takes a type T and a list of variant types Variants and - * yields a type Type, selected from Variants, that can store a value of type T - * or a reference to type T. If no such type was found, Type is not defined. - */ -template -struct SelectVariantType - : public SelectVariantTypeHelper::Type>::Type, - Variants...> -{ }; - -// Compute a fast, compact type that can be used to hold integral values that -// distinctly map to every type in Ts. -template -struct VariantTag -{ -private: - static const size_t TypeCount = sizeof...(Ts); - -public: - using Type = - typename Conditional::Type - >::Type; -}; - -// TagHelper gets the given sentinel tag value for the given type T. This has to -// be split out from VariantImplementation because you can't nest a partial -// template specialization within a template class. - -template -struct TagHelper; - -// In the case where T != U, we continue recursion. -template -struct TagHelper -{ - static Tag tag() { return Next::template tag(); } -}; - -// In the case where T == U, return the tag number. -template -struct TagHelper -{ - static Tag tag() { return Tag(N); } -}; - -// The VariantImplementation template provides the guts of mozilla::Variant. We -// create a VariantImplementation for each T in Ts... which handles -// construction, destruction, etc for when the Variant's type is T. If the -// Variant's type isn't T, it punts the request on to the next -// VariantImplementation. - -template -struct VariantImplementation; - -// The singly typed Variant / recursion base case. -template -struct VariantImplementation -{ - template - static Tag tag() { - static_assert(mozilla::IsSame::value, - "mozilla::Variant: tag: bad type!"); - return Tag(N); - } - - template - static void copyConstruct(void* aLhs, const Variant& aRhs) { - new (aLhs) T(aRhs.template as()); - } - - template - static void moveConstruct(void* aLhs, Variant&& aRhs) { - new (aLhs) T(aRhs.template extract()); - } - - template - static void destroy(Variant& aV) { - aV.template as().~T(); - } - - template - static bool - equal(const Variant& aLhs, const Variant& aRhs) { - return aLhs.template as() == aRhs.template as(); - } - - template - static auto - match(Matcher&& aMatcher, ConcreteVariant& aV) - -> decltype(aMatcher.match(aV.template as())) - { - return aMatcher.match(aV.template as()); - } -}; - -// VariantImplementation for some variant type T. -template -struct VariantImplementation -{ - // The next recursive VariantImplementation. - using Next = VariantImplementation; - - template - static Tag tag() { - return TagHelper::value>::tag(); - } - - template - static void copyConstruct(void* aLhs, const Variant& aRhs) { - if (aRhs.template is()) { - new (aLhs) T(aRhs.template as()); - } else { - Next::copyConstruct(aLhs, aRhs); - } - } - - template - static void moveConstruct(void* aLhs, Variant&& aRhs) { - if (aRhs.template is()) { - new (aLhs) T(aRhs.template extract()); - } else { - Next::moveConstruct(aLhs, aRhs); - } - } - - template - static void destroy(Variant& aV) { - if (aV.template is()) { - aV.template as().~T(); - } else { - Next::destroy(aV); - } - } - - template - static bool equal(const Variant& aLhs, const Variant& aRhs) { - if (aLhs.template is()) { - MOZ_ASSERT(aRhs.template is()); - return aLhs.template as() == aRhs.template as(); - } else { - return Next::equal(aLhs, aRhs); - } - } - - template - static auto - match(Matcher&& aMatcher, ConcreteVariant& aV) - -> decltype(aMatcher.match(aV.template as())) - { - if (aV.template is()) { - return aMatcher.match(aV.template as()); - } else { - // If you're seeing compilation errors here like "no matching - // function for call to 'match'" then that means that the - // Matcher doesn't exhaust all variant types. There must exist a - // Matcher::match(T&) for every variant type T. - // - // If you're seeing compilation errors here like "cannot - // initialize return object of type <...> with an rvalue of type - // <...>" then that means that the Matcher::match(T&) overloads - // are returning different types. They must all return the same - // Matcher::ReturnType type. - return Next::match(aMatcher, aV); - } - } -}; - -/** - * AsVariantTemporary stores a value of type T to allow construction of a - * Variant value via type inference. Because T is copied and there's no - * guarantee that the copy can be elided, AsVariantTemporary is best used with - * primitive or very small types. - */ -template -struct AsVariantTemporary -{ - explicit AsVariantTemporary(const T& aValue) - : mValue(aValue) - {} - - template - explicit AsVariantTemporary(U&& aValue) - : mValue(Forward(aValue)) - {} - - AsVariantTemporary(const AsVariantTemporary& aOther) - : mValue(aOther.mValue) - {} - - AsVariantTemporary(AsVariantTemporary&& aOther) - : mValue(Move(aOther.mValue)) - {} - - AsVariantTemporary() = delete; - void operator=(const AsVariantTemporary&) = delete; - void operator=(AsVariantTemporary&&) = delete; - - typename RemoveConst::Type>::Type mValue; -}; - -} // namespace detail - -/** - * # mozilla::Variant - * - * A variant / tagged union / heterogenous disjoint union / sum-type template - * class. Similar in concept to (but not derived from) `boost::variant`. - * - * Sometimes, you may wish to use a C union with non-POD types. However, this is - * forbidden in C++ because it is not clear which type in the union should have - * its constructor and destructor run on creation and deletion - * respectively. This is the problem that `mozilla::Variant` solves. - * - * ## Usage - * - * A `mozilla::Variant` instance is constructed (via move or copy) from one of - * its variant types (ignoring const and references). It does *not* support - * construction from subclasses of variant types or types that coerce to one of - * the variant types. - * - * Variant v1('a'); - * Variant, B, C> v2(MakeUnique()); - * - * Because specifying the full type of a Variant value is often verbose, - * AsVariant() can be used to construct a Variant value using type inference in - * contexts such as expressions or when returning values from functions. Because - * AsVariant() must copy or move the value into a temporary and this cannot - * necessarily be elided by the compiler, it's mostly appropriate only for use - * with primitive or very small types. - * - * - * Variant Foo() { return AsVariant('x'); } - * // ... - * Variant v1 = Foo(); // v1 holds char('x'). - * - * All access to the contained value goes through type-safe accessors. - * - * void - * Foo(Variant v) - * { - * if (v.is()) { - * A& ref = v.as(); - * ... - * } else { - * ... - * } - * } - * - * Attempting to use the contained value as type `T1` when the `Variant` - * instance contains a value of type `T2` causes an assertion failure. - * - * A a; - * Variant v(a); - * v.as(); // <--- Assertion failure! - * - * Trying to use a `Variant` instance as some type `U` that is not a - * member of the set of `Ts...` is a compiler error. - * - * A a; - * Variant v(a); - * v.as(); // <--- Compiler error! - * - * Additionally, you can turn a `Variant` that `is` into a `T` by moving it - * out of the containing `Variant` instance with the `extract` method: - * - * Variant, B, C> v(MakeUnique()); - * auto ptr = v.extract>(); - * - * Finally, you can exhaustively match on the contained variant and branch into - * different code paths depending which type is contained. This is preferred to - * manually checking every variant type T with is() because it provides - * compile-time checking that you handled every type, rather than runtime - * assertion failures. - * - * // Bad! - * char* foo(Variant& v) { - * if (v.is()) { - * return ...; - * } else if (v.is()) { - * return ...; - * } else { - * return doSomething(v.as()); // Forgot about case D! - * } - * } - * - * // Good! - * struct FooMatcher - * { - * // The return type of all matchers must be identical. - * char* match(A& a) { ... } - * char* match(B& b) { ... } - * char* match(C& c) { ... } - * char* match(D& d) { ... } // Compile-time error to forget D! - * } - * char* foo(Variant& v) { - * return v.match(FooMatcher()); - * } - * - * ## Examples - * - * A tree is either an empty leaf, or a node with a value and two children: - * - * struct Leaf { }; - * - * template - * struct Node - * { - * T value; - * Tree* left; - * Tree* right; - * }; - * - * template - * using Tree = Variant>; - * - * A copy-on-write string is either a non-owning reference to some existing - * string, or an owning reference to our copy: - * - * class CopyOnWriteString - * { - * Variant> string; - * - * ... - * }; - */ -template -class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS Variant -{ - using Tag = typename detail::VariantTag::Type; - using Impl = detail::VariantImplementation; - using RawData = AlignedStorage::size>; - - // Raw storage for the contained variant value. - RawData raw; - - // Each type is given a unique tag value that lets us keep track of the - // contained variant value's type. - Tag tag; - - void* ptr() { - return reinterpret_cast(&raw); - } - -public: - /** Perfect forwarding construction for some variant type T. */ - template::Type> - explicit Variant(RefT&& aT) - : tag(Impl::template tag()) - { - new (ptr()) T(Forward(aT)); - } - - /** - * Constructs this Variant from an AsVariantTemporary such that T can be - * stored in one of the types allowable in this Variant. This is used in the - * implementation of AsVariant(). - */ - template::Type> - MOZ_IMPLICIT Variant(detail::AsVariantTemporary&& aValue) - : tag(Impl::template tag()) - { - new (ptr()) T(Move(aValue.mValue)); - } - - /** Copy construction. */ - Variant(const Variant& aRhs) - : tag(aRhs.tag) - { - Impl::copyConstruct(ptr(), aRhs); - } - - /** Move construction. */ - Variant(Variant&& aRhs) - : tag(aRhs.tag) - { - Impl::moveConstruct(ptr(), Move(aRhs)); - } - - /** Copy assignment. */ - Variant& operator=(const Variant& aRhs) { - MOZ_ASSERT(&aRhs != this, "self-assign disallowed"); - this->~Variant(); - new (this) Variant(aRhs); - return *this; - } - - /** Move assignment. */ - Variant& operator=(Variant&& aRhs) { - MOZ_ASSERT(&aRhs != this, "self-assign disallowed"); - this->~Variant(); - new (this) Variant(Move(aRhs)); - return *this; - } - - /** Move assignment from AsVariant(). */ - template - Variant& operator=(detail::AsVariantTemporary&& aValue) - { - this->~Variant(); - new (this) Variant(Move(aValue)); - return *this; - } - - ~Variant() - { - Impl::destroy(*this); - } - - /** Check which variant type is currently contained. */ - template - bool is() const { - static_assert(detail::IsVariant::value, - "provided a type not found in this Variant's type list"); - return Impl::template tag() == tag; - } - - /** - * Operator == overload that defers to the variant type's operator== - * implementation if the rhs is tagged as the same type as this one. - */ - bool operator==(const Variant& aRhs) const { - return tag == aRhs.tag && Impl::equal(*this, aRhs); - } - - /** - * Operator != overload that defers to the negation of the variant type's - * operator== implementation if the rhs is tagged as the same type as this - * one. - */ - bool operator!=(const Variant& aRhs) const { - return !(*this == aRhs); - } - - // Accessors for working with the contained variant value. - - /** Mutable reference. */ - template - T& as() { - static_assert(detail::IsVariant::value, - "provided a type not found in this Variant's type list"); - MOZ_ASSERT(is()); - return *reinterpret_cast(&raw); - } - - /** Immutable const reference. */ - template - const T& as() const { - static_assert(detail::IsVariant::value, - "provided a type not found in this Variant's type list"); - MOZ_ASSERT(is()); - return *reinterpret_cast(&raw); - } - - /** - * Extract the contained variant value from this container into a temporary - * value. On completion, the value in the variant will be in a - * safely-destructible state, as determined by the behavior of T's move - * constructor when provided the variant's internal value. - */ - template - T extract() { - static_assert(detail::IsVariant::value, - "provided a type not found in this Variant's type list"); - MOZ_ASSERT(is()); - return T(Move(as())); - } - - // Exhaustive matching of all variant types on the contained value. - - /** Match on an immutable const reference. */ - template - auto - match(Matcher&& aMatcher) const - -> decltype(Impl::match(aMatcher, *this)) - { - return Impl::match(aMatcher, *this); - } - - /** Match on a mutable non-const reference. */ - template - auto - match(Matcher&& aMatcher) - -> decltype(Impl::match(aMatcher, *this)) - { - return Impl::match(aMatcher, *this); - } -}; - -/* - * AsVariant() is used to construct a Variant value containing the - * provided T value using type inference. It can be used to construct Variant - * values in expressions or return them from functions without specifying the - * entire Variant type. - * - * Because AsVariant() must copy or move the value into a temporary and this - * cannot necessarily be elided by the compiler, it's mostly appropriate only - * for use with primitive or very small types. - * - * AsVariant() returns a AsVariantTemporary value which is implicitly - * convertible to any Variant that can hold a value of type T. - */ -template -detail::AsVariantTemporary -AsVariant(T&& aValue) -{ - return detail::AsVariantTemporary(Forward(aValue)); -} - -} // namespace mozilla - -#endif /* mozilla_Variant_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/Vector.h b/android/armeabi-v7a/include/spidermonkey/mozilla/Vector.h deleted file mode 100644 index fc43afcf..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/Vector.h +++ /dev/null @@ -1,1491 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A type/length-parametrized vector class. */ - -#ifndef mozilla_Vector_h -#define mozilla_Vector_h - -#include "mozilla/Alignment.h" -#include "mozilla/AllocPolicy.h" -#include "mozilla/ArrayUtils.h" // for PointerRangeSize -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/MathAlgorithms.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" -#include "mozilla/OperatorNewExtensions.h" -#include "mozilla/ReentrancyGuard.h" -#include "mozilla/TemplateLib.h" -#include "mozilla/TypeTraits.h" - -#include // for placement new - -/* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */ -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4345) -#endif - -namespace mozilla { - -template -class Vector; - -namespace detail { - -/* - * Check that the given capacity wastes the minimal amount of space if - * allocated on the heap. This means that aCapacity*sizeof(T) is as close to a - * power-of-two as possible. growStorageBy() is responsible for ensuring this. - */ -template -static bool CapacityHasExcessSpace(size_t aCapacity) -{ - size_t size = aCapacity * sizeof(T); - return RoundUpPow2(size) - size >= sizeof(T); -} - -/* - * This template class provides a default implementation for vector operations - * when the element type is not known to be a POD, as judged by IsPod. - */ -template -struct VectorImpl -{ - /* - * Constructs an object in the uninitialized memory at *aDst with aArgs. - */ - template - MOZ_NONNULL(1) - static inline void new_(T* aDst, Args&&... aArgs) - { - new(KnownNotNull, aDst) T(Forward(aArgs)...); - } - - /* Destroys constructed objects in the range [aBegin, aEnd). */ - static inline void destroy(T* aBegin, T* aEnd) - { - MOZ_ASSERT(aBegin <= aEnd); - for (T* p = aBegin; p < aEnd; ++p) { - p->~T(); - } - } - - /* Constructs objects in the uninitialized range [aBegin, aEnd). */ - static inline void initialize(T* aBegin, T* aEnd) - { - MOZ_ASSERT(aBegin <= aEnd); - for (T* p = aBegin; p < aEnd; ++p) { - new_(p); - } - } - - /* - * Copy-constructs objects in the uninitialized range - * [aDst, aDst+(aSrcEnd-aSrcStart)) from the range [aSrcStart, aSrcEnd). - */ - template - static inline void copyConstruct(T* aDst, - const U* aSrcStart, const U* aSrcEnd) - { - MOZ_ASSERT(aSrcStart <= aSrcEnd); - for (const U* p = aSrcStart; p < aSrcEnd; ++p, ++aDst) { - new_(aDst, *p); - } - } - - /* - * Move-constructs objects in the uninitialized range - * [aDst, aDst+(aSrcEnd-aSrcStart)) from the range [aSrcStart, aSrcEnd). - */ - template - static inline void moveConstruct(T* aDst, U* aSrcStart, U* aSrcEnd) - { - MOZ_ASSERT(aSrcStart <= aSrcEnd); - for (U* p = aSrcStart; p < aSrcEnd; ++p, ++aDst) { - new_(aDst, Move(*p)); - } - } - - /* - * Copy-constructs objects in the uninitialized range [aDst, aDst+aN) from - * the same object aU. - */ - template - static inline void copyConstructN(T* aDst, size_t aN, const U& aU) - { - for (T* end = aDst + aN; aDst < end; ++aDst) { - new_(aDst, aU); - } - } - - /* - * Grows the given buffer to have capacity aNewCap, preserving the objects - * constructed in the range [begin, end) and updating aV. Assumes that (1) - * aNewCap has not overflowed, and (2) multiplying aNewCap by sizeof(T) will - * not overflow. - */ - static inline MOZ_MUST_USE bool - growTo(Vector& aV, size_t aNewCap) - { - MOZ_ASSERT(!aV.usingInlineStorage()); - MOZ_ASSERT(!CapacityHasExcessSpace(aNewCap)); - T* newbuf = aV.template pod_malloc(aNewCap); - if (MOZ_UNLIKELY(!newbuf)) { - return false; - } - T* dst = newbuf; - T* src = aV.beginNoCheck(); - for (; src < aV.endNoCheck(); ++dst, ++src) { - new_(dst, Move(*src)); - } - VectorImpl::destroy(aV.beginNoCheck(), aV.endNoCheck()); - aV.free_(aV.mBegin); - aV.mBegin = newbuf; - /* aV.mLength is unchanged. */ - aV.mCapacity = aNewCap; - return true; - } -}; - -/* - * This partial template specialization provides a default implementation for - * vector operations when the element type is known to be a POD, as judged by - * IsPod. - */ -template -struct VectorImpl -{ - template - MOZ_NONNULL(1) - static inline void new_(T* aDst, Args&&... aArgs) - { - // Explicitly construct a local object instead of using a temporary since - // T(args...) will be treated like a C-style cast in the unary case and - // allow unsafe conversions. Both forms should be equivalent to an - // optimizing compiler. - T temp(Forward(aArgs)...); - *aDst = temp; - } - - static inline void destroy(T*, T*) {} - - static inline void initialize(T* aBegin, T* aEnd) - { - /* - * You would think that memset would be a big win (or even break even) - * when we know T is a POD. But currently it's not. This is probably - * because |append| tends to be given small ranges and memset requires - * a function call that doesn't get inlined. - * - * memset(aBegin, 0, sizeof(T) * (aEnd - aBegin)); - */ - MOZ_ASSERT(aBegin <= aEnd); - for (T* p = aBegin; p < aEnd; ++p) { - new_(p); - } - } - - template - static inline void copyConstruct(T* aDst, - const U* aSrcStart, const U* aSrcEnd) - { - /* - * See above memset comment. Also, notice that copyConstruct is - * currently templated (T != U), so memcpy won't work without - * requiring T == U. - * - * memcpy(aDst, aSrcStart, sizeof(T) * (aSrcEnd - aSrcStart)); - */ - MOZ_ASSERT(aSrcStart <= aSrcEnd); - for (const U* p = aSrcStart; p < aSrcEnd; ++p, ++aDst) { - new_(aDst, *p); - } - } - - template - static inline void moveConstruct(T* aDst, - const U* aSrcStart, const U* aSrcEnd) - { - copyConstruct(aDst, aSrcStart, aSrcEnd); - } - - static inline void copyConstructN(T* aDst, size_t aN, const T& aT) - { - for (T* end = aDst + aN; aDst < end; ++aDst) { - new_(aDst, aT); - } - } - - static inline MOZ_MUST_USE bool - growTo(Vector& aV, size_t aNewCap) - { - MOZ_ASSERT(!aV.usingInlineStorage()); - MOZ_ASSERT(!CapacityHasExcessSpace(aNewCap)); - T* newbuf = aV.template pod_realloc(aV.mBegin, aV.mCapacity, aNewCap); - if (MOZ_UNLIKELY(!newbuf)) { - return false; - } - aV.mBegin = newbuf; - /* aV.mLength is unchanged. */ - aV.mCapacity = aNewCap; - return true; - } - - static inline void - podResizeToFit(Vector& aV) - { - if (aV.usingInlineStorage() || aV.mLength == aV.mCapacity) { - return; - } - T* newbuf = aV.template pod_realloc(aV.mBegin, aV.mCapacity, aV.mLength); - if (MOZ_UNLIKELY(!newbuf)) { - return; - } - aV.mBegin = newbuf; - aV.mCapacity = aV.mLength; - } -}; - -// A struct for TestVector.cpp to access private internal fields. -// DO NOT DEFINE IN YOUR OWN CODE. -struct VectorTesting; - -} // namespace detail - -/* - * STL-like container providing a short-lived, dynamic buffer. Vector calls the - * constructors/destructors of all elements stored in its internal buffer, so - * non-PODs may be safely used. Additionally, Vector will store the first N - * elements in-place before resorting to dynamic allocation. - * - * T requirements: - * - default and copy constructible, assignable, destructible - * - operations do not throw - * MinInlineCapacity requirements: - * - any value, however, MinInlineCapacity is clamped to min/max values - * AllocPolicy: - * - see "Allocation policies" in AllocPolicy.h (defaults to - * mozilla::MallocAllocPolicy) - * - * Vector is not reentrant: T member functions called during Vector member - * functions must not call back into the same object! - */ -template -class Vector final : private AllocPolicy -{ - /* utilities */ - - static const bool kElemIsPod = IsPod::value; - typedef detail::VectorImpl Impl; - friend struct detail::VectorImpl; - - friend struct detail::VectorTesting; - - MOZ_MUST_USE bool growStorageBy(size_t aIncr); - MOZ_MUST_USE bool convertToHeapStorage(size_t aNewCap); - MOZ_MUST_USE bool maybeCheckSimulatedOOM(size_t aRequestedSize); - - /* magic constants */ - - static const int kMaxInlineBytes = 1024; - - /* compute constants */ - - /* - * Consider element size to be 1 for buffer sizing if there are 0 inline - * elements. This allows us to compile when the definition of the element - * type is not visible here. - * - * Explicit specialization is only allowed at namespace scope, so in order - * to keep everything here, we use a dummy template parameter with partial - * specialization. - */ - template - struct ElemSize - { - static const size_t value = sizeof(T); - }; - template - struct ElemSize<0, Dummy> - { - static const size_t value = 1; - }; - - static const size_t kInlineCapacity = - tl::Min::value>::value; - - /* Calculate inline buffer size; avoid 0-sized array. */ - static const size_t kInlineBytes = - tl::Max<1, kInlineCapacity * ElemSize::value>::value; - - /* member data */ - - /* - * Pointer to the buffer, be it inline or heap-allocated. Only [mBegin, - * mBegin + mLength) hold valid constructed T objects. The range [mBegin + - * mLength, mBegin + mCapacity) holds uninitialized memory. The range - * [mBegin + mLength, mBegin + mReserved) also holds uninitialized memory - * previously allocated by a call to reserve(). - */ - T* mBegin; - - /* Number of elements in the vector. */ - size_t mLength; - - /* Max number of elements storable in the vector without resizing. */ - size_t mCapacity; - -#ifdef DEBUG - /* Max elements of reserved or used space in this vector. */ - size_t mReserved; -#endif - - /* Memory used for inline storage. */ - AlignedStorage mStorage; - -#ifdef DEBUG - friend class ReentrancyGuard; - bool mEntered; -#endif - - /* private accessors */ - - bool usingInlineStorage() const - { - return mBegin == const_cast(this)->inlineStorage(); - } - - T* inlineStorage() - { - return static_cast(mStorage.addr()); - } - - T* beginNoCheck() const - { - return mBegin; - } - - T* endNoCheck() - { - return mBegin + mLength; - } - - const T* endNoCheck() const - { - return mBegin + mLength; - } - -#ifdef DEBUG - /** - * The amount of explicitly allocated space in this vector that is immediately - * available to be filled by appending additional elements. This value is - * always greater than or equal to |length()| -- the vector's actual elements - * are implicitly reserved. This value is always less than or equal to - * |capacity()|. It may be explicitly increased using the |reserve()| method. - */ - size_t reserved() const - { - MOZ_ASSERT(mLength <= mReserved); - MOZ_ASSERT(mReserved <= mCapacity); - return mReserved; - } -#endif - - /* Append operations guaranteed to succeed due to pre-reserved space. */ - template void internalAppend(U&& aU); - template - void internalAppendAll(const Vector& aU); - void internalAppendN(const T& aT, size_t aN); - template void internalAppend(const U* aBegin, size_t aLength); - -public: - static const size_t sMaxInlineStorage = MinInlineCapacity; - - typedef T ElementType; - - explicit Vector(AllocPolicy = AllocPolicy()); - Vector(Vector&&); /* Move constructor. */ - Vector& operator=(Vector&&); /* Move assignment. */ - ~Vector(); - - /* accessors */ - - const AllocPolicy& allocPolicy() const { return *this; } - - AllocPolicy& allocPolicy() { return *this; } - - enum { InlineLength = MinInlineCapacity }; - - size_t length() const { return mLength; } - - bool empty() const { return mLength == 0; } - - size_t capacity() const { return mCapacity; } - - T* begin() - { - MOZ_ASSERT(!mEntered); - return mBegin; - } - - const T* begin() const - { - MOZ_ASSERT(!mEntered); - return mBegin; - } - - T* end() - { - MOZ_ASSERT(!mEntered); - return mBegin + mLength; - } - - const T* end() const - { - MOZ_ASSERT(!mEntered); - return mBegin + mLength; - } - - T& operator[](size_t aIndex) - { - MOZ_ASSERT(!mEntered); - MOZ_ASSERT(aIndex < mLength); - return begin()[aIndex]; - } - - const T& operator[](size_t aIndex) const - { - MOZ_ASSERT(!mEntered); - MOZ_ASSERT(aIndex < mLength); - return begin()[aIndex]; - } - - T& back() - { - MOZ_ASSERT(!mEntered); - MOZ_ASSERT(!empty()); - return *(end() - 1); - } - - const T& back() const - { - MOZ_ASSERT(!mEntered); - MOZ_ASSERT(!empty()); - return *(end() - 1); - } - - class Range - { - friend class Vector; - T* mCur; - T* mEnd; - Range(T* aCur, T* aEnd) - : mCur(aCur) - , mEnd(aEnd) - { - MOZ_ASSERT(aCur <= aEnd); - } - - public: - bool empty() const { return mCur == mEnd; } - size_t remain() const { return PointerRangeSize(mCur, mEnd); } - T& front() const { MOZ_ASSERT(!empty()); return *mCur; } - void popFront() { MOZ_ASSERT(!empty()); ++mCur; } - T popCopyFront() { MOZ_ASSERT(!empty()); return *mCur++; } - }; - - class ConstRange - { - friend class Vector; - const T* mCur; - const T* mEnd; - ConstRange(const T* aCur, const T* aEnd) - : mCur(aCur) - , mEnd(aEnd) - { - MOZ_ASSERT(aCur <= aEnd); - } - - public: - bool empty() const { return mCur == mEnd; } - size_t remain() const { return PointerRangeSize(mCur, mEnd); } - const T& front() const { MOZ_ASSERT(!empty()); return *mCur; } - void popFront() { MOZ_ASSERT(!empty()); ++mCur; } - T popCopyFront() { MOZ_ASSERT(!empty()); return *mCur++; } - }; - - Range all() { return Range(begin(), end()); } - ConstRange all() const { return ConstRange(begin(), end()); } - - /* mutators */ - - /** - * Reverse the order of the elements in the vector in place. - */ - void reverse(); - - /** - * Given that the vector is empty, grow the internal capacity to |aRequest|, - * keeping the length 0. - */ - MOZ_MUST_USE bool initCapacity(size_t aRequest); - - /** - * Given that the vector is empty, grow the internal capacity and length to - * |aRequest| leaving the elements' memory completely uninitialized (with all - * the associated hazards and caveats). This avoids the usual allocation-size - * rounding that happens in resize and overhead of initialization for elements - * that are about to be overwritten. - */ - MOZ_MUST_USE bool initLengthUninitialized(size_t aRequest); - - /** - * If reserve(aRequest) succeeds and |aRequest >= length()|, then appending - * |aRequest - length()| elements, in any sequence of append/appendAll calls, - * is guaranteed to succeed. - * - * A request to reserve an amount less than the current length does not affect - * reserved space. - */ - MOZ_MUST_USE bool reserve(size_t aRequest); - - /** - * Destroy elements in the range [end() - aIncr, end()). Does not deallocate - * or unreserve storage for those elements. - */ - void shrinkBy(size_t aIncr); - - /** - * Destroy elements in the range [aNewLength, end()). Does not deallocate - * or unreserve storage for those elements. - */ - void shrinkTo(size_t aNewLength); - - /** Grow the vector by aIncr elements. */ - MOZ_MUST_USE bool growBy(size_t aIncr); - - /** Call shrinkBy or growBy based on whether newSize > length(). */ - MOZ_MUST_USE bool resize(size_t aNewLength); - - /** - * Increase the length of the vector, but don't initialize the new elements - * -- leave them as uninitialized memory. - */ - MOZ_MUST_USE bool growByUninitialized(size_t aIncr); - void infallibleGrowByUninitialized(size_t aIncr); - MOZ_MUST_USE bool resizeUninitialized(size_t aNewLength); - - /** Shorthand for shrinkBy(length()). */ - void clear(); - - /** Clears and releases any heap-allocated storage. */ - void clearAndFree(); - - /** - * Calls the AllocPolicy's pod_realloc to release excess capacity. Since - * realloc is only safe on PODs, this method fails to compile if IsPod - * is false. - */ - void podResizeToFit(); - - /** - * If true, appending |aNeeded| elements won't reallocate elements storage. - * This *doesn't* mean that infallibleAppend may be used! You still must - * reserve the extra space, even if this method indicates that appends won't - * need to reallocate elements storage. - */ - bool canAppendWithoutRealloc(size_t aNeeded) const; - - /** Potentially fallible append operations. */ - - /** - * This can take either a T& or a T&&. Given a T&&, it moves |aU| into the - * vector, instead of copying it. If it fails, |aU| is left unmoved. ("We are - * not amused.") - */ - template MOZ_MUST_USE bool append(U&& aU); - - /** - * Construct a T in-place as a new entry at the end of this vector. - */ - template - MOZ_MUST_USE bool emplaceBack(Args&&... aArgs) - { - if (!growByUninitialized(1)) - return false; - Impl::new_(&back(), Forward(aArgs)...); - return true; - } - - template - MOZ_MUST_USE bool appendAll(const Vector& aU); - MOZ_MUST_USE bool appendN(const T& aT, size_t aN); - template MOZ_MUST_USE bool append(const U* aBegin, const U* aEnd); - template MOZ_MUST_USE bool append(const U* aBegin, size_t aLength); - - /* - * Guaranteed-infallible append operations for use upon vectors whose - * memory has been pre-reserved. Don't use this if you haven't reserved the - * memory! - */ - template void infallibleAppend(U&& aU) - { - internalAppend(Forward(aU)); - } - void infallibleAppendN(const T& aT, size_t aN) - { - internalAppendN(aT, aN); - } - template void infallibleAppend(const U* aBegin, const U* aEnd) - { - internalAppend(aBegin, PointerRangeSize(aBegin, aEnd)); - } - template void infallibleAppend(const U* aBegin, size_t aLength) - { - internalAppend(aBegin, aLength); - } - template - void infallibleEmplaceBack(Args&&... aArgs) - { - infallibleGrowByUninitialized(1); - Impl::new_(&back(), Forward(aArgs)...); - } - - void popBack(); - - T popCopy(); - - /** - * If elements are stored in-place, return nullptr and leave this vector - * unmodified. - * - * Otherwise return this vector's elements buffer, and clear this vector as if - * by clearAndFree(). The caller now owns the buffer and is responsible for - * deallocating it consistent with this vector's AllocPolicy. - * - * N.B. Although a T*, only the range [0, length()) is constructed. - */ - MOZ_MUST_USE T* extractRawBuffer(); - - /** - * If elements are stored in-place, allocate a new buffer, move this vector's - * elements into it, and return that buffer. - * - * Otherwise return this vector's elements buffer. The caller now owns the - * buffer and is responsible for deallocating it consistent with this vector's - * AllocPolicy. - * - * This vector is cleared, as if by clearAndFree(), when this method - * succeeds. This method fails and returns nullptr only if new elements buffer - * allocation fails. - * - * N.B. Only the range [0, length()) of the returned buffer is constructed. - * If any of these elements are uninitialized (as growByUninitialized - * enables), behavior is undefined. - */ - MOZ_MUST_USE T* extractOrCopyRawBuffer(); - - /** - * Transfer ownership of an array of objects into the vector. The caller - * must have allocated the array in accordance with this vector's - * AllocPolicy. - * - * N.B. This call assumes that there are no uninitialized elements in the - * passed array. - */ - void replaceRawBuffer(T* aP, size_t aLength); - - /** - * Places |aVal| at position |aP|, shifting existing elements from |aP| onward - * one position higher. On success, |aP| should not be reused because it'll - * be a dangling pointer if reallocation of the vector storage occurred; the - * return value should be used instead. On failure, nullptr is returned. - * - * Example usage: - * - * if (!(p = vec.insert(p, val))) { - * - * } - * - * - * This is inherently a linear-time operation. Be careful! - */ - template - MOZ_MUST_USE T* insert(T* aP, U&& aVal); - - /** - * Removes the element |aT|, which must fall in the bounds [begin, end), - * shifting existing elements from |aT + 1| onward one position lower. - */ - void erase(T* aT); - - /** - * Removes the elements [|aBegin|, |aEnd|), which must fall in the bounds - * [begin, end), shifting existing elements from |aEnd + 1| onward to aBegin's - * old position. - */ - void erase(T* aBegin, T* aEnd); - - /** - * Measure the size of the vector's heap-allocated storage. - */ - size_t sizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const; - - /** - * Like sizeOfExcludingThis, but also measures the size of the vector - * object (which must be heap-allocated) itself. - */ - size_t sizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const; - - void swap(Vector& aOther); - -private: - Vector(const Vector&) = delete; - void operator=(const Vector&) = delete; -}; - -/* This does the re-entrancy check plus several other sanity checks. */ -#define MOZ_REENTRANCY_GUARD_ET_AL \ - ReentrancyGuard g(*this); \ - MOZ_ASSERT_IF(usingInlineStorage(), mCapacity == kInlineCapacity); \ - MOZ_ASSERT(reserved() <= mCapacity); \ - MOZ_ASSERT(mLength <= reserved()); \ - MOZ_ASSERT(mLength <= mCapacity) - -/* Vector Implementation */ - -template -MOZ_ALWAYS_INLINE -Vector::Vector(AP aAP) - : AP(aAP) - , mLength(0) - , mCapacity(kInlineCapacity) -#ifdef DEBUG - , mReserved(0) - , mEntered(false) -#endif -{ - mBegin = static_cast(mStorage.addr()); -} - -/* Move constructor. */ -template -MOZ_ALWAYS_INLINE -Vector::Vector(Vector&& aRhs) - : AllocPolicy(Move(aRhs)) -#ifdef DEBUG - , mEntered(false) -#endif -{ - mLength = aRhs.mLength; - mCapacity = aRhs.mCapacity; -#ifdef DEBUG - mReserved = aRhs.mReserved; -#endif - - if (aRhs.usingInlineStorage()) { - /* We can't move the buffer over in this case, so copy elements. */ - mBegin = static_cast(mStorage.addr()); - Impl::moveConstruct(mBegin, aRhs.beginNoCheck(), aRhs.endNoCheck()); - /* - * Leave aRhs's mLength, mBegin, mCapacity, and mReserved as they are. - * The elements in its in-line storage still need to be destroyed. - */ - } else { - /* - * Take src's buffer, and turn src into an empty vector using - * in-line storage. - */ - mBegin = aRhs.mBegin; - aRhs.mBegin = static_cast(aRhs.mStorage.addr()); - aRhs.mCapacity = kInlineCapacity; - aRhs.mLength = 0; -#ifdef DEBUG - aRhs.mReserved = 0; -#endif - } -} - -/* Move assignment. */ -template -MOZ_ALWAYS_INLINE Vector& -Vector::operator=(Vector&& aRhs) -{ - MOZ_ASSERT(this != &aRhs, "self-move assignment is prohibited"); - this->~Vector(); - new(KnownNotNull, this) Vector(Move(aRhs)); - return *this; -} - -template -MOZ_ALWAYS_INLINE -Vector::~Vector() -{ - MOZ_REENTRANCY_GUARD_ET_AL; - Impl::destroy(beginNoCheck(), endNoCheck()); - if (!usingInlineStorage()) { - this->free_(beginNoCheck()); - } -} - -template -MOZ_ALWAYS_INLINE void -Vector::reverse() { - MOZ_REENTRANCY_GUARD_ET_AL; - T* elems = mBegin; - size_t len = mLength; - size_t mid = len / 2; - for (size_t i = 0; i < mid; i++) { - Swap(elems[i], elems[len - i - 1]); - } -} - -/* - * This function will create a new heap buffer with capacity aNewCap, - * move all elements in the inline buffer to this new buffer, - * and fail on OOM. - */ -template -inline bool -Vector::convertToHeapStorage(size_t aNewCap) -{ - MOZ_ASSERT(usingInlineStorage()); - - /* Allocate buffer. */ - MOZ_ASSERT(!detail::CapacityHasExcessSpace(aNewCap)); - T* newBuf = this->template pod_malloc(aNewCap); - if (MOZ_UNLIKELY(!newBuf)) { - return false; - } - - /* Copy inline elements into heap buffer. */ - Impl::moveConstruct(newBuf, beginNoCheck(), endNoCheck()); - Impl::destroy(beginNoCheck(), endNoCheck()); - - /* Switch in heap buffer. */ - mBegin = newBuf; - /* mLength is unchanged. */ - mCapacity = aNewCap; - return true; -} - -template -MOZ_NEVER_INLINE bool -Vector::growStorageBy(size_t aIncr) -{ - MOZ_ASSERT(mLength + aIncr > mCapacity); - - /* - * When choosing a new capacity, its size should is as close to 2**N bytes - * as possible. 2**N-sized requests are best because they are unlikely to - * be rounded up by the allocator. Asking for a 2**N number of elements - * isn't as good, because if sizeof(T) is not a power-of-two that would - * result in a non-2**N request size. - */ - - size_t newCap; - - if (aIncr == 1) { - if (usingInlineStorage()) { - /* This case occurs in ~70--80% of the calls to this function. */ - size_t newSize = - tl::RoundUpPow2<(kInlineCapacity + 1) * sizeof(T)>::value; - newCap = newSize / sizeof(T); - goto convert; - } - - if (mLength == 0) { - /* This case occurs in ~0--10% of the calls to this function. */ - newCap = 1; - goto grow; - } - - /* This case occurs in ~15--20% of the calls to this function. */ - - /* - * Will mLength * 4 *sizeof(T) overflow? This condition limits a vector - * to 1GB of memory on a 32-bit system, which is a reasonable limit. It - * also ensures that - * - * static_cast(end()) - static_cast(begin()) - * - * doesn't overflow ptrdiff_t (see bug 510319). - */ - if (MOZ_UNLIKELY(mLength & tl::MulOverflowMask<4 * sizeof(T)>::value)) { - this->reportAllocOverflow(); - return false; - } - - /* - * If we reach here, the existing capacity will have a size that is already - * as close to 2^N as sizeof(T) will allow. Just double the capacity, and - * then there might be space for one more element. - */ - newCap = mLength * 2; - if (detail::CapacityHasExcessSpace(newCap)) { - newCap += 1; - } - } else { - /* This case occurs in ~2% of the calls to this function. */ - size_t newMinCap = mLength + aIncr; - - /* Did mLength + aIncr overflow? Will newCap * sizeof(T) overflow? */ - if (MOZ_UNLIKELY(newMinCap < mLength || - newMinCap & tl::MulOverflowMask<2 * sizeof(T)>::value)) - { - this->reportAllocOverflow(); - return false; - } - - size_t newMinSize = newMinCap * sizeof(T); - size_t newSize = RoundUpPow2(newMinSize); - newCap = newSize / sizeof(T); - } - - if (usingInlineStorage()) { -convert: - return convertToHeapStorage(newCap); - } - -grow: - return Impl::growTo(*this, newCap); -} - -template -inline bool -Vector::initCapacity(size_t aRequest) -{ - MOZ_ASSERT(empty()); - MOZ_ASSERT(usingInlineStorage()); - if (aRequest == 0) { - return true; - } - T* newbuf = this->template pod_malloc(aRequest); - if (MOZ_UNLIKELY(!newbuf)) { - return false; - } - mBegin = newbuf; - mCapacity = aRequest; -#ifdef DEBUG - mReserved = aRequest; -#endif - return true; -} - -template -inline bool -Vector::initLengthUninitialized(size_t aRequest) -{ - if (!initCapacity(aRequest)) { - return false; - } - infallibleGrowByUninitialized(aRequest); - return true; -} - -template -inline bool -Vector::maybeCheckSimulatedOOM(size_t aRequestedSize) -{ - if (aRequestedSize <= N) { - return true; - } - -#ifdef DEBUG - if (aRequestedSize <= mReserved) { - return true; - } -#endif - - return allocPolicy().checkSimulatedOOM(); -} - -template -inline bool -Vector::reserve(size_t aRequest) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - if (aRequest > mCapacity) { - if (MOZ_UNLIKELY(!growStorageBy(aRequest - mLength))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(aRequest)) { - return false; - } -#ifdef DEBUG - if (aRequest > mReserved) { - mReserved = aRequest; - } - MOZ_ASSERT(mLength <= mReserved); - MOZ_ASSERT(mReserved <= mCapacity); -#endif - return true; -} - -template -inline void -Vector::shrinkBy(size_t aIncr) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - MOZ_ASSERT(aIncr <= mLength); - Impl::destroy(endNoCheck() - aIncr, endNoCheck()); - mLength -= aIncr; -} - -template -MOZ_ALWAYS_INLINE void -Vector::shrinkTo(size_t aNewLength) -{ - MOZ_ASSERT(aNewLength <= mLength); - shrinkBy(mLength - aNewLength); -} - -template -MOZ_ALWAYS_INLINE bool -Vector::growBy(size_t aIncr) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - if (aIncr > mCapacity - mLength) { - if (MOZ_UNLIKELY(!growStorageBy(aIncr))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(mLength + aIncr)) { - return false; - } - MOZ_ASSERT(mLength + aIncr <= mCapacity); - T* newend = endNoCheck() + aIncr; - Impl::initialize(endNoCheck(), newend); - mLength += aIncr; -#ifdef DEBUG - if (mLength > mReserved) { - mReserved = mLength; - } -#endif - return true; -} - -template -MOZ_ALWAYS_INLINE bool -Vector::growByUninitialized(size_t aIncr) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - if (aIncr > mCapacity - mLength) { - if (MOZ_UNLIKELY(!growStorageBy(aIncr))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(mLength + aIncr)) { - return false; - } -#ifdef DEBUG - if (mLength + aIncr > mReserved) { - mReserved = mLength + aIncr; - } -#endif - infallibleGrowByUninitialized(aIncr); - return true; -} - -template -MOZ_ALWAYS_INLINE void -Vector::infallibleGrowByUninitialized(size_t aIncr) -{ - MOZ_ASSERT(mLength + aIncr <= reserved()); - mLength += aIncr; -} - -template -inline bool -Vector::resize(size_t aNewLength) -{ - size_t curLength = mLength; - if (aNewLength > curLength) { - return growBy(aNewLength - curLength); - } - shrinkBy(curLength - aNewLength); - return true; -} - -template -MOZ_ALWAYS_INLINE bool -Vector::resizeUninitialized(size_t aNewLength) -{ - size_t curLength = mLength; - if (aNewLength > curLength) { - return growByUninitialized(aNewLength - curLength); - } - shrinkBy(curLength - aNewLength); - return true; -} - -template -inline void -Vector::clear() -{ - MOZ_REENTRANCY_GUARD_ET_AL; - Impl::destroy(beginNoCheck(), endNoCheck()); - mLength = 0; -} - -template -inline void -Vector::clearAndFree() -{ - clear(); - - if (usingInlineStorage()) { - return; - } - this->free_(beginNoCheck()); - mBegin = static_cast(mStorage.addr()); - mCapacity = kInlineCapacity; -#ifdef DEBUG - mReserved = 0; -#endif -} - -template -inline void -Vector::podResizeToFit() -{ - // This function is only defined if IsPod is true and will fail to compile - // otherwise. - Impl::podResizeToFit(*this); -} - -template -inline bool -Vector::canAppendWithoutRealloc(size_t aNeeded) const -{ - return mLength + aNeeded <= mCapacity; -} - -template -template -MOZ_ALWAYS_INLINE void -Vector::internalAppendAll(const Vector& aOther) -{ - internalAppend(aOther.begin(), aOther.length()); -} - -template -template -MOZ_ALWAYS_INLINE void -Vector::internalAppend(U&& aU) -{ - MOZ_ASSERT(mLength + 1 <= mReserved); - MOZ_ASSERT(mReserved <= mCapacity); - Impl::new_(endNoCheck(), Forward(aU)); - ++mLength; -} - -template -MOZ_ALWAYS_INLINE bool -Vector::appendN(const T& aT, size_t aNeeded) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - if (mLength + aNeeded > mCapacity) { - if (MOZ_UNLIKELY(!growStorageBy(aNeeded))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(mLength + aNeeded)) { - return false; - } -#ifdef DEBUG - if (mLength + aNeeded > mReserved) { - mReserved = mLength + aNeeded; - } -#endif - internalAppendN(aT, aNeeded); - return true; -} - -template -MOZ_ALWAYS_INLINE void -Vector::internalAppendN(const T& aT, size_t aNeeded) -{ - MOZ_ASSERT(mLength + aNeeded <= mReserved); - MOZ_ASSERT(mReserved <= mCapacity); - Impl::copyConstructN(endNoCheck(), aNeeded, aT); - mLength += aNeeded; -} - -template -template -inline T* -Vector::insert(T* aP, U&& aVal) -{ - MOZ_ASSERT(begin() <= aP); - MOZ_ASSERT(aP <= end()); - size_t pos = aP - begin(); - MOZ_ASSERT(pos <= mLength); - size_t oldLength = mLength; - if (pos == oldLength) { - if (!append(Forward(aVal))) { - return nullptr; - } - } else { - T oldBack = Move(back()); - if (!append(Move(oldBack))) { /* Dup the last element. */ - return nullptr; - } - for (size_t i = oldLength; i > pos; --i) { - (*this)[i] = Move((*this)[i - 1]); - } - (*this)[pos] = Forward(aVal); - } - return begin() + pos; -} - -template -inline void -Vector::erase(T* aIt) -{ - MOZ_ASSERT(begin() <= aIt); - MOZ_ASSERT(aIt < end()); - while (aIt + 1 < end()) { - *aIt = Move(*(aIt + 1)); - ++aIt; - } - popBack(); -} - -template -inline void -Vector::erase(T* aBegin, T* aEnd) -{ - MOZ_ASSERT(begin() <= aBegin); - MOZ_ASSERT(aBegin <= aEnd); - MOZ_ASSERT(aEnd <= end()); - while (aEnd < end()) { - *aBegin++ = Move(*aEnd++); - } - shrinkBy(aEnd - aBegin); -} - -template -template -MOZ_ALWAYS_INLINE bool -Vector::append(const U* aInsBegin, const U* aInsEnd) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - size_t aNeeded = PointerRangeSize(aInsBegin, aInsEnd); - if (mLength + aNeeded > mCapacity) { - if (MOZ_UNLIKELY(!growStorageBy(aNeeded))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(mLength + aNeeded)) { - return false; - } -#ifdef DEBUG - if (mLength + aNeeded > mReserved) { - mReserved = mLength + aNeeded; - } -#endif - internalAppend(aInsBegin, aNeeded); - return true; -} - -template -template -MOZ_ALWAYS_INLINE void -Vector::internalAppend(const U* aInsBegin, size_t aInsLength) -{ - MOZ_ASSERT(mLength + aInsLength <= mReserved); - MOZ_ASSERT(mReserved <= mCapacity); - Impl::copyConstruct(endNoCheck(), aInsBegin, aInsBegin + aInsLength); - mLength += aInsLength; -} - -template -template -MOZ_ALWAYS_INLINE bool -Vector::append(U&& aU) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - if (mLength == mCapacity) { - if (MOZ_UNLIKELY(!growStorageBy(1))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(mLength + 1)) { - return false; - } -#ifdef DEBUG - if (mLength + 1 > mReserved) { - mReserved = mLength + 1; - } -#endif - internalAppend(Forward(aU)); - return true; -} - -template -template -MOZ_ALWAYS_INLINE bool -Vector::appendAll(const Vector& aOther) -{ - return append(aOther.begin(), aOther.length()); -} - -template -template -MOZ_ALWAYS_INLINE bool -Vector::append(const U* aInsBegin, size_t aInsLength) -{ - return append(aInsBegin, aInsBegin + aInsLength); -} - -template -MOZ_ALWAYS_INLINE void -Vector::popBack() -{ - MOZ_REENTRANCY_GUARD_ET_AL; - MOZ_ASSERT(!empty()); - --mLength; - endNoCheck()->~T(); -} - -template -MOZ_ALWAYS_INLINE T -Vector::popCopy() -{ - T ret = back(); - popBack(); - return ret; -} - -template -inline T* -Vector::extractRawBuffer() -{ - MOZ_REENTRANCY_GUARD_ET_AL; - - if (usingInlineStorage()) { - return nullptr; - } - - T* ret = mBegin; - mBegin = static_cast(mStorage.addr()); - mLength = 0; - mCapacity = kInlineCapacity; -#ifdef DEBUG - mReserved = 0; -#endif - return ret; -} - -template -inline T* -Vector::extractOrCopyRawBuffer() -{ - if (T* ret = extractRawBuffer()) { - return ret; - } - - MOZ_REENTRANCY_GUARD_ET_AL; - - T* copy = this->template pod_malloc(mLength); - if (!copy) { - return nullptr; - } - - Impl::moveConstruct(copy, beginNoCheck(), endNoCheck()); - Impl::destroy(beginNoCheck(), endNoCheck()); - mBegin = static_cast(mStorage.addr()); - mLength = 0; - mCapacity = kInlineCapacity; -#ifdef DEBUG - mReserved = 0; -#endif - return copy; -} - -template -inline void -Vector::replaceRawBuffer(T* aP, size_t aLength) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - - /* Destroy what we have. */ - Impl::destroy(beginNoCheck(), endNoCheck()); - if (!usingInlineStorage()) { - this->free_(beginNoCheck()); - } - - /* Take in the new buffer. */ - if (aLength <= kInlineCapacity) { - /* - * We convert to inline storage if possible, even though aP might - * otherwise be acceptable. Maybe this behaviour should be - * specifiable with an argument to this function. - */ - mBegin = static_cast(mStorage.addr()); - mLength = aLength; - mCapacity = kInlineCapacity; - Impl::moveConstruct(mBegin, aP, aP + aLength); - Impl::destroy(aP, aP + aLength); - this->free_(aP); - } else { - mBegin = aP; - mLength = aLength; - mCapacity = aLength; - } -#ifdef DEBUG - mReserved = aLength; -#endif -} - -template -inline size_t -Vector::sizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const -{ - return usingInlineStorage() ? 0 : aMallocSizeOf(beginNoCheck()); -} - -template -inline size_t -Vector::sizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const -{ - return aMallocSizeOf(this) + sizeOfExcludingThis(aMallocSizeOf); -} - -template -inline void -Vector::swap(Vector& aOther) -{ - static_assert(N == 0, - "still need to implement this for N != 0"); - - // This only works when inline storage is always empty. - if (!usingInlineStorage() && aOther.usingInlineStorage()) { - aOther.mBegin = mBegin; - mBegin = inlineStorage(); - } else if (usingInlineStorage() && !aOther.usingInlineStorage()) { - mBegin = aOther.mBegin; - aOther.mBegin = aOther.inlineStorage(); - } else if (!usingInlineStorage() && !aOther.usingInlineStorage()) { - Swap(mBegin, aOther.mBegin); - } else { - // This case is a no-op, since we'd set both to use their inline storage. - } - - Swap(mLength, aOther.mLength); - Swap(mCapacity, aOther.mCapacity); -#ifdef DEBUG - Swap(mReserved, aOther.mReserved); -#endif -} - -} // namespace mozilla - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#endif /* mozilla_Vector_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/WeakPtr.h b/android/armeabi-v7a/include/spidermonkey/mozilla/WeakPtr.h deleted file mode 100644 index ef0c19f4..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/WeakPtr.h +++ /dev/null @@ -1,283 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Weak pointer functionality, implemented as a mixin for use with any class. */ - -/** - * SupportsWeakPtr lets you have a pointer to an object 'Foo' without affecting - * its lifetime. It works by creating a single shared reference counted object - * (WeakReference) that each WeakPtr will access 'Foo' through. This lets 'Foo' - * clear the pointer in the WeakReference without having to know about all of - * the WeakPtrs to it and allows the WeakReference to live beyond the lifetime - * of 'Foo'. - * - * PLEASE NOTE: This weak pointer implementation is not thread-safe. - * - * Note that when deriving from SupportsWeakPtr you should add - * MOZ_DECLARE_WEAKREFERENCE_TYPENAME(ClassName) to the public section of your - * class, where ClassName is the name of your class. - * - * The overhead of WeakPtr is that accesses to 'Foo' becomes an additional - * dereference, and an additional heap allocated pointer sized object shared - * between all of the WeakPtrs. - * - * Example of usage: - * - * // To have a class C support weak pointers, inherit from - * // SupportsWeakPtr. - * class C : public SupportsWeakPtr - * { - * public: - * MOZ_DECLARE_WEAKREFERENCE_TYPENAME(C) - * int mNum; - * void act(); - * }; - * - * C* ptr = new C(); - * - * // Get weak pointers to ptr. The first time a weak pointer - * // is obtained, a reference counted WeakReference object is created that - * // can live beyond the lifetime of 'ptr'. The WeakReference - * // object will be notified of 'ptr's destruction. - * WeakPtr weak = ptr; - * WeakPtr other = ptr; - * - * // Test a weak pointer for validity before using it. - * if (weak) { - * weak->mNum = 17; - * weak->act(); - * } - * - * // Destroying the underlying object clears weak pointers to it. - * delete ptr; - * - * MOZ_ASSERT(!weak, "Deleting |ptr| clears weak pointers to it."); - * MOZ_ASSERT(!other, "Deleting |ptr| clears all weak pointers to it."); - * - * WeakPtr is typesafe and may be used with any class. It is not required that - * the class be reference-counted or allocated in any particular way. - * - * The API was loosely inspired by Chromium's weak_ptr.h: - * http://src.chromium.org/svn/trunk/src/base/memory/weak_ptr.h - */ - -#ifndef mozilla_WeakPtr_h -#define mozilla_WeakPtr_h - -#include "mozilla/ArrayUtils.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/RefCounted.h" -#include "mozilla/RefPtr.h" -#include "mozilla/TypeTraits.h" - -#include - -// Weak referencing is not implemeted as thread safe. When a WeakPtr -// is created or dereferenced on thread A but the real object is just -// being Released() on thread B, there is a possibility of a race -// when the proxy object (detail::WeakReference) is notified about -// the real object destruction just between when thread A is storing -// the object pointer locally and is about to add a reference to it. -// -// Hence, a non-null weak proxy object is considered to have a single -// "owning thread". It means that each query for a weak reference, -// its dereference, and destruction of the real object must all happen -// on a single thread. The following macros implement assertions for -// checking these conditions. -// -// We disable this on MinGW. MinGW has two threading models: win32 -// API based, which disables std::thread; and POSIX based which -// enables it but requires an emulation library (winpthreads). -// Rather than attempting to switch to pthread emulation at this point, -// we are disabling the std::thread based assertion checking. -// -// In the future, to enable it we could -// a. have libgcc/stdc++ support win32 threads natively -// b. switch to POSIX-based threading in MinGW with pthread emulation -// c. refactor it to not use std::thread - -#if !defined(__MINGW32__) && (defined(DEBUG) || (defined(NIGHTLY_BUILD) && !defined(MOZ_PROFILING))) - -#include -#define MOZ_WEAKPTR_DECLARE_THREAD_SAFETY_CHECK \ - std::thread::id _owningThread; \ - bool _empty; // If it was initialized as a placeholder with mPtr = nullptr. -#define MOZ_WEAKPTR_INIT_THREAD_SAFETY_CHECK() \ - do { \ - _owningThread = std::this_thread::get_id(); \ - _empty = !p; \ - } while (false) -#define MOZ_WEAKPTR_ASSERT_THREAD_SAFETY() \ - MOZ_DIAGNOSTIC_ASSERT(_empty || _owningThread == std::this_thread::get_id(), \ - "WeakPtr used on multiple threads") -#define MOZ_WEAKPTR_ASSERT_THREAD_SAFETY_DELEGATED(that) \ - (that)->AssertThreadSafety(); - -#define MOZ_WEAKPTR_THREAD_SAFETY_CHECKING 1 - -#else - -#define MOZ_WEAKPTR_DECLARE_THREAD_SAFETY_CHECK -#define MOZ_WEAKPTR_INIT_THREAD_SAFETY_CHECK() do { } while (false) -#define MOZ_WEAKPTR_ASSERT_THREAD_SAFETY() do { } while (false) -#define MOZ_WEAKPTR_ASSERT_THREAD_SAFETY_DELEGATED(that) do { } while (false) - -#endif - -namespace mozilla { - -template class WeakPtr; -template class SupportsWeakPtr; - -#ifdef MOZ_REFCOUNTED_LEAK_CHECKING -#define MOZ_DECLARE_WEAKREFERENCE_TYPENAME(T) \ - static const char* weakReferenceTypeName() { return "WeakReference<" #T ">"; } -#else -#define MOZ_DECLARE_WEAKREFERENCE_TYPENAME(T) -#endif - -namespace detail { - -// This can live beyond the lifetime of the class derived from -// SupportsWeakPtr. -template -class WeakReference : public ::mozilla::RefCounted > -{ -public: - explicit WeakReference(T* p) : mPtr(p) - { - MOZ_WEAKPTR_INIT_THREAD_SAFETY_CHECK(); - } - - T* get() const { - MOZ_WEAKPTR_ASSERT_THREAD_SAFETY(); - return mPtr; - } - -#ifdef MOZ_REFCOUNTED_LEAK_CHECKING - const char* typeName() const - { - // The first time this is called mPtr is null, so don't - // invoke any methods on mPtr. - return T::weakReferenceTypeName(); - } - size_t typeSize() const { return sizeof(*this); } -#endif - -#ifdef MOZ_WEAKPTR_THREAD_SAFETY_CHECKING - void AssertThreadSafety() { MOZ_WEAKPTR_ASSERT_THREAD_SAFETY(); } -#endif - -private: - friend class mozilla::SupportsWeakPtr; - - void detach() { - MOZ_WEAKPTR_ASSERT_THREAD_SAFETY(); - mPtr = nullptr; - } - - T* MOZ_NON_OWNING_REF mPtr; - MOZ_WEAKPTR_DECLARE_THREAD_SAFETY_CHECK -}; - -} // namespace detail - -template -class SupportsWeakPtr -{ -protected: - ~SupportsWeakPtr() - { - static_assert(IsBaseOf, T>::value, - "T must derive from SupportsWeakPtr"); - if (mSelfReferencingWeakPtr) { - mSelfReferencingWeakPtr.mRef->detach(); - } - } - -private: - const WeakPtr& SelfReferencingWeakPtr() - { - if (!mSelfReferencingWeakPtr) { - mSelfReferencingWeakPtr.mRef = new detail::WeakReference(static_cast(this)); - } else { - MOZ_WEAKPTR_ASSERT_THREAD_SAFETY_DELEGATED(mSelfReferencingWeakPtr.mRef); - } - return mSelfReferencingWeakPtr; - } - - const WeakPtr& SelfReferencingWeakPtr() const - { - const WeakPtr& p = const_cast(this)->SelfReferencingWeakPtr(); - return reinterpret_cast&>(p); - } - - friend class WeakPtr; - friend class WeakPtr; - - WeakPtr mSelfReferencingWeakPtr; -}; - -template -class WeakPtr -{ - typedef detail::WeakReference WeakReference; - -public: - WeakPtr& operator=(const WeakPtr& aOther) - { - mRef = aOther.mRef; - MOZ_WEAKPTR_ASSERT_THREAD_SAFETY_DELEGATED(mRef); - return *this; - } - - WeakPtr(const WeakPtr& aOther) - { - // The thread safety check is performed inside of the operator= method. - *this = aOther; - } - - WeakPtr& operator=(T* aOther) - { - if (aOther) { - *this = aOther->SelfReferencingWeakPtr(); - } else if (!mRef || mRef->get()) { - // Ensure that mRef is dereferenceable in the uninitialized state. - mRef = new WeakReference(nullptr); - } - // The thread safety check happens inside SelfReferencingWeakPtr - // or is initialized in the WeakReference constructor. - return *this; - } - - MOZ_IMPLICIT WeakPtr(T* aOther) - { - *this = aOther; - MOZ_WEAKPTR_ASSERT_THREAD_SAFETY_DELEGATED(mRef); - } - - // Ensure that mRef is dereferenceable in the uninitialized state. - WeakPtr() : mRef(new WeakReference(nullptr)) {} - - operator T*() const { return mRef->get(); } - T& operator*() const { return *mRef->get(); } - - T* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN { return mRef->get(); } - - T* get() const { return mRef->get(); } - -private: - friend class SupportsWeakPtr; - - explicit WeakPtr(const RefPtr& aOther) : mRef(aOther) {} - - RefPtr mRef; -}; - -} // namespace mozilla - -#endif /* mozilla_WeakPtr_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/XorShift128PlusRNG.h b/android/armeabi-v7a/include/spidermonkey/mozilla/XorShift128PlusRNG.h deleted file mode 100644 index 2f182f0f..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/XorShift128PlusRNG.h +++ /dev/null @@ -1,121 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* The xorshift128+ pseudo-random number generator. */ - -#ifndef mozilla_XorShift128Plus_h -#define mozilla_XorShift128Plus_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/FloatingPoint.h" - -#include - -namespace mozilla { -namespace non_crypto { - -/* - * A stream of pseudo-random numbers generated using the xorshift+ technique - * described here: - * - * Vigna, Sebastiano (2014). "Further scramblings of Marsaglia's xorshift - * generators". arXiv:1404.0390 (http://arxiv.org/abs/1404.0390) - * - * That paper says: - * - * In particular, we propose a tightly coded xorshift128+ generator that - * does not fail systematically any test from the BigCrush suite of TestU01 - * (even reversed) and generates 64 pseudorandom bits in 1.10 ns on an - * Intel(R) Core(TM) i7-4770 CPU @3.40GHz (Haswell). It is the fastest - * generator we are aware of with such empirical statistical properties. - * - * The stream of numbers produced by this method repeats every 2**128 - 1 calls - * (i.e. never, for all practical purposes). Zero appears 2**64 - 1 times in - * this period; all other numbers appear 2**64 times. Additionally, each *bit* - * in the produced numbers repeats every 2**128 - 1 calls. - * - * This generator is not suitable as a cryptographically secure random number - * generator. - */ -class XorShift128PlusRNG { - uint64_t mState[2]; - - public: - /* - * Construct a xorshift128+ pseudo-random number stream using |aInitial0| and - * |aInitial1| as the initial state. These MUST NOT both be zero. - * - * If the initial states contain many zeros, for a few iterations you'll see - * many zeroes in the generated numbers. It's suggested to seed a SplitMix64 - * generator and use its first two - * outputs to seed xorshift128+. - */ - XorShift128PlusRNG(uint64_t aInitial0, uint64_t aInitial1) { - setState(aInitial0, aInitial1); - } - - /** - * Return a pseudo-random 64-bit number. - */ - uint64_t next() { - /* - * The offsetOfState*() methods below are provided so that exceedingly-rare - * callers that want to observe or poke at RNG state in C++ type-system- - * ignoring means can do so. Don't change the next() or nextDouble() - * algorithms without altering code that uses offsetOfState*()! - */ - uint64_t s1 = mState[0]; - const uint64_t s0 = mState[1]; - mState[0] = s0; - s1 ^= s1 << 23; - mState[1] = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26); - return mState[1] + s0; - } - - /* - * Return a pseudo-random floating-point value in the range [0, 1). More - * precisely, choose an integer in the range [0, 2**53) and divide it by - * 2**53. Given the 2**128 - 1 period noted above, the produced doubles are - * all but uniformly distributed in this range. - */ - double nextDouble() { - /* - * Because the IEEE 64-bit floating point format stores the leading '1' bit - * of the mantissa implicitly, it effectively represents a mantissa in the - * range [0, 2**53) in only 52 bits. FloatingPoint::kExponentShift - * is the width of the bitfield in the in-memory format, so we must add one - * to get the mantissa's range. - */ - static constexpr int kMantissaBits = - mozilla::FloatingPoint::kExponentShift + 1; - uint64_t mantissa = next() & ((UINT64_C(1) << kMantissaBits) - 1); - return double(mantissa) / (UINT64_C(1) << kMantissaBits); - } - - /* - * Set the stream's current state to |aState0| and |aState1|. These must not - * both be zero; ideally, they should have an almost even mix of zero and one - * bits. - */ - void setState(uint64_t aState0, uint64_t aState1) { - MOZ_ASSERT(aState0 || aState1); - mState[0] = aState0; - mState[1] = aState1; - } - - static size_t offsetOfState0() { - return offsetof(XorShift128PlusRNG, mState[0]); - } - static size_t offsetOfState1() { - return offsetof(XorShift128PlusRNG, mState[1]); - } -}; - -} // namespace non_crypto -} // namespace mozilla - -#endif // mozilla_XorShift128Plus_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/double-conversion.h b/android/armeabi-v7a/include/spidermonkey/mozilla/double-conversion.h deleted file mode 100644 index 957575cf..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/double-conversion.h +++ /dev/null @@ -1,538 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ -#define DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ - -#include "mozilla/Types.h" -#include "utils.h" - -namespace double_conversion { - -class DoubleToStringConverter { - public: - // When calling ToFixed with a double > 10^kMaxFixedDigitsBeforePoint - // or a requested_digits parameter > kMaxFixedDigitsAfterPoint then the - // function returns false. - static const int kMaxFixedDigitsBeforePoint = 60; - static const int kMaxFixedDigitsAfterPoint = 60; - - // When calling ToExponential with a requested_digits - // parameter > kMaxExponentialDigits then the function returns false. - static const int kMaxExponentialDigits = 120; - - // When calling ToPrecision with a requested_digits - // parameter < kMinPrecisionDigits or requested_digits > kMaxPrecisionDigits - // then the function returns false. - static const int kMinPrecisionDigits = 1; - static const int kMaxPrecisionDigits = 120; - - enum Flags { - NO_FLAGS = 0, - EMIT_POSITIVE_EXPONENT_SIGN = 1, - EMIT_TRAILING_DECIMAL_POINT = 2, - EMIT_TRAILING_ZERO_AFTER_POINT = 4, - UNIQUE_ZERO = 8 - }; - - // Flags should be a bit-or combination of the possible Flags-enum. - // - NO_FLAGS: no special flags. - // - EMIT_POSITIVE_EXPONENT_SIGN: when the number is converted into exponent - // form, emits a '+' for positive exponents. Example: 1.2e+2. - // - EMIT_TRAILING_DECIMAL_POINT: when the input number is an integer and is - // converted into decimal format then a trailing decimal point is appended. - // Example: 2345.0 is converted to "2345.". - // - EMIT_TRAILING_ZERO_AFTER_POINT: in addition to a trailing decimal point - // emits a trailing '0'-character. This flag requires the - // EXMIT_TRAILING_DECIMAL_POINT flag. - // Example: 2345.0 is converted to "2345.0". - // - UNIQUE_ZERO: "-0.0" is converted to "0.0". - // - // Infinity symbol and nan_symbol provide the string representation for these - // special values. If the string is NULL and the special value is encountered - // then the conversion functions return false. - // - // The exponent_character is used in exponential representations. It is - // usually 'e' or 'E'. - // - // When converting to the shortest representation the converter will - // represent input numbers in decimal format if they are in the interval - // [10^decimal_in_shortest_low; 10^decimal_in_shortest_high[ - // (lower boundary included, greater boundary excluded). - // Example: with decimal_in_shortest_low = -6 and - // decimal_in_shortest_high = 21: - // ToShortest(0.000001) -> "0.000001" - // ToShortest(0.0000001) -> "1e-7" - // ToShortest(111111111111111111111.0) -> "111111111111111110000" - // ToShortest(100000000000000000000.0) -> "100000000000000000000" - // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21" - // - // When converting to precision mode the converter may add - // max_leading_padding_zeroes before returning the number in exponential - // format. - // Example with max_leading_padding_zeroes_in_precision_mode = 6. - // ToPrecision(0.0000012345, 2) -> "0.0000012" - // ToPrecision(0.00000012345, 2) -> "1.2e-7" - // Similarily the converter may add up to - // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid - // returning an exponential representation. A zero added by the - // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit. - // Examples for max_trailing_padding_zeroes_in_precision_mode = 1: - // ToPrecision(230.0, 2) -> "230" - // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT. - // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT. - DoubleToStringConverter(int flags, - const char* infinity_symbol, - const char* nan_symbol, - char exponent_character, - int decimal_in_shortest_low, - int decimal_in_shortest_high, - int max_leading_padding_zeroes_in_precision_mode, - int max_trailing_padding_zeroes_in_precision_mode) - : flags_(flags), - infinity_symbol_(infinity_symbol), - nan_symbol_(nan_symbol), - exponent_character_(exponent_character), - decimal_in_shortest_low_(decimal_in_shortest_low), - decimal_in_shortest_high_(decimal_in_shortest_high), - max_leading_padding_zeroes_in_precision_mode_( - max_leading_padding_zeroes_in_precision_mode), - max_trailing_padding_zeroes_in_precision_mode_( - max_trailing_padding_zeroes_in_precision_mode) { - // When 'trailing zero after the point' is set, then 'trailing point' - // must be set too. - ASSERT(((flags & EMIT_TRAILING_DECIMAL_POINT) != 0) || - !((flags & EMIT_TRAILING_ZERO_AFTER_POINT) != 0)); - } - - // Returns a converter following the EcmaScript specification. - static MFBT_API const DoubleToStringConverter& EcmaScriptConverter(); - - // Computes the shortest string of digits that correctly represent the input - // number. Depending on decimal_in_shortest_low and decimal_in_shortest_high - // (see constructor) it then either returns a decimal representation, or an - // exponential representation. - // Example with decimal_in_shortest_low = -6, - // decimal_in_shortest_high = 21, - // EMIT_POSITIVE_EXPONENT_SIGN activated, and - // EMIT_TRAILING_DECIMAL_POINT deactived: - // ToShortest(0.000001) -> "0.000001" - // ToShortest(0.0000001) -> "1e-7" - // ToShortest(111111111111111111111.0) -> "111111111111111110000" - // ToShortest(100000000000000000000.0) -> "100000000000000000000" - // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21" - // - // Note: the conversion may round the output if the returned string - // is accurate enough to uniquely identify the input-number. - // For example the most precise representation of the double 9e59 equals - // "899999999999999918767229449717619953810131273674690656206848", but - // the converter will return the shorter (but still correct) "9e59". - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except when the input value is special and no infinity_symbol or - // nan_symbol has been given to the constructor. - bool ToShortest(double value, StringBuilder* result_builder) const { - return ToShortestIeeeNumber(value, result_builder, SHORTEST); - } - - // Same as ToShortest, but for single-precision floats. - bool ToShortestSingle(float value, StringBuilder* result_builder) const { - return ToShortestIeeeNumber(value, result_builder, SHORTEST_SINGLE); - } - - - // Computes a decimal representation with a fixed number of digits after the - // decimal point. The last emitted digit is rounded. - // - // Examples: - // ToFixed(3.12, 1) -> "3.1" - // ToFixed(3.1415, 3) -> "3.142" - // ToFixed(1234.56789, 4) -> "1234.5679" - // ToFixed(1.23, 5) -> "1.23000" - // ToFixed(0.1, 4) -> "0.1000" - // ToFixed(1e30, 2) -> "1000000000000000019884624838656.00" - // ToFixed(0.1, 30) -> "0.100000000000000005551115123126" - // ToFixed(0.1, 17) -> "0.10000000000000001" - // - // If requested_digits equals 0, then the tail of the result depends on - // the EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT. - // Examples, for requested_digits == 0, - // let EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT be - // - false and false: then 123.45 -> 123 - // 0.678 -> 1 - // - true and false: then 123.45 -> 123. - // 0.678 -> 1. - // - true and true: then 123.45 -> 123.0 - // 0.678 -> 1.0 - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except for the following cases: - // - the input value is special and no infinity_symbol or nan_symbol has - // been provided to the constructor, - // - 'value' > 10^kMaxFixedDigitsBeforePoint, or - // - 'requested_digits' > kMaxFixedDigitsAfterPoint. - // The last two conditions imply that the result will never contain more than - // 1 + kMaxFixedDigitsBeforePoint + 1 + kMaxFixedDigitsAfterPoint characters - // (one additional character for the sign, and one for the decimal point). - MFBT_API bool ToFixed(double value, - int requested_digits, - StringBuilder* result_builder) const; - - // Computes a representation in exponential format with requested_digits - // after the decimal point. The last emitted digit is rounded. - // If requested_digits equals -1, then the shortest exponential representation - // is computed. - // - // Examples with EMIT_POSITIVE_EXPONENT_SIGN deactivated, and - // exponent_character set to 'e'. - // ToExponential(3.12, 1) -> "3.1e0" - // ToExponential(5.0, 3) -> "5.000e0" - // ToExponential(0.001, 2) -> "1.00e-3" - // ToExponential(3.1415, -1) -> "3.1415e0" - // ToExponential(3.1415, 4) -> "3.1415e0" - // ToExponential(3.1415, 3) -> "3.142e0" - // ToExponential(123456789000000, 3) -> "1.235e14" - // ToExponential(1000000000000000019884624838656.0, -1) -> "1e30" - // ToExponential(1000000000000000019884624838656.0, 32) -> - // "1.00000000000000001988462483865600e30" - // ToExponential(1234, 0) -> "1e3" - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except for the following cases: - // - the input value is special and no infinity_symbol or nan_symbol has - // been provided to the constructor, - // - 'requested_digits' > kMaxExponentialDigits. - // The last condition implies that the result will never contain more than - // kMaxExponentialDigits + 8 characters (the sign, the digit before the - // decimal point, the decimal point, the exponent character, the - // exponent's sign, and at most 3 exponent digits). - MFBT_API bool ToExponential(double value, - int requested_digits, - StringBuilder* result_builder) const; - - // Computes 'precision' leading digits of the given 'value' and returns them - // either in exponential or decimal format, depending on - // max_{leading|trailing}_padding_zeroes_in_precision_mode (given to the - // constructor). - // The last computed digit is rounded. - // - // Example with max_leading_padding_zeroes_in_precision_mode = 6. - // ToPrecision(0.0000012345, 2) -> "0.0000012" - // ToPrecision(0.00000012345, 2) -> "1.2e-7" - // Similarily the converter may add up to - // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid - // returning an exponential representation. A zero added by the - // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit. - // Examples for max_trailing_padding_zeroes_in_precision_mode = 1: - // ToPrecision(230.0, 2) -> "230" - // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT. - // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT. - // Examples for max_trailing_padding_zeroes_in_precision_mode = 3, and no - // EMIT_TRAILING_ZERO_AFTER_POINT: - // ToPrecision(123450.0, 6) -> "123450" - // ToPrecision(123450.0, 5) -> "123450" - // ToPrecision(123450.0, 4) -> "123500" - // ToPrecision(123450.0, 3) -> "123000" - // ToPrecision(123450.0, 2) -> "1.2e5" - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except for the following cases: - // - the input value is special and no infinity_symbol or nan_symbol has - // been provided to the constructor, - // - precision < kMinPericisionDigits - // - precision > kMaxPrecisionDigits - // The last condition implies that the result will never contain more than - // kMaxPrecisionDigits + 7 characters (the sign, the decimal point, the - // exponent character, the exponent's sign, and at most 3 exponent digits). - MFBT_API bool ToPrecision(double value, - int precision, - bool* used_exponential_notation, - StringBuilder* result_builder) const; - - enum DtoaMode { - // Produce the shortest correct representation. - // For example the output of 0.299999999999999988897 is (the less accurate - // but correct) 0.3. - SHORTEST, - // Same as SHORTEST, but for single-precision floats. - SHORTEST_SINGLE, - // Produce a fixed number of digits after the decimal point. - // For instance fixed(0.1, 4) becomes 0.1000 - // If the input number is big, the output will be big. - FIXED, - // Fixed number of digits (independent of the decimal point). - PRECISION - }; - - // The maximal number of digits that are needed to emit a double in base 10. - // A higher precision can be achieved by using more digits, but the shortest - // accurate representation of any double will never use more digits than - // kBase10MaximalLength. - // Note that DoubleToAscii null-terminates its input. So the given buffer - // should be at least kBase10MaximalLength + 1 characters long. - static const MFBT_DATA int kBase10MaximalLength = 17; - - // Converts the given double 'v' to ascii. 'v' must not be NaN, +Infinity, or - // -Infinity. In SHORTEST_SINGLE-mode this restriction also applies to 'v' - // after it has been casted to a single-precision float. That is, in this - // mode static_cast(v) must not be NaN, +Infinity or -Infinity. - // - // The result should be interpreted as buffer * 10^(point-length). - // - // The output depends on the given mode: - // - SHORTEST: produce the least amount of digits for which the internal - // identity requirement is still satisfied. If the digits are printed - // (together with the correct exponent) then reading this number will give - // 'v' again. The buffer will choose the representation that is closest to - // 'v'. If there are two at the same distance, than the one farther away - // from 0 is chosen (halfway cases - ending with 5 - are rounded up). - // In this mode the 'requested_digits' parameter is ignored. - // - SHORTEST_SINGLE: same as SHORTEST but with single-precision. - // - FIXED: produces digits necessary to print a given number with - // 'requested_digits' digits after the decimal point. The produced digits - // might be too short in which case the caller has to fill the remainder - // with '0's. - // Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2. - // Halfway cases are rounded towards +/-Infinity (away from 0). The call - // toFixed(0.15, 2) thus returns buffer="2", point=0. - // The returned buffer may contain digits that would be truncated from the - // shortest representation of the input. - // - PRECISION: produces 'requested_digits' where the first digit is not '0'. - // Even though the length of produced digits usually equals - // 'requested_digits', the function is allowed to return fewer digits, in - // which case the caller has to fill the missing digits with '0's. - // Halfway cases are again rounded away from 0. - // DoubleToAscii expects the given buffer to be big enough to hold all - // digits and a terminating null-character. In SHORTEST-mode it expects a - // buffer of at least kBase10MaximalLength + 1. In all other modes the - // requested_digits parameter and the padding-zeroes limit the size of the - // output. Don't forget the decimal point, the exponent character and the - // terminating null-character when computing the maximal output size. - // The given length is only used in debug mode to ensure the buffer is big - // enough. - static MFBT_API void DoubleToAscii(double v, - DtoaMode mode, - int requested_digits, - char* buffer, - int buffer_length, - bool* sign, - int* length, - int* point); - - private: - // Implementation for ToShortest and ToShortestSingle. - MFBT_API bool ToShortestIeeeNumber(double value, - StringBuilder* result_builder, - DtoaMode mode) const; - - // If the value is a special value (NaN or Infinity) constructs the - // corresponding string using the configured infinity/nan-symbol. - // If either of them is NULL or the value is not special then the - // function returns false. - MFBT_API bool HandleSpecialValues(double value, StringBuilder* result_builder) const; - // Constructs an exponential representation (i.e. 1.234e56). - // The given exponent assumes a decimal point after the first decimal digit. - MFBT_API void CreateExponentialRepresentation(const char* decimal_digits, - int length, - int exponent, - StringBuilder* result_builder) const; - // Creates a decimal representation (i.e 1234.5678). - MFBT_API void CreateDecimalRepresentation(const char* decimal_digits, - int length, - int decimal_point, - int digits_after_point, - StringBuilder* result_builder) const; - - const int flags_; - const char* const infinity_symbol_; - const char* const nan_symbol_; - const char exponent_character_; - const int decimal_in_shortest_low_; - const int decimal_in_shortest_high_; - const int max_leading_padding_zeroes_in_precision_mode_; - const int max_trailing_padding_zeroes_in_precision_mode_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter); -}; - - -class StringToDoubleConverter { - public: - // Enumeration for allowing octals and ignoring junk when converting - // strings to numbers. - enum Flags { - NO_FLAGS = 0, - ALLOW_HEX = 1, - ALLOW_OCTALS = 2, - ALLOW_TRAILING_JUNK = 4, - ALLOW_LEADING_SPACES = 8, - ALLOW_TRAILING_SPACES = 16, - ALLOW_SPACES_AFTER_SIGN = 32 - }; - - // Flags should be a bit-or combination of the possible Flags-enum. - // - NO_FLAGS: no special flags. - // - ALLOW_HEX: recognizes the prefix "0x". Hex numbers may only be integers. - // Ex: StringToDouble("0x1234") -> 4660.0 - // In StringToDouble("0x1234.56") the characters ".56" are trailing - // junk. The result of the call is hence dependent on - // the ALLOW_TRAILING_JUNK flag and/or the junk value. - // With this flag "0x" is a junk-string. Even with ALLOW_TRAILING_JUNK, - // the string will not be parsed as "0" followed by junk. - // - // - ALLOW_OCTALS: recognizes the prefix "0" for octals: - // If a sequence of octal digits starts with '0', then the number is - // read as octal integer. Octal numbers may only be integers. - // Ex: StringToDouble("01234") -> 668.0 - // StringToDouble("012349") -> 12349.0 // Not a sequence of octal - // // digits. - // In StringToDouble("01234.56") the characters ".56" are trailing - // junk. The result of the call is hence dependent on - // the ALLOW_TRAILING_JUNK flag and/or the junk value. - // In StringToDouble("01234e56") the characters "e56" are trailing - // junk, too. - // - ALLOW_TRAILING_JUNK: ignore trailing characters that are not part of - // a double literal. - // - ALLOW_LEADING_SPACES: skip over leading spaces. - // - ALLOW_TRAILING_SPACES: ignore trailing spaces. - // - ALLOW_SPACES_AFTER_SIGN: ignore spaces after the sign. - // Ex: StringToDouble("- 123.2") -> -123.2. - // StringToDouble("+ 123.2") -> 123.2 - // - // empty_string_value is returned when an empty string is given as input. - // If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a string - // containing only spaces is converted to the 'empty_string_value', too. - // - // junk_string_value is returned when - // a) ALLOW_TRAILING_JUNK is not set, and a junk character (a character not - // part of a double-literal) is found. - // b) ALLOW_TRAILING_JUNK is set, but the string does not start with a - // double literal. - // - // infinity_symbol and nan_symbol are strings that are used to detect - // inputs that represent infinity and NaN. They can be null, in which case - // they are ignored. - // The conversion routine first reads any possible signs. Then it compares the - // following character of the input-string with the first character of - // the infinity, and nan-symbol. If either matches, the function assumes, that - // a match has been found, and expects the following input characters to match - // the remaining characters of the special-value symbol. - // This means that the following restrictions apply to special-value symbols: - // - they must not start with signs ('+', or '-'), - // - they must not have the same first character. - // - they must not start with digits. - // - // Examples: - // flags = ALLOW_HEX | ALLOW_TRAILING_JUNK, - // empty_string_value = 0.0, - // junk_string_value = NaN, - // infinity_symbol = "infinity", - // nan_symbol = "nan": - // StringToDouble("0x1234") -> 4660.0. - // StringToDouble("0x1234K") -> 4660.0. - // StringToDouble("") -> 0.0 // empty_string_value. - // StringToDouble(" ") -> NaN // junk_string_value. - // StringToDouble(" 1") -> NaN // junk_string_value. - // StringToDouble("0x") -> NaN // junk_string_value. - // StringToDouble("-123.45") -> -123.45. - // StringToDouble("--123.45") -> NaN // junk_string_value. - // StringToDouble("123e45") -> 123e45. - // StringToDouble("123E45") -> 123e45. - // StringToDouble("123e+45") -> 123e45. - // StringToDouble("123E-45") -> 123e-45. - // StringToDouble("123e") -> 123.0 // trailing junk ignored. - // StringToDouble("123e-") -> 123.0 // trailing junk ignored. - // StringToDouble("+NaN") -> NaN // NaN string literal. - // StringToDouble("-infinity") -> -inf. // infinity literal. - // StringToDouble("Infinity") -> NaN // junk_string_value. - // - // flags = ALLOW_OCTAL | ALLOW_LEADING_SPACES, - // empty_string_value = 0.0, - // junk_string_value = NaN, - // infinity_symbol = NULL, - // nan_symbol = NULL: - // StringToDouble("0x1234") -> NaN // junk_string_value. - // StringToDouble("01234") -> 668.0. - // StringToDouble("") -> 0.0 // empty_string_value. - // StringToDouble(" ") -> 0.0 // empty_string_value. - // StringToDouble(" 1") -> 1.0 - // StringToDouble("0x") -> NaN // junk_string_value. - // StringToDouble("0123e45") -> NaN // junk_string_value. - // StringToDouble("01239E45") -> 1239e45. - // StringToDouble("-infinity") -> NaN // junk_string_value. - // StringToDouble("NaN") -> NaN // junk_string_value. - StringToDoubleConverter(int flags, - double empty_string_value, - double junk_string_value, - const char* infinity_symbol, - const char* nan_symbol) - : flags_(flags), - empty_string_value_(empty_string_value), - junk_string_value_(junk_string_value), - infinity_symbol_(infinity_symbol), - nan_symbol_(nan_symbol) { - } - - // Performs the conversion. - // The output parameter 'processed_characters_count' is set to the number - // of characters that have been processed to read the number. - // Spaces than are processed with ALLOW_{LEADING|TRAILING}_SPACES are included - // in the 'processed_characters_count'. Trailing junk is never included. - double StringToDouble(const char* buffer, - int length, - int* processed_characters_count) const { - return StringToIeee(buffer, length, processed_characters_count, true); - } - - // Same as StringToDouble but reads a float. - // Note that this is not equivalent to static_cast(StringToDouble(...)) - // due to potential double-rounding. - float StringToFloat(const char* buffer, - int length, - int* processed_characters_count) const { - return static_cast(StringToIeee(buffer, length, - processed_characters_count, false)); - } - - private: - const int flags_; - const double empty_string_value_; - const double junk_string_value_; - const char* const infinity_symbol_; - const char* const nan_symbol_; - - double StringToIeee(const char* buffer, - int length, - int* processed_characters_count, - bool read_as_double) const; - - DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter); -}; - -} // namespace double_conversion - -#endif // DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/fallible.h b/android/armeabi-v7a/include/spidermonkey/mozilla/fallible.h deleted file mode 100644 index c028360b..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/fallible.h +++ /dev/null @@ -1,68 +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/. */ - -#ifndef mozilla_fallible_h -#define mozilla_fallible_h - -#if defined(__cplusplus) - -/* Explicit fallible allocation - * - * Memory allocation (normally) defaults to abort in case of failed - * allocation. That is, it never returns NULL, and crashes instead. - * - * Code can explicitely request for fallible memory allocation thanks - * to the declarations below. - * - * The typical use of the mozilla::fallible const is with placement new, - * like the following: - * - * foo = new (mozilla::fallible) Foo(); - * - * The following forms, or derivatives, are also possible but deprecated: - * - * foo = new ((mozilla::fallible_t())) Foo(); - * - * const mozilla::fallible_t fallible = mozilla::fallible_t(); - * bar = new (f) Bar(); - * - * It is also possible to declare method overloads with fallible allocation - * alternatives, like so: - * - * class Foo { - * public: - * void Method(void *); - * void Method(void *, const mozilla::fallible_t&); - * }; - * - * Foo foo; - * foo.Method(nullptr, mozilla::fallible); - * - * If that last method call is in a method that itself takes a const - * fallible_t& argument, it is recommended to propagate that argument - * instead of using mozilla::fallible: - * - * void Func(Foo &foo, const mozilla::fallible_t& aFallible) { - * foo.Method(nullptr, aFallible); - * } - * - */ -namespace mozilla { - -struct fallible_t { }; - -/* This symbol is kept unexported, such that in corner cases where the - * compiler can't remove its use (essentially, cross compilation-unit - * calls), the smallest machine code is used. - * Depending how the linker packs symbols, it will consume between 1 and - * 8 bytes of read-only data in each executable or shared library, but - * only in those where it's actually not optimized out by the compiler. - */ -extern const fallible_t fallible; - -} // namespace mozilla - -#endif - -#endif // mozilla_fallible_h diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/mozalloc.h b/android/armeabi-v7a/include/spidermonkey/mozilla/mozalloc.h deleted file mode 100644 index f7ddb7e6..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/mozalloc.h +++ /dev/null @@ -1,361 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: sw=4 ts=4 et : - */ -/* 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 mozilla_mozalloc_h -#define mozilla_mozalloc_h - -/* - * https://bugzilla.mozilla.org/show_bug.cgi?id=427099 - */ - -#if defined(__cplusplus) -# include -// Since libstdc++ 6, including the C headers (e.g. stdlib.h) instead of the -// corresponding C++ header (e.g. cstdlib) can cause confusion in C++ code -// using things defined there. Specifically, with stdlib.h, the use of abs() -// in gfx/graphite2/src/inc/UtfCodec.h somehow ends up picking the wrong abs() -# include -# include -#else -# include -# include -#endif - -#if defined(__cplusplus) -#include "mozilla/fallible.h" -#include "mozilla/mozalloc_abort.h" -#include "mozilla/TemplateLib.h" -#endif -#include "mozilla/Attributes.h" -#include "mozilla/Types.h" - -#define MOZALLOC_HAVE_XMALLOC - -#if defined(MOZ_ALWAYS_INLINE_EVEN_DEBUG) -# define MOZALLOC_INLINE MOZ_ALWAYS_INLINE_EVEN_DEBUG -#elif defined(HAVE_FORCEINLINE) -# define MOZALLOC_INLINE __forceinline -#else -# define MOZALLOC_INLINE inline -#endif - -/* Workaround build problem with Sun Studio 12 */ -#if defined(__SUNPRO_C) || defined(__SUNPRO_CC) -# undef MOZ_MUST_USE -# define MOZ_MUST_USE -# undef MOZ_ALLOCATOR -# define MOZ_ALLOCATOR -#endif - -#if defined(__cplusplus) -extern "C" { -#endif /* ifdef __cplusplus */ - -/* - * We need to use malloc_impl and free_impl in this file when they are - * defined, because of how mozglue.dll is linked on Windows, where using - * malloc/free would end up using the symbols from the MSVCRT instead of - * ours. - */ -#ifndef free_impl -#define free_impl free -#define free_impl_ -#endif -#ifndef malloc_impl -#define malloc_impl malloc -#define malloc_impl_ -#endif - -/* - * Each declaration below is analogous to a "standard" allocation - * function, except that the out-of-memory handling is made explicit. - * The |moz_x| versions will never return a NULL pointer; if memory - * is exhausted, they abort. The |moz_| versions may return NULL - * pointers if memory is exhausted: their return value must be checked. - * - * All these allocation functions are *guaranteed* to return a pointer - * to memory allocated in such a way that that memory can be freed by - * passing that pointer to |free()|. - */ - -MFBT_API void* moz_xmalloc(size_t size) - MOZ_ALLOCATOR; - -MFBT_API void* moz_xcalloc(size_t nmemb, size_t size) - MOZ_ALLOCATOR; - -MFBT_API void* moz_xrealloc(void* ptr, size_t size) - MOZ_ALLOCATOR; - -MFBT_API char* moz_xstrdup(const char* str) - MOZ_ALLOCATOR; - -MFBT_API size_t moz_malloc_usable_size(void *ptr); - -MFBT_API size_t moz_malloc_size_of(const void *ptr); - -#if defined(HAVE_STRNDUP) -MFBT_API char* moz_xstrndup(const char* str, size_t strsize) - MOZ_ALLOCATOR; -#endif /* if defined(HAVE_STRNDUP) */ - - -#if defined(HAVE_POSIX_MEMALIGN) -MFBT_API MOZ_MUST_USE -int moz_xposix_memalign(void **ptr, size_t alignment, size_t size); - -MFBT_API MOZ_MUST_USE -int moz_posix_memalign(void **ptr, size_t alignment, size_t size); -#endif /* if defined(HAVE_POSIX_MEMALIGN) */ - - -#if defined(HAVE_MEMALIGN) -MFBT_API void* moz_xmemalign(size_t boundary, size_t size) - MOZ_ALLOCATOR; -#endif /* if defined(HAVE_MEMALIGN) */ - - -#if defined(HAVE_VALLOC) -MFBT_API void* moz_xvalloc(size_t size) - MOZ_ALLOCATOR; -#endif /* if defined(HAVE_VALLOC) */ - - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* ifdef __cplusplus */ - - -#ifdef __cplusplus - -/* - * We implement the default operators new/delete as part of - * libmozalloc, replacing their definitions in libstdc++. The - * operator new* definitions in libmozalloc will never return a NULL - * pointer. - * - * Each operator new immediately below returns a pointer to memory - * that can be delete'd by any of - * - * (1) the matching infallible operator delete immediately below - * (2) the matching "fallible" operator delete further below - * (3) the matching system |operator delete(void*, std::nothrow)| - * (4) the matching system |operator delete(void*) throw(std::bad_alloc)| - * - * NB: these are declared |throw(std::bad_alloc)|, though they will never - * throw that exception. This declaration is consistent with the rule - * that |::operator new() throw(std::bad_alloc)| will never return NULL. - */ - -/* NB: This is defined just to silence vacuous warnings about symbol - * visibility on OS X/gcc. These symbols are force-inline and not - * exported. */ -#if defined(XP_MACOSX) -# define MOZALLOC_EXPORT_NEW MFBT_API -#else -# define MOZALLOC_EXPORT_NEW -#endif - -#if defined(ANDROID) -/* - * It's important to always specify 'throw()' in GCC because it's used to tell - * GCC that 'new' may return null. That makes GCC null-check the result before - * potentially initializing the memory to zero. - * Also, the Android minimalistic headers don't include std::bad_alloc. - */ -#define MOZALLOC_THROW_IF_HAS_EXCEPTIONS throw() -#define MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS -#elif defined(_MSC_VER) -/* - * Suppress build warning spam (bug 578546). - */ -#define MOZALLOC_THROW_IF_HAS_EXCEPTIONS -#define MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS -#else -#define MOZALLOC_THROW_IF_HAS_EXCEPTIONS throw() -#define MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS throw(std::bad_alloc) -#endif - -#define MOZALLOC_THROW_BAD_ALLOC MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS - -MOZALLOC_EXPORT_NEW -#if defined(__GNUC__) && !defined(__clang__) && defined(__SANITIZE_ADDRESS__) -/* gcc's asan somehow doesn't like always_inline on this function. */ -__attribute__((gnu_inline)) inline -#else -MOZALLOC_INLINE -#endif -void* operator new(size_t size) MOZALLOC_THROW_BAD_ALLOC -{ - return moz_xmalloc(size); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void* operator new(size_t size, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return malloc_impl(size); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void* operator new[](size_t size) MOZALLOC_THROW_BAD_ALLOC -{ - return moz_xmalloc(size); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void* operator new[](size_t size, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return malloc_impl(size); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void operator delete(void* ptr) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return free_impl(ptr); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void operator delete(void* ptr, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return free_impl(ptr); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void operator delete[](void* ptr) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return free_impl(ptr); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void operator delete[](void* ptr, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return free_impl(ptr); -} - - -/* - * We also add a new allocator variant: "fallible operator new." - * Unlike libmozalloc's implementations of the standard nofail - * allocators, this allocator is allowed to return NULL. It can be used - * as follows - * - * Foo* f = new (mozilla::fallible) Foo(...); - * - * operator delete(fallible) is defined for completeness only. - * - * Each operator new below returns a pointer to memory that can be - * delete'd by any of - * - * (1) the matching "fallible" operator delete below - * (2) the matching infallible operator delete above - * (3) the matching system |operator delete(void*, std::nothrow)| - * (4) the matching system |operator delete(void*) throw(std::bad_alloc)| - */ - -MOZALLOC_INLINE -void* operator new(size_t size, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return malloc_impl(size); -} - -MOZALLOC_INLINE -void* operator new[](size_t size, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return malloc_impl(size); -} - -MOZALLOC_INLINE -void operator delete(void* ptr, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - free_impl(ptr); -} - -MOZALLOC_INLINE -void operator delete[](void* ptr, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - free_impl(ptr); -} - - -/* - * This policy is identical to MallocAllocPolicy, except it uses - * moz_xmalloc/moz_xcalloc/moz_xrealloc instead of - * malloc/calloc/realloc. - */ -class InfallibleAllocPolicy -{ -public: - template - T* maybe_pod_malloc(size_t aNumElems) - { - return pod_malloc(aNumElems); - } - - template - T* maybe_pod_calloc(size_t aNumElems) - { - return pod_calloc(aNumElems); - } - - template - T* maybe_pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) - { - return pod_realloc(aPtr, aOldSize, aNewSize); - } - - template - T* pod_malloc(size_t aNumElems) - { - if (aNumElems & mozilla::tl::MulOverflowMask::value) { - reportAllocOverflow(); - } - return static_cast(moz_xmalloc(aNumElems * sizeof(T))); - } - - template - T* pod_calloc(size_t aNumElems) - { - return static_cast(moz_xcalloc(aNumElems, sizeof(T))); - } - - template - T* pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) - { - if (aNewSize & mozilla::tl::MulOverflowMask::value) { - reportAllocOverflow(); - } - return static_cast(moz_xrealloc(aPtr, aNewSize * sizeof(T))); - } - - void free_(void* aPtr) - { - free_impl(aPtr); - } - - void reportAllocOverflow() const - { - mozalloc_abort("alloc overflow"); - } - - bool checkSimulatedOOM() const - { - return true; - } -}; - -#endif /* ifdef __cplusplus */ - -#ifdef malloc_impl_ -#undef malloc_impl_ -#undef malloc_impl -#endif -#ifdef free_impl_ -#undef free_impl_ -#undef free_impl -#endif - -#endif /* ifndef mozilla_mozalloc_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/mozalloc_abort.h b/android/armeabi-v7a/include/spidermonkey/mozilla/mozalloc_abort.h deleted file mode 100644 index 065cebcb..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/mozalloc_abort.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: sw=4 ts=4 et : - */ -/* 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 mozilla_mozalloc_abort_h -#define mozilla_mozalloc_abort_h - -#include "mozilla/Attributes.h" -#include "mozilla/Types.h" - -/** - * Terminate this process in such a way that breakpad is triggered, if - * at all possible. - * - * Note: MOZ_NORETURN seems to break crash stacks on ARM, so we don't - * use that annotation there. - */ -MFBT_API -#if !defined(__arm__) - MOZ_NORETURN -#endif - void mozalloc_abort(const char* const msg); - - -#endif /* ifndef mozilla_mozalloc_abort_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/mozalloc_oom.h b/android/armeabi-v7a/include/spidermonkey/mozilla/mozalloc_oom.h deleted file mode 100644 index 35bb9acc..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/mozalloc_oom.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: sw=4 ts=4 et : - */ -/* 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 mozilla_mozalloc_oom_h -#define mozilla_mozalloc_oom_h - -#include "mozalloc.h" - -/** - * Called when memory is critically low. Returns iff it was able to - * remedy the critical memory situation; if not, it will abort(). - */ -MFBT_API void mozalloc_handle_oom(size_t requestedSize); - -/** - * Called by embedders (specifically Mozilla breakpad) which wants to be - * notified of an intentional abort, to annotate any crash report with - * the size of the allocation on which we aborted. - */ -typedef void (*mozalloc_oom_abort_handler)(size_t size); -MFBT_API void mozalloc_set_oom_abort_handler(mozalloc_oom_abort_handler handler); - -/* TODO: functions to query system memory usage and register - * critical-memory handlers. */ - - -#endif /* ifndef mozilla_mozalloc_oom_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozilla/utils.h b/android/armeabi-v7a/include/spidermonkey/mozilla/utils.h deleted file mode 100644 index 15dd4bfb..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozilla/utils.h +++ /dev/null @@ -1,298 +0,0 @@ -// Copyright 2010 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DOUBLE_CONVERSION_UTILS_H_ -#define DOUBLE_CONVERSION_UTILS_H_ - -#include -#include - -#include "mozilla/Assertions.h" -#ifndef ASSERT -#define ASSERT(condition) MOZ_ASSERT(condition) -#endif -#ifndef UNIMPLEMENTED -#define UNIMPLEMENTED() MOZ_CRASH() -#endif -#ifndef UNREACHABLE -#define UNREACHABLE() MOZ_CRASH() -#endif - -// Double operations detection based on target architecture. -// Linux uses a 80bit wide floating point stack on x86. This induces double -// rounding, which in turn leads to wrong results. -// An easy way to test if the floating-point operations are correct is to -// evaluate: 89255.0/1e22. If the floating-point stack is 64 bits wide then -// the result is equal to 89255e-22. -// The best way to test this, is to create a division-function and to compare -// the output of the division with the expected result. (Inlining must be -// disabled.) -// On Linux,x86 89255e-22 != Div_double(89255.0/1e22) -#if defined(_M_X64) || defined(__x86_64__) || \ - defined(__ARMEL__) || defined(__avr32__) || \ - defined(__hppa__) || defined(__ia64__) || \ - defined(__mips__) || \ - defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \ - defined(__sparc__) || defined(__sparc) || defined(__s390__) || \ - defined(__SH4__) || defined(__alpha__) || \ - defined(_MIPS_ARCH_MIPS32R2) || \ - defined(__AARCH64EL__) || defined(__aarch64__) -#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 -#elif defined(_M_IX86) || defined(__i386__) || defined(__i386) -#if defined(_WIN32) -// Windows uses a 64bit wide floating point stack. -#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 -#else -#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS -#endif // _WIN32 -#else -#error Target architecture was not detected as supported by Double-Conversion. -#endif - - -#include - -// The following macro works on both 32 and 64-bit platforms. -// Usage: instead of writing 0x1234567890123456 -// write UINT64_2PART_C(0x12345678,90123456); -#define UINT64_2PART_C(a, b) (((static_cast(a) << 32) + 0x##b##u)) - - -// The expression ARRAY_SIZE(a) is a compile-time constant of type -// size_t which represents the number of elements of the given -// array. You should only use ARRAY_SIZE on statically allocated -// arrays. -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) \ - ((sizeof(a) / sizeof(*(a))) / \ - static_cast(!(sizeof(a) % sizeof(*(a))))) -#endif - -// A macro to disallow the evil copy constructor and operator= functions -// This should be used in the private: declarations for a class -#ifndef DISALLOW_COPY_AND_ASSIGN -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) -#endif - -// A macro to disallow all the implicit constructors, namely the -// default constructor, copy constructor and operator= functions. -// -// This should be used in the private: declarations for a class -// that wants to prevent anyone from instantiating it. This is -// especially useful for classes containing only static methods. -#ifndef DISALLOW_IMPLICIT_CONSTRUCTORS -#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ - TypeName(); \ - DISALLOW_COPY_AND_ASSIGN(TypeName) -#endif - -namespace double_conversion { - -static const int kCharSize = sizeof(char); - -// Returns the maximum of the two parameters. -template -static T Max(T a, T b) { - return a < b ? b : a; -} - - -// Returns the minimum of the two parameters. -template -static T Min(T a, T b) { - return a < b ? a : b; -} - - -inline int StrLength(const char* string) { - size_t length = strlen(string); - ASSERT(length == static_cast(static_cast(length))); - return static_cast(length); -} - -// This is a simplified version of V8's Vector class. -template -class Vector { - public: - Vector() : start_(NULL), length_(0) {} - Vector(T* data, int len) : start_(data), length_(len) { - ASSERT(len == 0 || (len > 0 && data != NULL)); - } - - // Returns a vector using the same backing storage as this one, - // spanning from and including 'from', to but not including 'to'. - Vector SubVector(int from, int to) { - ASSERT(to <= length_); - ASSERT(from < to); - ASSERT(0 <= from); - return Vector(start() + from, to - from); - } - - // Returns the length of the vector. - int length() const { return length_; } - - // Returns whether or not the vector is empty. - bool is_empty() const { return length_ == 0; } - - // Returns the pointer to the start of the data in the vector. - T* start() const { return start_; } - - // Access individual vector elements - checks bounds in debug mode. - T& operator[](int index) const { - ASSERT(0 <= index && index < length_); - return start_[index]; - } - - T& first() { return start_[0]; } - - T& last() { return start_[length_ - 1]; } - - private: - T* start_; - int length_; -}; - - -// Helper class for building result strings in a character buffer. The -// purpose of the class is to use safe operations that checks the -// buffer bounds on all operations in debug mode. -class StringBuilder { - public: - StringBuilder(char* buffer, int buffer_size) - : buffer_(buffer, buffer_size), position_(0) { } - - ~StringBuilder() { if (!is_finalized()) Finalize(); } - - int size() const { return buffer_.length(); } - - // Get the current position in the builder. - int position() const { - ASSERT(!is_finalized()); - return position_; - } - - // Reset the position. - void Reset() { position_ = 0; } - - // Add a single character to the builder. It is not allowed to add - // 0-characters; use the Finalize() method to terminate the string - // instead. - void AddCharacter(char c) { - ASSERT(c != '\0'); - ASSERT(!is_finalized() && position_ < buffer_.length()); - buffer_[position_++] = c; - } - - // Add an entire string to the builder. Uses strlen() internally to - // compute the length of the input string. - void AddString(const char* s) { - AddSubstring(s, StrLength(s)); - } - - // Add the first 'n' characters of the given string 's' to the - // builder. The input string must have enough characters. - void AddSubstring(const char* s, int n) { - ASSERT(!is_finalized() && position_ + n < buffer_.length()); - ASSERT(static_cast(n) <= strlen(s)); - memmove(&buffer_[position_], s, n * kCharSize); - position_ += n; - } - - - // Add character padding to the builder. If count is non-positive, - // nothing is added to the builder. - void AddPadding(char c, int count) { - for (int i = 0; i < count; i++) { - AddCharacter(c); - } - } - - // Finalize the string by 0-terminating it and returning the buffer. - char* Finalize() { - ASSERT(!is_finalized() && position_ < buffer_.length()); - buffer_[position_] = '\0'; - // Make sure nobody managed to add a 0-character to the - // buffer while building the string. - ASSERT(strlen(buffer_.start()) == static_cast(position_)); - position_ = -1; - ASSERT(is_finalized()); - return buffer_.start(); - } - - private: - Vector buffer_; - int position_; - - bool is_finalized() const { return position_ < 0; } - - DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder); -}; - -// The type-based aliasing rule allows the compiler to assume that pointers of -// different types (for some definition of different) never alias each other. -// Thus the following code does not work: -// -// float f = foo(); -// int fbits = *(int*)(&f); -// -// The compiler 'knows' that the int pointer can't refer to f since the types -// don't match, so the compiler may cache f in a register, leaving random data -// in fbits. Using C++ style casts makes no difference, however a pointer to -// char data is assumed to alias any other pointer. This is the 'memcpy -// exception'. -// -// Bit_cast uses the memcpy exception to move the bits from a variable of one -// type of a variable of another type. Of course the end result is likely to -// be implementation dependent. Most compilers (gcc-4.2 and MSVC 2005) -// will completely optimize BitCast away. -// -// There is an additional use for BitCast. -// Recent gccs will warn when they see casts that may result in breakage due to -// the type-based aliasing rule. If you have checked that there is no breakage -// you can use BitCast to cast one pointer type to another. This confuses gcc -// enough that it can no longer see that you have cast one pointer type to -// another thus avoiding the warning. -template -inline Dest BitCast(const Source& source) { - static_assert(sizeof(Dest) == sizeof(Source), - "BitCast's source and destination types must be the same size"); - - Dest dest; - memmove(&dest, &source, sizeof(dest)); - return dest; -} - -template -inline Dest BitCast(Source* source) { - return BitCast(reinterpret_cast(source)); -} - -} // namespace double_conversion - -#endif // DOUBLE_CONVERSION_UTILS_H_ diff --git a/android/armeabi-v7a/include/spidermonkey/mozmemory.h b/android/armeabi-v7a/include/spidermonkey/mozmemory.h deleted file mode 100644 index 84007fff..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozmemory.h +++ /dev/null @@ -1,91 +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/. */ - -#ifndef mozmemory_h -#define mozmemory_h - -/* - * This header is meant to be used when the following functions are - * necessary: - * - malloc_good_size (used to be called je_malloc_usable_in_advance) - * - jemalloc_stats - * - jemalloc_purge_freed_pages - * - jemalloc_free_dirty_pages - */ - -#ifndef MOZ_MEMORY -# error Should not include mozmemory.h when MOZ_MEMORY is not set -#endif - -#include "mozmemory_wrap.h" -#include "mozilla/Attributes.h" -#include "mozilla/Types.h" -#include "jemalloc_types.h" - -MOZ_BEGIN_EXTERN_C - -/* - * On OSX, malloc/malloc.h contains the declaration for malloc_good_size, - * which will call back in jemalloc, through the zone allocator so just use it. - */ -#ifdef XP_DARWIN -# include -#else -MOZ_MEMORY_API size_t malloc_good_size_impl(size_t size); - -/* Note: the MOZ_GLUE_IN_PROGRAM ifdef below is there to avoid -Werror turning - * the protective if into errors. MOZ_GLUE_IN_PROGRAM is what triggers MFBT_API - * to use weak imports. */ - -static inline size_t _malloc_good_size(size_t size) { -# if defined(MOZ_GLUE_IN_PROGRAM) && !defined(IMPL_MFBT) - if (!malloc_good_size) - return size; -# endif - return malloc_good_size_impl(size); -} - -# define malloc_good_size _malloc_good_size -#endif - -MOZ_JEMALLOC_API void jemalloc_stats(jemalloc_stats_t *stats); - -/* - * On some operating systems (Mac), we use madvise(MADV_FREE) to hand pages - * back to the operating system. On Mac, the operating system doesn't take - * this memory back immediately; instead, the OS takes it back only when the - * machine is running out of physical memory. - * - * This is great from the standpoint of efficiency, but it makes measuring our - * actual RSS difficult, because pages which we've MADV_FREE'd shouldn't count - * against our RSS. - * - * This function explicitly purges any MADV_FREE'd pages from physical memory, - * causing our reported RSS match the amount of memory we're actually using. - * - * Note that this call is expensive in two ways. First, it may be slow to - * execute, because it may make a number of slow syscalls to free memory. This - * function holds the big jemalloc locks, so basically all threads are blocked - * while this function runs. - * - * This function is also expensive in that the next time we go to access a page - * which we've just explicitly decommitted, the operating system has to attach - * to it a physical page! If we hadn't run this function, the OS would have - * less work to do. - * - * If MALLOC_DOUBLE_PURGE is not defined, this function does nothing. - */ -MOZ_JEMALLOC_API void jemalloc_purge_freed_pages(); - -/* - * Free all unused dirty pages in all arenas. Calling this function will slow - * down subsequent allocations so it is recommended to use it only when - * memory needs to be reclaimed at all costs (see bug 805855). This function - * provides functionality similar to mallctl("arenas.purge") in jemalloc 3. - */ -MOZ_JEMALLOC_API void jemalloc_free_dirty_pages(); - -MOZ_END_EXTERN_C - -#endif /* mozmemory_h */ diff --git a/android/armeabi-v7a/include/spidermonkey/mozmemory_wrap.h b/android/armeabi-v7a/include/spidermonkey/mozmemory_wrap.h deleted file mode 100644 index 066d5778..00000000 --- a/android/armeabi-v7a/include/spidermonkey/mozmemory_wrap.h +++ /dev/null @@ -1,219 +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/. */ - -#ifndef mozmemory_wrap_h -#define mozmemory_wrap_h - -/* - * This header contains #defines which tweak the names of various memory - * allocation functions. - * - * There are several types of functions related to memory allocation - * that are meant to be used publicly by the Gecko codebase: - * - * - malloc implementation functions: - * - malloc - * - posix_memalign - * - aligned_alloc - * - calloc - * - realloc - * - free - * - memalign - * - valloc - * - malloc_usable_size - * - malloc_good_size - * Some of these functions are specific to some systems, but for - * convenience, they are treated as being cross-platform, and available - * as such. - * - * - duplication functions: - * - strndup - * - strdup - * - wcsdup (Windows only) - * - * - jemalloc specific functions: - * - jemalloc_stats - * - jemalloc_purge_freed_pages - * - jemalloc_free_dirty_pages - * (these functions are native to mozjemalloc, and have compatibility - * implementations for jemalloc3) - * - * These functions are all exported as part of libmozglue (see - * $(topsrcdir)/mozglue/build/Makefile.in), with a few implementation - * peculiarities: - * - * - On Windows, the malloc implementation functions are all prefixed with - * "je_", the duplication functions are prefixed with "wrap_", and jemalloc - * specific functions are left unprefixed. All these functions are however - * aliased when exporting them, such that the resulting mozglue.dll exports - * them unprefixed (see $(topsrcdir)/mozglue/build/mozglue.def.in). The - * prefixed malloc implementation and duplication functions are not - * exported. - * - * - On MacOSX, the system libc has a zone allocator, which allows us to - * hook custom malloc implementation functions without exporting them. - * The malloc implementation functions are all prefixed with "je_" and used - * this way from the custom zone allocator. They are not exported. - * Duplication functions are not included, since they will call the custom - * zone allocator anyways. Jemalloc-specific functions are also left - * unprefixed. - * - * - On Android and Gonk, all functions are left unprefixed. Additionally, - * C++ allocation functions (operator new/delete) are also exported and - * unprefixed. - * - * - On other systems (mostly Linux), all functions are left unprefixed. - * - * Only Android and Gonk add C++ allocation functions. - * - * Proper exporting of the various functions is done with the MOZ_MEMORY_API - * and MOZ_JEMALLOC_API macros. MOZ_MEMORY_API is meant to be used for malloc - * implementation and duplication functions, while MOZ_JEMALLOC_API is - * dedicated to jemalloc specific functions. - * - * - * All these functions are meant to be called with no prefix from Gecko code. - * In most cases, this is because that's how they are available at runtime. - * However, on Android, this relies on faulty.lib (the custom dynamic linker) - * resolving mozglue symbols before libc symbols, which is guaranteed by the - * way faulty.lib works (it respects the DT_NEEDED order, and libc always - * appears after mozglue ; which we double check when building anyways) - * - * - * Within libmozglue (when MOZ_MEMORY_IMPL is defined), all the functions - * should be suffixed with "_impl" both for declarations and use. - * That is, the implementation declaration for e.g. strdup would look like: - * char* strdup_impl(const char *) - * That implementation would call malloc by using "malloc_impl". - * - * While mozjemalloc uses these "_impl" suffixed helpers, jemalloc3, being - * third-party code, doesn't, but instead has an elaborate way to mangle - * individual functions. See under "Run jemalloc configure script" in - * $(topsrcdir)/configure.in. - * - * - * When building with replace-malloc support, the above still holds, but - * the malloc implementation and jemalloc specific functions are the - * replace-malloc functions from replace_malloc.c. - * - * The actual jemalloc/mozjemalloc implementation is prefixed with "je_". - * - * Thus, when MOZ_REPLACE_MALLOC is defined, the "_impl" suffixed macros - * expand to "je_" prefixed function when building mozjemalloc or - * jemalloc3/mozjemalloc_compat, where MOZ_JEMALLOC_IMPL is defined. - * - * In other cases, the "_impl" suffixed macros follow the original scheme, - * except on Windows and MacOSX, where they would expand to "je_" prefixed - * functions. Instead, they are left unmodified (malloc_impl expands to - * malloc_impl). - */ - -#ifndef MOZ_MEMORY -# error Should only include mozmemory_wrap.h when MOZ_MEMORY is set. -#endif - -#if defined(MOZ_JEMALLOC_IMPL) && !defined(MOZ_MEMORY_IMPL) -# define MOZ_MEMORY_IMPL -#endif -#if defined(MOZ_MEMORY_IMPL) && !defined(IMPL_MFBT) -# ifdef MFBT_API /* mozilla/Types.h was already included */ -# error mozmemory_wrap.h has to be included before mozilla/Types.h when MOZ_MEMORY_IMPL is set and IMPL_MFBT is not. -# endif -# define IMPL_MFBT -#endif - -#include "mozilla/Types.h" - -#if !defined(MOZ_SYSTEM_JEMALLOC) -# ifdef MOZ_MEMORY_IMPL -# if defined(MOZ_JEMALLOC_IMPL) && defined(MOZ_REPLACE_MALLOC) && !defined(MOZ_REPLACE_JEMALLOC) -# define mozmem_malloc_impl(a) je_ ## a -# define mozmem_jemalloc_impl(a) je_ ## a -# else -# define MOZ_JEMALLOC_API MFBT_API -# ifdef MOZ_REPLACE_JEMALLOC -# define MOZ_MEMORY_API MFBT_API -# define mozmem_malloc_impl(a) replace_ ## a -# define mozmem_jemalloc_impl(a) replace_ ## a -# elif (defined(XP_WIN) || defined(XP_DARWIN)) -# if defined(MOZ_REPLACE_MALLOC) -# define mozmem_malloc_impl(a) a ## _impl -# else -# define mozmem_malloc_impl(a) je_ ## a -# endif -# else -# define MOZ_MEMORY_API MFBT_API -# if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK) -# define MOZ_WRAP_NEW_DELETE -# endif -# endif -# endif -# ifdef XP_WIN -# define mozmem_dup_impl(a) wrap_ ## a -# endif -# endif - -/* All other jemalloc3 functions are prefixed with "je_", except when - * building against an unprefixed system jemalloc library */ -# define je_(a) je_ ## a -#else /* defined(MOZ_SYSTEM_JEMALLOC) */ -# define je_(a) a -#endif - -#if !defined(MOZ_MEMORY_IMPL) || defined(MOZ_SYSTEM_JEMALLOC) -# define MOZ_MEMORY_API MFBT_API -# define MOZ_JEMALLOC_API MFBT_API -#endif - -#ifndef MOZ_MEMORY_API -# define MOZ_MEMORY_API -#endif -#ifndef MOZ_JEMALLOC_API -# define MOZ_JEMALLOC_API -#endif - -#ifndef mozmem_malloc_impl -# define mozmem_malloc_impl(a) a -#endif -#ifndef mozmem_dup_impl -# define mozmem_dup_impl(a) a -#endif -#ifndef mozmem_jemalloc_impl -# define mozmem_jemalloc_impl(a) a -#endif - -/* Malloc implementation functions */ -#define malloc_impl mozmem_malloc_impl(malloc) -#define posix_memalign_impl mozmem_malloc_impl(posix_memalign) -#define aligned_alloc_impl mozmem_malloc_impl(aligned_alloc) -#define calloc_impl mozmem_malloc_impl(calloc) -#define realloc_impl mozmem_malloc_impl(realloc) -#define free_impl mozmem_malloc_impl(free) -#define memalign_impl mozmem_malloc_impl(memalign) -#define valloc_impl mozmem_malloc_impl(valloc) -#define malloc_usable_size_impl mozmem_malloc_impl(malloc_usable_size) -#define malloc_good_size_impl mozmem_malloc_impl(malloc_good_size) - -/* Duplication functions */ -#define strndup_impl mozmem_dup_impl(strndup) -#define strdup_impl mozmem_dup_impl(strdup) -#ifdef XP_WIN -# define wcsdup_impl mozmem_dup_impl(wcsdup) -#endif - -/* String functions */ -#ifdef ANDROID -/* Bug 801571 and Bug 879668, libstagefright uses vasprintf, causing malloc()/ - * free() to be mismatched between bionic and mozglue implementation. - */ -#define vasprintf_impl mozmem_dup_impl(vasprintf) -#define asprintf_impl mozmem_dup_impl(asprintf) -#endif - -/* Jemalloc specific function */ -#define jemalloc_stats_impl mozmem_jemalloc_impl(jemalloc_stats) -#define jemalloc_purge_freed_pages_impl mozmem_jemalloc_impl(jemalloc_purge_freed_pages) -#define jemalloc_free_dirty_pages_impl mozmem_jemalloc_impl(jemalloc_free_dirty_pages) - -#endif /* mozmemory_wrap_h */ diff --git a/android/armeabi-v7a/libjs_static.a b/android/armeabi-v7a/libjs_static.a deleted file mode 100644 index cceaffd5..00000000 Binary files a/android/armeabi-v7a/libjs_static.a and /dev/null differ diff --git a/android/armeabi-v7a/libmozglue.a b/android/armeabi-v7a/libmozglue.a deleted file mode 100644 index d988a215..00000000 Binary files a/android/armeabi-v7a/libmozglue.a and /dev/null differ diff --git a/android/x86/include/spidermonkey/fdlibm.h b/android/x86/include/spidermonkey/fdlibm.h deleted file mode 100644 index 0ad21591..00000000 --- a/android/x86/include/spidermonkey/fdlibm.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* - * from: @(#)fdlibm.h 5.1 93/09/24 - * $FreeBSD$ - */ - -#ifndef mozilla_imported_fdlibm_h -#define mozilla_imported_fdlibm_h - -namespace fdlibm { - -double acos(double); -double asin(double); -double atan(double); -double atan2(double, double); - -double cosh(double); -double sinh(double); -double tanh(double); - -double exp(double); -double log(double); -double log10(double); - -double pow(double, double); -double sqrt(double); -double fabs(double); - -double floor(double); -double trunc(double); -double ceil(double); - -double acosh(double); -double asinh(double); -double atanh(double); -double cbrt(double); -double expm1(double); -double hypot(double, double); -double log1p(double); -double log2(double); -double rint(double); -double copysign(double, double); -double nearbyint(double); -double scalbn(double, int); - -float ceilf(float); -float floorf(float); - -float nearbyintf(float); -float rintf(float); -float truncf(float); - -} /* namespace fdlibm */ - -#endif /* mozilla_imported_fdlibm_h */ diff --git a/android/x86/include/spidermonkey/jemalloc_types.h b/android/x86/include/spidermonkey/jemalloc_types.h deleted file mode 100644 index ae8dc441..00000000 --- a/android/x86/include/spidermonkey/jemalloc_types.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- Mode: C; tab-width: 8; c-basic-offset: 8 -*- */ -/* vim:set softtabstop=8 shiftwidth=8: */ -/*- - * Copyright (C) 2006-2008 Jason Evans . - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _JEMALLOC_TYPES_H_ -#define _JEMALLOC_TYPES_H_ - -/* grab size_t */ -#ifdef _MSC_VER -#include -#else -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef unsigned char jemalloc_bool; - -/* - * jemalloc_stats() is not a stable interface. When using jemalloc_stats_t, be - * sure that the compiled results of jemalloc.c are in sync with this header - * file. - */ -typedef struct { - /* - * Run-time configuration settings. - */ - jemalloc_bool opt_abort; /* abort(3) on error? */ - jemalloc_bool opt_junk; /* Fill allocated memory with 0xe4? */ - jemalloc_bool opt_poison; /* Fill free memory with 0xe5? */ - jemalloc_bool opt_utrace; /* Trace all allocation events? */ - jemalloc_bool opt_sysv; /* SysV semantics? */ - jemalloc_bool opt_xmalloc; /* abort(3) on OOM? */ - jemalloc_bool opt_zero; /* Fill allocated memory with 0x0? */ - size_t narenas; /* Number of arenas. */ - size_t balance_threshold; /* Arena contention rebalance threshold. */ - size_t quantum; /* Allocation quantum. */ - size_t small_max; /* Max quantum-spaced allocation size. */ - size_t large_max; /* Max sub-chunksize allocation size. */ - size_t chunksize; /* Size of each virtual memory mapping. */ - size_t dirty_max; /* Max dirty pages per arena. */ - - /* - * Current memory usage statistics. - */ - size_t mapped; /* Bytes mapped (not necessarily committed). */ - size_t allocated; /* Bytes allocated (committed, in use by application). */ - size_t waste; /* Bytes committed, not in use by the - application, and not intentionally left - unused (i.e., not dirty). */ - size_t page_cache; /* Committed, unused pages kept around as a - cache. (jemalloc calls these "dirty".) */ - size_t bookkeeping; /* Committed bytes used internally by the - allocator. */ - size_t bin_unused; /* Bytes committed to a bin but currently unused. */ -} jemalloc_stats_t; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* _JEMALLOC_TYPES_H_ */ diff --git a/android/x86/include/spidermonkey/js-config.h b/android/x86/include/spidermonkey/js-config.h deleted file mode 100644 index f21bdf41..00000000 --- a/android/x86/include/spidermonkey/js-config.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=78: - * - * 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 js_config_h -#define js_config_h - -/* Definitions set at build time that affect SpiderMonkey's public API. - This header file is generated by the SpiderMonkey configure script, - and installed along with jsapi.h. */ - -/* Define to 1 if SpiderMonkey is in debug mode. */ -/* #undef JS_DEBUG */ - -/* - * NB: We have a special case for rust-bindgen, which wants to be able to - * generate both debug and release bindings on a single objdir. - */ -#ifdef JS_DEBUG -#if !defined(DEBUG) && !defined(RUST_BINDGEN) -# error "SpiderMonkey was configured with --enable-debug, so DEBUG must be defined when including this header" -# endif -#else -# if defined(DEBUG) && !defined(RUST_BINDGEN) -# error "SpiderMonkey was configured with --disable-debug, so DEBUG must be not defined when including this header" -# endif -#endif - -/* Define to 1 if SpiderMonkey should not use struct types in debug builds. */ -/* #undef JS_NO_JSVAL_JSID_STRUCT_TYPES */ - -/* Define to 1 if SpiderMonkey should support multi-threaded clients. */ -/* #undef JS_THREADSAFE */ - -/* Define to 1 if SpiderMonkey should include ctypes support. */ -/* #undef JS_HAS_CTYPES */ - -/* Define to 1 if SpiderMonkey should support the ability to perform - entirely too much GC. */ -/* #undef JS_GC_ZEAL */ - -/* Define to 1 if SpiderMonkey should use small chunks. */ -/* #undef JS_GC_SMALL_CHUNK_SIZE */ - -/* Define to 1 to perform extra assertions and heap poisoning. */ -/* #undef JS_CRASH_DIAGNOSTICS */ - -/* Define to 1 if SpiderMonkey is in NUNBOX32 mode. */ -#define JS_NUNBOX32 1 - -/* Define to 1 if SpiderMonkey is in PUNBOX64 mode. */ -/* #undef JS_PUNBOX64 */ - -/* MOZILLA JSAPI version number components */ -#define MOZJS_MAJOR_VERSION 52 -#define MOZJS_MINOR_VERSION 0 - -#endif /* js_config_h */ diff --git a/android/x86/include/spidermonkey/js.msg b/android/x86/include/spidermonkey/js.msg deleted file mode 100644 index 246e363c..00000000 --- a/android/x86/include/spidermonkey/js.msg +++ /dev/null @@ -1,581 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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/. */ - -/* - * This is the JavaScript error message file. - * - * The format for each JS error message is: - * - * MSG_DEF(, , , - * ) - * - * where ; - * is a legal C identifer that will be used in the - * JS engine source. - * - * is an integer literal specifying the total number of - * replaceable arguments in the following format string. - * - * is an exception index from the enum in jsexn.c; - * JSEXN_NONE for none. The given exception index will be raised by the - * engine when the corresponding error occurs. - * - * is a string literal, optionally containing sequences - * {X} where X is an integer representing the argument number that will - * be replaced with a string value when the error is reported. - * - * e.g. - * - * MSG_DEF(JSMSG_NOT_A_SUBSPECIES, 2, JSEXN_NONE, - * "{0} is not a member of the {1} family") - * - * can be used: - * - * JS_ReportErrorNumberASCII(JSMSG_NOT_A_SUBSPECIES, "Rhino", "Monkey"); - * - * to report: - * - * "Rhino is not a member of the Monkey family" - */ - -MSG_DEF(JSMSG_NOT_AN_ERROR, 0, JSEXN_ERR, "") -MSG_DEF(JSMSG_NOT_DEFINED, 1, JSEXN_REFERENCEERR, "{0} is not defined") -MSG_DEF(JSMSG_MORE_ARGS_NEEDED, 3, JSEXN_TYPEERR, "{0} requires more than {1} argument{2}") -MSG_DEF(JSMSG_INCOMPATIBLE_PROTO, 3, JSEXN_TYPEERR, "{0}.prototype.{1} called on incompatible {2}") -MSG_DEF(JSMSG_NO_CONSTRUCTOR, 1, JSEXN_TYPEERR, "{0} has no constructor") -MSG_DEF(JSMSG_BAD_SORT_ARG, 0, JSEXN_TYPEERR, "invalid Array.prototype.sort argument") -MSG_DEF(JSMSG_CANT_WATCH, 1, JSEXN_TYPEERR, "can't watch non-native objects of class {0}") -MSG_DEF(JSMSG_READ_ONLY, 1, JSEXN_TYPEERR, "{0} is read-only") -MSG_DEF(JSMSG_CANT_DELETE, 1, JSEXN_TYPEERR, "property {0} is non-configurable and can't be deleted") -MSG_DEF(JSMSG_CANT_TRUNCATE_ARRAY, 0, JSEXN_TYPEERR, "can't delete non-configurable array element") -MSG_DEF(JSMSG_NOT_FUNCTION, 1, JSEXN_TYPEERR, "{0} is not a function") -MSG_DEF(JSMSG_NOT_CONSTRUCTOR, 1, JSEXN_TYPEERR, "{0} is not a constructor") -MSG_DEF(JSMSG_CANT_CONVERT_TO, 2, JSEXN_TYPEERR, "can't convert {0} to {1}") -MSG_DEF(JSMSG_TOPRIMITIVE_NOT_CALLABLE, 2, JSEXN_TYPEERR, "can't convert {0} to {1}: its [Symbol.toPrimitive] property is not a function") -MSG_DEF(JSMSG_TOPRIMITIVE_RETURNED_OBJECT, 2, JSEXN_TYPEERR, "can't convert {0} to {1}: its [Symbol.toPrimitive] method returned an object") -MSG_DEF(JSMSG_NO_PROPERTIES, 1, JSEXN_TYPEERR, "{0} has no properties") -MSG_DEF(JSMSG_BAD_REGEXP_FLAG, 1, JSEXN_SYNTAXERR, "invalid regular expression flag {0}") -MSG_DEF(JSMSG_ARG_INDEX_OUT_OF_RANGE, 1, JSEXN_RANGEERR, "argument {0} accesses an index that is out of range") -MSG_DEF(JSMSG_SPREAD_TOO_LARGE, 0, JSEXN_RANGEERR, "array too large due to spread operand(s)") -MSG_DEF(JSMSG_BAD_WEAKMAP_KEY, 0, JSEXN_TYPEERR, "cannot use the given object as a weak map key") -MSG_DEF(JSMSG_BAD_GETTER_OR_SETTER, 1, JSEXN_TYPEERR, "invalid {0} usage") -MSG_DEF(JSMSG_BAD_ARRAY_LENGTH, 0, JSEXN_RANGEERR, "invalid array length") -MSG_DEF(JSMSG_REDECLARED_VAR, 2, JSEXN_SYNTAXERR, "redeclaration of {0} {1}") -MSG_DEF(JSMSG_UNDECLARED_VAR, 1, JSEXN_REFERENCEERR, "assignment to undeclared variable {0}") -MSG_DEF(JSMSG_GETTER_ONLY, 0, JSEXN_TYPEERR, "setting a property that has only a getter") -MSG_DEF(JSMSG_OVERWRITING_ACCESSOR, 1, JSEXN_TYPEERR, "can't overwrite accessor property {0}") -MSG_DEF(JSMSG_UNDEFINED_PROP, 1, JSEXN_REFERENCEERR, "reference to undefined property {0}") -MSG_DEF(JSMSG_INVALID_MAP_ITERABLE, 1, JSEXN_TYPEERR, "iterable for {0} should have array-like objects") -MSG_DEF(JSMSG_NESTING_GENERATOR, 0, JSEXN_TYPEERR, "already executing generator") -MSG_DEF(JSMSG_INCOMPATIBLE_METHOD, 3, JSEXN_TYPEERR, "{0} {1} called on incompatible {2}") -MSG_DEF(JSMSG_OBJECT_WATCH_DEPRECATED, 0, JSEXN_WARN, "Object.prototype.watch and unwatch are very slow, non-standard, and deprecated; use a getter/setter instead") -MSG_DEF(JSMSG_ARRAYBUFFER_SLICE_DEPRECATED, 0, JSEXN_WARN, "ArrayBuffer.slice is deprecated; use ArrayBuffer.prototype.slice instead") -MSG_DEF(JSMSG_BAD_SURROGATE_CHAR, 1, JSEXN_TYPEERR, "bad surrogate character {0}") -MSG_DEF(JSMSG_UTF8_CHAR_TOO_LARGE, 1, JSEXN_TYPEERR, "UTF-8 character {0} too large") -MSG_DEF(JSMSG_MALFORMED_UTF8_CHAR, 1, JSEXN_TYPEERR, "malformed UTF-8 character sequence at offset {0}") -MSG_DEF(JSMSG_BUILTIN_CTOR_NO_NEW, 1, JSEXN_TYPEERR, "calling a builtin {0} constructor without new is forbidden") -MSG_DEF(JSMSG_BAD_GENERATOR_YIELD, 1, JSEXN_TYPEERR, "yield from closing generator {0}") -MSG_DEF(JSMSG_EMPTY_ARRAY_REDUCE, 0, JSEXN_TYPEERR, "reduce of empty array with no initial value") -MSG_DEF(JSMSG_UNEXPECTED_TYPE, 2, JSEXN_TYPEERR, "{0} is {1}") -MSG_DEF(JSMSG_MISSING_FUN_ARG, 2, JSEXN_TYPEERR, "missing argument {0} when calling function {1}") -MSG_DEF(JSMSG_NOT_NONNULL_OBJECT, 1, JSEXN_TYPEERR, "{0} is not a non-null object") -MSG_DEF(JSMSG_SET_NON_OBJECT_RECEIVER, 1, JSEXN_TYPEERR, "can't assign to properties of {0}: not an object") -MSG_DEF(JSMSG_INVALID_DESCRIPTOR, 0, JSEXN_TYPEERR, "property descriptors must not specify a value or be writable when a getter or setter has been specified") -MSG_DEF(JSMSG_OBJECT_NOT_EXTENSIBLE, 1, JSEXN_TYPEERR, "{0}: Object is not extensible") -MSG_DEF(JSMSG_CANT_DEFINE_PROP_OBJECT_NOT_EXTENSIBLE, 2, JSEXN_TYPEERR, "can't define property {1}: {0} is not extensible") -MSG_DEF(JSMSG_CANT_REDEFINE_PROP, 1, JSEXN_TYPEERR, "can't redefine non-configurable property {0}") -MSG_DEF(JSMSG_CANT_REDEFINE_ARRAY_LENGTH, 0, JSEXN_TYPEERR, "can't redefine array length") -MSG_DEF(JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH, 0, JSEXN_TYPEERR, "can't define array index property past the end of an array with non-writable length") -MSG_DEF(JSMSG_BAD_GET_SET_FIELD, 1, JSEXN_TYPEERR, "property descriptor's {0} field is neither undefined nor a function") -MSG_DEF(JSMSG_THROW_TYPE_ERROR, 0, JSEXN_TYPEERR, "'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them") -MSG_DEF(JSMSG_NOT_EXPECTED_TYPE, 3, JSEXN_TYPEERR, "{0}: expected {1}, got {2}") -MSG_DEF(JSMSG_NOT_ITERABLE, 1, JSEXN_TYPEERR, "{0} is not iterable") -MSG_DEF(JSMSG_NOT_ITERATOR, 1, JSEXN_TYPEERR, "{0} is not iterator") -MSG_DEF(JSMSG_ALREADY_HAS_PRAGMA, 2, JSEXN_WARN, "{0} is being assigned a {1}, but already has one") -MSG_DEF(JSMSG_GET_ITER_RETURNED_PRIMITIVE, 0, JSEXN_TYPEERR, "[Symbol.iterator]() returned a non-object value") -MSG_DEF(JSMSG_NEXT_RETURNED_PRIMITIVE, 0, JSEXN_TYPEERR, "iterator.next() returned a non-object value") -MSG_DEF(JSMSG_CANT_SET_PROTO, 0, JSEXN_TYPEERR, "can't set prototype of this object") -MSG_DEF(JSMSG_CANT_SET_PROTO_OF, 1, JSEXN_TYPEERR, "can't set prototype of {0}") -MSG_DEF(JSMSG_CANT_SET_PROTO_CYCLE, 0, JSEXN_TYPEERR, "can't set prototype: it would cause a prototype chain cycle") -MSG_DEF(JSMSG_INVALID_ARG_TYPE, 3, JSEXN_TYPEERR, "Invalid type: {0} can't be a{1} {2}") -MSG_DEF(JSMSG_TERMINATED, 1, JSEXN_ERR, "Script terminated by timeout at:\n{0}") -MSG_DEF(JSMSG_PROTO_NOT_OBJORNULL, 1, JSEXN_TYPEERR, "{0}.prototype is not an object or null") -MSG_DEF(JSMSG_CANT_CALL_CLASS_CONSTRUCTOR, 0, JSEXN_TYPEERR, "class constructors must be invoked with |new|") -MSG_DEF(JSMSG_UNINITIALIZED_THIS, 1, JSEXN_REFERENCEERR, "|this| used uninitialized in {0} class constructor") -MSG_DEF(JSMSG_UNINITIALIZED_THIS_ARROW, 0, JSEXN_REFERENCEERR, "|this| used uninitialized in arrow function in class constructor") -MSG_DEF(JSMSG_BAD_DERIVED_RETURN, 1, JSEXN_TYPEERR, "derived class constructor returned invalid value {0}") - -// JSON -MSG_DEF(JSMSG_JSON_BAD_PARSE, 3, JSEXN_SYNTAXERR, "JSON.parse: {0} at line {1} column {2} of the JSON data") -MSG_DEF(JSMSG_JSON_CYCLIC_VALUE, 0, JSEXN_TYPEERR, "cyclic object value") - -// Runtime errors -MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS, 1, JSEXN_TYPEERR, "invalid 'instanceof' operand {0}") -MSG_DEF(JSMSG_BAD_LEFTSIDE_OF_ASS, 0, JSEXN_REFERENCEERR, "invalid assignment left-hand side") -MSG_DEF(JSMSG_BAD_PROTOTYPE, 1, JSEXN_TYPEERR, "'prototype' property of {0} is not an object") -MSG_DEF(JSMSG_IN_NOT_OBJECT, 1, JSEXN_TYPEERR, "invalid 'in' operand {0}") -MSG_DEF(JSMSG_TOO_MANY_CON_SPREADARGS, 0, JSEXN_RANGEERR, "too many constructor arguments") -MSG_DEF(JSMSG_TOO_MANY_FUN_SPREADARGS, 0, JSEXN_RANGEERR, "too many function arguments") -MSG_DEF(JSMSG_UNINITIALIZED_LEXICAL, 1, JSEXN_REFERENCEERR, "can't access lexical declaration `{0}' before initialization") -MSG_DEF(JSMSG_BAD_CONST_ASSIGN, 1, JSEXN_TYPEERR, "invalid assignment to const `{0}'") -MSG_DEF(JSMSG_CANT_DECLARE_GLOBAL_BINDING, 2, JSEXN_TYPEERR, "cannot declare global binding `{0}': {1}") - -// Date -MSG_DEF(JSMSG_INVALID_DATE, 0, JSEXN_RANGEERR, "invalid date") -MSG_DEF(JSMSG_BAD_TOISOSTRING_PROP, 0, JSEXN_TYPEERR, "toISOString property is not callable") - -// String -MSG_DEF(JSMSG_BAD_URI, 0, JSEXN_URIERR, "malformed URI sequence") -MSG_DEF(JSMSG_INVALID_NORMALIZE_FORM, 0, JSEXN_RANGEERR, "form must be one of 'NFC', 'NFD', 'NFKC', or 'NFKD'") -MSG_DEF(JSMSG_NEGATIVE_REPETITION_COUNT, 0, JSEXN_RANGEERR, "repeat count must be non-negative") -MSG_DEF(JSMSG_NOT_A_CODEPOINT, 1, JSEXN_RANGEERR, "{0} is not a valid code point") -MSG_DEF(JSMSG_RESULTING_STRING_TOO_LARGE, 0, JSEXN_RANGEERR, "repeat count must be less than infinity and not overflow maximum string size") - -// Number -MSG_DEF(JSMSG_BAD_RADIX, 0, JSEXN_RANGEERR, "radix must be an integer at least 2 and no greater than 36") -MSG_DEF(JSMSG_PRECISION_RANGE, 1, JSEXN_RANGEERR, "precision {0} out of range") - -// Function -MSG_DEF(JSMSG_BAD_APPLY_ARGS, 1, JSEXN_TYPEERR, "second argument to Function.prototype.{0} must be an array") -MSG_DEF(JSMSG_BAD_FORMAL, 0, JSEXN_SYNTAXERR, "malformed formal parameter") -MSG_DEF(JSMSG_CALLER_IS_STRICT, 0, JSEXN_TYPEERR, "access to strict mode caller function is censored") -MSG_DEF(JSMSG_DEPRECATED_USAGE, 1, JSEXN_REFERENCEERR, "deprecated {0} usage") -MSG_DEF(JSMSG_NOT_SCRIPTED_FUNCTION, 1, JSEXN_TYPEERR, "{0} is not a scripted function") -MSG_DEF(JSMSG_NO_REST_NAME, 0, JSEXN_SYNTAXERR, "no parameter name after ...") -MSG_DEF(JSMSG_PARAMETER_AFTER_REST, 0, JSEXN_SYNTAXERR, "parameter after rest parameter") -MSG_DEF(JSMSG_TOO_MANY_ARGUMENTS, 0, JSEXN_RANGEERR, "too many arguments provided for a function call") - -// CSP -MSG_DEF(JSMSG_CSP_BLOCKED_EVAL, 0, JSEXN_ERR, "call to eval() blocked by CSP") -MSG_DEF(JSMSG_CSP_BLOCKED_FUNCTION, 0, JSEXN_ERR, "call to Function() blocked by CSP") - -// Wrappers -MSG_DEF(JSMSG_ACCESSOR_DEF_DENIED, 1, JSEXN_ERR, "Permission denied to define accessor property {0}") -MSG_DEF(JSMSG_DEAD_OBJECT, 0, JSEXN_TYPEERR, "can't access dead object") -MSG_DEF(JSMSG_UNWRAP_DENIED, 0, JSEXN_ERR, "permission denied to unwrap object") - -// JSAPI-only (Not thrown as JS exceptions) -MSG_DEF(JSMSG_BAD_CLONE_FUNOBJ_SCOPE, 0, JSEXN_TYPEERR, "bad cloned function scope chain") -MSG_DEF(JSMSG_CANT_CLONE_OBJECT, 0, JSEXN_TYPEERR, "can't clone object") -MSG_DEF(JSMSG_CANT_OPEN, 2, JSEXN_ERR, "can't open {0}: {1}") -MSG_DEF(JSMSG_USER_DEFINED_ERROR, 0, JSEXN_ERR, "JS_ReportError was called") - -// Internal errors -MSG_DEF(JSMSG_ALLOC_OVERFLOW, 0, JSEXN_INTERNALERR, "allocation size overflow") -MSG_DEF(JSMSG_BAD_BYTECODE, 1, JSEXN_INTERNALERR, "unimplemented JavaScript bytecode {0}") -MSG_DEF(JSMSG_BUFFER_TOO_SMALL, 0, JSEXN_INTERNALERR, "buffer too small") -MSG_DEF(JSMSG_BUILD_ID_NOT_AVAILABLE, 0, JSEXN_INTERNALERR, "build ID is not available") -MSG_DEF(JSMSG_BYTECODE_TOO_BIG, 2, JSEXN_INTERNALERR, "bytecode {0} too large (limit {1})") -MSG_DEF(JSMSG_ERR_DURING_THROW, 0, JSEXN_INTERNALERR, "an internal error occurred while throwing an exception") -MSG_DEF(JSMSG_NEED_DIET, 1, JSEXN_INTERNALERR, "{0} too large") -MSG_DEF(JSMSG_OUT_OF_MEMORY, 0, JSEXN_INTERNALERR, "out of memory") -MSG_DEF(JSMSG_OVER_RECURSED, 0, JSEXN_INTERNALERR, "too much recursion") -MSG_DEF(JSMSG_TOO_BIG_TO_ENCODE, 0, JSEXN_INTERNALERR, "data are to big to encode") -MSG_DEF(JSMSG_TOO_DEEP, 1, JSEXN_INTERNALERR, "{0} nested too deeply") -MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION, 1, JSEXN_INTERNALERR, "uncaught exception: {0}") -MSG_DEF(JSMSG_UNKNOWN_FORMAT, 1, JSEXN_INTERNALERR, "unknown bytecode format {0}") - -// Frontend -MSG_DEF(JSMSG_ACCESSOR_WRONG_ARGS, 3, JSEXN_SYNTAXERR, "{0} functions must have {1} argument{2}") -MSG_DEF(JSMSG_ARRAY_COMP_LEFTSIDE, 0, JSEXN_SYNTAXERR, "invalid array comprehension left-hand side") -MSG_DEF(JSMSG_ARRAY_INIT_TOO_BIG, 0, JSEXN_INTERNALERR, "array initializer too large") -MSG_DEF(JSMSG_AS_AFTER_IMPORT_STAR, 0, JSEXN_SYNTAXERR, "missing keyword 'as' after import *") -MSG_DEF(JSMSG_AS_AFTER_RESERVED_WORD, 1, JSEXN_SYNTAXERR, "missing keyword 'as' after reserved word '{0}'") -MSG_DEF(JSMSG_ASYNC_GENERATOR, 0, JSEXN_SYNTAXERR, "generator function or method can't be async") -MSG_DEF(JSMSG_AWAIT_IN_DEFAULT, 0, JSEXN_SYNTAXERR, "await can't be used in default expression") -MSG_DEF(JSMSG_BAD_ANON_GENERATOR_RETURN, 0, JSEXN_TYPEERR, "anonymous generator function returns a value") -MSG_DEF(JSMSG_BAD_ARROW_ARGS, 0, JSEXN_SYNTAXERR, "invalid arrow-function arguments (parentheses around the arrow-function may help)") -MSG_DEF(JSMSG_BAD_BINDING, 1, JSEXN_SYNTAXERR, "redefining {0} is deprecated") -MSG_DEF(JSMSG_BAD_CONST_DECL, 0, JSEXN_SYNTAXERR, "missing = in const declaration") -MSG_DEF(JSMSG_BAD_CONTINUE, 0, JSEXN_SYNTAXERR, "continue must be inside loop") -MSG_DEF(JSMSG_BAD_DESTRUCT_ASS, 0, JSEXN_REFERENCEERR, "invalid destructuring assignment operator") -MSG_DEF(JSMSG_BAD_DESTRUCT_TARGET, 0, JSEXN_SYNTAXERR, "invalid destructuring target") -MSG_DEF(JSMSG_BAD_DESTRUCT_PARENS, 0, JSEXN_SYNTAXERR, "destructuring patterns in assignments can't be parenthesized") -MSG_DEF(JSMSG_BAD_DESTRUCT_DECL, 0, JSEXN_SYNTAXERR, "missing = in destructuring declaration") -MSG_DEF(JSMSG_BAD_DUP_ARGS, 0, JSEXN_SYNTAXERR, "duplicate argument names not allowed in this context") -MSG_DEF(JSMSG_BAD_FOR_EACH_LOOP, 0, JSEXN_SYNTAXERR, "invalid for each loop") -MSG_DEF(JSMSG_BAD_FOR_LEFTSIDE, 0, JSEXN_SYNTAXERR, "invalid for-in/of left-hand side") -MSG_DEF(JSMSG_LEXICAL_DECL_DEFINES_LET,0, JSEXN_SYNTAXERR, "a lexical declaration can't define a 'let' binding") -MSG_DEF(JSMSG_LET_STARTING_FOROF_LHS, 0, JSEXN_SYNTAXERR, "an expression X in 'for (X of Y)' must not start with 'let'") -MSG_DEF(JSMSG_BAD_GENERATOR_RETURN, 1, JSEXN_TYPEERR, "generator function {0} returns a value") -MSG_DEF(JSMSG_BAD_GENEXP_BODY, 1, JSEXN_SYNTAXERR, "illegal use of {0} in generator expression") -MSG_DEF(JSMSG_BAD_INCOP_OPERAND, 0, JSEXN_REFERENCEERR, "invalid increment/decrement operand") -MSG_DEF(JSMSG_BAD_METHOD_DEF, 0, JSEXN_SYNTAXERR, "bad method definition") -MSG_DEF(JSMSG_BAD_OCTAL, 1, JSEXN_SYNTAXERR, "{0} is not a legal ECMA-262 octal constant") -MSG_DEF(JSMSG_BAD_OPERAND, 1, JSEXN_SYNTAXERR, "invalid {0} operand") -MSG_DEF(JSMSG_BAD_POW_LEFTSIDE, 0, JSEXN_SYNTAXERR, "unparenthesized unary expression can't appear on the left-hand side of '**'") -MSG_DEF(JSMSG_BAD_PROP_ID, 0, JSEXN_SYNTAXERR, "invalid property id") -MSG_DEF(JSMSG_BAD_RETURN_OR_YIELD, 1, JSEXN_SYNTAXERR, "{0} not in function") -MSG_DEF(JSMSG_BAD_STRICT_ASSIGN, 1, JSEXN_SYNTAXERR, "'{0}' can't be defined or assigned to in strict mode code") -MSG_DEF(JSMSG_BAD_SWITCH, 0, JSEXN_SYNTAXERR, "invalid switch statement") -MSG_DEF(JSMSG_BAD_SUPER, 0, JSEXN_SYNTAXERR, "invalid use of keyword 'super'") -MSG_DEF(JSMSG_BAD_SUPERPROP, 1, JSEXN_SYNTAXERR, "use of super {0} accesses only valid within methods or eval code within methods") -MSG_DEF(JSMSG_BAD_SUPERCALL, 0, JSEXN_SYNTAXERR, "super() is only valid in derived class constructors") -MSG_DEF(JSMSG_BRACKET_AFTER_ARRAY_COMPREHENSION, 0, JSEXN_SYNTAXERR, "missing ] after array comprehension") -MSG_DEF(JSMSG_BRACKET_AFTER_LIST, 0, JSEXN_SYNTAXERR, "missing ] after element list") -MSG_DEF(JSMSG_BRACKET_IN_INDEX, 0, JSEXN_SYNTAXERR, "missing ] in index expression") -MSG_DEF(JSMSG_CATCH_AFTER_GENERAL, 0, JSEXN_SYNTAXERR, "catch after unconditional catch") -MSG_DEF(JSMSG_CATCH_IDENTIFIER, 0, JSEXN_SYNTAXERR, "missing identifier in catch") -MSG_DEF(JSMSG_CATCH_OR_FINALLY, 0, JSEXN_SYNTAXERR, "missing catch or finally after try") -MSG_DEF(JSMSG_CATCH_WITHOUT_TRY, 0, JSEXN_SYNTAXERR, "catch without try") -MSG_DEF(JSMSG_COLON_AFTER_CASE, 0, JSEXN_SYNTAXERR, "missing : after case label") -MSG_DEF(JSMSG_COLON_AFTER_ID, 0, JSEXN_SYNTAXERR, "missing : after property id") -MSG_DEF(JSMSG_COLON_IN_COND, 0, JSEXN_SYNTAXERR, "missing : in conditional expression") -MSG_DEF(JSMSG_COMP_PROP_UNTERM_EXPR, 0, JSEXN_SYNTAXERR, "missing ] in computed property name") -MSG_DEF(JSMSG_CONTRARY_NONDIRECTIVE, 1, JSEXN_SYNTAXERR, "'{0}' statement won't be enforced as a directive because it isn't in directive prologue position") -MSG_DEF(JSMSG_CURLY_AFTER_BODY, 0, JSEXN_SYNTAXERR, "missing } after function body") -MSG_DEF(JSMSG_CURLY_AFTER_CATCH, 0, JSEXN_SYNTAXERR, "missing } after catch block") -MSG_DEF(JSMSG_CURLY_AFTER_FINALLY, 0, JSEXN_SYNTAXERR, "missing } after finally block") -MSG_DEF(JSMSG_CURLY_AFTER_LIST, 0, JSEXN_SYNTAXERR, "missing } after property list") -MSG_DEF(JSMSG_CURLY_AFTER_TRY, 0, JSEXN_SYNTAXERR, "missing } after try block") -MSG_DEF(JSMSG_CURLY_BEFORE_BODY, 0, JSEXN_SYNTAXERR, "missing { before function body") -MSG_DEF(JSMSG_CURLY_BEFORE_CATCH, 0, JSEXN_SYNTAXERR, "missing { before catch block") -MSG_DEF(JSMSG_CURLY_BEFORE_CLASS, 0, JSEXN_SYNTAXERR, "missing { before class body") -MSG_DEF(JSMSG_CURLY_BEFORE_FINALLY, 0, JSEXN_SYNTAXERR, "missing { before finally block") -MSG_DEF(JSMSG_CURLY_BEFORE_SWITCH, 0, JSEXN_SYNTAXERR, "missing { before switch body") -MSG_DEF(JSMSG_CURLY_BEFORE_TRY, 0, JSEXN_SYNTAXERR, "missing { before try block") -MSG_DEF(JSMSG_CURLY_IN_COMPOUND, 0, JSEXN_SYNTAXERR, "missing } in compound statement") -MSG_DEF(JSMSG_DECLARATION_AFTER_EXPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'export' keyword") -MSG_DEF(JSMSG_DECLARATION_AFTER_IMPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'import' keyword") -MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 0, JSEXN_SYNTAXERR, "applying the 'delete' operator to an unqualified name is deprecated") -MSG_DEF(JSMSG_DEPRECATED_EXPR_CLOSURE, 0, JSEXN_WARN, "expression closures are deprecated") -MSG_DEF(JSMSG_DEPRECATED_FOR_EACH, 0, JSEXN_WARN, "JavaScript 1.6's for-each-in loops are deprecated; consider using ES6 for-of instead") -MSG_DEF(JSMSG_DEPRECATED_OCTAL, 0, JSEXN_SYNTAXERR, "\"0\"-prefixed octal literals and octal escape sequences are deprecated; for octal literals use the \"0o\" prefix instead") -MSG_DEF(JSMSG_DEPRECATED_PRAGMA, 1, JSEXN_WARN, "Using //@ to indicate {0} pragmas is deprecated. Use //# instead") -MSG_DEF(JSMSG_DEPRECATED_BLOCK_SCOPE_FUN_REDECL, 1, JSEXN_WARN, "redeclaration of block-scoped function `{0}' is deprecated") -MSG_DEF(JSMSG_DUPLICATE_EXPORT_NAME, 1, JSEXN_SYNTAXERR, "duplicate export name '{0}'") -MSG_DEF(JSMSG_DUPLICATE_FORMAL, 1, JSEXN_SYNTAXERR, "duplicate formal argument {0}") -MSG_DEF(JSMSG_DUPLICATE_LABEL, 0, JSEXN_SYNTAXERR, "duplicate label") -MSG_DEF(JSMSG_DUPLICATE_PROPERTY, 1, JSEXN_SYNTAXERR, "property name {0} appears more than once in object literal") -MSG_DEF(JSMSG_DUPLICATE_PROTO_PROPERTY, 0, JSEXN_SYNTAXERR, "property name __proto__ appears more than once in object literal") -MSG_DEF(JSMSG_EMPTY_CONSEQUENT, 0, JSEXN_SYNTAXERR, "mistyped ; after conditional?") -MSG_DEF(JSMSG_EQUAL_AS_ASSIGN, 0, JSEXN_SYNTAXERR, "test for equality (==) mistyped as assignment (=)?") -MSG_DEF(JSMSG_EXPORT_DECL_AT_TOP_LEVEL,0, JSEXN_SYNTAXERR, "export declarations may only appear at top level of a module") -MSG_DEF(JSMSG_FINALLY_WITHOUT_TRY, 0, JSEXN_SYNTAXERR, "finally without try") -MSG_DEF(JSMSG_FORBIDDEN_AS_STATEMENT, 1, JSEXN_SYNTAXERR, "{0} can't appear in single-statement context") -MSG_DEF(JSMSG_FROM_AFTER_IMPORT_CLAUSE, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after import clause") -MSG_DEF(JSMSG_FROM_AFTER_EXPORT_STAR, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after export *") -MSG_DEF(JSMSG_GARBAGE_AFTER_INPUT, 2, JSEXN_SYNTAXERR, "unexpected garbage after {0}, starting with {1}") -MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER, 0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal") -MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 0, JSEXN_SYNTAXERR, "illegal character") -MSG_DEF(JSMSG_IMPORT_DECL_AT_TOP_LEVEL, 0, JSEXN_SYNTAXERR, "import declarations may only appear at top level of a module") -MSG_DEF(JSMSG_INVALID_FOR_IN_DECL_WITH_INIT,0,JSEXN_SYNTAXERR,"for-in loop head declarations may not have initializers") -MSG_DEF(JSMSG_LABEL_NOT_FOUND, 0, JSEXN_SYNTAXERR, "label not found") -MSG_DEF(JSMSG_LET_COMP_BINDING, 0, JSEXN_SYNTAXERR, "'let' is not a valid name for a comprehension variable") -MSG_DEF(JSMSG_LEXICAL_DECL_NOT_IN_BLOCK, 1, JSEXN_SYNTAXERR, "{0} declaration not directly within block") -MSG_DEF(JSMSG_LEXICAL_DECL_LABEL, 1, JSEXN_SYNTAXERR, "{0} declarations cannot be labelled") -MSG_DEF(JSMSG_GENERATOR_LABEL, 0, JSEXN_SYNTAXERR, "generator functions cannot be labelled") -MSG_DEF(JSMSG_FUNCTION_LABEL, 0, JSEXN_SYNTAXERR, "functions cannot be labelled") -MSG_DEF(JSMSG_SLOPPY_FUNCTION_LABEL, 0, JSEXN_SYNTAXERR, "functions can only be labelled inside blocks") -MSG_DEF(JSMSG_LINE_BREAK_AFTER_THROW, 0, JSEXN_SYNTAXERR, "no line break is allowed between 'throw' and its expression") -MSG_DEF(JSMSG_LINE_BREAK_BEFORE_ARROW, 0, JSEXN_SYNTAXERR, "no line break is allowed before '=>'") -MSG_DEF(JSMSG_MALFORMED_ESCAPE, 1, JSEXN_SYNTAXERR, "malformed {0} character escape sequence") -MSG_DEF(JSMSG_MISSING_BINARY_DIGITS, 0, JSEXN_SYNTAXERR, "missing binary digits after '0b'") -MSG_DEF(JSMSG_MISSING_EXPONENT, 0, JSEXN_SYNTAXERR, "missing exponent") -MSG_DEF(JSMSG_MISSING_EXPR_AFTER_THROW,0, JSEXN_SYNTAXERR, "throw statement is missing an expression") -MSG_DEF(JSMSG_MISSING_FORMAL, 0, JSEXN_SYNTAXERR, "missing formal parameter") -MSG_DEF(JSMSG_MISSING_HEXDIGITS, 0, JSEXN_SYNTAXERR, "missing hexadecimal digits after '0x'") -MSG_DEF(JSMSG_MISSING_OCTAL_DIGITS, 0, JSEXN_SYNTAXERR, "missing octal digits after '0o'") -MSG_DEF(JSMSG_MODULE_SPEC_AFTER_FROM, 0, JSEXN_SYNTAXERR, "missing module specifier after 'from' keyword") -MSG_DEF(JSMSG_NAME_AFTER_DOT, 0, JSEXN_SYNTAXERR, "missing name after . operator") -MSG_DEF(JSMSG_NAMED_IMPORTS_OR_NAMESPACE_IMPORT, 0, JSEXN_SYNTAXERR, "expected named imports or namespace import after comma") -MSG_DEF(JSMSG_NO_BINDING_NAME, 0, JSEXN_SYNTAXERR, "missing binding name") -MSG_DEF(JSMSG_NO_EXPORT_NAME, 0, JSEXN_SYNTAXERR, "missing export name") -MSG_DEF(JSMSG_NO_IMPORT_NAME, 0, JSEXN_SYNTAXERR, "missing import name") -MSG_DEF(JSMSG_NO_VARIABLE_NAME, 0, JSEXN_SYNTAXERR, "missing variable name") -MSG_DEF(JSMSG_OF_AFTER_FOR_NAME, 0, JSEXN_SYNTAXERR, "missing 'of' after for") -MSG_DEF(JSMSG_PAREN_AFTER_ARGS, 0, JSEXN_SYNTAXERR, "missing ) after argument list") -MSG_DEF(JSMSG_PAREN_AFTER_CATCH, 0, JSEXN_SYNTAXERR, "missing ) after catch") -MSG_DEF(JSMSG_PAREN_AFTER_COND, 0, JSEXN_SYNTAXERR, "missing ) after condition") -MSG_DEF(JSMSG_PAREN_AFTER_FOR, 0, JSEXN_SYNTAXERR, "missing ( after for") -MSG_DEF(JSMSG_PAREN_AFTER_FORMAL, 0, JSEXN_SYNTAXERR, "missing ) after formal parameters") -MSG_DEF(JSMSG_PAREN_AFTER_FOR_CTRL, 0, JSEXN_SYNTAXERR, "missing ) after for-loop control") -MSG_DEF(JSMSG_PAREN_AFTER_FOR_OF_ITERABLE, 0, JSEXN_SYNTAXERR, "missing ) after for-of iterable") -MSG_DEF(JSMSG_PAREN_AFTER_SWITCH, 0, JSEXN_SYNTAXERR, "missing ) after switch expression") -MSG_DEF(JSMSG_PAREN_AFTER_WITH, 0, JSEXN_SYNTAXERR, "missing ) after with-statement object") -MSG_DEF(JSMSG_PAREN_BEFORE_CATCH, 0, JSEXN_SYNTAXERR, "missing ( before catch") -MSG_DEF(JSMSG_PAREN_BEFORE_COND, 0, JSEXN_SYNTAXERR, "missing ( before condition") -MSG_DEF(JSMSG_PAREN_BEFORE_FORMAL, 0, JSEXN_SYNTAXERR, "missing ( before formal parameters") -MSG_DEF(JSMSG_PAREN_BEFORE_SWITCH, 0, JSEXN_SYNTAXERR, "missing ( before switch expression") -MSG_DEF(JSMSG_PAREN_BEFORE_WITH, 0, JSEXN_SYNTAXERR, "missing ( before with-statement object") -MSG_DEF(JSMSG_PAREN_IN_PAREN, 0, JSEXN_SYNTAXERR, "missing ) in parenthetical") -MSG_DEF(JSMSG_RC_AFTER_EXPORT_SPEC_LIST, 0, JSEXN_SYNTAXERR, "missing '}' after export specifier list") -MSG_DEF(JSMSG_RC_AFTER_IMPORT_SPEC_LIST, 0, JSEXN_SYNTAXERR, "missing '}' after module specifier list") -MSG_DEF(JSMSG_REDECLARED_CATCH_IDENTIFIER, 1, JSEXN_SYNTAXERR, "redeclaration of identifier '{0}' in catch") -MSG_DEF(JSMSG_RESERVED_ID, 1, JSEXN_SYNTAXERR, "{0} is a reserved identifier") -MSG_DEF(JSMSG_REST_WITH_COMMA, 0, JSEXN_SYNTAXERR, "rest element may not have a trailing comma") -MSG_DEF(JSMSG_REST_WITH_DEFAULT, 0, JSEXN_SYNTAXERR, "rest parameter may not have a default") -MSG_DEF(JSMSG_SELFHOSTED_TOP_LEVEL_LEXICAL, 1, JSEXN_SYNTAXERR, "self-hosted code cannot contain top-level {0} declarations") -MSG_DEF(JSMSG_SELFHOSTED_METHOD_CALL, 0, JSEXN_SYNTAXERR, "self-hosted code may not contain direct method calls. Use callFunction() or callContentFunction()") -MSG_DEF(JSMSG_SELFHOSTED_UNBOUND_NAME, 0, JSEXN_TYPEERR, "self-hosted code may not contain unbound name lookups") -MSG_DEF(JSMSG_SEMI_AFTER_FOR_COND, 0, JSEXN_SYNTAXERR, "missing ; after for-loop condition") -MSG_DEF(JSMSG_SEMI_AFTER_FOR_INIT, 0, JSEXN_SYNTAXERR, "missing ; after for-loop initializer") -MSG_DEF(JSMSG_SEMI_BEFORE_STMNT, 0, JSEXN_SYNTAXERR, "missing ; before statement") -MSG_DEF(JSMSG_SOURCE_TOO_LONG, 0, JSEXN_RANGEERR, "source is too long") -MSG_DEF(JSMSG_STMT_AFTER_RETURN, 0, JSEXN_WARN, "unreachable code after return statement") -MSG_DEF(JSMSG_STRICT_CODE_WITH, 0, JSEXN_SYNTAXERR, "strict mode code may not contain 'with' statements") -MSG_DEF(JSMSG_STRICT_NON_SIMPLE_PARAMS, 1, JSEXN_SYNTAXERR, "\"use strict\" not allowed in function with {0} parameter") -MSG_DEF(JSMSG_TEMPLSTR_UNTERM_EXPR, 0, JSEXN_SYNTAXERR, "missing } in template string") -MSG_DEF(JSMSG_SIMD_NOT_A_VECTOR, 2, JSEXN_TYPEERR, "expecting a SIMD {0} object as argument {1}") -MSG_DEF(JSMSG_TOO_MANY_CASES, 0, JSEXN_INTERNALERR, "too many switch cases") -MSG_DEF(JSMSG_TOO_MANY_CATCH_VARS, 0, JSEXN_SYNTAXERR, "too many catch variables") -MSG_DEF(JSMSG_TOO_MANY_CON_ARGS, 0, JSEXN_SYNTAXERR, "too many constructor arguments") -MSG_DEF(JSMSG_TOO_MANY_DEFAULTS, 0, JSEXN_SYNTAXERR, "more than one switch default") -MSG_DEF(JSMSG_TOO_MANY_FUN_ARGS, 0, JSEXN_SYNTAXERR, "too many function arguments") -MSG_DEF(JSMSG_TOO_MANY_LOCALS, 0, JSEXN_SYNTAXERR, "too many local variables") -MSG_DEF(JSMSG_TOO_MANY_YIELDS, 0, JSEXN_SYNTAXERR, "too many yield expressions") -MSG_DEF(JSMSG_TOUGH_BREAK, 0, JSEXN_SYNTAXERR, "unlabeled break must be inside loop or switch") -MSG_DEF(JSMSG_UNEXPECTED_TOKEN, 2, JSEXN_SYNTAXERR, "expected {0}, got {1}") -MSG_DEF(JSMSG_UNNAMED_CLASS_STMT, 0, JSEXN_SYNTAXERR, "class statement requires a name") -MSG_DEF(JSMSG_UNNAMED_FUNCTION_STMT, 0, JSEXN_SYNTAXERR, "function statement requires a name") -MSG_DEF(JSMSG_UNTERMINATED_COMMENT, 0, JSEXN_SYNTAXERR, "unterminated comment") -MSG_DEF(JSMSG_UNTERMINATED_REGEXP, 0, JSEXN_SYNTAXERR, "unterminated regular expression literal") -MSG_DEF(JSMSG_UNTERMINATED_STRING, 0, JSEXN_SYNTAXERR, "unterminated string literal") -MSG_DEF(JSMSG_USELESS_EXPR, 0, JSEXN_TYPEERR, "useless expression") -MSG_DEF(JSMSG_USE_ASM_DIRECTIVE_FAIL, 0, JSEXN_SYNTAXERR, "\"use asm\" is only meaningful in the Directive Prologue of a function body") -MSG_DEF(JSMSG_VAR_HIDES_ARG, 1, JSEXN_TYPEERR, "variable {0} redeclares argument") -MSG_DEF(JSMSG_WHILE_AFTER_DO, 0, JSEXN_SYNTAXERR, "missing while after do-loop body") -MSG_DEF(JSMSG_YIELD_IN_ARROW, 0, JSEXN_SYNTAXERR, "arrow function may not contain yield") -MSG_DEF(JSMSG_YIELD_IN_DEFAULT, 0, JSEXN_SYNTAXERR, "yield in default expression") -MSG_DEF(JSMSG_YIELD_IN_METHOD, 0, JSEXN_SYNTAXERR, "non-generator method definitions may not contain yield") -MSG_DEF(JSMSG_BAD_COLUMN_NUMBER, 0, JSEXN_RANGEERR, "column number out of range") -MSG_DEF(JSMSG_COMPUTED_NAME_IN_PATTERN,0, JSEXN_SYNTAXERR, "computed property names aren't supported in this destructuring declaration") -MSG_DEF(JSMSG_DEFAULT_IN_PATTERN, 0, JSEXN_SYNTAXERR, "destructuring defaults aren't supported in this destructuring declaration") -MSG_DEF(JSMSG_BAD_NEWTARGET, 0, JSEXN_SYNTAXERR, "new.target only allowed within functions") -MSG_DEF(JSMSG_ESCAPED_KEYWORD, 0, JSEXN_SYNTAXERR, "keywords must be written literally, without embedded escapes") - -// asm.js -MSG_DEF(JSMSG_USE_ASM_TYPE_FAIL, 1, JSEXN_TYPEERR, "asm.js type error: {0}") -MSG_DEF(JSMSG_USE_ASM_LINK_FAIL, 1, JSEXN_TYPEERR, "asm.js link error: {0}") -MSG_DEF(JSMSG_USE_ASM_TYPE_OK, 1, JSEXN_WARN, "Successfully compiled asm.js code ({0})") - -// wasm -MSG_DEF(JSMSG_WASM_COMPILE_ERROR, 1, JSEXN_WASMCOMPILEERROR, "{0}") -MSG_DEF(JSMSG_WASM_IND_CALL_TO_NULL, 0, JSEXN_WASMRUNTIMEERROR, "indirect call to null") -MSG_DEF(JSMSG_WASM_IND_CALL_BAD_SIG, 0, JSEXN_WASMRUNTIMEERROR, "indirect call signature mismatch") -MSG_DEF(JSMSG_WASM_UNREACHABLE, 0, JSEXN_WASMRUNTIMEERROR, "unreachable executed") -MSG_DEF(JSMSG_WASM_INTEGER_OVERFLOW, 0, JSEXN_WASMRUNTIMEERROR, "integer overflow") -MSG_DEF(JSMSG_WASM_INVALID_CONVERSION, 0, JSEXN_WASMRUNTIMEERROR, "invalid conversion to integer") -MSG_DEF(JSMSG_WASM_INT_DIVIDE_BY_ZERO, 0, JSEXN_WASMRUNTIMEERROR, "integer divide by zero") -MSG_DEF(JSMSG_WASM_OUT_OF_BOUNDS, 0, JSEXN_WASMRUNTIMEERROR, "index out of bounds") -MSG_DEF(JSMSG_WASM_UNALIGNED_ACCESS, 0, JSEXN_WASMRUNTIMEERROR, "unaligned memory access") -MSG_DEF(JSMSG_WASM_BAD_UINT32, 2, JSEXN_RANGEERR, "bad {0} {1}") -MSG_DEF(JSMSG_WASM_BAD_GROW, 1, JSEXN_RANGEERR, "failed to grow {0}") -MSG_DEF(JSMSG_WASM_BAD_FIT, 2, JSEXN_RANGEERR, "{0} segment does not fit in {1}") -MSG_DEF(JSMSG_WASM_BAD_BUF_ARG, 0, JSEXN_TYPEERR, "first argument must be an ArrayBuffer or typed array object") -MSG_DEF(JSMSG_WASM_BAD_MOD_ARG, 0, JSEXN_TYPEERR, "first argument must be a WebAssembly.Module") -MSG_DEF(JSMSG_WASM_BAD_BUF_MOD_ARG, 0, JSEXN_TYPEERR, "first argument must be a WebAssembly.Module, ArrayBuffer or typed array object") -MSG_DEF(JSMSG_WASM_BAD_DESC_ARG, 1, JSEXN_TYPEERR, "first argument must be a {0} descriptor") -MSG_DEF(JSMSG_WASM_BAD_IMP_SIZE, 1, JSEXN_TYPEERR, "imported {0} with incompatible size") -MSG_DEF(JSMSG_WASM_BAD_IMP_MAX, 1, JSEXN_TYPEERR, "imported {0} with incompatible maximum size") -MSG_DEF(JSMSG_WASM_BAD_ELEMENT, 0, JSEXN_TYPEERR, "\"element\" property of table descriptor must be \"anyfunc\"") -MSG_DEF(JSMSG_WASM_BAD_IMPORT_ARG, 0, JSEXN_TYPEERR, "second argument must be an object") -MSG_DEF(JSMSG_WASM_BAD_IMPORT_FIELD, 2, JSEXN_TYPEERR, "import object field '{0}' is not {1}") -MSG_DEF(JSMSG_WASM_BAD_IMPORT_SIG, 0, JSEXN_TYPEERR, "imported function signature mismatch") -MSG_DEF(JSMSG_WASM_BAD_TABLE_VALUE, 0, JSEXN_TYPEERR, "can only assign WebAssembly exported functions to Table") -MSG_DEF(JSMSG_WASM_BAD_I64, 0, JSEXN_TYPEERR, "cannot pass i64 to or from JS") -MSG_DEF(JSMSG_WASM_NO_TRANSFER, 0, JSEXN_TYPEERR, "cannot transfer WebAssembly/asm.js ArrayBuffer") -MSG_DEF(JSMSG_WASM_TEXT_FAIL, 1, JSEXN_SYNTAXERR, "wasm text error: {0}") - -// Proxy -MSG_DEF(JSMSG_BAD_TRAP_RETURN_VALUE, 2, JSEXN_TYPEERR,"trap {1} for {0} returned a primitive value") -MSG_DEF(JSMSG_BAD_GETPROTOTYPEOF_TRAP_RETURN,0,JSEXN_TYPEERR,"proxy getPrototypeOf handler returned a non-object, non-null value") -MSG_DEF(JSMSG_INCONSISTENT_GETPROTOTYPEOF_TRAP,0,JSEXN_TYPEERR,"proxy getPrototypeOf handler didn't return the target object's prototype") -MSG_DEF(JSMSG_PROXY_SETPROTOTYPEOF_RETURNED_FALSE, 0, JSEXN_TYPEERR, "proxy setPrototypeOf handler returned false") -MSG_DEF(JSMSG_PROXY_ISEXTENSIBLE_RETURNED_FALSE,0,JSEXN_TYPEERR,"proxy isExtensible handler must return the same extensibility as target") -MSG_DEF(JSMSG_INCONSISTENT_SETPROTOTYPEOF_TRAP,0,JSEXN_TYPEERR,"proxy setPrototypeOf handler returned true, even though the target's prototype is immutable because the target is non-extensible") -MSG_DEF(JSMSG_CANT_CHANGE_EXTENSIBILITY, 0, JSEXN_TYPEERR, "can't change object's extensibility") -MSG_DEF(JSMSG_CANT_DEFINE_INVALID, 0, JSEXN_TYPEERR, "proxy can't define an incompatible property descriptor") -MSG_DEF(JSMSG_CANT_DEFINE_NEW, 0, JSEXN_TYPEERR, "proxy can't define a new property on a non-extensible object") -MSG_DEF(JSMSG_CANT_DEFINE_NE_AS_NC, 0, JSEXN_TYPEERR, "proxy can't define a non-existent property as non-configurable") -MSG_DEF(JSMSG_PROXY_DEFINE_RETURNED_FALSE, 1, JSEXN_TYPEERR, "proxy defineProperty handler returned false for property '{0}'") -MSG_DEF(JSMSG_PROXY_DELETE_RETURNED_FALSE, 1, JSEXN_TYPEERR, "can't delete property '{0}': proxy deleteProperty handler returned false") -MSG_DEF(JSMSG_PROXY_PREVENTEXTENSIONS_RETURNED_FALSE, 0, JSEXN_TYPEERR, "proxy preventExtensions handler returned false") -MSG_DEF(JSMSG_PROXY_SET_RETURNED_FALSE, 1, JSEXN_TYPEERR, "proxy set handler returned false for property '{0}'") -MSG_DEF(JSMSG_CANT_REPORT_AS_NON_EXTENSIBLE, 0, JSEXN_TYPEERR, "proxy can't report an extensible object as non-extensible") -MSG_DEF(JSMSG_CANT_REPORT_C_AS_NC, 0, JSEXN_TYPEERR, "proxy can't report existing configurable property as non-configurable") -MSG_DEF(JSMSG_CANT_REPORT_E_AS_NE, 0, JSEXN_TYPEERR, "proxy can't report an existing own property as non-existent on a non-extensible object") -MSG_DEF(JSMSG_CANT_REPORT_INVALID, 0, JSEXN_TYPEERR, "proxy can't report an incompatible property descriptor") -MSG_DEF(JSMSG_CANT_REPORT_NC_AS_NE, 0, JSEXN_TYPEERR, "proxy can't report a non-configurable own property as non-existent") -MSG_DEF(JSMSG_CANT_REPORT_NEW, 0, JSEXN_TYPEERR, "proxy can't report a new property on a non-extensible object") -MSG_DEF(JSMSG_CANT_REPORT_NE_AS_NC, 0, JSEXN_TYPEERR, "proxy can't report a non-existent property as non-configurable") -MSG_DEF(JSMSG_CANT_SET_NW_NC, 0, JSEXN_TYPEERR, "proxy can't successfully set a non-writable, non-configurable property") -MSG_DEF(JSMSG_CANT_SET_WO_SETTER, 0, JSEXN_TYPEERR, "proxy can't succesfully set an accessor property without a setter") -MSG_DEF(JSMSG_CANT_SKIP_NC, 0, JSEXN_TYPEERR, "proxy can't skip a non-configurable property") -MSG_DEF(JSMSG_ONWKEYS_STR_SYM, 0, JSEXN_TYPEERR, "proxy [[OwnPropertyKeys]] must return an array with only string and symbol elements") -MSG_DEF(JSMSG_MUST_REPORT_SAME_VALUE, 0, JSEXN_TYPEERR, "proxy must report the same value for a non-writable, non-configurable property") -MSG_DEF(JSMSG_MUST_REPORT_UNDEFINED, 0, JSEXN_TYPEERR, "proxy must report undefined for a non-configurable accessor property without a getter") -MSG_DEF(JSMSG_OBJECT_ACCESS_DENIED, 0, JSEXN_ERR, "Permission denied to access object") -MSG_DEF(JSMSG_PROPERTY_ACCESS_DENIED, 1, JSEXN_ERR, "Permission denied to access property {0}") -MSG_DEF(JSMSG_PROXY_CONSTRUCT_OBJECT, 0, JSEXN_TYPEERR, "proxy [[Construct]] must return an object") -MSG_DEF(JSMSG_PROXY_EXTENSIBILITY, 0, JSEXN_TYPEERR, "proxy must report same extensiblitity as target") -MSG_DEF(JSMSG_PROXY_GETOWN_OBJORUNDEF, 0, JSEXN_TYPEERR, "proxy [[GetOwnProperty]] must return an object or undefined") -MSG_DEF(JSMSG_PROXY_REVOKED, 0, JSEXN_TYPEERR, "illegal operation attempted on a revoked proxy") -MSG_DEF(JSMSG_PROXY_ARG_REVOKED, 1, JSEXN_TYPEERR, "argument {0} cannot be a revoked proxy") -MSG_DEF(JSMSG_BAD_TRAP, 1, JSEXN_TYPEERR, "proxy handler's {0} trap wasn't undefined, null, or callable") - -// Structured cloning -MSG_DEF(JSMSG_SC_BAD_CLONE_VERSION, 0, JSEXN_ERR, "unsupported structured clone version") -MSG_DEF(JSMSG_SC_BAD_SERIALIZED_DATA, 1, JSEXN_INTERNALERR, "bad serialized structured data ({0})") -MSG_DEF(JSMSG_SC_DUP_TRANSFERABLE, 0, JSEXN_TYPEERR, "duplicate transferable for structured clone") -MSG_DEF(JSMSG_SC_NOT_TRANSFERABLE, 0, JSEXN_TYPEERR, "invalid transferable array for structured clone") -MSG_DEF(JSMSG_SC_UNSUPPORTED_TYPE, 0, JSEXN_TYPEERR, "unsupported type for structured data") -MSG_DEF(JSMSG_SC_NOT_CLONABLE, 1, JSEXN_TYPEERR, "{0} cannot be cloned in this context") -MSG_DEF(JSMSG_SC_SAB_TRANSFER, 0, JSEXN_WARN, "SharedArrayBuffer must not be in the transfer list") -MSG_DEF(JSMSG_SC_SAB_DISABLED, 0, JSEXN_TYPEERR, "SharedArrayBuffer not cloned - shared memory disabled in receiver") - -// Debugger -MSG_DEF(JSMSG_ASSIGN_FUNCTION_OR_NULL, 1, JSEXN_TYPEERR, "value assigned to {0} must be a function or null") -MSG_DEF(JSMSG_DEBUG_BAD_AWAIT, 0, JSEXN_TYPEERR, "await expression received invalid value") -MSG_DEF(JSMSG_DEBUG_BAD_LINE, 0, JSEXN_TYPEERR, "invalid line number") -MSG_DEF(JSMSG_DEBUG_BAD_OFFSET, 0, JSEXN_TYPEERR, "invalid script offset") -MSG_DEF(JSMSG_DEBUG_BAD_REFERENT, 2, JSEXN_TYPEERR, "{0} does not refer to {1}") -MSG_DEF(JSMSG_DEBUG_BAD_RESUMPTION, 0, JSEXN_TYPEERR, "debugger resumption value must be undefined, {throw: val}, {return: val}, or null") -MSG_DEF(JSMSG_DEBUG_BAD_YIELD, 0, JSEXN_TYPEERR, "generator yielded invalid value") -MSG_DEF(JSMSG_DEBUG_CANT_DEBUG_GLOBAL, 0, JSEXN_TYPEERR, "passing non-debuggable global to addDebuggee") -MSG_DEF(JSMSG_DEBUG_CCW_REQUIRED, 1, JSEXN_TYPEERR, "{0}: argument must be an object from a different compartment") -MSG_DEF(JSMSG_DEBUG_COMPARTMENT_MISMATCH, 2, JSEXN_TYPEERR, "{0}: descriptor .{1} property is an object in a different compartment than the target object") -MSG_DEF(JSMSG_DEBUG_LOOP, 0, JSEXN_TYPEERR, "cannot debug an object in same compartment as debugger or a compartment that is already debugging the debugger") -MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGEE, 2, JSEXN_ERR, "{0} is not a debuggee {1}") -MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGING, 0, JSEXN_ERR, "can't set breakpoint: script global is not a debuggee") -MSG_DEF(JSMSG_DEBUG_NOT_IDLE, 0, JSEXN_ERR, "can't start debugging: a debuggee script is on the stack") -MSG_DEF(JSMSG_DEBUG_NOT_LIVE, 1, JSEXN_ERR, "{0} is not live") -MSG_DEF(JSMSG_DEBUG_NO_ENV_OBJECT, 0, JSEXN_TYPEERR, "declarative Environments don't have binding objects") -MSG_DEF(JSMSG_DEBUG_PROTO, 2, JSEXN_TYPEERR, "{0}.prototype is not a valid {1} instance") -MSG_DEF(JSMSG_DEBUG_WRONG_OWNER, 1, JSEXN_TYPEERR, "{0} belongs to a different Debugger") -MSG_DEF(JSMSG_DEBUG_OPTIMIZED_OUT, 1, JSEXN_ERR, "variable `{0}' has been optimized out") -MSG_DEF(JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED, 0, JSEXN_TYPEERR, "resumption values are disallowed in this hook") -MSG_DEF(JSMSG_DEBUG_VARIABLE_NOT_FOUND,0, JSEXN_TYPEERR, "variable not found in environment") -MSG_DEF(JSMSG_DEBUG_WRAPPER_IN_WAY, 3, JSEXN_TYPEERR, "{0} is {1}{2}a global object, but a direct reference is required") -MSG_DEF(JSMSG_DEBUGGEE_WOULD_RUN, 2, JSEXN_DEBUGGEEWOULDRUN, "debuggee `{0}:{1}' would run") -MSG_DEF(JSMSG_NOT_CALLABLE_OR_UNDEFINED, 0, JSEXN_TYPEERR, "value is not a function or undefined") -MSG_DEF(JSMSG_NOT_TRACKING_ALLOCATIONS, 1, JSEXN_ERR, "Cannot call {0} without setting trackingAllocationSites to true") -MSG_DEF(JSMSG_OBJECT_METADATA_CALLBACK_ALREADY_SET, 0, JSEXN_ERR, "Cannot track object allocation, because other tools are already doing so") -MSG_DEF(JSMSG_QUERY_INNERMOST_WITHOUT_LINE_URL, 0, JSEXN_TYPEERR, "findScripts query object with 'innermost' property must have 'line' and either 'displayURL', 'url', or 'source'") -MSG_DEF(JSMSG_QUERY_LINE_WITHOUT_URL, 0, JSEXN_TYPEERR, "findScripts query object has 'line' property, but no 'displayURL', 'url', or 'source' property") -MSG_DEF(JSMSG_DEBUG_CANT_SET_OPT_ENV, 1, JSEXN_REFERENCEERR, "can't set `{0}' in an optimized-out environment") -MSG_DEF(JSMSG_DEBUG_INVISIBLE_COMPARTMENT, 0, JSEXN_TYPEERR, "object in compartment marked as invisible to Debugger") -MSG_DEF(JSMSG_DEBUG_CENSUS_BREAKDOWN, 1, JSEXN_TYPEERR, "unrecognized 'by' value in takeCensus breakdown: {0}") -MSG_DEF(JSMSG_DEBUG_PROMISE_NOT_RESOLVED, 0, JSEXN_TYPEERR, "Promise hasn't been resolved") -MSG_DEF(JSMSG_DEBUG_PROMISE_NOT_FULFILLED, 0, JSEXN_TYPEERR, "Promise hasn't been fulfilled") -MSG_DEF(JSMSG_DEBUG_PROMISE_NOT_REJECTED, 0, JSEXN_TYPEERR, "Promise hasn't been rejected") - -// Tracelogger -MSG_DEF(JSMSG_TRACELOGGER_ENABLE_FAIL, 1, JSEXN_ERR, "enabling tracelogger failed: {0}") - -// Intl -MSG_DEF(JSMSG_DATE_NOT_FINITE, 0, JSEXN_RANGEERR, "date value is not finite in DateTimeFormat.format()") -MSG_DEF(JSMSG_INTERNAL_INTL_ERROR, 0, JSEXN_ERR, "internal error while computing Intl data") -MSG_DEF(JSMSG_INTL_OBJECT_NOT_INITED, 3, JSEXN_TYPEERR, "Intl.{0}.prototype.{1} called on value that's not an object initialized as a {2}") -MSG_DEF(JSMSG_INTL_OBJECT_REINITED, 0, JSEXN_TYPEERR, "can't initialize object twice as an object of an Intl constructor") -MSG_DEF(JSMSG_INVALID_CURRENCY_CODE, 1, JSEXN_RANGEERR, "invalid currency code in NumberFormat(): {0}") -MSG_DEF(JSMSG_INVALID_DIGITS_VALUE, 1, JSEXN_RANGEERR, "invalid digits value: {0}") -MSG_DEF(JSMSG_INVALID_LANGUAGE_TAG, 1, JSEXN_RANGEERR, "invalid language tag: {0}") -MSG_DEF(JSMSG_INVALID_LOCALES_ELEMENT, 0, JSEXN_TYPEERR, "invalid element in locales argument") -MSG_DEF(JSMSG_INVALID_LOCALE_MATCHER, 1, JSEXN_RANGEERR, "invalid locale matcher in supportedLocalesOf(): {0}") -MSG_DEF(JSMSG_INVALID_OPTION_VALUE, 2, JSEXN_RANGEERR, "invalid value {1} for option {0}") -MSG_DEF(JSMSG_INVALID_TIME_ZONE, 1, JSEXN_RANGEERR, "invalid time zone in DateTimeFormat(): {0}") -MSG_DEF(JSMSG_UNDEFINED_CURRENCY, 0, JSEXN_TYPEERR, "undefined currency in NumberFormat() with currency style") - -// RegExp -MSG_DEF(JSMSG_BACK_REF_OUT_OF_RANGE, 0, JSEXN_SYNTAXERR, "back reference out of range in regular expression") -MSG_DEF(JSMSG_BAD_CLASS_RANGE, 0, JSEXN_SYNTAXERR, "invalid range in character class") -MSG_DEF(JSMSG_ESCAPE_AT_END_OF_REGEXP, 0, JSEXN_SYNTAXERR, "\\ at end of pattern") -MSG_DEF(JSMSG_EXEC_NOT_OBJORNULL, 0, JSEXN_TYPEERR, "RegExp exec method should return object or null") -MSG_DEF(JSMSG_INVALID_DECIMAL_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid decimal escape in regular expression") -MSG_DEF(JSMSG_INVALID_GROUP, 0, JSEXN_SYNTAXERR, "invalid regexp group") -MSG_DEF(JSMSG_INVALID_IDENTITY_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid identity escape in regular expression") -MSG_DEF(JSMSG_INVALID_UNICODE_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid unicode escape in regular expression") -MSG_DEF(JSMSG_MISSING_PAREN, 0, JSEXN_SYNTAXERR, "unterminated parenthetical") -MSG_DEF(JSMSG_NEWREGEXP_FLAGGED, 0, JSEXN_TYPEERR, "can't supply flags when constructing one RegExp from another") -MSG_DEF(JSMSG_NOTHING_TO_REPEAT, 0, JSEXN_SYNTAXERR, "nothing to repeat") -MSG_DEF(JSMSG_NUMBERS_OUT_OF_ORDER, 0, JSEXN_SYNTAXERR, "numbers out of order in {} quantifier.") -MSG_DEF(JSMSG_RANGE_WITH_CLASS_ESCAPE, 0, JSEXN_SYNTAXERR, "character class escape cannot be used in class range in regular expression") -MSG_DEF(JSMSG_RAW_BRACE_IN_REGEP, 0, JSEXN_SYNTAXERR, "raw brace is not allowed in regular expression with unicode flag") -MSG_DEF(JSMSG_RAW_BRACKET_IN_REGEP, 0, JSEXN_SYNTAXERR, "raw bracket is not allowed in regular expression with unicode flag") -MSG_DEF(JSMSG_TOO_MANY_PARENS, 0, JSEXN_INTERNALERR, "too many parentheses in regular expression") -MSG_DEF(JSMSG_UNICODE_OVERFLOW, 0, JSEXN_SYNTAXERR, "unicode codepoint should not be greater than 0x10FFFF in regular expression") -MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN, 0, JSEXN_SYNTAXERR, "unmatched ) in regular expression") -MSG_DEF(JSMSG_UNTERM_CLASS, 0, JSEXN_SYNTAXERR, "unterminated character class") - -// Self-hosting -MSG_DEF(JSMSG_DEFAULT_LOCALE_ERROR, 0, JSEXN_ERR, "internal error getting the default locale") -MSG_DEF(JSMSG_NO_SUCH_SELF_HOSTED_PROP,1, JSEXN_ERR, "No such property on self-hosted object: {0}") - -// Typed object / SIMD -MSG_DEF(JSMSG_INVALID_PROTOTYPE, 0, JSEXN_TYPEERR, "prototype field is not an object") -MSG_DEF(JSMSG_TYPEDOBJECT_BAD_ARGS, 0, JSEXN_TYPEERR, "invalid arguments") -MSG_DEF(JSMSG_TYPEDOBJECT_BINARYARRAY_BAD_INDEX, 0, JSEXN_RANGEERR, "invalid or out-of-range index") -MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED, 0, JSEXN_TYPEERR, "handle unattached") -MSG_DEF(JSMSG_TYPEDOBJECT_STRUCTTYPE_BAD_ARGS, 0, JSEXN_RANGEERR, "invalid field descriptor") -MSG_DEF(JSMSG_TYPEDOBJECT_TOO_BIG, 0, JSEXN_ERR, "Type is too large to allocate") -MSG_DEF(JSMSG_SIMD_FAILED_CONVERSION, 0, JSEXN_RANGEERR, "SIMD conversion loses precision") -MSG_DEF(JSMSG_SIMD_TO_NUMBER, 0, JSEXN_TYPEERR, "can't convert SIMD value to number") - -// Array -MSG_DEF(JSMSG_TOO_LONG_ARRAY, 0, JSEXN_TYPEERR, "Too long array") - -// Typed array -MSG_DEF(JSMSG_BAD_INDEX, 0, JSEXN_RANGEERR, "invalid or out-of-range index") -MSG_DEF(JSMSG_NON_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected ArrayBuffer, but species constructor returned non-ArrayBuffer") -MSG_DEF(JSMSG_SAME_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected different ArrayBuffer, but species constructor returned same ArrayBuffer") -MSG_DEF(JSMSG_SHORT_ARRAY_BUFFER_RETURNED, 2, JSEXN_TYPEERR, "expected ArrayBuffer with at least {0} bytes, but species constructor returns ArrayBuffer with {1} bytes") -MSG_DEF(JSMSG_TYPED_ARRAY_BAD_ARGS, 0, JSEXN_TYPEERR, "invalid arguments") -MSG_DEF(JSMSG_TYPED_ARRAY_NEGATIVE_ARG,1, JSEXN_RANGEERR, "argument {0} must be >= 0") -MSG_DEF(JSMSG_TYPED_ARRAY_DETACHED, 0, JSEXN_TYPEERR, "attempting to access detached ArrayBuffer") -MSG_DEF(JSMSG_TYPED_ARRAY_CONSTRUCT_BOUNDS, 0, JSEXN_RANGEERR, "attempting to construct out-of-bounds TypedArray on ArrayBuffer") -MSG_DEF(JSMSG_TYPED_ARRAY_CALL_OR_CONSTRUCT, 1, JSEXN_TYPEERR, "cannot directly {0} builtin %TypedArray%") -MSG_DEF(JSMSG_NON_TYPED_ARRAY_RETURNED, 0, JSEXN_TYPEERR, "constructor didn't return TypedArray object") -MSG_DEF(JSMSG_SHORT_TYPED_ARRAY_RETURNED, 2, JSEXN_TYPEERR, "expected TypedArray of at least length {0}, but constructor returned TypedArray of length {1}") - -// Shared array buffer -MSG_DEF(JSMSG_SHARED_ARRAY_BAD_LENGTH, 0, JSEXN_RANGEERR, "length argument out of range") -MSG_DEF(JSMSG_NON_SHARED_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected SharedArrayBuffer, but species constructor returned non-SharedArrayBuffer") -MSG_DEF(JSMSG_SAME_SHARED_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected different SharedArrayBuffer, but species constructor returned same SharedArrayBuffer") -MSG_DEF(JSMSG_SHORT_SHARED_ARRAY_BUFFER_RETURNED, 2, JSEXN_TYPEERR, "expected SharedArrayBuffer with at least {0} bytes, but species constructor returns SharedArrayBuffer with {1} bytes") - -// Reflect -MSG_DEF(JSMSG_BAD_PARSE_NODE, 0, JSEXN_INTERNALERR, "bad parse node") - -// Symbol -MSG_DEF(JSMSG_SYMBOL_TO_STRING, 0, JSEXN_TYPEERR, "can't convert symbol to string") -MSG_DEF(JSMSG_SYMBOL_TO_NUMBER, 0, JSEXN_TYPEERR, "can't convert symbol to number") - -// Atomics and futexes -MSG_DEF(JSMSG_ATOMICS_BAD_ARRAY, 0, JSEXN_TYPEERR, "invalid array type for the operation") -MSG_DEF(JSMSG_ATOMICS_TOO_LONG, 0, JSEXN_RANGEERR, "timeout value too large") -MSG_DEF(JSMSG_ATOMICS_WAIT_NOT_ALLOWED, 0, JSEXN_ERR, "waiting is not allowed on this thread") - -// XPConnect wrappers and DOM bindings -MSG_DEF(JSMSG_CANT_SET_INTERPOSED, 1, JSEXN_TYPEERR, "unable to set interposed data property '{0}'") -MSG_DEF(JSMSG_CANT_DEFINE_WINDOW_ELEMENT, 0, JSEXN_TYPEERR, "can't define elements on a Window object") -MSG_DEF(JSMSG_CANT_DELETE_WINDOW_ELEMENT, 0, JSEXN_TYPEERR, "can't delete elements from a Window object") -MSG_DEF(JSMSG_CANT_DELETE_WINDOW_NAMED_PROPERTY, 1, JSEXN_TYPEERR, "can't delete property {0} from window's named properties object") -MSG_DEF(JSMSG_CANT_PREVENT_EXTENSIONS, 0, JSEXN_TYPEERR, "can't prevent extensions on this proxy object") -MSG_DEF(JSMSG_NO_NAMED_SETTER, 2, JSEXN_TYPEERR, "{0} doesn't have a named property setter for '{1}'") -MSG_DEF(JSMSG_NO_INDEXED_SETTER, 2, JSEXN_TYPEERR, "{0} doesn't have an indexed property setter for '{1}'") - -// Super -MSG_DEF(JSMSG_CANT_DELETE_SUPER, 0, JSEXN_REFERENCEERR, "invalid delete involving 'super'") -MSG_DEF(JSMSG_REINIT_THIS, 0, JSEXN_REFERENCEERR, "super() called twice in derived class constructor") - -// Modules -MSG_DEF(JSMSG_BAD_DEFAULT_EXPORT, 0, JSEXN_SYNTAXERR, "default export cannot be provided by export *") -MSG_DEF(JSMSG_MISSING_INDIRECT_EXPORT, 1, JSEXN_SYNTAXERR, "indirect export '{0}' not found") -MSG_DEF(JSMSG_AMBIGUOUS_INDIRECT_EXPORT, 1, JSEXN_SYNTAXERR, "ambiguous indirect export '{0}'") -MSG_DEF(JSMSG_MISSING_IMPORT, 1, JSEXN_SYNTAXERR, "import '{0}' not found") -MSG_DEF(JSMSG_AMBIGUOUS_IMPORT, 1, JSEXN_SYNTAXERR, "ambiguous import '{0}'") -MSG_DEF(JSMSG_MISSING_NAMESPACE_EXPORT, 0, JSEXN_SYNTAXERR, "export not found for namespace") -MSG_DEF(JSMSG_MISSING_EXPORT, 1, JSEXN_SYNTAXERR, "local binding for export '{0}' not found") -MSG_DEF(JSMSG_MODULE_INSTANTIATE_FAILED, 0, JSEXN_INTERNALERR, "attempt to re-instantiate module after failure") -MSG_DEF(JSMSG_BAD_MODULE_STATE, 0, JSEXN_INTERNALERR, "module record in unexpected state") - -// Promise -MSG_DEF(JSMSG_CANNOT_RESOLVE_PROMISE_WITH_ITSELF, 0, JSEXN_TYPEERR, "A promise cannot be resolved with itself.") -MSG_DEF(JSMSG_PROMISE_CAPABILITY_HAS_SOMETHING_ALREADY, 0, JSEXN_TYPEERR, "GetCapabilitiesExecutor function already invoked with non-undefined values.") -MSG_DEF(JSMSG_PROMISE_RESOLVE_FUNCTION_NOT_CALLABLE, 0, JSEXN_TYPEERR, "A Promise subclass passed a non-callable value as the resolve function.") -MSG_DEF(JSMSG_PROMISE_REJECT_FUNCTION_NOT_CALLABLE, 0, JSEXN_TYPEERR, "A Promise subclass passed a non-callable value as the reject function.") -MSG_DEF(JSMSG_PROMISE_ERROR_IN_WRAPPED_REJECTION_REASON,0, JSEXN_INTERNALERR, "Promise rejection value is a non-unwrappable cross-compartment wrapper.") diff --git a/android/x86/include/spidermonkey/js/CallArgs.h b/android/x86/include/spidermonkey/js/CallArgs.h deleted file mode 100644 index 1e0d909a..00000000 --- a/android/x86/include/spidermonkey/js/CallArgs.h +++ /dev/null @@ -1,369 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* - * Helper classes encapsulating access to the callee, |this| value, arguments, - * and argument count for a call/construct operation. - * - * JS::CallArgs encapsulates access to a JSNative's un-abstracted - * |unsigned argc, Value* vp| arguments. The principal way to create a - * JS::CallArgs is using JS::CallArgsFromVp: - * - * // If provided no arguments or a non-numeric first argument, return zero. - * // Otherwise return |this| exactly as given, without boxing. - * static bool - * Func(JSContext* cx, unsigned argc, JS::Value* vp) - * { - * JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - * - * // Guard against no arguments or a non-numeric arg0. - * if (args.length() == 0 || !args[0].isNumber()) { - * args.rval().setInt32(0); - * return true; - * } - * - * // Access to the callee must occur before accessing/setting - * // the return value. - * JSObject& callee = args.callee(); - * args.rval().setObject(callee); - * - * // callee() and calleev() will now assert. - * - * // It's always fine to access thisv(). - * HandleValue thisv = args.thisv(); - * args.rval().set(thisv); - * - * // As the return value was last set to |this|, returns |this|. - * return true; - * } - * - * CallArgs is exposed publicly and used internally. Not all parts of its - * public interface are meant to be used by embedders! See inline comments to - * for details. - * - * It's possible (albeit deprecated) to manually index into |vp| to access the - * callee, |this|, and arguments of a function, and to set its return value. - * It's also possible to use the supported API of JS_CALLEE, JS_THIS, JS_ARGV, - * JS_RVAL, and JS_SET_RVAL to the same ends. - * - * But neither API has the error-handling or moving-GC correctness of CallArgs. - * New code should use CallArgs instead whenever possible. - * - * The eventual plan is to change JSNative to take |const CallArgs&| directly, - * for automatic assertion of correct use and to make calling functions more - * efficient. Embedders should start internally switching away from using - * |argc| and |vp| directly, except to create a |CallArgs|. Then, when an - * eventual release making that change occurs, porting efforts will require - * changing methods' signatures but won't require invasive changes to the - * methods' implementations, potentially under time pressure. - */ - -#ifndef js_CallArgs_h -#define js_CallArgs_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/TypeTraits.h" - -#include "jstypes.h" - -#include "js/RootingAPI.h" -#include "js/Value.h" - -/* Typedef for native functions called by the JS VM. */ -typedef bool -(* JSNative)(JSContext* cx, unsigned argc, JS::Value* vp); - -namespace JS { - -extern JS_PUBLIC_DATA(const HandleValue) UndefinedHandleValue; - -namespace detail { - -/* - * Compute |this| for the |vp| inside a JSNative, either boxing primitives or - * replacing with the global object as necessary. - */ -extern JS_PUBLIC_API(Value) -ComputeThis(JSContext* cx, JS::Value* vp); - -#ifdef JS_DEBUG -extern JS_PUBLIC_API(void) -CheckIsValidConstructible(const Value& v); -#endif - -class MOZ_STACK_CLASS IncludeUsedRval -{ - protected: -#ifdef JS_DEBUG - mutable bool usedRval_; - void setUsedRval() const { usedRval_ = true; } - void clearUsedRval() const { usedRval_ = false; } - void assertUnusedRval() const { MOZ_ASSERT(!usedRval_); } -#else - void setUsedRval() const {} - void clearUsedRval() const {} - void assertUnusedRval() const {} -#endif -}; - -class MOZ_STACK_CLASS NoUsedRval -{ - protected: - void setUsedRval() const {} - void clearUsedRval() const {} - void assertUnusedRval() const {} -}; - -template -class MOZ_STACK_CLASS CallArgsBase : public WantUsedRval -{ - static_assert(mozilla::IsSame::value || - mozilla::IsSame::value, - "WantUsedRval can only be IncludeUsedRval or NoUsedRval"); - - protected: - Value* argv_; - unsigned argc_; - bool constructing_; - - public: - // CALLEE ACCESS - - /* - * Returns the function being called, as a value. Must not be called after - * rval() has been used! - */ - HandleValue calleev() const { - this->assertUnusedRval(); - return HandleValue::fromMarkedLocation(&argv_[-2]); - } - - /* - * Returns the function being called, as an object. Must not be called - * after rval() has been used! - */ - JSObject& callee() const { - return calleev().toObject(); - } - - // CALLING/CONSTRUCTING-DIFFERENTIATIONS - - bool isConstructing() const { - if (!argv_[-1].isMagic()) - return false; - -#ifdef JS_DEBUG - if (!this->usedRval_) - CheckIsValidConstructible(calleev()); -#endif - - return true; - } - - MutableHandleValue newTarget() const { - MOZ_ASSERT(constructing_); - return MutableHandleValue::fromMarkedLocation(&this->argv_[argc_]); - } - - /* - * Returns the |this| value passed to the function. This method must not - * be called when the function is being called as a constructor via |new|. - * The value may or may not be an object: it is the individual function's - * responsibility to box the value if needed. - */ - HandleValue thisv() const { - // Some internal code uses thisv() in constructing cases, so don't do - // this yet. - // MOZ_ASSERT(!argv_[-1].isMagic(JS_IS_CONSTRUCTING)); - return HandleValue::fromMarkedLocation(&argv_[-1]); - } - - Value computeThis(JSContext* cx) const { - if (thisv().isObject()) - return thisv(); - - return ComputeThis(cx, base()); - } - - // ARGUMENTS - - /* Returns the number of arguments. */ - unsigned length() const { return argc_; } - - /* Returns the i-th zero-indexed argument. */ - MutableHandleValue operator[](unsigned i) const { - MOZ_ASSERT(i < argc_); - return MutableHandleValue::fromMarkedLocation(&this->argv_[i]); - } - - /* - * Returns the i-th zero-indexed argument, or |undefined| if there's no - * such argument. - */ - HandleValue get(unsigned i) const { - return i < length() - ? HandleValue::fromMarkedLocation(&this->argv_[i]) - : UndefinedHandleValue; - } - - /* - * Returns true if the i-th zero-indexed argument is present and is not - * |undefined|. - */ - bool hasDefined(unsigned i) const { - return i < argc_ && !this->argv_[i].isUndefined(); - } - - // RETURN VALUE - - /* - * Returns the currently-set return value. The initial contents of this - * value are unspecified. Once this method has been called, callee() and - * calleev() can no longer be used. (If you're compiling against a debug - * build of SpiderMonkey, these methods will assert to aid debugging.) - * - * If the method you're implementing succeeds by returning true, you *must* - * set this. (SpiderMonkey doesn't currently assert this, but it will do - * so eventually.) You don't need to use or change this if your method - * fails. - */ - MutableHandleValue rval() const { - this->setUsedRval(); - return MutableHandleValue::fromMarkedLocation(&argv_[-2]); - } - - public: - // These methods are publicly exposed, but they are *not* to be used when - // implementing a JSNative method and encapsulating access to |vp| within - // it. You probably don't want to use these! - - void setCallee(const Value& aCalleev) const { - this->clearUsedRval(); - argv_[-2] = aCalleev; - } - - void setThis(const Value& aThisv) const { - argv_[-1] = aThisv; - } - - MutableHandleValue mutableThisv() const { - return MutableHandleValue::fromMarkedLocation(&argv_[-1]); - } - - public: - // These methods are publicly exposed, but we're unsure of the interfaces - // (because they're hackish and drop assertions). Avoid using these if you - // can. - - Value* array() const { return argv_; } - Value* end() const { return argv_ + argc_ + constructing_; } - - public: - // These methods are only intended for internal use. Embedders shouldn't - // use them! - - Value* base() const { return argv_ - 2; } - - Value* spAfterCall() const { - this->setUsedRval(); - return argv_ - 1; - } -}; - -} // namespace detail - -class MOZ_STACK_CLASS CallArgs : public detail::CallArgsBase -{ - private: - friend CallArgs CallArgsFromVp(unsigned argc, Value* vp); - friend CallArgs CallArgsFromSp(unsigned stackSlots, Value* sp, bool constructing); - - static CallArgs create(unsigned argc, Value* argv, bool constructing) { - CallArgs args; - args.clearUsedRval(); - args.argv_ = argv; - args.argc_ = argc; - args.constructing_ = constructing; -#ifdef DEBUG - for (unsigned i = 0; i < argc; ++i) - MOZ_ASSERT_IF(argv[i].isMarkable(), !GCThingIsMarkedGray(GCCellPtr(argv[i]))); -#endif - return args; - } - - public: - /* - * Returns true if there are at least |required| arguments passed in. If - * false, it reports an error message on the context. - */ - bool requireAtLeast(JSContext* cx, const char* fnname, unsigned required) const; - -}; - -MOZ_ALWAYS_INLINE CallArgs -CallArgsFromVp(unsigned argc, Value* vp) -{ - return CallArgs::create(argc, vp + 2, vp[1].isMagic(JS_IS_CONSTRUCTING)); -} - -// This method is only intended for internal use in SpiderMonkey. We may -// eventually move it to an internal header. Embedders should use -// JS::CallArgsFromVp! -MOZ_ALWAYS_INLINE CallArgs -CallArgsFromSp(unsigned stackSlots, Value* sp, bool constructing = false) -{ - return CallArgs::create(stackSlots - constructing, sp - stackSlots, constructing); -} - -} // namespace JS - -/* - * Macros to hide interpreter stack layout details from a JSNative using its - * JS::Value* vp parameter. DO NOT USE THESE! Instead use JS::CallArgs and - * friends, above. These macros will be removed when we change JSNative to - * take a const JS::CallArgs&. - */ - -/* - * Return |this| if |this| is an object. Otherwise, return the global object - * if |this| is null or undefined, and finally return a boxed version of any - * other primitive. - * - * Note: if this method returns null, an error has occurred and must be - * propagated or caught. - */ -MOZ_ALWAYS_INLINE JS::Value -JS_THIS(JSContext* cx, JS::Value* vp) -{ - return vp[1].isPrimitive() ? JS::detail::ComputeThis(cx, vp) : vp[1]; -} - -/* - * A note on JS_THIS_OBJECT: no equivalent method is part of the CallArgs - * interface, and we're unlikely to add one (functions shouldn't be implicitly - * exposing the global object to arbitrary callers). Continue using |vp| - * directly for this case, but be aware this API will eventually be replaced - * with a function that operates directly upon |args.thisv()|. - */ -#define JS_THIS_OBJECT(cx,vp) (JS_THIS(cx,vp).toObjectOrNull()) - -/* - * |this| is passed to functions in ES5 without change. Functions themselves - * do any post-processing they desire to box |this|, compute the global object, - * &c. This macro retrieves a function's unboxed |this| value. - * - * This macro must not be used in conjunction with JS_THIS or JS_THIS_OBJECT, - * or vice versa. Either use the provided this value with this macro, or - * compute the boxed |this| value using those. JS_THIS_VALUE must not be used - * if the function is being called as a constructor. - * - * But: DO NOT USE THIS! Instead use JS::CallArgs::thisv(), above. - * - */ -#define JS_THIS_VALUE(cx,vp) ((vp)[1]) - -#endif /* js_CallArgs_h */ diff --git a/android/x86/include/spidermonkey/js/CallNonGenericMethod.h b/android/x86/include/spidermonkey/js/CallNonGenericMethod.h deleted file mode 100644 index 9a1cf010..00000000 --- a/android/x86/include/spidermonkey/js/CallNonGenericMethod.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_CallNonGenericMethod_h -#define js_CallNonGenericMethod_h - -#include "jstypes.h" - -#include "js/CallArgs.h" - -namespace JS { - -// Returns true if |v| is considered an acceptable this-value. -typedef bool (*IsAcceptableThis)(HandleValue v); - -// Implements the guts of a method; guaranteed to be provided an acceptable -// this-value, as determined by a corresponding IsAcceptableThis method. -typedef bool (*NativeImpl)(JSContext* cx, const CallArgs& args); - -namespace detail { - -// DON'T CALL THIS DIRECTLY. It's for use only by CallNonGenericMethod! -extern JS_PUBLIC_API(bool) -CallMethodIfWrapped(JSContext* cx, IsAcceptableThis test, NativeImpl impl, const CallArgs& args); - -} // namespace detail - -// Methods usually act upon |this| objects only from a single global object and -// compartment. Sometimes, however, a method must act upon |this| values from -// multiple global objects or compartments. In such cases the |this| value a -// method might see will be wrapped, such that various access to the object -- -// to its class, its private data, its reserved slots, and so on -- will not -// work properly without entering that object's compartment. This method -// implements a solution to this problem. -// -// To implement a method that accepts |this| values from multiple compartments, -// define two functions. The first function matches the IsAcceptableThis type -// and indicates whether the provided value is an acceptable |this| for the -// method; it must be a pure function only of its argument. -// -// static const JSClass AnswerClass = { ... }; -// -// static bool -// IsAnswerObject(const Value& v) -// { -// if (!v.isObject()) -// return false; -// return JS_GetClass(&v.toObject()) == &AnswerClass; -// } -// -// The second function implements the NativeImpl signature and defines the -// behavior of the method when it is provided an acceptable |this| value. -// Aside from some typing niceties -- see the CallArgs interface for details -- -// its interface is the same as that of JSNative. -// -// static bool -// answer_getAnswer_impl(JSContext* cx, JS::CallArgs args) -// { -// args.rval().setInt32(42); -// return true; -// } -// -// The implementation function is guaranteed to be called *only* with a |this| -// value which is considered acceptable. -// -// Now to implement the actual method, write a JSNative that calls the method -// declared below, passing the appropriate template and runtime arguments. -// -// static bool -// answer_getAnswer(JSContext* cx, unsigned argc, JS::Value* vp) -// { -// JS::CallArgs args = JS::CallArgsFromVp(argc, vp); -// return JS::CallNonGenericMethod(cx, args); -// } -// -// Note that, because they are used as template arguments, the predicate -// and implementation functions must have external linkage. (This is -// unfortunate, but GCC wasn't inlining things as one would hope when we -// passed them as function arguments.) -// -// JS::CallNonGenericMethod will test whether |args.thisv()| is acceptable. If -// it is, it will call the provided implementation function, which will return -// a value and indicate success. If it is not, it will attempt to unwrap -// |this| and call the implementation function on the unwrapped |this|. If -// that succeeds, all well and good. If it doesn't succeed, a TypeError will -// be thrown. -// -// Note: JS::CallNonGenericMethod will only work correctly if it's called in -// tail position in a JSNative. Do not call it from any other place. -// -template -MOZ_ALWAYS_INLINE bool -CallNonGenericMethod(JSContext* cx, const CallArgs& args) -{ - HandleValue thisv = args.thisv(); - if (Test(thisv)) - return Impl(cx, args); - - return detail::CallMethodIfWrapped(cx, Test, Impl, args); -} - -MOZ_ALWAYS_INLINE bool -CallNonGenericMethod(JSContext* cx, IsAcceptableThis Test, NativeImpl Impl, const CallArgs& args) -{ - HandleValue thisv = args.thisv(); - if (Test(thisv)) - return Impl(cx, args); - - return detail::CallMethodIfWrapped(cx, Test, Impl, args); -} - -} // namespace JS - -#endif /* js_CallNonGenericMethod_h */ diff --git a/android/x86/include/spidermonkey/js/CharacterEncoding.h b/android/x86/include/spidermonkey/js/CharacterEncoding.h deleted file mode 100644 index fe39a415..00000000 --- a/android/x86/include/spidermonkey/js/CharacterEncoding.h +++ /dev/null @@ -1,338 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_CharacterEncoding_h -#define js_CharacterEncoding_h - -#include "mozilla/Range.h" - -#include "js/TypeDecls.h" -#include "js/Utility.h" - -namespace js { -class ExclusiveContext; -} // namespace js - -class JSFlatString; - -namespace JS { - -/* - * By default, all C/C++ 1-byte-per-character strings passed into the JSAPI - * are treated as ISO/IEC 8859-1, also known as Latin-1. That is, each - * byte is treated as a 2-byte character, and there is no way to pass in a - * string containing characters beyond U+00FF. - */ -class Latin1Chars : public mozilla::Range -{ - typedef mozilla::Range Base; - - public: - using CharT = Latin1Char; - - Latin1Chars() : Base() {} - Latin1Chars(char* aBytes, size_t aLength) : Base(reinterpret_cast(aBytes), aLength) {} - Latin1Chars(const Latin1Char* aBytes, size_t aLength) - : Base(const_cast(aBytes), aLength) - {} - Latin1Chars(const char* aBytes, size_t aLength) - : Base(reinterpret_cast(const_cast(aBytes)), aLength) - {} -}; - -/* - * A Latin1Chars, but with \0 termination for C compatibility. - */ -class Latin1CharsZ : public mozilla::RangedPtr -{ - typedef mozilla::RangedPtr Base; - - public: - using CharT = Latin1Char; - - Latin1CharsZ() : Base(nullptr, 0) {} - - Latin1CharsZ(char* aBytes, size_t aLength) - : Base(reinterpret_cast(aBytes), aLength) - { - MOZ_ASSERT(aBytes[aLength] == '\0'); - } - - Latin1CharsZ(Latin1Char* aBytes, size_t aLength) - : Base(aBytes, aLength) - { - MOZ_ASSERT(aBytes[aLength] == '\0'); - } - - using Base::operator=; - - char* c_str() { return reinterpret_cast(get()); } -}; - -class UTF8Chars : public mozilla::Range -{ - typedef mozilla::Range Base; - - public: - using CharT = unsigned char; - - UTF8Chars() : Base() {} - UTF8Chars(char* aBytes, size_t aLength) - : Base(reinterpret_cast(aBytes), aLength) - {} - UTF8Chars(const char* aBytes, size_t aLength) - : Base(reinterpret_cast(const_cast(aBytes)), aLength) - {} -}; - -/* - * SpiderMonkey also deals directly with UTF-8 encoded text in some places. - */ -class UTF8CharsZ : public mozilla::RangedPtr -{ - typedef mozilla::RangedPtr Base; - - public: - using CharT = unsigned char; - - UTF8CharsZ() : Base(nullptr, 0) {} - - UTF8CharsZ(char* aBytes, size_t aLength) - : Base(reinterpret_cast(aBytes), aLength) - { - MOZ_ASSERT(aBytes[aLength] == '\0'); - } - - UTF8CharsZ(unsigned char* aBytes, size_t aLength) - : Base(aBytes, aLength) - { - MOZ_ASSERT(aBytes[aLength] == '\0'); - } - - using Base::operator=; - - char* c_str() { return reinterpret_cast(get()); } -}; - -/* - * A wrapper for a "const char*" that is encoded using UTF-8. - * This class does not manage ownership of the data; that is left - * to others. This differs from UTF8CharsZ in that the chars are - * const and it allows assignment. - */ -class ConstUTF8CharsZ -{ - const char* data_; - - public: - using CharT = unsigned char; - - ConstUTF8CharsZ() : data_(nullptr) - {} - - ConstUTF8CharsZ(const char* aBytes, size_t aLength) - : data_(aBytes) - { - MOZ_ASSERT(aBytes[aLength] == '\0'); -#ifdef DEBUG - validate(aLength); -#endif - } - - const void* get() const { return data_; } - - const char* c_str() const { return data_; } - - explicit operator bool() const { return data_ != nullptr; } - - private: -#ifdef DEBUG - void validate(size_t aLength); -#endif -}; - -/* - * SpiderMonkey uses a 2-byte character representation: it is a - * 2-byte-at-a-time view of a UTF-16 byte stream. This is similar to UCS-2, - * but unlike UCS-2, we do not strip UTF-16 extension bytes. This allows a - * sufficiently dedicated JavaScript program to be fully unicode-aware by - * manually interpreting UTF-16 extension characters embedded in the JS - * string. - */ -class TwoByteChars : public mozilla::Range -{ - typedef mozilla::Range Base; - - public: - using CharT = char16_t; - - TwoByteChars() : Base() {} - TwoByteChars(char16_t* aChars, size_t aLength) : Base(aChars, aLength) {} - TwoByteChars(const char16_t* aChars, size_t aLength) : Base(const_cast(aChars), aLength) {} -}; - -/* - * A TwoByteChars, but \0 terminated for compatibility with JSFlatString. - */ -class TwoByteCharsZ : public mozilla::RangedPtr -{ - typedef mozilla::RangedPtr Base; - - public: - using CharT = char16_t; - - TwoByteCharsZ() : Base(nullptr, 0) {} - - TwoByteCharsZ(char16_t* chars, size_t length) - : Base(chars, length) - { - MOZ_ASSERT(chars[length] == '\0'); - } - - using Base::operator=; -}; - -typedef mozilla::RangedPtr ConstCharPtr; - -/* - * Like TwoByteChars, but the chars are const. - */ -class ConstTwoByteChars : public mozilla::Range -{ - typedef mozilla::Range Base; - - public: - using CharT = char16_t; - - ConstTwoByteChars() : Base() {} - ConstTwoByteChars(const char16_t* aChars, size_t aLength) : Base(aChars, aLength) {} -}; - -/* - * Convert a 2-byte character sequence to "ISO-Latin-1". This works by - * truncating each 2-byte pair in the sequence to a 1-byte pair. If the source - * contains any UTF-16 extension characters, then this may give invalid Latin1 - * output. The returned string is zero terminated. The returned string or the - * returned string's |start()| must be freed with JS_free or js_free, - * respectively. If allocation fails, an OOM error will be set and the method - * will return a nullptr chars (which can be tested for with the ! operator). - * This method cannot trigger GC. - */ -extern Latin1CharsZ -LossyTwoByteCharsToNewLatin1CharsZ(js::ExclusiveContext* cx, - const mozilla::Range tbchars); - -inline Latin1CharsZ -LossyTwoByteCharsToNewLatin1CharsZ(js::ExclusiveContext* cx, const char16_t* begin, size_t length) -{ - const mozilla::Range tbchars(begin, length); - return JS::LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars); -} - -template -extern UTF8CharsZ -CharsToNewUTF8CharsZ(js::ExclusiveContext* maybeCx, const mozilla::Range chars); - -uint32_t -Utf8ToOneUcs4Char(const uint8_t* utf8Buffer, int utf8Length); - -/* - * Inflate bytes in UTF-8 encoding to char16_t. - * - On error, returns an empty TwoByteCharsZ. - * - On success, returns a malloc'd TwoByteCharsZ, and updates |outlen| to hold - * its length; the length value excludes the trailing null. - */ -extern TwoByteCharsZ -UTF8CharsToNewTwoByteCharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen); - -/* - * Like UTF8CharsToNewTwoByteCharsZ, but for ConstUTF8CharsZ. - */ -extern TwoByteCharsZ -UTF8CharsToNewTwoByteCharsZ(JSContext* cx, const ConstUTF8CharsZ& utf8, size_t* outlen); - -/* - * The same as UTF8CharsToNewTwoByteCharsZ(), except that any malformed UTF-8 characters - * will be replaced by \uFFFD. No exception will be thrown for malformed UTF-8 - * input. - */ -extern TwoByteCharsZ -LossyUTF8CharsToNewTwoByteCharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen); - -extern TwoByteCharsZ -LossyUTF8CharsToNewTwoByteCharsZ(JSContext* cx, const ConstUTF8CharsZ& utf8, size_t* outlen); - -/* - * Returns the length of the char buffer required to encode |s| as UTF8. - * Does not include the null-terminator. - */ -JS_PUBLIC_API(size_t) -GetDeflatedUTF8StringLength(JSFlatString* s); - -/* - * Encode |src| as UTF8. The caller must either ensure |dst| has enough space - * to encode the entire string or pass the length of the buffer as |dstlenp|, - * in which case the function will encode characters from the string until - * the buffer is exhausted. Does not write the null terminator. - * - * If |dstlenp| is provided, it will be updated to hold the number of bytes - * written to the buffer. If |numcharsp| is provided, it will be updated to hold - * the number of Unicode characters written to the buffer (which can be less - * than the length of the string, if the buffer is exhausted before the string - * is fully encoded). - */ -JS_PUBLIC_API(void) -DeflateStringToUTF8Buffer(JSFlatString* src, mozilla::RangedPtr dst, - size_t* dstlenp = nullptr, size_t* numcharsp = nullptr); - -/* - * The smallest character encoding capable of fully representing a particular - * string. - */ -enum class SmallestEncoding { - ASCII, - Latin1, - UTF16 -}; - -/* - * Returns the smallest encoding possible for the given string: if all - * codepoints are <128 then ASCII, otherwise if all codepoints are <256 - * Latin-1, else UTF16. - */ -JS_PUBLIC_API(SmallestEncoding) -FindSmallestEncoding(UTF8Chars utf8); - -/* - * Return a null-terminated Latin-1 string copied from the input string, - * storing its length (excluding null terminator) in |*outlen|. Fail and - * report an error if the string contains non-Latin-1 codepoints. Returns - * Latin1CharsZ() on failure. - */ -extern Latin1CharsZ -UTF8CharsToNewLatin1CharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen); - -/* - * Return a null-terminated Latin-1 string copied from the input string, - * storing its length (excluding null terminator) in |*outlen|. Non-Latin-1 - * codepoints are replaced by '?'. Returns Latin1CharsZ() on failure. - */ -extern Latin1CharsZ -LossyUTF8CharsToNewLatin1CharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen); - -/* - * Returns true if all characters in the given null-terminated string are - * ASCII, i.e. < 0x80, false otherwise. - */ -extern bool -StringIsASCII(const char* s); - -} // namespace JS - -inline void JS_free(JS::Latin1CharsZ& ptr) { js_free((void*)ptr.get()); } -inline void JS_free(JS::UTF8CharsZ& ptr) { js_free((void*)ptr.get()); } - -#endif /* js_CharacterEncoding_h */ diff --git a/android/x86/include/spidermonkey/js/Class.h b/android/x86/include/spidermonkey/js/Class.h deleted file mode 100644 index 3b502387..00000000 --- a/android/x86/include/spidermonkey/js/Class.h +++ /dev/null @@ -1,995 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* JSClass definition and its component types, plus related interfaces. */ - -#ifndef js_Class_h -#define js_Class_h - -#include "jstypes.h" - -#include "js/CallArgs.h" -#include "js/Id.h" -#include "js/TypeDecls.h" - -/* - * A JSClass acts as a vtable for JS objects that allows JSAPI clients to - * control various aspects of the behavior of an object like property lookup. - * js::Class is an engine-private extension that allows more control over - * object behavior and, e.g., allows custom slow layout. - */ - -struct JSAtomState; -struct JSFreeOp; -struct JSFunctionSpec; - -namespace js { - -struct Class; -class FreeOp; -class Shape; - -// This is equal to JSFunction::class_. Use it in places where you don't want -// to #include jsfun.h. -extern JS_FRIEND_DATA(const js::Class* const) FunctionClassPtr; - -} // namespace js - -namespace JS { - -class AutoIdVector; - -/** - * The answer to a successful query as to whether an object is an Array per - * ES6's internal |IsArray| operation (as exposed by |Array.isArray|). - */ -enum class IsArrayAnswer -{ - Array, - NotArray, - RevokedProxy -}; - -/** - * ES6 7.2.2. - * - * Returns false on failure, otherwise returns true and sets |*isArray| - * indicating whether the object passes ECMAScript's IsArray test. This is the - * same test performed by |Array.isArray|. - * - * This is NOT the same as asking whether |obj| is an Array or a wrapper around - * one. If |obj| is a proxy created by |Proxy.revocable()| and has been - * revoked, or if |obj| is a proxy whose target (at any number of hops) is a - * revoked proxy, this method throws a TypeError and returns false. - */ -extern JS_PUBLIC_API(bool) -IsArray(JSContext* cx, HandleObject obj, bool* isArray); - -/** - * Identical to IsArray above, but the nature of the object (if successfully - * determined) is communicated via |*answer|. In particular this method - * returns true and sets |*answer = IsArrayAnswer::RevokedProxy| when called on - * a revoked proxy. - * - * Most users will want the overload above, not this one. - */ -extern JS_PUBLIC_API(bool) -IsArray(JSContext* cx, HandleObject obj, IsArrayAnswer* answer); - -/** - * Per ES6, the [[DefineOwnProperty]] internal method has three different - * possible outcomes: - * - * - It can throw an exception (which we indicate by returning false). - * - * - It can return true, indicating unvarnished success. - * - * - It can return false, indicating "strict failure". The property could - * not be defined. It's an error, but no exception was thrown. - * - * It's not just [[DefineOwnProperty]]: all the mutating internal methods have - * the same three outcomes. (The other affected internal methods are [[Set]], - * [[Delete]], [[SetPrototypeOf]], and [[PreventExtensions]].) - * - * If you think this design is awful, you're not alone. But as it's the - * standard, we must represent these boolean "success" values somehow. - * ObjectOpSuccess is the class for this. It's like a bool, but when it's false - * it also stores an error code. - * - * Typical usage: - * - * ObjectOpResult result; - * if (!DefineProperty(cx, obj, id, ..., result)) - * return false; - * if (!result) - * return result.reportError(cx, obj, id); - * - * Users don't have to call `result.report()`; another possible ending is: - * - * argv.rval().setBoolean(bool(result)); - * return true; - */ -class ObjectOpResult -{ - private: - /** - * code_ is either one of the special codes OkCode or Uninitialized, or - * an error code. For now the error codes are private to the JS engine; - * they're defined in js/src/js.msg. - * - * code_ is uintptr_t (rather than uint32_t) for the convenience of the - * JITs, which would otherwise have to deal with either padding or stack - * alignment on 64-bit platforms. - */ - uintptr_t code_; - - public: - enum SpecialCodes : uintptr_t { - OkCode = 0, - Uninitialized = uintptr_t(-1) - }; - - ObjectOpResult() : code_(Uninitialized) {} - - /* Return true if succeed() was called. */ - bool ok() const { - MOZ_ASSERT(code_ != Uninitialized); - return code_ == OkCode; - } - - explicit operator bool() const { return ok(); } - - /* Set this ObjectOpResult to true and return true. */ - bool succeed() { - code_ = OkCode; - return true; - } - - /* - * Set this ObjectOpResult to false with an error code. - * - * Always returns true, as a convenience. Typical usage will be: - * - * if (funny condition) - * return result.fail(JSMSG_CANT_DO_THE_THINGS); - * - * The true return value indicates that no exception is pending, and it - * would be OK to ignore the failure and continue. - */ - bool fail(uint32_t msg) { - MOZ_ASSERT(msg != OkCode); - code_ = msg; - return true; - } - - JS_PUBLIC_API(bool) failCantRedefineProp(); - JS_PUBLIC_API(bool) failReadOnly(); - JS_PUBLIC_API(bool) failGetterOnly(); - JS_PUBLIC_API(bool) failCantDelete(); - - JS_PUBLIC_API(bool) failCantSetInterposed(); - JS_PUBLIC_API(bool) failCantDefineWindowElement(); - JS_PUBLIC_API(bool) failCantDeleteWindowElement(); - JS_PUBLIC_API(bool) failCantDeleteWindowNamedProperty(); - JS_PUBLIC_API(bool) failCantPreventExtensions(); - JS_PUBLIC_API(bool) failCantSetProto(); - JS_PUBLIC_API(bool) failNoNamedSetter(); - JS_PUBLIC_API(bool) failNoIndexedSetter(); - - uint32_t failureCode() const { - MOZ_ASSERT(!ok()); - return uint32_t(code_); - } - - /* - * Report an error or warning if necessary; return true to proceed and - * false if an error was reported. Call this when failure should cause - * a warning if extraWarnings are enabled. - * - * The precise rules are like this: - * - * - If ok(), then we succeeded. Do nothing and return true. - * - Otherwise, if |strict| is true, or if cx has both extraWarnings and - * werrorOption enabled, throw a TypeError and return false. - * - Otherwise, if cx has extraWarnings enabled, emit a warning and - * return true. - * - Otherwise, do nothing and return true. - */ - bool checkStrictErrorOrWarning(JSContext* cx, HandleObject obj, HandleId id, bool strict) { - if (ok()) - return true; - return reportStrictErrorOrWarning(cx, obj, id, strict); - } - - /* - * The same as checkStrictErrorOrWarning(cx, id, strict), except the - * operation is not associated with a particular property id. This is - * used for [[PreventExtensions]] and [[SetPrototypeOf]]. failureCode() - * must not be an error that has "{0}" in the error message. - */ - bool checkStrictErrorOrWarning(JSContext* cx, HandleObject obj, bool strict) { - return ok() || reportStrictErrorOrWarning(cx, obj, strict); - } - - /* Throw a TypeError. Call this only if !ok(). */ - bool reportError(JSContext* cx, HandleObject obj, HandleId id) { - return reportStrictErrorOrWarning(cx, obj, id, true); - } - - /* - * The same as reportError(cx, obj, id), except the operation is not - * associated with a particular property id. - */ - bool reportError(JSContext* cx, HandleObject obj) { - return reportStrictErrorOrWarning(cx, obj, true); - } - - /* Helper function for checkStrictErrorOrWarning's slow path. */ - JS_PUBLIC_API(bool) reportStrictErrorOrWarning(JSContext* cx, HandleObject obj, HandleId id, bool strict); - JS_PUBLIC_API(bool) reportStrictErrorOrWarning(JSContext* cx, HandleObject obj, bool strict); - - /* - * Convenience method. Return true if ok() or if strict is false; otherwise - * throw a TypeError and return false. - */ - bool checkStrict(JSContext* cx, HandleObject obj, HandleId id) { - return checkStrictErrorOrWarning(cx, obj, id, true); - } - - /* - * Convenience method. The same as checkStrict(cx, id), except the - * operation is not associated with a particular property id. - */ - bool checkStrict(JSContext* cx, HandleObject obj) { - return checkStrictErrorOrWarning(cx, obj, true); - } -}; - -} // namespace JS - -// JSClass operation signatures. - -/** - * Get a property named by id in obj. Note the jsid id type -- id may - * be a string (Unicode property identifier) or an int (element index). The - * *vp out parameter, on success, is the new property value after the action. - */ -typedef bool -(* JSGetterOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp); - -/** Add a property named by id to obj. */ -typedef bool -(* JSAddPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v); - -/** - * Set a property named by id in obj, treating the assignment as strict - * mode code if strict is true. Note the jsid id type -- id may be a string - * (Unicode property identifier) or an int (element index). The *vp out - * parameter, on success, is the new property value after the - * set. - */ -typedef bool -(* JSSetterOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp, JS::ObjectOpResult& result); - -/** - * Delete a property named by id in obj. - * - * If an error occurred, return false as per normal JSAPI error practice. - * - * If no error occurred, but the deletion attempt wasn't allowed (perhaps - * because the property was non-configurable), call result.fail() and - * return true. This will cause |delete obj[id]| to evaluate to false in - * non-strict mode code, and to throw a TypeError in strict mode code. - * - * If no error occurred and the deletion wasn't disallowed (this is *not* the - * same as saying that a deletion actually occurred -- deleting a non-existent - * property, or an inherited property, is allowed -- it's just pointless), - * call result.succeed() and return true. - */ -typedef bool -(* JSDeletePropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::ObjectOpResult& result); - -/** - * The type of ObjectOps::enumerate. This callback overrides a portion of - * SpiderMonkey's default [[Enumerate]] internal method. When an ordinary object - * is enumerated, that object and each object on its prototype chain is tested - * for an enumerate op, and those ops are called in order. The properties each - * op adds to the 'properties' vector are added to the set of values the for-in - * loop will iterate over. All of this is nonstandard. - * - * An object is "enumerated" when it's the target of a for-in loop or - * JS_Enumerate(). The callback's job is to populate 'properties' with the - * object's property keys. If `enumerableOnly` is true, the callback should only - * add enumerable properties. - */ -typedef bool -(* JSNewEnumerateOp)(JSContext* cx, JS::HandleObject obj, JS::AutoIdVector& properties, - bool enumerableOnly); - -/** - * The old-style JSClass.enumerate op should define all lazy properties not - * yet reflected in obj. - */ -typedef bool -(* JSEnumerateOp)(JSContext* cx, JS::HandleObject obj); - -/** - * The type of ObjectOps::funToString. This callback allows an object to - * provide a custom string to use when Function.prototype.toString is invoked on - * that object. A null return value means OOM. - */ -typedef JSString* -(* JSFunToStringOp)(JSContext* cx, JS::HandleObject obj, unsigned indent); - -/** - * Resolve a lazy property named by id in obj by defining it directly in obj. - * Lazy properties are those reflected from some peer native property space - * (e.g., the DOM attributes for a given node reflected as obj) on demand. - * - * JS looks for a property in an object, and if not found, tries to resolve - * the given id. *resolvedp should be set to true iff the property was defined - * on |obj|. - */ -typedef bool -(* JSResolveOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - bool* resolvedp); - -/** - * A class with a resolve hook can optionally have a mayResolve hook. This hook - * must have no side effects and must return true for a given id if the resolve - * hook may resolve this id. This is useful when we're doing a "pure" lookup: if - * mayResolve returns false, we know we don't have to call the effectful resolve - * hook. - * - * maybeObj, if non-null, is the object on which we're doing the lookup. This - * can be nullptr: during JIT compilation we sometimes know the Class but not - * the object. - */ -typedef bool -(* JSMayResolveOp)(const JSAtomState& names, jsid id, JSObject* maybeObj); - -/** - * Finalize obj, which the garbage collector has determined to be unreachable - * from other live objects or from GC roots. Obviously, finalizers must never - * store a reference to obj. - */ -typedef void -(* JSFinalizeOp)(JSFreeOp* fop, JSObject* obj); - -/** Finalizes external strings created by JS_NewExternalString. */ -struct JSStringFinalizer { - void (*finalize)(JS::Zone* zone, const JSStringFinalizer* fin, char16_t* chars); -}; - -/** - * Check whether v is an instance of obj. Return false on error or exception, - * true on success with true in *bp if v is an instance of obj, false in - * *bp otherwise. - */ -typedef bool -(* JSHasInstanceOp)(JSContext* cx, JS::HandleObject obj, JS::MutableHandleValue vp, - bool* bp); - -/** - * Function type for trace operation of the class called to enumerate all - * traceable things reachable from obj's private data structure. For each such - * thing, a trace implementation must call JS::TraceEdge on the thing's - * location. - * - * JSTraceOp implementation can assume that no other threads mutates object - * state. It must not change state of the object or corresponding native - * structures. The only exception for this rule is the case when the embedding - * needs a tight integration with GC. In that case the embedding can check if - * the traversal is a part of the marking phase through calling - * JS_IsGCMarkingTracer and apply a special code like emptying caches or - * marking its native structures. - */ -typedef void -(* JSTraceOp)(JSTracer* trc, JSObject* obj); - -typedef JSObject* -(* JSWeakmapKeyDelegateOp)(JSObject* obj); - -typedef void -(* JSObjectMovedOp)(JSObject* obj, const JSObject* old); - -/* js::Class operation signatures. */ - -namespace js { - -typedef bool -(* LookupPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleObject objp, JS::MutableHandle propp); -typedef bool -(* DefinePropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::Handle desc, - JS::ObjectOpResult& result); -typedef bool -(* HasPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp); -typedef bool -(* GetPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleValue receiver, JS::HandleId id, - JS::MutableHandleValue vp); -typedef bool -(* SetPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v, - JS::HandleValue receiver, JS::ObjectOpResult& result); -typedef bool -(* GetOwnPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandle desc); -typedef bool -(* DeletePropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::ObjectOpResult& result); - -typedef bool -(* WatchOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable); - -typedef bool -(* UnwatchOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id); - -class JS_FRIEND_API(ElementAdder) -{ - public: - enum GetBehavior { - // Check if the element exists before performing the Get and preserve - // holes. - CheckHasElemPreserveHoles, - - // Perform a Get operation, like obj[index] in JS. - GetElement - }; - - private: - // Only one of these is used. - JS::RootedObject resObj_; - JS::Value* vp_; - - uint32_t index_; -#ifdef DEBUG - uint32_t length_; -#endif - GetBehavior getBehavior_; - - public: - ElementAdder(JSContext* cx, JSObject* obj, uint32_t length, GetBehavior behavior) - : resObj_(cx, obj), vp_(nullptr), index_(0), -#ifdef DEBUG - length_(length), -#endif - getBehavior_(behavior) - {} - ElementAdder(JSContext* cx, JS::Value* vp, uint32_t length, GetBehavior behavior) - : resObj_(cx), vp_(vp), index_(0), -#ifdef DEBUG - length_(length), -#endif - getBehavior_(behavior) - {} - - GetBehavior getBehavior() const { return getBehavior_; } - - bool append(JSContext* cx, JS::HandleValue v); - void appendHole(); -}; - -typedef bool -(* GetElementsOp)(JSContext* cx, JS::HandleObject obj, uint32_t begin, uint32_t end, - ElementAdder* adder); - -typedef void -(* FinalizeOp)(FreeOp* fop, JSObject* obj); - -// The special treatment of |finalize| and |trace| is necessary because if we -// assign either of those hooks to a local variable and then call it -- as is -// done with the other hooks -- the GC hazard analysis gets confused. -#define JS_CLASS_MEMBERS(ClassOpsType, FreeOpType) \ - const char* name; \ - uint32_t flags; \ - const ClassOpsType* cOps; \ - \ - JSAddPropertyOp getAddProperty() const { return cOps ? cOps->addProperty : nullptr; } \ - JSDeletePropertyOp getDelProperty() const { return cOps ? cOps->delProperty : nullptr; } \ - JSGetterOp getGetProperty() const { return cOps ? cOps->getProperty : nullptr; } \ - JSSetterOp getSetProperty() const { return cOps ? cOps->setProperty : nullptr; } \ - JSEnumerateOp getEnumerate() const { return cOps ? cOps->enumerate : nullptr; } \ - JSResolveOp getResolve() const { return cOps ? cOps->resolve : nullptr; } \ - JSMayResolveOp getMayResolve() const { return cOps ? cOps->mayResolve : nullptr; } \ - JSNative getCall() const { return cOps ? cOps->call : nullptr; } \ - JSHasInstanceOp getHasInstance() const { return cOps ? cOps->hasInstance : nullptr; } \ - JSNative getConstruct() const { return cOps ? cOps->construct : nullptr; } \ - \ - bool hasFinalize() const { return cOps && cOps->finalize; } \ - bool hasTrace() const { return cOps && cOps->trace; } \ - \ - bool isTrace(JSTraceOp trace) const { return cOps && cOps->trace == trace; } \ - \ - void doFinalize(FreeOpType* fop, JSObject* obj) const { \ - MOZ_ASSERT(cOps && cOps->finalize); \ - cOps->finalize(fop, obj); \ - } \ - void doTrace(JSTracer* trc, JSObject* obj) const { \ - MOZ_ASSERT(cOps && cOps->trace); \ - cOps->trace(trc, obj); \ - } - -struct ClassOps -{ - /* Function pointer members (may be null). */ - JSAddPropertyOp addProperty; - JSDeletePropertyOp delProperty; - JSGetterOp getProperty; - JSSetterOp setProperty; - JSEnumerateOp enumerate; - JSResolveOp resolve; - JSMayResolveOp mayResolve; - FinalizeOp finalize; - JSNative call; - JSHasInstanceOp hasInstance; - JSNative construct; - JSTraceOp trace; -}; - -/** Callback for the creation of constructor and prototype objects. */ -typedef JSObject* (*ClassObjectCreationOp)(JSContext* cx, JSProtoKey key); - -/** Callback for custom post-processing after class initialization via ClassSpec. */ -typedef bool (*FinishClassInitOp)(JSContext* cx, JS::HandleObject ctor, - JS::HandleObject proto); - -const size_t JSCLASS_CACHED_PROTO_WIDTH = 6; - -struct ClassSpec -{ - // All properties except flags should be accessed through accessor. - ClassObjectCreationOp createConstructor_; - ClassObjectCreationOp createPrototype_; - const JSFunctionSpec* constructorFunctions_; - const JSPropertySpec* constructorProperties_; - const JSFunctionSpec* prototypeFunctions_; - const JSPropertySpec* prototypeProperties_; - FinishClassInitOp finishInit_; - uintptr_t flags; - - static const size_t ProtoKeyWidth = JSCLASS_CACHED_PROTO_WIDTH; - - static const uintptr_t ProtoKeyMask = (1 << ProtoKeyWidth) - 1; - static const uintptr_t DontDefineConstructor = 1 << ProtoKeyWidth; - static const uintptr_t IsDelegated = 1 << (ProtoKeyWidth + 1); - - bool defined() const { return !!createConstructor_; } - - bool delegated() const { - return (flags & IsDelegated); - } - - // The ProtoKey this class inherits from. - JSProtoKey inheritanceProtoKey() const { - MOZ_ASSERT(defined()); - static_assert(JSProto_Null == 0, "zeroed key must be null"); - - // Default: Inherit from Object. - if (!(flags & ProtoKeyMask)) - return JSProto_Object; - - return JSProtoKey(flags & ProtoKeyMask); - } - - bool shouldDefineConstructor() const { - MOZ_ASSERT(defined()); - return !(flags & DontDefineConstructor); - } - - const ClassSpec* delegatedClassSpec() const { - MOZ_ASSERT(delegated()); - return reinterpret_cast(createConstructor_); - } - - ClassObjectCreationOp createConstructorHook() const { - if (delegated()) - return delegatedClassSpec()->createConstructorHook(); - return createConstructor_; - } - ClassObjectCreationOp createPrototypeHook() const { - if (delegated()) - return delegatedClassSpec()->createPrototypeHook(); - return createPrototype_; - } - const JSFunctionSpec* constructorFunctions() const { - if (delegated()) - return delegatedClassSpec()->constructorFunctions(); - return constructorFunctions_; - } - const JSPropertySpec* constructorProperties() const { - if (delegated()) - return delegatedClassSpec()->constructorProperties(); - return constructorProperties_; - } - const JSFunctionSpec* prototypeFunctions() const { - if (delegated()) - return delegatedClassSpec()->prototypeFunctions(); - return prototypeFunctions_; - } - const JSPropertySpec* prototypeProperties() const { - if (delegated()) - return delegatedClassSpec()->prototypeProperties(); - return prototypeProperties_; - } - FinishClassInitOp finishInitHook() const { - if (delegated()) - return delegatedClassSpec()->finishInitHook(); - return finishInit_; - } -}; - -struct ClassExtension -{ - /** - * If an object is used as a key in a weakmap, it may be desirable for the - * garbage collector to keep that object around longer than it otherwise - * would. A common case is when the key is a wrapper around an object in - * another compartment, and we want to avoid collecting the wrapper (and - * removing the weakmap entry) as long as the wrapped object is alive. In - * that case, the wrapped object is returned by the wrapper's - * weakmapKeyDelegateOp hook. As long as the wrapper is used as a weakmap - * key, it will not be collected (and remain in the weakmap) until the - * wrapped object is collected. - */ - JSWeakmapKeyDelegateOp weakmapKeyDelegateOp; - - /** - * Optional hook called when an object is moved by a compacting GC. - * - * There may exist weak pointers to an object that are not traced through - * when the normal trace APIs are used, for example objects in the wrapper - * cache. This hook allows these pointers to be updated. - * - * Note that this hook can be called before JS_NewObject() returns if a GC - * is triggered during construction of the object. This can happen for - * global objects for example. - */ - JSObjectMovedOp objectMovedOp; -}; - -inline ClassObjectCreationOp DELEGATED_CLASSSPEC(const ClassSpec* spec) { - return reinterpret_cast(const_cast(spec)); -} - -#define JS_NULL_CLASS_SPEC nullptr -#define JS_NULL_CLASS_EXT nullptr - -struct ObjectOps -{ - LookupPropertyOp lookupProperty; - DefinePropertyOp defineProperty; - HasPropertyOp hasProperty; - GetPropertyOp getProperty; - SetPropertyOp setProperty; - GetOwnPropertyOp getOwnPropertyDescriptor; - DeletePropertyOp deleteProperty; - WatchOp watch; - UnwatchOp unwatch; - GetElementsOp getElements; - JSNewEnumerateOp enumerate; - JSFunToStringOp funToString; -}; - -#define JS_NULL_OBJECT_OPS nullptr - -} // namespace js - -// Classes, objects, and properties. - -typedef void (*JSClassInternal)(); - -struct JSClassOps -{ - /* Function pointer members (may be null). */ - JSAddPropertyOp addProperty; - JSDeletePropertyOp delProperty; - JSGetterOp getProperty; - JSSetterOp setProperty; - JSEnumerateOp enumerate; - JSResolveOp resolve; - JSMayResolveOp mayResolve; - JSFinalizeOp finalize; - JSNative call; - JSHasInstanceOp hasInstance; - JSNative construct; - JSTraceOp trace; -}; - -#define JS_NULL_CLASS_OPS nullptr - -struct JSClass { - JS_CLASS_MEMBERS(JSClassOps, JSFreeOp); - - void* reserved[3]; -}; - -#define JSCLASS_HAS_PRIVATE (1<<0) // objects have private slot -#define JSCLASS_DELAY_METADATA_BUILDER (1<<1) // class's initialization code - // will call - // SetNewObjectMetadata itself -#define JSCLASS_IS_WRAPPED_NATIVE (1<<2) // class is an XPCWrappedNative. - // WeakMaps use this to override - // the wrapper disposal - // mechanism. -#define JSCLASS_PRIVATE_IS_NSISUPPORTS (1<<3) // private is (nsISupports*) -#define JSCLASS_IS_DOMJSCLASS (1<<4) // objects are DOM -#define JSCLASS_HAS_XRAYED_CONSTRUCTOR (1<<5) // if wrapped by an xray - // wrapper, the builtin - // class's constructor won't - // be unwrapped and invoked. - // Instead, the constructor is - // resolved in the caller's - // compartment and invoked - // with a wrapped newTarget. - // The constructor has to - // detect and handle this - // situation. - // See PromiseConstructor for - // details. -#define JSCLASS_EMULATES_UNDEFINED (1<<6) // objects of this class act - // like the value undefined, - // in some contexts -#define JSCLASS_USERBIT1 (1<<7) // Reserved for embeddings. - -// To reserve slots fetched and stored via JS_Get/SetReservedSlot, bitwise-or -// JSCLASS_HAS_RESERVED_SLOTS(n) into the initializer for JSClass.flags, where -// n is a constant in [1, 255]. Reserved slots are indexed from 0 to n-1. -#define JSCLASS_RESERVED_SLOTS_SHIFT 8 // room for 8 flags below */ -#define JSCLASS_RESERVED_SLOTS_WIDTH 8 // and 16 above this field */ -#define JSCLASS_RESERVED_SLOTS_MASK JS_BITMASK(JSCLASS_RESERVED_SLOTS_WIDTH) -#define JSCLASS_HAS_RESERVED_SLOTS(n) (((n) & JSCLASS_RESERVED_SLOTS_MASK) \ - << JSCLASS_RESERVED_SLOTS_SHIFT) -#define JSCLASS_RESERVED_SLOTS(clasp) (((clasp)->flags \ - >> JSCLASS_RESERVED_SLOTS_SHIFT) \ - & JSCLASS_RESERVED_SLOTS_MASK) - -#define JSCLASS_HIGH_FLAGS_SHIFT (JSCLASS_RESERVED_SLOTS_SHIFT + \ - JSCLASS_RESERVED_SLOTS_WIDTH) - -#define JSCLASS_IS_ANONYMOUS (1<<(JSCLASS_HIGH_FLAGS_SHIFT+0)) -#define JSCLASS_IS_GLOBAL (1<<(JSCLASS_HIGH_FLAGS_SHIFT+1)) -#define JSCLASS_INTERNAL_FLAG2 (1<<(JSCLASS_HIGH_FLAGS_SHIFT+2)) -#define JSCLASS_INTERNAL_FLAG3 (1<<(JSCLASS_HIGH_FLAGS_SHIFT+3)) - -#define JSCLASS_IS_PROXY (1<<(JSCLASS_HIGH_FLAGS_SHIFT+4)) - -#define JSCLASS_SKIP_NURSERY_FINALIZE (1<<(JSCLASS_HIGH_FLAGS_SHIFT+5)) - -// Reserved for embeddings. -#define JSCLASS_USERBIT2 (1<<(JSCLASS_HIGH_FLAGS_SHIFT+6)) -#define JSCLASS_USERBIT3 (1<<(JSCLASS_HIGH_FLAGS_SHIFT+7)) - -#define JSCLASS_BACKGROUND_FINALIZE (1<<(JSCLASS_HIGH_FLAGS_SHIFT+8)) -#define JSCLASS_FOREGROUND_FINALIZE (1<<(JSCLASS_HIGH_FLAGS_SHIFT+9)) - -// Bits 26 through 31 are reserved for the CACHED_PROTO_KEY mechanism, see -// below. - -// ECMA-262 requires that most constructors used internally create objects -// with "the original Foo.prototype value" as their [[Prototype]] (__proto__) -// member initial value. The "original ... value" verbiage is there because -// in ECMA-262, global properties naming class objects are read/write and -// deleteable, for the most part. -// -// Implementing this efficiently requires that global objects have classes -// with the following flags. Failure to use JSCLASS_GLOBAL_FLAGS was -// previously allowed, but is now an ES5 violation and thus unsupported. -// -// JSCLASS_GLOBAL_APPLICATION_SLOTS is the number of slots reserved at -// the beginning of every global object's slots for use by the -// application. -#define JSCLASS_GLOBAL_APPLICATION_SLOTS 5 -#define JSCLASS_GLOBAL_SLOT_COUNT \ - (JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 39) -#define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \ - (JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n))) -#define JSCLASS_GLOBAL_FLAGS \ - JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(0) -#define JSCLASS_HAS_GLOBAL_FLAG_AND_SLOTS(clasp) \ - (((clasp)->flags & JSCLASS_IS_GLOBAL) \ - && JSCLASS_RESERVED_SLOTS(clasp) >= JSCLASS_GLOBAL_SLOT_COUNT) - -// Fast access to the original value of each standard class's prototype. -#define JSCLASS_CACHED_PROTO_SHIFT (JSCLASS_HIGH_FLAGS_SHIFT + 10) -#define JSCLASS_CACHED_PROTO_MASK JS_BITMASK(js::JSCLASS_CACHED_PROTO_WIDTH) -#define JSCLASS_HAS_CACHED_PROTO(key) (uint32_t(key) << JSCLASS_CACHED_PROTO_SHIFT) -#define JSCLASS_CACHED_PROTO_KEY(clasp) ((JSProtoKey) \ - (((clasp)->flags \ - >> JSCLASS_CACHED_PROTO_SHIFT) \ - & JSCLASS_CACHED_PROTO_MASK)) - -// Initializer for unused members of statically initialized JSClass structs. -#define JSCLASS_NO_INTERNAL_MEMBERS {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} -#define JSCLASS_NO_OPTIONAL_MEMBERS 0,0,0,0,0,JSCLASS_NO_INTERNAL_MEMBERS - -namespace js { - -struct Class -{ - JS_CLASS_MEMBERS(js::ClassOps, FreeOp); - const ClassSpec* spec; - const ClassExtension* ext; - const ObjectOps* oOps; - - /* - * Objects of this class aren't native objects. They don't have Shapes that - * describe their properties and layout. Classes using this flag must - * provide their own property behavior, either by being proxy classes (do - * this) or by overriding all the ObjectOps except getElements, watch and - * unwatch (don't do this). - */ - static const uint32_t NON_NATIVE = JSCLASS_INTERNAL_FLAG2; - - bool isNative() const { - return !(flags & NON_NATIVE); - } - - bool hasPrivate() const { - return !!(flags & JSCLASS_HAS_PRIVATE); - } - - bool emulatesUndefined() const { - return flags & JSCLASS_EMULATES_UNDEFINED; - } - - bool isJSFunction() const { - return this == js::FunctionClassPtr; - } - - bool nonProxyCallable() const { - MOZ_ASSERT(!isProxy()); - return isJSFunction() || getCall(); - } - - bool isProxy() const { - return flags & JSCLASS_IS_PROXY; - } - - bool isDOMClass() const { - return flags & JSCLASS_IS_DOMJSCLASS; - } - - bool shouldDelayMetadataBuilder() const { - return flags & JSCLASS_DELAY_METADATA_BUILDER; - } - - bool isWrappedNative() const { - return flags & JSCLASS_IS_WRAPPED_NATIVE; - } - - static size_t offsetOfFlags() { return offsetof(Class, flags); } - - bool specDefined() const { return spec ? spec->defined() : false; } - JSProtoKey specInheritanceProtoKey() - const { return spec ? spec->inheritanceProtoKey() : JSProto_Null; } - bool specShouldDefineConstructor() - const { return spec ? spec->shouldDefineConstructor() : true; } - ClassObjectCreationOp specCreateConstructorHook() - const { return spec ? spec->createConstructorHook() : nullptr; } - ClassObjectCreationOp specCreatePrototypeHook() - const { return spec ? spec->createPrototypeHook() : nullptr; } - const JSFunctionSpec* specConstructorFunctions() - const { return spec ? spec->constructorFunctions() : nullptr; } - const JSPropertySpec* specConstructorProperties() - const { return spec ? spec->constructorProperties() : nullptr; } - const JSFunctionSpec* specPrototypeFunctions() - const { return spec ? spec->prototypeFunctions() : nullptr; } - const JSPropertySpec* specPrototypeProperties() - const { return spec ? spec->prototypeProperties() : nullptr; } - FinishClassInitOp specFinishInitHook() - const { return spec ? spec->finishInitHook() : nullptr; } - - JSWeakmapKeyDelegateOp extWeakmapKeyDelegateOp() - const { return ext ? ext->weakmapKeyDelegateOp : nullptr; } - JSObjectMovedOp extObjectMovedOp() - const { return ext ? ext->objectMovedOp : nullptr; } - - LookupPropertyOp getOpsLookupProperty() const { return oOps ? oOps->lookupProperty : nullptr; } - DefinePropertyOp getOpsDefineProperty() const { return oOps ? oOps->defineProperty : nullptr; } - HasPropertyOp getOpsHasProperty() const { return oOps ? oOps->hasProperty : nullptr; } - GetPropertyOp getOpsGetProperty() const { return oOps ? oOps->getProperty : nullptr; } - SetPropertyOp getOpsSetProperty() const { return oOps ? oOps->setProperty : nullptr; } - GetOwnPropertyOp getOpsGetOwnPropertyDescriptor() - const { return oOps ? oOps->getOwnPropertyDescriptor - : nullptr; } - DeletePropertyOp getOpsDeleteProperty() const { return oOps ? oOps->deleteProperty : nullptr; } - WatchOp getOpsWatch() const { return oOps ? oOps->watch : nullptr; } - UnwatchOp getOpsUnwatch() const { return oOps ? oOps->unwatch : nullptr; } - GetElementsOp getOpsGetElements() const { return oOps ? oOps->getElements : nullptr; } - JSNewEnumerateOp getOpsEnumerate() const { return oOps ? oOps->enumerate : nullptr; } - JSFunToStringOp getOpsFunToString() const { return oOps ? oOps->funToString : nullptr; } -}; - -static_assert(offsetof(JSClassOps, addProperty) == offsetof(ClassOps, addProperty), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, delProperty) == offsetof(ClassOps, delProperty), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, getProperty) == offsetof(ClassOps, getProperty), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, setProperty) == offsetof(ClassOps, setProperty), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, enumerate) == offsetof(ClassOps, enumerate), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, resolve) == offsetof(ClassOps, resolve), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, mayResolve) == offsetof(ClassOps, mayResolve), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, finalize) == offsetof(ClassOps, finalize), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, call) == offsetof(ClassOps, call), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, construct) == offsetof(ClassOps, construct), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, hasInstance) == offsetof(ClassOps, hasInstance), - "ClassOps and JSClassOps must be consistent"); -static_assert(offsetof(JSClassOps, trace) == offsetof(ClassOps, trace), - "ClassOps and JSClassOps must be consistent"); -static_assert(sizeof(JSClassOps) == sizeof(ClassOps), - "ClassOps and JSClassOps must be consistent"); - -static_assert(offsetof(JSClass, name) == offsetof(Class, name), - "Class and JSClass must be consistent"); -static_assert(offsetof(JSClass, flags) == offsetof(Class, flags), - "Class and JSClass must be consistent"); -static_assert(offsetof(JSClass, cOps) == offsetof(Class, cOps), - "Class and JSClass must be consistent"); -static_assert(sizeof(JSClass) == sizeof(Class), - "Class and JSClass must be consistent"); - -static MOZ_ALWAYS_INLINE const JSClass* -Jsvalify(const Class* c) -{ - return (const JSClass*)c; -} - -static MOZ_ALWAYS_INLINE const Class* -Valueify(const JSClass* c) -{ - return (const Class*)c; -} - -/** - * Enumeration describing possible values of the [[Class]] internal property - * value of objects. - */ -enum class ESClass { - Object, - Array, - Number, - String, - Boolean, - RegExp, - ArrayBuffer, - SharedArrayBuffer, - Date, - Set, - Map, - Promise, - MapIterator, - SetIterator, - Arguments, - Error, - - /** None of the above. */ - Other -}; - -/* Fills |vp| with the unboxed value for boxed types, or undefined otherwise. */ -bool -Unbox(JSContext* cx, JS::HandleObject obj, JS::MutableHandleValue vp); - -#ifdef DEBUG -JS_FRIEND_API(bool) -HasObjectMovedOp(JSObject* obj); -#endif - -} /* namespace js */ - -#endif /* js_Class_h */ diff --git a/android/x86/include/spidermonkey/js/Conversions.h b/android/x86/include/spidermonkey/js/Conversions.h deleted file mode 100644 index 1cee31c5..00000000 --- a/android/x86/include/spidermonkey/js/Conversions.h +++ /dev/null @@ -1,581 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* ECMAScript conversion operations. */ - -#ifndef js_Conversions_h -#define js_Conversions_h - -#include "mozilla/Casting.h" -#include "mozilla/FloatingPoint.h" -#include "mozilla/TypeTraits.h" - -#include - -#include "jspubtd.h" - -#include "js/RootingAPI.h" -#include "js/Value.h" - -struct JSContext; - -namespace js { - -/* DO NOT CALL THIS. Use JS::ToBoolean. */ -extern JS_PUBLIC_API(bool) -ToBooleanSlow(JS::HandleValue v); - -/* DO NOT CALL THIS. Use JS::ToNumber. */ -extern JS_PUBLIC_API(bool) -ToNumberSlow(JSContext* cx, JS::HandleValue v, double* dp); - -/* DO NOT CALL THIS. Use JS::ToInt8. */ -extern JS_PUBLIC_API(bool) -ToInt8Slow(JSContext *cx, JS::HandleValue v, int8_t *out); - -/* DO NOT CALL THIS. Use JS::ToUint8. */ -extern JS_PUBLIC_API(bool) -ToUint8Slow(JSContext *cx, JS::HandleValue v, uint8_t *out); - -/* DO NOT CALL THIS. Use JS::ToInt16. */ -extern JS_PUBLIC_API(bool) -ToInt16Slow(JSContext *cx, JS::HandleValue v, int16_t *out); - -/* DO NOT CALL THIS. Use JS::ToInt32. */ -extern JS_PUBLIC_API(bool) -ToInt32Slow(JSContext* cx, JS::HandleValue v, int32_t* out); - -/* DO NOT CALL THIS. Use JS::ToUint32. */ -extern JS_PUBLIC_API(bool) -ToUint32Slow(JSContext* cx, JS::HandleValue v, uint32_t* out); - -/* DO NOT CALL THIS. Use JS::ToUint16. */ -extern JS_PUBLIC_API(bool) -ToUint16Slow(JSContext* cx, JS::HandleValue v, uint16_t* out); - -/* DO NOT CALL THIS. Use JS::ToInt64. */ -extern JS_PUBLIC_API(bool) -ToInt64Slow(JSContext* cx, JS::HandleValue v, int64_t* out); - -/* DO NOT CALL THIS. Use JS::ToUint64. */ -extern JS_PUBLIC_API(bool) -ToUint64Slow(JSContext* cx, JS::HandleValue v, uint64_t* out); - -/* DO NOT CALL THIS. Use JS::ToString. */ -extern JS_PUBLIC_API(JSString*) -ToStringSlow(JSContext* cx, JS::HandleValue v); - -/* DO NOT CALL THIS. Use JS::ToObject. */ -extern JS_PUBLIC_API(JSObject*) -ToObjectSlow(JSContext* cx, JS::HandleValue v, bool reportScanStack); - -} // namespace js - -namespace JS { - -namespace detail { - -#ifdef JS_DEBUG -/** - * Assert that we're not doing GC on cx, that we're in a request as - * needed, and that the compartments for cx and v are correct. - * Also check that GC would be safe at this point. - */ -extern JS_PUBLIC_API(void) -AssertArgumentsAreSane(JSContext* cx, HandleValue v); -#else -inline void AssertArgumentsAreSane(JSContext* cx, HandleValue v) -{} -#endif /* JS_DEBUG */ - -} // namespace detail - -/** - * ES6 draft 20141224, 7.1.1, second algorithm. - * - * Most users shouldn't call this -- use JS::ToBoolean, ToNumber, or ToString - * instead. This will typically only be called from custom convert hooks that - * wish to fall back to the ES6 default conversion behavior shared by most - * objects in JS, codified as OrdinaryToPrimitive. - */ -extern JS_PUBLIC_API(bool) -OrdinaryToPrimitive(JSContext* cx, HandleObject obj, JSType type, MutableHandleValue vp); - -/* ES6 draft 20141224, 7.1.2. */ -MOZ_ALWAYS_INLINE bool -ToBoolean(HandleValue v) -{ - if (v.isBoolean()) - return v.toBoolean(); - if (v.isInt32()) - return v.toInt32() != 0; - if (v.isNullOrUndefined()) - return false; - if (v.isDouble()) { - double d = v.toDouble(); - return !mozilla::IsNaN(d) && d != 0; - } - if (v.isSymbol()) - return true; - - /* The slow path handles strings and objects. */ - return js::ToBooleanSlow(v); -} - -/* ES6 draft 20141224, 7.1.3. */ -MOZ_ALWAYS_INLINE bool -ToNumber(JSContext* cx, HandleValue v, double* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isNumber()) { - *out = v.toNumber(); - return true; - } - return js::ToNumberSlow(cx, v, out); -} - -/* ES6 draft 20141224, ToInteger (specialized for doubles). */ -inline double -ToInteger(double d) -{ - if (d == 0) - return d; - - if (!mozilla::IsFinite(d)) { - if (mozilla::IsNaN(d)) - return 0; - return d; - } - - return d < 0 ? ceil(d) : floor(d); -} - -/* ES6 draft 20141224, 7.1.5. */ -MOZ_ALWAYS_INLINE bool -ToInt32(JSContext* cx, JS::HandleValue v, int32_t* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = v.toInt32(); - return true; - } - return js::ToInt32Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.6. */ -MOZ_ALWAYS_INLINE bool -ToUint32(JSContext* cx, HandleValue v, uint32_t* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = uint32_t(v.toInt32()); - return true; - } - return js::ToUint32Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.7. */ -MOZ_ALWAYS_INLINE bool -ToInt16(JSContext *cx, JS::HandleValue v, int16_t *out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = int16_t(v.toInt32()); - return true; - } - return js::ToInt16Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.8. */ -MOZ_ALWAYS_INLINE bool -ToUint16(JSContext* cx, HandleValue v, uint16_t* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = uint16_t(v.toInt32()); - return true; - } - return js::ToUint16Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.9 */ -MOZ_ALWAYS_INLINE bool -ToInt8(JSContext *cx, JS::HandleValue v, int8_t *out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = int8_t(v.toInt32()); - return true; - } - return js::ToInt8Slow(cx, v, out); -} - -/* ES6 ECMA-262, 7.1.10 */ -MOZ_ALWAYS_INLINE bool -ToUint8(JSContext *cx, JS::HandleValue v, uint8_t *out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = uint8_t(v.toInt32()); - return true; - } - return js::ToUint8Slow(cx, v, out); -} - -/* - * Non-standard, with behavior similar to that of ToInt32, except in its - * producing an int64_t. - */ -MOZ_ALWAYS_INLINE bool -ToInt64(JSContext* cx, HandleValue v, int64_t* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = int64_t(v.toInt32()); - return true; - } - return js::ToInt64Slow(cx, v, out); -} - -/* - * Non-standard, with behavior similar to that of ToUint32, except in its - * producing a uint64_t. - */ -MOZ_ALWAYS_INLINE bool -ToUint64(JSContext* cx, HandleValue v, uint64_t* out) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = uint64_t(v.toInt32()); - return true; - } - return js::ToUint64Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.12. */ -MOZ_ALWAYS_INLINE JSString* -ToString(JSContext* cx, HandleValue v) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isString()) - return v.toString(); - return js::ToStringSlow(cx, v); -} - -/* ES6 draft 20141224, 7.1.13. */ -inline JSObject* -ToObject(JSContext* cx, HandleValue v) -{ - detail::AssertArgumentsAreSane(cx, v); - - if (v.isObject()) - return &v.toObject(); - return js::ToObjectSlow(cx, v, false); -} - -namespace detail { - -/* - * Convert a double value to ResultType (an unsigned integral type) using - * ECMAScript-style semantics (that is, in like manner to how ECMAScript's - * ToInt32 converts to int32_t). - * - * If d is infinite or NaN, return 0. - * Otherwise compute d2 = sign(d) * floor(abs(d)), and return the ResultType - * value congruent to d2 mod 2**(bit width of ResultType). - * - * The algorithm below is inspired by that found in - * - * but has been generalized to all integer widths. - */ -template -inline ResultType -ToUintWidth(double d) -{ - static_assert(mozilla::IsUnsigned::value, - "ResultType must be an unsigned type"); - - uint64_t bits = mozilla::BitwiseCast(d); - unsigned DoubleExponentShift = mozilla::FloatingPoint::kExponentShift; - - // Extract the exponent component. (Be careful here! It's not technically - // the exponent in NaN, infinities, and subnormals.) - int_fast16_t exp = - int_fast16_t((bits & mozilla::FloatingPoint::kExponentBits) >> DoubleExponentShift) - - int_fast16_t(mozilla::FloatingPoint::kExponentBias); - - // If the exponent's less than zero, abs(d) < 1, so the result is 0. (This - // also handles subnormals.) - if (exp < 0) - return 0; - - uint_fast16_t exponent = mozilla::AssertedCast(exp); - - // If the exponent is greater than or equal to the bits of precision of a - // double plus ResultType's width, the number is either infinite, NaN, or - // too large to have lower-order bits in the congruent value. (Example: - // 2**84 is exactly representable as a double. The next exact double is - // 2**84 + 2**32. Thus if ResultType is int32_t, an exponent >= 84 implies - // floor(abs(d)) == 0 mod 2**32.) Return 0 in all these cases. - const size_t ResultWidth = CHAR_BIT * sizeof(ResultType); - if (exponent >= DoubleExponentShift + ResultWidth) - return 0; - - // The significand contains the bits that will determine the final result. - // Shift those bits left or right, according to the exponent, to their - // locations in the unsigned binary representation of floor(abs(d)). - static_assert(sizeof(ResultType) <= sizeof(uint64_t), - "Left-shifting below would lose upper bits"); - ResultType result = (exponent > DoubleExponentShift) - ? ResultType(bits << (exponent - DoubleExponentShift)) - : ResultType(bits >> (DoubleExponentShift - exponent)); - - // Two further complications remain. First, |result| may contain bogus - // sign/exponent bits. Second, IEEE-754 numbers' significands (excluding - // subnormals, but we already handled those) have an implicit leading 1 - // which may affect the final result. - // - // It may appear that there's complexity here depending on how ResultWidth - // and DoubleExponentShift relate, but it turns out there's not. - // - // Assume ResultWidth < DoubleExponentShift: - // Only right-shifts leave bogus bits in |result|. For this to happen, - // we must right-shift by > |DoubleExponentShift - ResultWidth|, implying - // |exponent < ResultWidth|. - // The implicit leading bit only matters if it appears in the final - // result -- if |2**exponent mod 2**ResultWidth != 0|. This implies - // |exponent < ResultWidth|. - // Otherwise assume ResultWidth >= DoubleExponentShift: - // Any left-shift less than |ResultWidth - DoubleExponentShift| leaves - // bogus bits in |result|. This implies |exponent < ResultWidth|. Any - // right-shift less than |ResultWidth| does too, which implies - // |DoubleExponentShift - ResultWidth < exponent|. By assumption, then, - // |exponent| is negative, but we excluded that above. So bogus bits - // need only |exponent < ResultWidth|. - // The implicit leading bit matters identically to the other case, so - // again, |exponent < ResultWidth|. - if (exponent < ResultWidth) { - ResultType implicitOne = ResultType(1) << exponent; - result &= implicitOne - 1; // remove bogus bits - result += implicitOne; // add the implicit bit - } - - // Compute the congruent value in the signed range. - return (bits & mozilla::FloatingPoint::kSignBit) ? ~result + 1 : result; -} - -template -inline ResultType -ToIntWidth(double d) -{ - static_assert(mozilla::IsSigned::value, - "ResultType must be a signed type"); - - const ResultType MaxValue = (1ULL << (CHAR_BIT * sizeof(ResultType) - 1)) - 1; - const ResultType MinValue = -MaxValue - 1; - - typedef typename mozilla::MakeUnsigned::Type UnsignedResult; - UnsignedResult u = ToUintWidth(d); - if (u <= UnsignedResult(MaxValue)) - return static_cast(u); - return (MinValue + static_cast(u - MaxValue)) - 1; -} - -} // namespace detail - -/* ES5 9.5 ToInt32 (specialized for doubles). */ -inline int32_t -ToInt32(double d) -{ - // clang crashes compiling this when targeting arm: - // https://llvm.org/bugs/show_bug.cgi?id=22974 -#if defined (__arm__) && defined (__GNUC__) && !defined(__clang__) - int32_t i; - uint32_t tmp0; - uint32_t tmp1; - uint32_t tmp2; - asm ( - // We use a pure integer solution here. In the 'softfp' ABI, the argument - // will start in r0 and r1, and VFP can't do all of the necessary ECMA - // conversions by itself so some integer code will be required anyway. A - // hybrid solution is faster on A9, but this pure integer solution is - // notably faster for A8. - - // %0 is the result register, and may alias either of the %[QR]1 registers. - // %Q4 holds the lower part of the mantissa. - // %R4 holds the sign, exponent, and the upper part of the mantissa. - // %1, %2 and %3 are used as temporary values. - - // Extract the exponent. -" mov %1, %R4, LSR #20\n" -" bic %1, %1, #(1 << 11)\n" // Clear the sign. - - // Set the implicit top bit of the mantissa. This clobbers a bit of the - // exponent, but we have already extracted that. -" orr %R4, %R4, #(1 << 20)\n" - - // Special Cases - // We should return zero in the following special cases: - // - Exponent is 0x000 - 1023: +/-0 or subnormal. - // - Exponent is 0x7ff - 1023: +/-INFINITY or NaN - // - This case is implicitly handled by the standard code path anyway, - // as shifting the mantissa up by the exponent will result in '0'. - // - // The result is composed of the mantissa, prepended with '1' and - // bit-shifted left by the (decoded) exponent. Note that because the r1[20] - // is the bit with value '1', r1 is effectively already shifted (left) by - // 20 bits, and r0 is already shifted by 52 bits. - - // Adjust the exponent to remove the encoding offset. If the decoded - // exponent is negative, quickly bail out with '0' as such values round to - // zero anyway. This also catches +/-0 and subnormals. -" sub %1, %1, #0xff\n" -" subs %1, %1, #0x300\n" -" bmi 8f\n" - - // %1 = (decoded) exponent >= 0 - // %R4 = upper mantissa and sign - - // ---- Lower Mantissa ---- -" subs %3, %1, #52\n" // Calculate exp-52 -" bmi 1f\n" - - // Shift r0 left by exp-52. - // Ensure that we don't overflow ARM's 8-bit shift operand range. - // We need to handle anything up to an 11-bit value here as we know that - // 52 <= exp <= 1024 (0x400). Any shift beyond 31 bits results in zero - // anyway, so as long as we don't touch the bottom 5 bits, we can use - // a logical OR to push long shifts into the 32 <= (exp&0xff) <= 255 range. -" bic %2, %3, #0xff\n" -" orr %3, %3, %2, LSR #3\n" - // We can now perform a straight shift, avoiding the need for any - // conditional instructions or extra branches. -" mov %Q4, %Q4, LSL %3\n" -" b 2f\n" -"1:\n" // Shift r0 right by 52-exp. - // We know that 0 <= exp < 52, and we can shift up to 255 bits so 52-exp - // will always be a valid shift and we can sk%3 the range check for this case. -" rsb %3, %1, #52\n" -" mov %Q4, %Q4, LSR %3\n" - - // %1 = (decoded) exponent - // %R4 = upper mantissa and sign - // %Q4 = partially-converted integer - -"2:\n" - // ---- Upper Mantissa ---- - // This is much the same as the lower mantissa, with a few different - // boundary checks and some masking to hide the exponent & sign bit in the - // upper word. - // Note that the upper mantissa is pre-shifted by 20 in %R4, but we shift - // it left more to remove the sign and exponent so it is effectively - // pre-shifted by 31 bits. -" subs %3, %1, #31\n" // Calculate exp-31 -" mov %1, %R4, LSL #11\n" // Re-use %1 as a temporary register. -" bmi 3f\n" - - // Shift %R4 left by exp-31. - // Avoid overflowing the 8-bit shift range, as before. -" bic %2, %3, #0xff\n" -" orr %3, %3, %2, LSR #3\n" - // Perform the shift. -" mov %2, %1, LSL %3\n" -" b 4f\n" -"3:\n" // Shift r1 right by 31-exp. - // We know that 0 <= exp < 31, and we can shift up to 255 bits so 31-exp - // will always be a valid shift and we can skip the range check for this case. -" rsb %3, %3, #0\n" // Calculate 31-exp from -(exp-31) -" mov %2, %1, LSR %3\n" // Thumb-2 can't do "LSR %3" in "orr". - - // %Q4 = partially-converted integer (lower) - // %R4 = upper mantissa and sign - // %2 = partially-converted integer (upper) - -"4:\n" - // Combine the converted parts. -" orr %Q4, %Q4, %2\n" - // Negate the result if we have to, and move it to %0 in the process. To - // avoid conditionals, we can do this by inverting on %R4[31], then adding - // %R4[31]>>31. -" eor %Q4, %Q4, %R4, ASR #31\n" -" add %0, %Q4, %R4, LSR #31\n" -" b 9f\n" -"8:\n" - // +/-INFINITY, +/-0, subnormals, NaNs, and anything else out-of-range that - // will result in a conversion of '0'. -" mov %0, #0\n" -"9:\n" - : "=r" (i), "=&r" (tmp0), "=&r" (tmp1), "=&r" (tmp2), "=&r" (d) - : "4" (d) - : "cc" - ); - return i; -#else - return detail::ToIntWidth(d); -#endif -} - -/* ES5 9.6 (specialized for doubles). */ -inline uint32_t -ToUint32(double d) -{ - return detail::ToUintWidth(d); -} - -/* WEBIDL 4.2.4 */ -inline int8_t -ToInt8(double d) -{ - return detail::ToIntWidth(d); -} - -/* ECMA-262 7.1.10 ToUInt8() specialized for doubles. */ -inline int8_t -ToUint8(double d) -{ - return detail::ToUintWidth(d); -} - -/* WEBIDL 4.2.6 */ -inline int16_t -ToInt16(double d) -{ - return detail::ToIntWidth(d); -} - -inline uint16_t -ToUint16(double d) -{ - return detail::ToUintWidth(d); -} - -/* WEBIDL 4.2.10 */ -inline int64_t -ToInt64(double d) -{ - return detail::ToIntWidth(d); -} - -/* WEBIDL 4.2.11 */ -inline uint64_t -ToUint64(double d) -{ - return detail::ToUintWidth(d); -} - -} // namespace JS - -#endif /* js_Conversions_h */ diff --git a/android/x86/include/spidermonkey/js/Date.h b/android/x86/include/spidermonkey/js/Date.h deleted file mode 100644 index cba0ea87..00000000 --- a/android/x86/include/spidermonkey/js/Date.h +++ /dev/null @@ -1,170 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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/. */ - -/* JavaScript date/time computation and creation functions. */ - -#ifndef js_Date_h -#define js_Date_h - -/* - * Dates in JavaScript are defined by IEEE-754 double precision numbers from - * the set: - * - * { t ∈ ℕ : -8.64e15 ≤ t ≤ +8.64e15 } ∪ { NaN } - * - * The single NaN value represents any invalid-date value. All other values - * represent idealized durations in milliseconds since the UTC epoch. (Leap - * seconds are ignored; leap days are not.) +0 is the only zero in this set. - * The limit represented by 8.64e15 milliseconds is 100 million days either - * side of 00:00 January 1, 1970 UTC. - * - * Dates in the above set are represented by the |ClippedTime| class. The - * double type is a superset of the above set, so it *may* (but need not) - * represent a date. Use ECMAScript's |TimeClip| method to produce a date from - * a double. - * - * Date *objects* are simply wrappers around |TimeClip|'d numbers, with a bunch - * of accessor methods to the various aspects of the represented date. - */ - -#include "mozilla/FloatingPoint.h" -#include "mozilla/MathAlgorithms.h" - -#include "js/Conversions.h" -#include "js/Value.h" - -struct JSContext; - -namespace JS { - -/** - * Re-query the system to determine the current time zone adjustment from UTC, - * including any component due to DST. If the time zone has changed, this will - * cause all Date object non-UTC methods and formatting functions to produce - * appropriately adjusted results. - * - * Left to its own devices, SpiderMonkey itself may occasionally call this - * method to attempt to keep up with system time changes. However, no - * particular frequency of checking is guaranteed. Embedders unable to accept - * occasional inaccuracies should call this method in response to system time - * changes, or immediately before operations requiring instantaneous - * correctness, to guarantee correct behavior. - */ -extern JS_PUBLIC_API(void) -ResetTimeZone(); - -class ClippedTime; -inline ClippedTime TimeClip(double time); - -/* - * |ClippedTime| represents the limited subset of dates/times described above. - * - * An invalid date/time may be created through the |ClippedTime::invalid| - * method. Otherwise, a |ClippedTime| may be created using the |TimeClip| - * method. - * - * In typical use, the user might wish to manipulate a timestamp. The user - * performs a series of operations on it, but the final value might not be a - * date as defined above -- it could have overflowed, acquired a fractional - * component, &c. So as a *final* step, the user passes that value through - * |TimeClip| to produce a number restricted to JavaScript's date range. - * - * APIs that accept a JavaScript date value thus accept a |ClippedTime|, not a - * double. This ensures that date/time APIs will only ever receive acceptable - * JavaScript dates. This also forces users to perform any desired clipping, - * as only the user knows what behavior is desired when clipping occurs. - */ -class ClippedTime -{ - double t; - - explicit ClippedTime(double time) : t(time) {} - friend ClippedTime TimeClip(double time); - - public: - // Create an invalid date. - ClippedTime() : t(mozilla::UnspecifiedNaN()) {} - - // Create an invalid date/time, more explicitly; prefer this to the default - // constructor. - static ClippedTime invalid() { return ClippedTime(); } - - double toDouble() const { return t; } - - bool isValid() const { return !mozilla::IsNaN(t); } -}; - -// ES6 20.3.1.15. -// -// Clip a double to JavaScript's date range (or to an invalid date) using the -// ECMAScript TimeClip algorithm. -inline ClippedTime -TimeClip(double time) -{ - // Steps 1-2. - const double MaxTimeMagnitude = 8.64e15; - if (!mozilla::IsFinite(time) || mozilla::Abs(time) > MaxTimeMagnitude) - return ClippedTime(mozilla::UnspecifiedNaN()); - - // Step 3. - return ClippedTime(ToInteger(time) + (+0.0)); -} - -// Produce a double Value from the given time. Because times may be NaN, -// prefer using this to manual canonicalization. -inline Value -TimeValue(ClippedTime time) -{ - return DoubleValue(JS::CanonicalizeNaN(time.toDouble())); -} - -// Create a new Date object whose [[DateValue]] internal slot contains the -// clipped |time|. (Users who must represent times outside that range must use -// another representation.) -extern JS_PUBLIC_API(JSObject*) -NewDateObject(JSContext* cx, ClippedTime time); - -// Year is a year, month is 0-11, day is 1-based. The return value is a number -// of milliseconds since the epoch. -// -// Consistent with the MakeDate algorithm defined in ECMAScript, this value is -// *not* clipped! Use JS::TimeClip if you need a clipped date. -JS_PUBLIC_API(double) -MakeDate(double year, unsigned month, unsigned day); - -// Takes an integer number of milliseconds since the epoch and returns the -// year. Can return NaN, and will do so if NaN is passed in. -JS_PUBLIC_API(double) -YearFromTime(double time); - -// Takes an integer number of milliseconds since the epoch and returns the -// month (0-11). Can return NaN, and will do so if NaN is passed in. -JS_PUBLIC_API(double) -MonthFromTime(double time); - -// Takes an integer number of milliseconds since the epoch and returns the -// day (1-based). Can return NaN, and will do so if NaN is passed in. -JS_PUBLIC_API(double) -DayFromTime(double time); - -// Takes an integer year and returns the number of days from epoch to the given -// year. -// NOTE: The calculation performed by this function is literally that given in -// the ECMAScript specification. Nonfinite years, years containing fractional -// components, and years outside ECMAScript's date range are not handled with -// any particular intelligence. Garbage in, garbage out. -JS_PUBLIC_API(double) -DayFromYear(double year); - -// Takes an integer number of milliseconds since the epoch and an integer year, -// returns the number of days in that year. If |time| is nonfinite, returns NaN. -// Otherwise |time| *must* correspond to a time within the valid year |year|. -// This should usually be ensured by computing |year| as |JS::DayFromYear(time)|. -JS_PUBLIC_API(double) -DayWithinYear(double time, double year); - -} // namespace JS - -#endif /* js_Date_h */ diff --git a/android/x86/include/spidermonkey/js/Debug.h b/android/x86/include/spidermonkey/js/Debug.h deleted file mode 100644 index 3e4183f0..00000000 --- a/android/x86/include/spidermonkey/js/Debug.h +++ /dev/null @@ -1,384 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -// Interfaces by which the embedding can interact with the Debugger API. - -#ifndef js_Debug_h -#define js_Debug_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/MemoryReporting.h" - -#include "jsapi.h" -#include "jspubtd.h" - -#include "js/GCAPI.h" -#include "js/RootingAPI.h" -#include "js/TypeDecls.h" - -namespace js { -class Debugger; -} // namespace js - -namespace JS { -namespace dbg { - -// Helping embedding code build objects for Debugger -// ------------------------------------------------- -// -// Some Debugger API features lean on the embedding application to construct -// their result values. For example, Debugger.Frame.prototype.scriptEntryReason -// calls hooks provided by the embedding to construct values explaining why it -// invoked JavaScript; if F is a frame called from a mouse click event handler, -// F.scriptEntryReason would return an object of the form: -// -// { eventType: "mousedown", event: } -// -// where is a Debugger.Object whose referent is the event being -// dispatched. -// -// However, Debugger implements a trust boundary. Debuggee code may be -// considered untrusted; debugger code needs to be protected from debuggee -// getters, setters, proxies, Object.watch watchpoints, and any other feature -// that might accidentally cause debugger code to set the debuggee running. The -// Debugger API tries to make it easy to write safe debugger code by only -// offering access to debuggee objects via Debugger.Object instances, which -// ensure that only those operations whose explicit purpose is to invoke -// debuggee code do so. But this protective membrane is only helpful if we -// interpose Debugger.Object instances in all the necessary spots. -// -// SpiderMonkey's compartment system also implements a trust boundary. The -// debuggee and debugger are always in different compartments. Inter-compartment -// work requires carefully tracking which compartment each JSObject or JS::Value -// belongs to, and ensuring that is is correctly wrapped for each operation. -// -// It seems precarious to expect the embedding's hooks to implement these trust -// boundaries. Instead, the JS::dbg::Builder API segregates the code which -// constructs trusted objects from that which deals with untrusted objects. -// Trusted objects have an entirely different C++ type, so code that improperly -// mixes trusted and untrusted objects is caught at compile time. -// -// In the structure shown above, there are two trusted objects, and one -// untrusted object: -// -// - The overall object, with the 'eventType' and 'event' properties, is a -// trusted object. We're going to return it to D.F.p.scriptEntryReason's -// caller, which will handle it directly. -// -// - The Debugger.Object instance appearing as the value of the 'event' property -// is a trusted object. It belongs to the same Debugger instance as the -// Debugger.Frame instance whose scriptEntryReason accessor was called, and -// presents a safe reflection-oriented API for inspecting its referent, which -// is: -// -// - The actual event object, an untrusted object, and the referent of the -// Debugger.Object above. (Content can do things like replacing accessors on -// Event.prototype.) -// -// Using JS::dbg::Builder, all objects and values the embedding deals with -// directly are considered untrusted, and are assumed to be debuggee values. The -// only way to construct trusted objects is to use Builder's own methods, which -// return a separate Object type. The only way to set a property on a trusted -// object is through that Object type. The actual trusted object is never -// exposed to the embedding. -// -// So, for example, the embedding might use code like the following to construct -// the object shown above, given a Builder passed to it by Debugger: -// -// bool -// MyScriptEntryReason::explain(JSContext* cx, -// Builder& builder, -// Builder::Object& result) -// { -// JSObject* eventObject = ... obtain debuggee event object somehow ...; -// if (!eventObject) -// return false; -// result = builder.newObject(cx); -// return result && -// result.defineProperty(cx, "eventType", SafelyFetchType(eventObject)) && -// result.defineProperty(cx, "event", eventObject); -// } -// -// -// Object::defineProperty also accepts an Object as the value to store on the -// property. By its type, we know that the value is trusted, so we set it -// directly as the property's value, without interposing a Debugger.Object -// wrapper. This allows the embedding to builted nested structures of trusted -// objects. -// -// The Builder and Builder::Object methods take care of doing whatever -// compartment switching and wrapping are necessary to construct the trusted -// values in the Debugger's compartment. -// -// The Object type is self-rooting. Construction, assignment, and destruction -// all properly root the referent object. - -class BuilderOrigin; - -class Builder { - // The Debugger instance whose client we are building a value for. We build - // objects in this object's compartment. - PersistentRootedObject debuggerObject; - - // debuggerObject's Debugger structure, for convenience. - js::Debugger* debugger; - - // Check that |thing| is in the same compartment as our debuggerObject. Used - // for assertions when constructing BuiltThings. We can overload this as we - // add more instantiations of BuiltThing. -#if DEBUG - void assertBuilt(JSObject* obj); -#else - void assertBuilt(JSObject* obj) { } -#endif - - protected: - // A reference to a trusted object or value. At the moment, we only use it - // with JSObject*. - template - class BuiltThing { - friend class BuilderOrigin; - - protected: - // The Builder to which this trusted thing belongs. - Builder& owner; - - // A rooted reference to our value. - PersistentRooted value; - - BuiltThing(JSContext* cx, Builder& owner_, T value_ = GCPolicy::initial()) - : owner(owner_), value(cx, value_) - { - owner.assertBuilt(value_); - } - - // Forward some things from our owner, for convenience. - js::Debugger* debugger() const { return owner.debugger; } - JSObject* debuggerObject() const { return owner.debuggerObject; } - - public: - BuiltThing(const BuiltThing& rhs) : owner(rhs.owner), value(rhs.value) { } - BuiltThing& operator=(const BuiltThing& rhs) { - MOZ_ASSERT(&owner == &rhs.owner); - owner.assertBuilt(rhs.value); - value = rhs.value; - return *this; - } - - explicit operator bool() const { - // If we ever instantiate BuiltThing, this might not suffice. - return value; - } - - private: - BuiltThing() = delete; - }; - - public: - // A reference to a trusted object, possibly null. Instances of Object are - // always properly rooted. They can be copied and assigned, as if they were - // pointers. - class Object: private BuiltThing { - friend class Builder; // for construction - friend class BuilderOrigin; // for unwrapping - - typedef BuiltThing Base; - - // This is private, because only Builders can create Objects that - // actually point to something (hence the 'friend' declaration). - Object(JSContext* cx, Builder& owner_, HandleObject obj) : Base(cx, owner_, obj.get()) { } - - bool definePropertyToTrusted(JSContext* cx, const char* name, - JS::MutableHandleValue value); - - public: - Object(JSContext* cx, Builder& owner_) : Base(cx, owner_, nullptr) { } - Object(const Object& rhs) : Base(rhs) { } - - // Our automatically-generated assignment operator can see our base - // class's assignment operator, so we don't need to write one out here. - - // Set the property named |name| on this object to |value|. - // - // If |value| is a string or primitive, re-wrap it for the debugger's - // compartment. - // - // If |value| is an object, assume it is a debuggee object and make a - // Debugger.Object instance referring to it. Set that as the propery's - // value. - // - // If |value| is another trusted object, store it directly as the - // property's value. - // - // On error, report the problem on cx and return false. - bool defineProperty(JSContext* cx, const char* name, JS::HandleValue value); - bool defineProperty(JSContext* cx, const char* name, JS::HandleObject value); - bool defineProperty(JSContext* cx, const char* name, Object& value); - - using Base::operator bool; - }; - - // Build an empty object for direct use by debugger code, owned by this - // Builder. If an error occurs, report it on cx and return a false Object. - Object newObject(JSContext* cx); - - protected: - Builder(JSContext* cx, js::Debugger* debugger); -}; - -// Debugger itself instantiates this subclass of Builder, which can unwrap -// BuiltThings that belong to it. -class BuilderOrigin : public Builder { - template - T unwrapAny(const BuiltThing& thing) { - MOZ_ASSERT(&thing.owner == this); - return thing.value.get(); - } - - public: - BuilderOrigin(JSContext* cx, js::Debugger* debugger_) - : Builder(cx, debugger_) - { } - - JSObject* unwrap(Object& object) { return unwrapAny(object); } -}; - - - -// Finding the size of blocks allocated with malloc -// ------------------------------------------------ -// -// Debugger.Memory wants to be able to report how many bytes items in memory are -// consuming. To do this, it needs a function that accepts a pointer to a block, -// and returns the number of bytes allocated to that block. SpiderMonkey itself -// doesn't know which function is appropriate to use, but the embedding does. - -// Tell Debuggers in |cx| to use |mallocSizeOf| to find the size of -// malloc'd blocks. -JS_PUBLIC_API(void) -SetDebuggerMallocSizeOf(JSContext* cx, mozilla::MallocSizeOf mallocSizeOf); - -// Get the MallocSizeOf function that the given context is using to find the -// size of malloc'd blocks. -JS_PUBLIC_API(mozilla::MallocSizeOf) -GetDebuggerMallocSizeOf(JSContext* cx); - - - -// Debugger and Garbage Collection Events -// -------------------------------------- -// -// The Debugger wants to report about its debuggees' GC cycles, however entering -// JS after a GC is troublesome since SpiderMonkey will often do something like -// force a GC and then rely on the nursery being empty. If we call into some -// Debugger's hook after the GC, then JS runs and the nursery won't be -// empty. Instead, we rely on embedders to call back into SpiderMonkey after a -// GC and notify Debuggers to call their onGarbageCollection hook. - - -// For each Debugger that observed a debuggee involved in the given GC event, -// call its `onGarbageCollection` hook. -JS_PUBLIC_API(bool) -FireOnGarbageCollectionHook(JSContext* cx, GarbageCollectionEvent::Ptr&& data); - - - -// Handlers for observing Promises -// ------------------------------- -// -// The Debugger wants to observe behavior of promises, which are implemented by -// Gecko with webidl and which SpiderMonkey knows nothing about. On the other -// hand, Gecko knows nothing about which (if any) debuggers are observing a -// promise's global. The compromise is that Gecko is responsible for calling -// these handlers at the appropriate times, and SpiderMonkey will handle -// notifying any Debugger instances that are observing the given promise's -// global. - -// Notify any Debugger instances observing this promise's global that a new -// promise was allocated. -JS_PUBLIC_API(void) -onNewPromise(JSContext* cx, HandleObject promise); - -// Notify any Debugger instances observing this promise's global that the -// promise has settled (ie, it has either been fulfilled or rejected). Note that -// this is *not* equivalent to the promise resolution (ie, the promise's fate -// getting locked in) because you can resolve a promise with another pending -// promise, in which case neither promise has settled yet. -// -// It is Gecko's responsibility to ensure that this is never called on the same -// promise more than once (because a promise can only make the transition from -// unsettled to settled once). -JS_PUBLIC_API(void) -onPromiseSettled(JSContext* cx, HandleObject promise); - - - -// Return true if the given value is a Debugger object, false otherwise. -JS_PUBLIC_API(bool) -IsDebugger(JSObject& obj); - -// Append each of the debuggee global objects observed by the Debugger object -// |dbgObj| to |vector|. Returns true on success, false on failure. -JS_PUBLIC_API(bool) -GetDebuggeeGlobals(JSContext* cx, JSObject& dbgObj, AutoObjectVector& vector); - - -// Hooks for reporting where JavaScript execution began. -// -// Our performance tools would like to be able to label blocks of JavaScript -// execution with the function name and source location where execution began: -// the event handler, the callback, etc. -// -// Construct an instance of this class on the stack, providing a JSContext -// belonging to the runtime in which execution will occur. Each time we enter -// JavaScript --- specifically, each time we push a JavaScript stack frame that -// has no older JS frames younger than this AutoEntryMonitor --- we will -// call the appropriate |Entry| member function to indicate where we've begun -// execution. - -class MOZ_STACK_CLASS AutoEntryMonitor { - JSRuntime* runtime_; - AutoEntryMonitor* savedMonitor_; - - public: - explicit AutoEntryMonitor(JSContext* cx); - ~AutoEntryMonitor(); - - // SpiderMonkey reports the JavaScript entry points occuring within this - // AutoEntryMonitor's scope to the following member functions, which the - // embedding is expected to override. - // - // It is important to note that |asyncCause| is owned by the caller and its - // lifetime must outlive the lifetime of the AutoEntryMonitor object. It is - // strongly encouraged that |asyncCause| be a string constant or similar - // statically allocated string. - - // We have begun executing |function|. Note that |function| may not be the - // actual closure we are running, but only the canonical function object to - // which the script refers. - virtual void Entry(JSContext* cx, JSFunction* function, - HandleValue asyncStack, - const char* asyncCause) = 0; - - // Execution has begun at the entry point of |script|, which is not a - // function body. (This is probably being executed by 'eval' or some - // JSAPI equivalent.) - virtual void Entry(JSContext* cx, JSScript* script, - HandleValue asyncStack, - const char* asyncCause) = 0; - - // Execution of the function or script has ended. - virtual void Exit(JSContext* cx) { } -}; - - - -} // namespace dbg -} // namespace JS - - -#endif /* js_Debug_h */ diff --git a/android/x86/include/spidermonkey/js/GCAPI.h b/android/x86/include/spidermonkey/js/GCAPI.h deleted file mode 100644 index 7a6675ca..00000000 --- a/android/x86/include/spidermonkey/js/GCAPI.h +++ /dev/null @@ -1,723 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_GCAPI_h -#define js_GCAPI_h - -#include "mozilla/Vector.h" - -#include "js/GCAnnotations.h" -#include "js/HeapAPI.h" -#include "js/UniquePtr.h" - -namespace js { -namespace gc { -class GCRuntime; -} // namespace gc -namespace gcstats { -struct Statistics; -} // namespace gcstats -} // namespace js - -typedef enum JSGCMode { - /** Perform only global GCs. */ - JSGC_MODE_GLOBAL = 0, - - /** Perform per-zone GCs until too much garbage has accumulated. */ - JSGC_MODE_ZONE = 1, - - /** - * Collect in short time slices rather than all at once. Implies - * JSGC_MODE_ZONE. - */ - JSGC_MODE_INCREMENTAL = 2 -} JSGCMode; - -/** - * Kinds of js_GC invocation. - */ -typedef enum JSGCInvocationKind { - /* Normal invocation. */ - GC_NORMAL = 0, - - /* Minimize GC triggers and release empty GC chunks right away. */ - GC_SHRINK = 1 -} JSGCInvocationKind; - -namespace JS { - -#define GCREASONS(D) \ - /* Reasons internal to the JS engine */ \ - D(API) \ - D(EAGER_ALLOC_TRIGGER) \ - D(DESTROY_RUNTIME) \ - D(UNUSED0) \ - D(LAST_DITCH) \ - D(TOO_MUCH_MALLOC) \ - D(ALLOC_TRIGGER) \ - D(DEBUG_GC) \ - D(COMPARTMENT_REVIVED) \ - D(RESET) \ - D(OUT_OF_NURSERY) \ - D(EVICT_NURSERY) \ - D(FULL_STORE_BUFFER) \ - D(SHARED_MEMORY_LIMIT) \ - D(UNUSED1) \ - D(INCREMENTAL_TOO_SLOW) \ - D(ABORT_GC) \ - \ - /* These are reserved for future use. */ \ - D(RESERVED0) \ - D(RESERVED1) \ - D(RESERVED2) \ - D(RESERVED3) \ - D(RESERVED4) \ - D(RESERVED5) \ - D(RESERVED6) \ - D(RESERVED7) \ - D(RESERVED8) \ - D(RESERVED9) \ - D(RESERVED10) \ - D(RESERVED11) \ - D(RESERVED12) \ - D(RESERVED13) \ - D(RESERVED14) \ - D(RESERVED15) \ - \ - /* Reasons from Firefox */ \ - D(DOM_WINDOW_UTILS) \ - D(COMPONENT_UTILS) \ - D(MEM_PRESSURE) \ - D(CC_WAITING) \ - D(CC_FORCED) \ - D(LOAD_END) \ - D(POST_COMPARTMENT) \ - D(PAGE_HIDE) \ - D(NSJSCONTEXT_DESTROY) \ - D(SET_NEW_DOCUMENT) \ - D(SET_DOC_SHELL) \ - D(DOM_UTILS) \ - D(DOM_IPC) \ - D(DOM_WORKER) \ - D(INTER_SLICE_GC) \ - D(REFRESH_FRAME) \ - D(FULL_GC_TIMER) \ - D(SHUTDOWN_CC) \ - D(FINISH_LARGE_EVALUATE) \ - D(USER_INACTIVE) \ - D(XPCONNECT_SHUTDOWN) - -namespace gcreason { - -/* GCReasons will end up looking like JSGC_MAYBEGC */ -enum Reason { -#define MAKE_REASON(name) name, - GCREASONS(MAKE_REASON) -#undef MAKE_REASON - NO_REASON, - NUM_REASONS, - - /* - * For telemetry, we want to keep a fixed max bucket size over time so we - * don't have to switch histograms. 100 is conservative; as of this writing - * there are 52. But the cost of extra buckets seems to be low while the - * cost of switching histograms is high. - */ - NUM_TELEMETRY_REASONS = 100 -}; - -/** - * Get a statically allocated C string explaining the given GC reason. - */ -extern JS_PUBLIC_API(const char*) -ExplainReason(JS::gcreason::Reason reason); - -} /* namespace gcreason */ - -/* - * Zone GC: - * - * SpiderMonkey's GC is capable of performing a collection on an arbitrary - * subset of the zones in the system. This allows an embedding to minimize - * collection time by only collecting zones that have run code recently, - * ignoring the parts of the heap that are unlikely to have changed. - * - * When triggering a GC using one of the functions below, it is first necessary - * to select the zones to be collected. To do this, you can call - * PrepareZoneForGC on each zone, or you can call PrepareForFullGC to select - * all zones. Failing to select any zone is an error. - */ - -/** - * Schedule the given zone to be collected as part of the next GC. - */ -extern JS_PUBLIC_API(void) -PrepareZoneForGC(Zone* zone); - -/** - * Schedule all zones to be collected in the next GC. - */ -extern JS_PUBLIC_API(void) -PrepareForFullGC(JSContext* cx); - -/** - * When performing an incremental GC, the zones that were selected for the - * previous incremental slice must be selected in subsequent slices as well. - * This function selects those slices automatically. - */ -extern JS_PUBLIC_API(void) -PrepareForIncrementalGC(JSContext* cx); - -/** - * Returns true if any zone in the system has been scheduled for GC with one of - * the functions above or by the JS engine. - */ -extern JS_PUBLIC_API(bool) -IsGCScheduled(JSContext* cx); - -/** - * Undoes the effect of the Prepare methods above. The given zone will not be - * collected in the next GC. - */ -extern JS_PUBLIC_API(void) -SkipZoneForGC(Zone* zone); - -/* - * Non-Incremental GC: - * - * The following functions perform a non-incremental GC. - */ - -/** - * Performs a non-incremental collection of all selected zones. - * - * If the gckind argument is GC_NORMAL, then some objects that are unreachable - * from the program may still be alive afterwards because of internal - * references; if GC_SHRINK is passed then caches and other temporary references - * to objects will be cleared and all unreferenced objects will be removed from - * the system. - */ -extern JS_PUBLIC_API(void) -GCForReason(JSContext* cx, JSGCInvocationKind gckind, gcreason::Reason reason); - -/* - * Incremental GC: - * - * Incremental GC divides the full mark-and-sweep collection into multiple - * slices, allowing client JavaScript code to run between each slice. This - * allows interactive apps to avoid long collection pauses. Incremental GC does - * not make collection take less time, it merely spreads that time out so that - * the pauses are less noticable. - * - * For a collection to be carried out incrementally the following conditions - * must be met: - * - The collection must be run by calling JS::IncrementalGC() rather than - * JS_GC(). - * - The GC mode must have been set to JSGC_MODE_INCREMENTAL with - * JS_SetGCParameter(). - * - * Note: Even if incremental GC is enabled and working correctly, - * non-incremental collections can still happen when low on memory. - */ - -/** - * Begin an incremental collection and perform one slice worth of work. When - * this function returns, the collection may not be complete. - * IncrementalGCSlice() must be called repeatedly until - * !IsIncrementalGCInProgress(cx). - * - * Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or - * shorter than the requested interval. - */ -extern JS_PUBLIC_API(void) -StartIncrementalGC(JSContext* cx, JSGCInvocationKind gckind, gcreason::Reason reason, - int64_t millis = 0); - -/** - * Perform a slice of an ongoing incremental collection. When this function - * returns, the collection may not be complete. It must be called repeatedly - * until !IsIncrementalGCInProgress(cx). - * - * Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or - * shorter than the requested interval. - */ -extern JS_PUBLIC_API(void) -IncrementalGCSlice(JSContext* cx, gcreason::Reason reason, int64_t millis = 0); - -/** - * If IsIncrementalGCInProgress(cx), this call finishes the ongoing collection - * by performing an arbitrarily long slice. If !IsIncrementalGCInProgress(cx), - * this is equivalent to GCForReason. When this function returns, - * IsIncrementalGCInProgress(cx) will always be false. - */ -extern JS_PUBLIC_API(void) -FinishIncrementalGC(JSContext* cx, gcreason::Reason reason); - -/** - * If IsIncrementalGCInProgress(cx), this call aborts the ongoing collection and - * performs whatever work needs to be done to return the collector to its idle - * state. This may take an arbitrarily long time. When this function returns, - * IsIncrementalGCInProgress(cx) will always be false. - */ -extern JS_PUBLIC_API(void) -AbortIncrementalGC(JSContext* cx); - -namespace dbg { - -// The `JS::dbg::GarbageCollectionEvent` class is essentially a view of the -// `js::gcstats::Statistics` data without the uber implementation-specific bits. -// It should generally be palatable for web developers. -class GarbageCollectionEvent -{ - // The major GC number of the GC cycle this data pertains to. - uint64_t majorGCNumber_; - - // Reference to a non-owned, statically allocated C string. This is a very - // short reason explaining why a GC was triggered. - const char* reason; - - // Reference to a nullable, non-owned, statically allocated C string. If the - // collection was forced to be non-incremental, this is a short reason of - // why the GC could not perform an incremental collection. - const char* nonincrementalReason; - - // Represents a single slice of a possibly multi-slice incremental garbage - // collection. - struct Collection { - double startTimestamp; - double endTimestamp; - }; - - // The set of garbage collection slices that made up this GC cycle. - mozilla::Vector collections; - - GarbageCollectionEvent(const GarbageCollectionEvent& rhs) = delete; - GarbageCollectionEvent& operator=(const GarbageCollectionEvent& rhs) = delete; - - public: - explicit GarbageCollectionEvent(uint64_t majorGCNum) - : majorGCNumber_(majorGCNum) - , reason(nullptr) - , nonincrementalReason(nullptr) - , collections() - { } - - using Ptr = js::UniquePtr; - static Ptr Create(JSRuntime* rt, ::js::gcstats::Statistics& stats, uint64_t majorGCNumber); - - JSObject* toJSObject(JSContext* cx) const; - - uint64_t majorGCNumber() const { return majorGCNumber_; } -}; - -} // namespace dbg - -enum GCProgress { - /* - * During non-incremental GC, the GC is bracketed by JSGC_CYCLE_BEGIN/END - * callbacks. During an incremental GC, the sequence of callbacks is as - * follows: - * JSGC_CYCLE_BEGIN, JSGC_SLICE_END (first slice) - * JSGC_SLICE_BEGIN, JSGC_SLICE_END (second slice) - * ... - * JSGC_SLICE_BEGIN, JSGC_CYCLE_END (last slice) - */ - - GC_CYCLE_BEGIN, - GC_SLICE_BEGIN, - GC_SLICE_END, - GC_CYCLE_END -}; - -struct JS_PUBLIC_API(GCDescription) { - bool isZone_; - JSGCInvocationKind invocationKind_; - gcreason::Reason reason_; - - GCDescription(bool isZone, JSGCInvocationKind kind, gcreason::Reason reason) - : isZone_(isZone), invocationKind_(kind), reason_(reason) {} - - char16_t* formatSliceMessage(JSContext* cx) const; - char16_t* formatSummaryMessage(JSContext* cx) const; - char16_t* formatJSON(JSContext* cx, uint64_t timestamp) const; - - JS::dbg::GarbageCollectionEvent::Ptr toGCEvent(JSContext* cx) const; -}; - -typedef void -(* GCSliceCallback)(JSContext* cx, GCProgress progress, const GCDescription& desc); - -/** - * The GC slice callback is called at the beginning and end of each slice. This - * callback may be used for GC notifications as well as to perform additional - * marking. - */ -extern JS_PUBLIC_API(GCSliceCallback) -SetGCSliceCallback(JSContext* cx, GCSliceCallback callback); - -/** - * Describes the progress of an observed nursery collection. - */ -enum class GCNurseryProgress { - /** - * The nursery collection is starting. - */ - GC_NURSERY_COLLECTION_START, - /** - * The nursery collection is ending. - */ - GC_NURSERY_COLLECTION_END -}; - -/** - * A nursery collection callback receives the progress of the nursery collection - * and the reason for the collection. - */ -using GCNurseryCollectionCallback = void(*)(JSContext* cx, GCNurseryProgress progress, - gcreason::Reason reason); - -/** - * Set the nursery collection callback for the given runtime. When set, it will - * be called at the start and end of every nursery collection. - */ -extern JS_PUBLIC_API(GCNurseryCollectionCallback) -SetGCNurseryCollectionCallback(JSContext* cx, GCNurseryCollectionCallback callback); - -typedef void -(* DoCycleCollectionCallback)(JSContext* cx); - -/** - * The purge gray callback is called after any COMPARTMENT_REVIVED GC in which - * the majority of compartments have been marked gray. - */ -extern JS_PUBLIC_API(DoCycleCollectionCallback) -SetDoCycleCollectionCallback(JSContext* cx, DoCycleCollectionCallback callback); - -/** - * Incremental GC defaults to enabled, but may be disabled for testing or in - * embeddings that have not yet implemented barriers on their native classes. - * There is not currently a way to re-enable incremental GC once it has been - * disabled on the runtime. - */ -extern JS_PUBLIC_API(void) -DisableIncrementalGC(JSContext* cx); - -/** - * Returns true if incremental GC is enabled. Simply having incremental GC - * enabled is not sufficient to ensure incremental collections are happening. - * See the comment "Incremental GC" above for reasons why incremental GC may be - * suppressed. Inspection of the "nonincremental reason" field of the - * GCDescription returned by GCSliceCallback may help narrow down the cause if - * collections are not happening incrementally when expected. - */ -extern JS_PUBLIC_API(bool) -IsIncrementalGCEnabled(JSContext* cx); - -/** - * Returns true while an incremental GC is ongoing, both when actively - * collecting and between slices. - */ -extern JS_PUBLIC_API(bool) -IsIncrementalGCInProgress(JSContext* cx); - -/* - * Returns true when writes to GC things must call an incremental (pre) barrier. - * This is generally only true when running mutator code in-between GC slices. - * At other times, the barrier may be elided for performance. - */ -extern JS_PUBLIC_API(bool) -IsIncrementalBarrierNeeded(JSContext* cx); - -/* - * Notify the GC that a reference to a GC thing is about to be overwritten. - * These methods must be called if IsIncrementalBarrierNeeded. - */ -extern JS_PUBLIC_API(void) -IncrementalReferenceBarrier(GCCellPtr thing); - -extern JS_PUBLIC_API(void) -IncrementalValueBarrier(const Value& v); - -extern JS_PUBLIC_API(void) -IncrementalObjectBarrier(JSObject* obj); - -/** - * Returns true if the most recent GC ran incrementally. - */ -extern JS_PUBLIC_API(bool) -WasIncrementalGC(JSContext* cx); - -/* - * Generational GC: - * - * Note: Generational GC is not yet enabled by default. The following class - * is non-functional unless SpiderMonkey was configured with - * --enable-gcgenerational. - */ - -/** Ensure that generational GC is disabled within some scope. */ -class JS_PUBLIC_API(AutoDisableGenerationalGC) -{ - js::gc::GCRuntime* gc; - - public: - explicit AutoDisableGenerationalGC(JSRuntime* rt); - ~AutoDisableGenerationalGC(); -}; - -/** - * Returns true if generational allocation and collection is currently enabled - * on the given runtime. - */ -extern JS_PUBLIC_API(bool) -IsGenerationalGCEnabled(JSRuntime* rt); - -/** - * Returns the GC's "number". This does not correspond directly to the number - * of GCs that have been run, but is guaranteed to be monotonically increasing - * with GC activity. - */ -extern JS_PUBLIC_API(size_t) -GetGCNumber(); - -/** - * Pass a subclass of this "abstract" class to callees to require that they - * never GC. Subclasses can use assertions or the hazard analysis to ensure no - * GC happens. - */ -class JS_PUBLIC_API(AutoRequireNoGC) -{ - protected: - AutoRequireNoGC() {} - ~AutoRequireNoGC() {} -}; - -/** - * Diagnostic assert (see MOZ_DIAGNOSTIC_ASSERT) that GC cannot occur while this - * class is live. This class does not disable the static rooting hazard - * analysis. - * - * This works by entering a GC unsafe region, which is checked on allocation and - * on GC. - */ -class JS_PUBLIC_API(AutoAssertNoGC) : public AutoRequireNoGC -{ - js::gc::GCRuntime* gc; - size_t gcNumber; - - public: - AutoAssertNoGC(); - explicit AutoAssertNoGC(JSRuntime* rt); - explicit AutoAssertNoGC(JSContext* cx); - ~AutoAssertNoGC(); -}; - -/** - * Assert if an allocation of a GC thing occurs while this class is live. This - * class does not disable the static rooting hazard analysis. - */ -class JS_PUBLIC_API(AutoAssertNoAlloc) -{ -#ifdef JS_DEBUG - js::gc::GCRuntime* gc; - - public: - AutoAssertNoAlloc() : gc(nullptr) {} - explicit AutoAssertNoAlloc(JSContext* cx); - void disallowAlloc(JSRuntime* rt); - ~AutoAssertNoAlloc(); -#else - public: - AutoAssertNoAlloc() {} - explicit AutoAssertNoAlloc(JSContext* cx) {} - void disallowAlloc(JSRuntime* rt) {} -#endif -}; - -/** - * Assert if a GC barrier is invoked while this class is live. This class does - * not disable the static rooting hazard analysis. - */ -class JS_PUBLIC_API(AutoAssertOnBarrier) -{ - JSContext* context; - bool prev; - - public: - explicit AutoAssertOnBarrier(JSContext* cx); - ~AutoAssertOnBarrier(); -}; - -/** - * Disable the static rooting hazard analysis in the live region and assert if - * any allocation that could potentially trigger a GC occurs while this guard - * object is live. This is most useful to help the exact rooting hazard analysis - * in complex regions, since it cannot understand dataflow. - * - * Note: GC behavior is unpredictable even when deterministic and is generally - * non-deterministic in practice. The fact that this guard has not - * asserted is not a guarantee that a GC cannot happen in the guarded - * region. As a rule, anyone performing a GC unsafe action should - * understand the GC properties of all code in that region and ensure - * that the hazard analysis is correct for that code, rather than relying - * on this class. - */ -class JS_PUBLIC_API(AutoSuppressGCAnalysis) : public AutoAssertNoAlloc -{ - public: - AutoSuppressGCAnalysis() : AutoAssertNoAlloc() {} - explicit AutoSuppressGCAnalysis(JSContext* cx) : AutoAssertNoAlloc(cx) {} -} JS_HAZ_GC_SUPPRESSED; - -/** - * Assert that code is only ever called from a GC callback, disable the static - * rooting hazard analysis and assert if any allocation that could potentially - * trigger a GC occurs while this guard object is live. - * - * This is useful to make the static analysis ignore code that runs in GC - * callbacks. - */ -class JS_PUBLIC_API(AutoAssertGCCallback) : public AutoSuppressGCAnalysis -{ - public: - explicit AutoAssertGCCallback(JSObject* obj); -}; - -/** - * Place AutoCheckCannotGC in scopes that you believe can never GC. These - * annotations will be verified both dynamically via AutoAssertNoGC, and - * statically with the rooting hazard analysis (implemented by making the - * analysis consider AutoCheckCannotGC to be a GC pointer, and therefore - * complain if it is live across a GC call.) It is useful when dealing with - * internal pointers to GC things where the GC thing itself may not be present - * for the static analysis: e.g. acquiring inline chars from a JSString* on the - * heap. - * - * We only do the assertion checking in DEBUG builds. - */ -#ifdef DEBUG -class JS_PUBLIC_API(AutoCheckCannotGC) : public AutoAssertNoGC -{ - public: - AutoCheckCannotGC() : AutoAssertNoGC() {} - explicit AutoCheckCannotGC(JSContext* cx) : AutoAssertNoGC(cx) {} -} JS_HAZ_GC_INVALIDATED; -#else -class JS_PUBLIC_API(AutoCheckCannotGC) : public AutoRequireNoGC -{ - public: - AutoCheckCannotGC() {} - explicit AutoCheckCannotGC(JSContext* cx) {} -} JS_HAZ_GC_INVALIDATED; -#endif - -/** - * Unsets the gray bit for anything reachable from |thing|. |kind| should not be - * JS::TraceKind::Shape. |thing| should be non-null. The return value indicates - * if anything was unmarked. - */ -extern JS_FRIEND_API(bool) -UnmarkGrayGCThingRecursively(GCCellPtr thing); - -} /* namespace JS */ - -namespace js { -namespace gc { - -static MOZ_ALWAYS_INLINE void -ExposeGCThingToActiveJS(JS::GCCellPtr thing) -{ - // GC things residing in the nursery cannot be gray: they have no mark bits. - // All live objects in the nursery are moved to tenured at the beginning of - // each GC slice, so the gray marker never sees nursery things. - if (IsInsideNursery(thing.asCell())) - return; - - // There's nothing to do for permanent GC things that might be owned by - // another runtime. - if (thing.mayBeOwnedByOtherRuntime()) - return; - - JS::shadow::Runtime* rt = detail::GetCellRuntime(thing.asCell()); - MOZ_DIAGNOSTIC_ASSERT(rt->allowGCBarriers()); - - if (IsIncrementalBarrierNeededOnTenuredGCThing(rt, thing)) - JS::IncrementalReferenceBarrier(thing); - else if (!thing.mayBeOwnedByOtherRuntime() && js::gc::detail::CellIsMarkedGray(thing.asCell())) - JS::UnmarkGrayGCThingRecursively(thing); -} - -static MOZ_ALWAYS_INLINE void -MarkGCThingAsLive(JSRuntime* aRt, JS::GCCellPtr thing) -{ - // Any object in the nursery will not be freed during any GC running at that - // time. - if (IsInsideNursery(thing.asCell())) - return; - - // There's nothing to do for permanent GC things that might be owned by - // another runtime. - if (thing.mayBeOwnedByOtherRuntime()) - return; - - JS::shadow::Runtime* rt = JS::shadow::Runtime::asShadowRuntime(aRt); - MOZ_DIAGNOSTIC_ASSERT(rt->allowGCBarriers()); - - if (IsIncrementalBarrierNeededOnTenuredGCThing(rt, thing)) - JS::IncrementalReferenceBarrier(thing); -} - -} /* namespace gc */ -} /* namespace js */ - -namespace JS { - -/* - * This should be called when an object that is marked gray is exposed to the JS - * engine (by handing it to running JS code or writing it into live JS - * data). During incremental GC, since the gray bits haven't been computed yet, - * we conservatively mark the object black. - */ -static MOZ_ALWAYS_INLINE void -ExposeObjectToActiveJS(JSObject* obj) -{ - MOZ_ASSERT(obj); - js::gc::ExposeGCThingToActiveJS(GCCellPtr(obj)); -} - -static MOZ_ALWAYS_INLINE void -ExposeScriptToActiveJS(JSScript* script) -{ - js::gc::ExposeGCThingToActiveJS(GCCellPtr(script)); -} - -/* - * If a GC is currently marking, mark the string black. - */ -static MOZ_ALWAYS_INLINE void -MarkStringAsLive(Zone* zone, JSString* string) -{ - JSRuntime* rt = JS::shadow::Zone::asShadowZone(zone)->runtimeFromMainThread(); - js::gc::MarkGCThingAsLive(rt, GCCellPtr(string)); -} - -/* - * Internal to Firefox. - * - * Note: this is not related to the PokeGC in nsJSEnvironment. - */ -extern JS_FRIEND_API(void) -PokeGC(JSContext* cx); - -/* - * Internal to Firefox. - */ -extern JS_FRIEND_API(void) -NotifyDidPaint(JSContext* cx); - -} /* namespace JS */ - -#endif /* js_GCAPI_h */ diff --git a/android/x86/include/spidermonkey/js/GCAnnotations.h b/android/x86/include/spidermonkey/js/GCAnnotations.h deleted file mode 100644 index 366d787b..00000000 --- a/android/x86/include/spidermonkey/js/GCAnnotations.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_GCAnnotations_h -#define js_GCAnnotations_h - -// Set of annotations for the rooting hazard analysis, used to categorize types -// and functions. -#ifdef XGILL_PLUGIN - -// Mark a type as being a GC thing (eg js::gc::Cell has this annotation). -# define JS_HAZ_GC_THING __attribute__((tag("GC Thing"))) - -// Mark a type as holding a pointer to a GC thing (eg JS::Value has this -// annotation.) -# define JS_HAZ_GC_POINTER __attribute__((tag("GC Pointer"))) - -// Mark a type as a rooted pointer, suitable for use on the stack (eg all -// Rooted instantiations should have this.) -# define JS_HAZ_ROOTED __attribute__((tag("Rooted Pointer"))) - -// Mark a type as something that should not be held live across a GC, but which -// is not itself a GC pointer. -# define JS_HAZ_GC_INVALIDATED __attribute__((tag("Invalidated by GC"))) - -// Mark a type that would otherwise be considered a GC Pointer (eg because it -// contains a JS::Value field) as a non-GC pointer. It is handled almost the -// same in the analysis as a rooted pointer, except it will not be reported as -// an unnecessary root if used across a GC call. This should rarely be used, -// but makes sense for something like ErrorResult, which only contains a GC -// pointer when it holds an exception (and it does its own rooting, -// conditionally.) -# define JS_HAZ_NON_GC_POINTER __attribute__((tag("Suppressed GC Pointer"))) - -// Mark a function as something that runs a garbage collection, potentially -// invalidating GC pointers. -# define JS_HAZ_GC_CALL __attribute__((tag("GC Call"))) - -// Mark an RAII class as suppressing GC within its scope. -# define JS_HAZ_GC_SUPPRESSED __attribute__((tag("Suppress GC"))) - -#else - -# define JS_HAZ_GC_THING -# define JS_HAZ_GC_POINTER -# define JS_HAZ_ROOTED -# define JS_HAZ_GC_INVALIDATED -# define JS_HAZ_NON_GC_POINTER -# define JS_HAZ_GC_CALL -# define JS_HAZ_GC_SUPPRESSED - -#endif - -#endif /* js_GCAnnotations_h */ diff --git a/android/x86/include/spidermonkey/js/GCHashTable.h b/android/x86/include/spidermonkey/js/GCHashTable.h deleted file mode 100644 index d6c2ce75..00000000 --- a/android/x86/include/spidermonkey/js/GCHashTable.h +++ /dev/null @@ -1,399 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 GCHashTable_h -#define GCHashTable_h - -#include "js/GCPolicyAPI.h" -#include "js/HashTable.h" -#include "js/RootingAPI.h" -#include "js/SweepingAPI.h" -#include "js/TracingAPI.h" - -namespace JS { - -// Define a reasonable default GC policy for GC-aware Maps. -template -struct DefaultMapSweepPolicy { - static bool needsSweep(Key* key, Value* value) { - return GCPolicy::needsSweep(key) || GCPolicy::needsSweep(value); - } -}; - -// A GCHashMap is a GC-aware HashMap, meaning that it has additional trace and -// sweep methods that know how to visit all keys and values in the table. -// HashMaps that contain GC pointers will generally want to use this GCHashMap -// specialization instead of HashMap, because this conveniently supports tracing -// keys and values, and cleaning up weak entries. -// -// GCHashMap::trace applies GCPolicy::trace to each entry's key and value. -// Most types of GC pointers already have appropriate specializations of -// GCPolicy, so they should just work as keys and values. Any struct type with a -// default constructor and trace and sweep functions should work as well. If you -// need to define your own GCPolicy specialization, generic helpers can be found -// in js/public/TracingAPI.h. -// -// The MapSweepPolicy template parameter controls how the table drops entries -// when swept. GCHashMap::sweep applies MapSweepPolicy::needsSweep to each table -// entry; if it returns true, the entry is dropped. The default MapSweepPolicy -// drops the entry if either the key or value is about to be finalized, -// according to its GCPolicy::needsSweep method. (This default is almost -// always fine: it's hard to imagine keeping such an entry around anyway.) -// -// Note that this HashMap only knows *how* to trace and sweep, but it does not -// itself cause tracing or sweeping to be invoked. For tracing, it must be used -// with Rooted or PersistentRooted, or barriered and traced manually. For -// sweeping, currently it requires an explicit call to .sweep(). -template , - typename AllocPolicy = js::TempAllocPolicy, - typename MapSweepPolicy = DefaultMapSweepPolicy> -class GCHashMap : public js::HashMap -{ - using Base = js::HashMap; - - public: - explicit GCHashMap(AllocPolicy a = AllocPolicy()) : Base(a) {} - - static void trace(GCHashMap* map, JSTracer* trc) { map->trace(trc); } - void trace(JSTracer* trc) { - if (!this->initialized()) - return; - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - GCPolicy::trace(trc, &e.front().value(), "hashmap value"); - GCPolicy::trace(trc, &e.front().mutableKey(), "hashmap key"); - } - } - - void sweep() { - if (!this->initialized()) - return; - - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - if (MapSweepPolicy::needsSweep(&e.front().mutableKey(), &e.front().value())) - e.removeFront(); - } - } - - // GCHashMap is movable - GCHashMap(GCHashMap&& rhs) : Base(mozilla::Move(rhs)) {} - void operator=(GCHashMap&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - Base::operator=(mozilla::Move(rhs)); - } - - private: - // GCHashMap is not copyable or assignable - GCHashMap(const GCHashMap& hm) = delete; - GCHashMap& operator=(const GCHashMap& hm) = delete; -}; - -} // namespace JS - -namespace js { - -// HashMap that supports rekeying. -// -// If your keys are pointers to something like JSObject that can be tenured or -// compacted, prefer to use GCHashMap with MovableCellHasher, which takes -// advantage of the Zone's stable id table to make rekeying unnecessary. -template , - typename AllocPolicy = TempAllocPolicy, - typename MapSweepPolicy = JS::DefaultMapSweepPolicy> -class GCRekeyableHashMap : public JS::GCHashMap -{ - using Base = JS::GCHashMap; - - public: - explicit GCRekeyableHashMap(AllocPolicy a = AllocPolicy()) : Base(a) {} - - void sweep() { - if (!this->initialized()) - return; - - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - Key key(e.front().key()); - if (MapSweepPolicy::needsSweep(&key, &e.front().value())) - e.removeFront(); - else if (!HashPolicy::match(key, e.front().key())) - e.rekeyFront(key); - } - } - - // GCRekeyableHashMap is movable - GCRekeyableHashMap(GCRekeyableHashMap&& rhs) : Base(mozilla::Move(rhs)) {} - void operator=(GCRekeyableHashMap&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - Base::operator=(mozilla::Move(rhs)); - } -}; - -template -class GCHashMapOperations -{ - using Map = JS::GCHashMap; - using Lookup = typename Map::Lookup; - - const Map& map() const { return static_cast(this)->get(); } - - public: - using AddPtr = typename Map::AddPtr; - using Ptr = typename Map::Ptr; - using Range = typename Map::Range; - - bool initialized() const { return map().initialized(); } - Ptr lookup(const Lookup& l) const { return map().lookup(l); } - AddPtr lookupForAdd(const Lookup& l) const { return map().lookupForAdd(l); } - Range all() const { return map().all(); } - bool empty() const { return map().empty(); } - uint32_t count() const { return map().count(); } - size_t capacity() const { return map().capacity(); } - bool has(const Lookup& l) const { return map().lookup(l).found(); } - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return map().sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + map().sizeOfExcludingThis(mallocSizeOf); - } -}; - -template -class MutableGCHashMapOperations - : public GCHashMapOperations -{ - using Map = JS::GCHashMap; - using Lookup = typename Map::Lookup; - - Map& map() { return static_cast(this)->get(); } - - public: - using AddPtr = typename Map::AddPtr; - struct Enum : public Map::Enum { explicit Enum(Outer& o) : Map::Enum(o.map()) {} }; - using Ptr = typename Map::Ptr; - using Range = typename Map::Range; - - bool init(uint32_t len = 16) { return map().init(len); } - void clear() { map().clear(); } - void finish() { map().finish(); } - void remove(Ptr p) { map().remove(p); } - - template - bool add(AddPtr& p, KeyInput&& k, ValueInput&& v) { - return map().add(p, mozilla::Forward(k), mozilla::Forward(v)); - } - - template - bool add(AddPtr& p, KeyInput&& k) { - return map().add(p, mozilla::Forward(k), Map::Value()); - } - - template - bool relookupOrAdd(AddPtr& p, KeyInput&& k, ValueInput&& v) { - return map().relookupOrAdd(p, k, - mozilla::Forward(k), - mozilla::Forward(v)); - } - - template - bool put(KeyInput&& k, ValueInput&& v) { - return map().put(mozilla::Forward(k), mozilla::Forward(v)); - } - - template - bool putNew(KeyInput&& k, ValueInput&& v) { - return map().putNew(mozilla::Forward(k), mozilla::Forward(v)); - } -}; - -template -class RootedBase> - : public MutableGCHashMapOperations>, A,B,C,D,E> -{}; - -template -class MutableHandleBase> - : public MutableGCHashMapOperations>, A,B,C,D,E> -{}; - -template -class HandleBase> - : public GCHashMapOperations>, A,B,C,D,E> -{}; - -template -class WeakCacheBase> - : public MutableGCHashMapOperations>, A,B,C,D,E> -{}; - -} // namespace js - -namespace JS { - -// A GCHashSet is a HashSet with an additional trace method that knows -// be traced to be kept alive will generally want to use this GCHashSet -// specialization in lieu of HashSet. -// -// Most types of GC pointers can be traced with no extra infrastructure. For -// structs and non-gc-pointer members, ensure that there is a specialization of -// GCPolicy with an appropriate trace method available to handle the custom -// type. Generic helpers can be found in js/public/TracingAPI.h. -// -// Note that although this HashSet's trace will deal correctly with moved -// elements, it does not itself know when to barrier or trace elements. To -// function properly it must either be used with Rooted or barriered and traced -// manually. -template , - typename AllocPolicy = js::TempAllocPolicy> -class GCHashSet : public js::HashSet -{ - using Base = js::HashSet; - - public: - explicit GCHashSet(AllocPolicy a = AllocPolicy()) : Base(a) {} - - static void trace(GCHashSet* set, JSTracer* trc) { set->trace(trc); } - void trace(JSTracer* trc) { - if (!this->initialized()) - return; - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) - GCPolicy::trace(trc, &e.mutableFront(), "hashset element"); - } - - void sweep() { - if (!this->initialized()) - return; - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - if (GCPolicy::needsSweep(&e.mutableFront())) - e.removeFront(); - } - } - - // GCHashSet is movable - GCHashSet(GCHashSet&& rhs) : Base(mozilla::Move(rhs)) {} - void operator=(GCHashSet&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - Base::operator=(mozilla::Move(rhs)); - } - - private: - // GCHashSet is not copyable or assignable - GCHashSet(const GCHashSet& hs) = delete; - GCHashSet& operator=(const GCHashSet& hs) = delete; -}; - -} // namespace JS - -namespace js { - -template -class GCHashSetOperations -{ - using Set = JS::GCHashSet; - using Lookup = typename Set::Lookup; - - const Set& set() const { return static_cast(this)->get(); } - - public: - using AddPtr = typename Set::AddPtr; - using Entry = typename Set::Entry; - using Ptr = typename Set::Ptr; - using Range = typename Set::Range; - - bool initialized() const { return set().initialized(); } - Ptr lookup(const Lookup& l) const { return set().lookup(l); } - AddPtr lookupForAdd(const Lookup& l) const { return set().lookupForAdd(l); } - Range all() const { return set().all(); } - bool empty() const { return set().empty(); } - uint32_t count() const { return set().count(); } - size_t capacity() const { return set().capacity(); } - bool has(const Lookup& l) const { return set().lookup(l).found(); } - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return set().sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + set().sizeOfExcludingThis(mallocSizeOf); - } -}; - -template -class MutableGCHashSetOperations - : public GCHashSetOperations -{ - using Set = JS::GCHashSet; - using Lookup = typename Set::Lookup; - - Set& set() { return static_cast(this)->get(); } - - public: - using AddPtr = typename Set::AddPtr; - using Entry = typename Set::Entry; - struct Enum : public Set::Enum { explicit Enum(Outer& o) : Set::Enum(o.set()) {} }; - using Ptr = typename Set::Ptr; - using Range = typename Set::Range; - - bool init(uint32_t len = 16) { return set().init(len); } - void clear() { set().clear(); } - void finish() { set().finish(); } - void remove(Ptr p) { set().remove(p); } - void remove(const Lookup& l) { set().remove(l); } - - template - bool add(AddPtr& p, TInput&& t) { - return set().add(p, mozilla::Forward(t)); - } - - template - bool relookupOrAdd(AddPtr& p, const Lookup& l, TInput&& t) { - return set().relookupOrAdd(p, l, mozilla::Forward(t)); - } - - template - bool put(TInput&& t) { - return set().put(mozilla::Forward(t)); - } - - template - bool putNew(TInput&& t) { - return set().putNew(mozilla::Forward(t)); - } - - template - bool putNew(const Lookup& l, TInput&& t) { - return set().putNew(l, mozilla::Forward(t)); - } -}; - -template -class RootedBase> - : public MutableGCHashSetOperations>, T, HP, AP> -{ -}; - -template -class MutableHandleBase> - : public MutableGCHashSetOperations>, T, HP, AP> -{ -}; - -template -class HandleBase> - : public GCHashSetOperations>, T, HP, AP> -{ -}; - -template -class WeakCacheBase> - : public MutableGCHashSetOperations>, T, HP, AP> -{ -}; - -} /* namespace js */ - -#endif /* GCHashTable_h */ diff --git a/android/x86/include/spidermonkey/js/GCPolicyAPI.h b/android/x86/include/spidermonkey/js/GCPolicyAPI.h deleted file mode 100644 index 054e397a..00000000 --- a/android/x86/include/spidermonkey/js/GCPolicyAPI.h +++ /dev/null @@ -1,164 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -// GC Policy Mechanism - -// A GCPolicy controls how the GC interacts with both direct pointers to GC -// things (e.g. JSObject* or JSString*), tagged and/or optional pointers to GC -// things (e.g. Value or jsid), and C++ container types (e.g. -// JSPropertyDescriptor or GCHashMap). -// -// The GCPolicy provides at a minimum: -// -// static T initial() -// - Construct and return an empty T. -// -// static void trace(JSTracer, T* tp, const char* name) -// - Trace the edge |*tp|, calling the edge |name|. Containers like -// GCHashMap and GCHashSet use this method to trace their children. -// -// static bool needsSweep(T* tp) -// - Return true if |*tp| is about to be finalized. Otherwise, update the -// edge for moving GC, and return false. Containers like GCHashMap and -// GCHashSet use this method to decide when to remove an entry: if this -// function returns true on a key/value/member/etc, its entry is dropped -// from the container. Specializing this method is the standard way to -// get custom weak behavior from a container type. -// -// The default GCPolicy assumes that T has a default constructor and |trace| -// and |needsSweep| methods, and forwards to them. GCPolicy has appropriate -// specializations for pointers to GC things and pointer-like types like -// JS::Heap and mozilla::UniquePtr. -// -// There are some stock structs your specializations can inherit from. -// IgnoreGCPolicy does nothing. StructGCPolicy forwards the methods to the -// referent type T. - -#ifndef GCPolicyAPI_h -#define GCPolicyAPI_h - -#include "mozilla/UniquePtr.h" - -#include "js/TraceKind.h" -#include "js/TracingAPI.h" - -// Expand the given macro D for each public GC pointer. -#define FOR_EACH_PUBLIC_GC_POINTER_TYPE(D) \ - D(JS::Symbol*) \ - D(JSAtom*) \ - D(JSFunction*) \ - D(JSObject*) \ - D(JSScript*) \ - D(JSString*) - -// Expand the given macro D for each public tagged GC pointer type. -#define FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(D) \ - D(JS::Value) \ - D(jsid) - -#define FOR_EACH_PUBLIC_AGGREGATE_GC_POINTER_TYPE(D) \ - D(JSPropertyDescriptor) - -class JSAtom; -class JSFunction; -class JSObject; -class JSScript; -class JSString; -namespace JS { -class Symbol; -} - -namespace JS { - -// Defines a policy for container types with non-GC, i.e. C storage. This -// policy dispatches to the underlying struct for GC interactions. -template -struct StructGCPolicy -{ - static T initial() { - return T(); - } - - static void trace(JSTracer* trc, T* tp, const char* name) { - tp->trace(trc); - } - - static void sweep(T* tp) { - return tp->sweep(); - } - - static bool needsSweep(T* tp) { - return tp->needsSweep(); - } -}; - -// The default GC policy attempts to defer to methods on the underlying type. -// Most C++ structures that contain a default constructor, a trace function and -// a sweep function will work out of the box with Rooted, Handle, GCVector, -// and GCHash{Set,Map}. -template struct GCPolicy : public StructGCPolicy {}; - -// This policy ignores any GC interaction, e.g. for non-GC types. -template -struct IgnoreGCPolicy { - static T initial() { return T(); } - static void trace(JSTracer* trc, T* t, const char* name) {} - static bool needsSweep(T* v) { return false; } -}; -template <> struct GCPolicy : public IgnoreGCPolicy {}; -template <> struct GCPolicy : public IgnoreGCPolicy {}; - -template -struct GCPointerPolicy -{ - static T initial() { return nullptr; } - static void trace(JSTracer* trc, T* vp, const char* name) { - if (*vp) - js::UnsafeTraceManuallyBarrieredEdge(trc, vp, name); - } - static bool needsSweep(T* vp) { - if (*vp) - return js::gc::IsAboutToBeFinalizedUnbarriered(vp); - return false; - } -}; -template <> struct GCPolicy : public GCPointerPolicy {}; -template <> struct GCPolicy : public GCPointerPolicy {}; -template <> struct GCPolicy : public GCPointerPolicy {}; -template <> struct GCPolicy : public GCPointerPolicy {}; -template <> struct GCPolicy : public GCPointerPolicy {}; -template <> struct GCPolicy : public GCPointerPolicy {}; - -template -struct GCPolicy> -{ - static void trace(JSTracer* trc, JS::Heap* thingp, const char* name) { - TraceEdge(trc, thingp, name); - } - static bool needsSweep(JS::Heap* thingp) { - return js::gc::EdgeNeedsSweep(thingp); - } -}; - -// GCPolicy> forwards the contained pointer to GCPolicy. -template -struct GCPolicy> -{ - static mozilla::UniquePtr initial() { return mozilla::UniquePtr(); } - static void trace(JSTracer* trc, mozilla::UniquePtr* tp, const char* name) { - if (tp->get()) - GCPolicy::trace(trc, tp->get(), name); - } - static bool needsSweep(mozilla::UniquePtr* tp) { - if (tp->get()) - return GCPolicy::needsSweep(tp->get()); - return false; - } -}; - -} // namespace JS - -#endif // GCPolicyAPI_h diff --git a/android/x86/include/spidermonkey/js/GCVariant.h b/android/x86/include/spidermonkey/js/GCVariant.h deleted file mode 100644 index 31ab23f5..00000000 --- a/android/x86/include/spidermonkey/js/GCVariant.h +++ /dev/null @@ -1,198 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_GCVariant_h -#define js_GCVariant_h - -#include "mozilla/Variant.h" - -#include "js/GCPolicyAPI.h" -#include "js/RootingAPI.h" -#include "js/TracingAPI.h" - -namespace JS { - -// These template specializations allow Variant to be used inside GC wrappers. -// -// When matching on GC wrappers around Variants, matching should be done on -// the wrapper itself. The matcher class's methods should take Handles or -// MutableHandles. For example, -// -// struct MyMatcher -// { -// using ReturnType = const char*; -// ReturnType match(HandleObject o) { return "object"; } -// ReturnType match(HandleScript s) { return "script"; } -// }; -// -// Rooted> v(cx, someScript); -// MyMatcher mm; -// v.match(mm); -// -// If you get compile errors about inability to upcast subclasses (e.g., from -// NativeObject* to JSObject*) and are inside js/src, be sure to also include -// "gc/Policy.h". - -namespace detail { - -template -struct GCVariantImplementation; - -// The base case. -template -struct GCVariantImplementation -{ - template - static void trace(JSTracer* trc, ConcreteVariant* v, const char* name) { - T& thing = v->template as(); - if (!mozilla::IsPointer::value || thing) - GCPolicy::trace(trc, &thing, name); - } - - template - static typename Matcher::ReturnType - match(Matcher& matcher, Handle v) { - const T& thing = v.get().template as(); - return matcher.match(Handle::fromMarkedLocation(&thing)); - } - - template - static typename Matcher::ReturnType - match(Matcher& matcher, MutableHandle v) { - T& thing = v.get().template as(); - return matcher.match(MutableHandle::fromMarkedLocation(&thing)); - } -}; - -// The inductive case. -template -struct GCVariantImplementation -{ - using Next = GCVariantImplementation; - - template - static void trace(JSTracer* trc, ConcreteVariant* v, const char* name) { - if (v->template is()) { - T& thing = v->template as(); - if (!mozilla::IsPointer::value || thing) - GCPolicy::trace(trc, &thing, name); - } else { - Next::trace(trc, v, name); - } - } - - template - static typename Matcher::ReturnType - match(Matcher& matcher, Handle v) { - if (v.get().template is()) { - const T& thing = v.get().template as(); - return matcher.match(Handle::fromMarkedLocation(&thing)); - } - return Next::match(matcher, v); - } - - template - static typename Matcher::ReturnType - match(Matcher& matcher, MutableHandle v) { - if (v.get().template is()) { - T& thing = v.get().template as(); - return matcher.match(MutableHandle::fromMarkedLocation(&thing)); - } - return Next::match(matcher, v); - } -}; - -} // namespace detail - -template -struct GCPolicy> -{ - using Impl = detail::GCVariantImplementation; - - // Variants do not provide initial(). They do not have a default initial - // value and one must be provided. - - static void trace(JSTracer* trc, mozilla::Variant* v, const char* name) { - Impl::trace(trc, v, name); - } -}; - -} // namespace JS - -namespace js { - -template -class GCVariantOperations -{ - using Impl = JS::detail::GCVariantImplementation; - using Variant = mozilla::Variant; - - const Variant& variant() const { return static_cast(this)->get(); } - - public: - template - bool is() const { - return variant().template is(); - } - - template - JS::Handle as() const { - return Handle::fromMarkedLocation(&variant().template as()); - } - - template - typename Matcher::ReturnType - match(Matcher& matcher) const { - return Impl::match(matcher, JS::Handle::fromMarkedLocation(&variant())); - } -}; - -template -class MutableGCVariantOperations - : public GCVariantOperations -{ - using Impl = JS::detail::GCVariantImplementation; - using Variant = mozilla::Variant; - - const Variant& variant() const { return static_cast(this)->get(); } - Variant& variant() { return static_cast(this)->get(); } - - public: - template - JS::MutableHandle as() { - return JS::MutableHandle::fromMarkedLocation(&variant().template as()); - } - - template - typename Matcher::ReturnType - match(Matcher& matcher) { - return Impl::match(matcher, JS::MutableHandle::fromMarkedLocation(&variant())); - } -}; - -template -class RootedBase> - : public MutableGCVariantOperations>, Ts...> -{ }; - -template -class MutableHandleBase> - : public MutableGCVariantOperations>, Ts...> -{ }; - -template -class HandleBase> - : public GCVariantOperations>, Ts...> -{ }; - -template -class PersistentRootedBase> - : public MutableGCVariantOperations>, Ts...> -{ }; - -} // namespace js - -#endif // js_GCVariant_h diff --git a/android/x86/include/spidermonkey/js/GCVector.h b/android/x86/include/spidermonkey/js/GCVector.h deleted file mode 100644 index 2668e65b..00000000 --- a/android/x86/include/spidermonkey/js/GCVector.h +++ /dev/null @@ -1,249 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_GCVector_h -#define js_GCVector_h - -#include "mozilla/Vector.h" - -#include "js/GCPolicyAPI.h" -#include "js/RootingAPI.h" -#include "js/TracingAPI.h" -#include "js/Vector.h" - -namespace JS { - -// A GCVector is a Vector with an additional trace method that knows how -// to visit all of the items stored in the Vector. For vectors that contain GC -// things, this is usually more convenient than manually iterating and marking -// the contents. -// -// Most types of GC pointers as keys and values can be traced with no extra -// infrastructure. For structs and non-gc-pointer members, ensure that there is -// a specialization of GCPolicy with an appropriate trace method available -// to handle the custom type. Generic helpers can be found in -// js/public/TracingAPI.h. -// -// Note that although this Vector's trace will deal correctly with moved items, -// it does not itself know when to barrier or trace items. To function properly -// it must either be used with Rooted, or barriered and traced manually. -template -class GCVector -{ - mozilla::Vector vector; - - public: - explicit GCVector(AllocPolicy alloc = AllocPolicy()) - : vector(alloc) - {} - - GCVector(GCVector&& vec) - : vector(mozilla::Move(vec.vector)) - {} - - GCVector& operator=(GCVector&& vec) { - vector = mozilla::Move(vec.vector); - return *this; - } - - size_t length() const { return vector.length(); } - bool empty() const { return vector.empty(); } - size_t capacity() const { return vector.capacity(); } - - T* begin() { return vector.begin(); } - const T* begin() const { return vector.begin(); } - - T* end() { return vector.end(); } - const T* end() const { return vector.end(); } - - T& operator[](size_t i) { return vector[i]; } - const T& operator[](size_t i) const { return vector[i]; } - - T& back() { return vector.back(); } - const T& back() const { return vector.back(); } - - bool initCapacity(size_t cap) { return vector.initCapacity(cap); } - bool reserve(size_t req) { return vector.reserve(req); } - void shrinkBy(size_t amount) { return vector.shrinkBy(amount); } - bool growBy(size_t amount) { return vector.growBy(amount); } - bool resize(size_t newLen) { return vector.resize(newLen); } - - void clear() { return vector.clear(); } - - template bool append(U&& item) { return vector.append(mozilla::Forward(item)); } - - template - bool - emplaceBack(Args&&... args) { - return vector.emplaceBack(mozilla::Forward(args)...); - } - - template - void infallibleAppend(U&& aU) { - return vector.infallibleAppend(mozilla::Forward(aU)); - } - void infallibleAppendN(const T& aT, size_t aN) { - return vector.infallibleAppendN(aT, aN); - } - template void - infallibleAppend(const U* aBegin, const U* aEnd) { - return vector.infallibleAppend(aBegin, aEnd); - } - template void infallibleAppend(const U* aBegin, size_t aLength) { - return vector.infallibleAppend(aBegin, aLength); - } - - template - bool appendAll(const mozilla::Vector& aU) { return vector.appendAll(aU); } - template - bool appendAll(const GCVector& aU) { return vector.append(aU.begin(), aU.length()); } - - bool appendN(const T& val, size_t count) { return vector.appendN(val, count); } - - template bool append(const U* aBegin, const U* aEnd) { - return vector.append(aBegin, aEnd); - } - template bool append(const U* aBegin, size_t aLength) { - return vector.append(aBegin, aLength); - } - - void popBack() { return vector.popBack(); } - T popCopy() { return vector.popCopy(); } - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return vector.sizeOfExcludingThis(mallocSizeOf); - } - - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return vector.sizeOfIncludingThis(mallocSizeOf); - } - - static void trace(GCVector* vec, JSTracer* trc) { vec->trace(trc); } - - void trace(JSTracer* trc) { - for (auto& elem : vector) - GCPolicy::trace(trc, &elem, "vector element"); - } -}; - -} // namespace JS - -namespace js { - -template -class GCVectorOperations -{ - using Vec = JS::GCVector; - const Vec& vec() const { return static_cast(this)->get(); } - - public: - const AllocPolicy& allocPolicy() const { return vec().allocPolicy(); } - size_t length() const { return vec().length(); } - bool empty() const { return vec().empty(); } - size_t capacity() const { return vec().capacity(); } - const T* begin() const { return vec().begin(); } - const T* end() const { return vec().end(); } - const T& back() const { return vec().back(); } - - JS::Handle operator[](size_t aIndex) const { - return JS::Handle::fromMarkedLocation(&vec().operator[](aIndex)); - } -}; - -template -class MutableGCVectorOperations - : public GCVectorOperations -{ - using Vec = JS::GCVector; - const Vec& vec() const { return static_cast(this)->get(); } - Vec& vec() { return static_cast(this)->get(); } - - public: - const AllocPolicy& allocPolicy() const { return vec().allocPolicy(); } - AllocPolicy& allocPolicy() { return vec().allocPolicy(); } - const T* begin() const { return vec().begin(); } - T* begin() { return vec().begin(); } - const T* end() const { return vec().end(); } - T* end() { return vec().end(); } - const T& back() const { return vec().back(); } - T& back() { return vec().back(); } - - JS::Handle operator[](size_t aIndex) const { - return JS::Handle::fromMarkedLocation(&vec().operator[](aIndex)); - } - JS::MutableHandle operator[](size_t aIndex) { - return JS::MutableHandle::fromMarkedLocation(&vec().operator[](aIndex)); - } - - bool initCapacity(size_t aRequest) { return vec().initCapacity(aRequest); } - bool reserve(size_t aRequest) { return vec().reserve(aRequest); } - void shrinkBy(size_t aIncr) { vec().shrinkBy(aIncr); } - bool growBy(size_t aIncr) { return vec().growBy(aIncr); } - bool resize(size_t aNewLength) { return vec().resize(aNewLength); } - bool growByUninitialized(size_t aIncr) { return vec().growByUninitialized(aIncr); } - void infallibleGrowByUninitialized(size_t aIncr) { vec().infallibleGrowByUninitialized(aIncr); } - bool resizeUninitialized(size_t aNewLength) { return vec().resizeUninitialized(aNewLength); } - void clear() { vec().clear(); } - void clearAndFree() { vec().clearAndFree(); } - template bool append(U&& aU) { return vec().append(mozilla::Forward(aU)); } - template bool emplaceBack(Args&&... aArgs) { - return vec().emplaceBack(mozilla::Forward(aArgs...)); - } - template - bool appendAll(const mozilla::Vector& aU) { return vec().appendAll(aU); } - template - bool appendAll(const JS::GCVector& aU) { return vec().appendAll(aU); } - bool appendN(const T& aT, size_t aN) { return vec().appendN(aT, aN); } - template bool append(const U* aBegin, const U* aEnd) { - return vec().append(aBegin, aEnd); - } - template bool append(const U* aBegin, size_t aLength) { - return vec().append(aBegin, aLength); - } - template void infallibleAppend(U&& aU) { - vec().infallibleAppend(mozilla::Forward(aU)); - } - void infallibleAppendN(const T& aT, size_t aN) { vec().infallibleAppendN(aT, aN); } - template void infallibleAppend(const U* aBegin, const U* aEnd) { - vec().infallibleAppend(aBegin, aEnd); - } - template void infallibleAppend(const U* aBegin, size_t aLength) { - vec().infallibleAppend(aBegin, aLength); - } - void popBack() { vec().popBack(); } - T popCopy() { return vec().popCopy(); } - template T* insert(T* aP, U&& aVal) { - return vec().insert(aP, mozilla::Forward(aVal)); - } - void erase(T* aT) { vec().erase(aT); } - void erase(T* aBegin, T* aEnd) { vec().erase(aBegin, aEnd); } -}; - -template -class RootedBase> - : public MutableGCVectorOperations>, T,N,AP> -{}; - -template -class MutableHandleBase> - : public MutableGCVectorOperations>, T,N,AP> -{}; - -template -class HandleBase> - : public GCVectorOperations>, T,N,AP> -{}; - -template -class PersistentRootedBase> - : public MutableGCVectorOperations>, T,N,AP> -{}; - -} // namespace js - -#endif // js_GCVector_h diff --git a/android/x86/include/spidermonkey/js/HashTable.h b/android/x86/include/spidermonkey/js/HashTable.h deleted file mode 100644 index 5d4c0665..00000000 --- a/android/x86/include/spidermonkey/js/HashTable.h +++ /dev/null @@ -1,1880 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_HashTable_h -#define js_HashTable_h - -#include "mozilla/Alignment.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Casting.h" -#include "mozilla/HashFunctions.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" -#include "mozilla/Opaque.h" -#include "mozilla/PodOperations.h" -#include "mozilla/ReentrancyGuard.h" -#include "mozilla/TemplateLib.h" -#include "mozilla/TypeTraits.h" -#include "mozilla/UniquePtr.h" - -#include "js/Utility.h" - -namespace js { - -class TempAllocPolicy; -template struct DefaultHasher; -template class HashMapEntry; -namespace detail { - template class HashTableEntry; - template class HashTable; -} // namespace detail - -/*****************************************************************************/ - -// The "generation" of a hash table is an opaque value indicating the state of -// modification of the hash table through its lifetime. If the generation of -// a hash table compares equal at times T1 and T2, then lookups in the hash -// table, pointers to (or into) hash table entries, etc. at time T1 are valid -// at time T2. If the generation compares unequal, these computations are all -// invalid and must be performed again to be used. -// -// Generations are meaningfully comparable only with respect to a single hash -// table. It's always nonsensical to compare the generation of distinct hash -// tables H1 and H2. -using Generation = mozilla::Opaque; - -// A JS-friendly, STL-like container providing a hash-based map from keys to -// values. In particular, HashMap calls constructors and destructors of all -// objects added so non-PODs may be used safely. -// -// Key/Value requirements: -// - movable, destructible, assignable -// HashPolicy requirements: -// - see Hash Policy section below -// AllocPolicy: -// - see jsalloc.h -// -// Note: -// - HashMap is not reentrant: Key/Value/HashPolicy/AllocPolicy members -// called by HashMap must not call back into the same HashMap object. -// - Due to the lack of exception handling, the user must call |init()|. -template , - class AllocPolicy = TempAllocPolicy> -class HashMap -{ - typedef HashMapEntry TableEntry; - - struct MapHashPolicy : HashPolicy - { - using Base = HashPolicy; - typedef Key KeyType; - static const Key& getKey(TableEntry& e) { return e.key(); } - static void setKey(TableEntry& e, Key& k) { HashPolicy::rekey(e.mutableKey(), k); } - }; - - typedef detail::HashTable Impl; - Impl impl; - - public: - typedef typename HashPolicy::Lookup Lookup; - typedef TableEntry Entry; - - // HashMap construction is fallible (due to OOM); thus the user must call - // init after constructing a HashMap and check the return value. - explicit HashMap(AllocPolicy a = AllocPolicy()) : impl(a) {} - MOZ_MUST_USE bool init(uint32_t len = 16) { return impl.init(len); } - bool initialized() const { return impl.initialized(); } - - // Return whether the given lookup value is present in the map. E.g.: - // - // typedef HashMap HM; - // HM h; - // if (HM::Ptr p = h.lookup(3)) { - // const HM::Entry& e = *p; // p acts like a pointer to Entry - // assert(p->key == 3); // Entry contains the key - // char val = p->value; // and value - // } - // - // Also see the definition of Ptr in HashTable above (with T = Entry). - typedef typename Impl::Ptr Ptr; - Ptr lookup(const Lookup& l) const { return impl.lookup(l); } - - // Like lookup, but does not assert if two threads call lookup at the same - // time. Only use this method when none of the threads will modify the map. - Ptr readonlyThreadsafeLookup(const Lookup& l) const { return impl.readonlyThreadsafeLookup(l); } - - // Assuming |p.found()|, remove |*p|. - void remove(Ptr p) { impl.remove(p); } - - // Like |lookup(l)|, but on miss, |p = lookupForAdd(l)| allows efficient - // insertion of Key |k| (where |HashPolicy::match(k,l) == true|) using - // |add(p,k,v)|. After |add(p,k,v)|, |p| points to the new Entry. E.g.: - // - // typedef HashMap HM; - // HM h; - // HM::AddPtr p = h.lookupForAdd(3); - // if (!p) { - // if (!h.add(p, 3, 'a')) - // return false; - // } - // const HM::Entry& e = *p; // p acts like a pointer to Entry - // assert(p->key == 3); // Entry contains the key - // char val = p->value; // and value - // - // Also see the definition of AddPtr in HashTable above (with T = Entry). - // - // N.B. The caller must ensure that no mutating hash table operations - // occur between a pair of |lookupForAdd| and |add| calls. To avoid - // looking up the key a second time, the caller may use the more efficient - // relookupOrAdd method. This method reuses part of the hashing computation - // to more efficiently insert the key if it has not been added. For - // example, a mutation-handling version of the previous example: - // - // HM::AddPtr p = h.lookupForAdd(3); - // if (!p) { - // call_that_may_mutate_h(); - // if (!h.relookupOrAdd(p, 3, 'a')) - // return false; - // } - // const HM::Entry& e = *p; - // assert(p->key == 3); - // char val = p->value; - typedef typename Impl::AddPtr AddPtr; - AddPtr lookupForAdd(const Lookup& l) const { - return impl.lookupForAdd(l); - } - - template - MOZ_MUST_USE bool add(AddPtr& p, KeyInput&& k, ValueInput&& v) { - return impl.add(p, - mozilla::Forward(k), - mozilla::Forward(v)); - } - - template - MOZ_MUST_USE bool add(AddPtr& p, KeyInput&& k) { - return impl.add(p, mozilla::Forward(k), Value()); - } - - template - MOZ_MUST_USE bool relookupOrAdd(AddPtr& p, KeyInput&& k, ValueInput&& v) { - return impl.relookupOrAdd(p, k, - mozilla::Forward(k), - mozilla::Forward(v)); - } - - // |all()| returns a Range containing |count()| elements. E.g.: - // - // typedef HashMap HM; - // HM h; - // for (HM::Range r = h.all(); !r.empty(); r.popFront()) - // char c = r.front().value(); - // - // Also see the definition of Range in HashTable above (with T = Entry). - typedef typename Impl::Range Range; - Range all() const { return impl.all(); } - - // Typedef for the enumeration class. An Enum may be used to examine and - // remove table entries: - // - // typedef HashMap HM; - // HM s; - // for (HM::Enum e(s); !e.empty(); e.popFront()) - // if (e.front().value() == 'l') - // e.removeFront(); - // - // Table resize may occur in Enum's destructor. Also see the definition of - // Enum in HashTable above (with T = Entry). - typedef typename Impl::Enum Enum; - - // Remove all entries. This does not shrink the table. For that consider - // using the finish() method. - void clear() { impl.clear(); } - - // Remove all the entries and release all internal buffers. The map must - // be initialized again before any use. - void finish() { impl.finish(); } - - // Does the table contain any entries? - bool empty() const { return impl.empty(); } - - // Number of live elements in the map. - uint32_t count() const { return impl.count(); } - - // Total number of allocation in the dynamic table. Note: resize will - // happen well before count() == capacity(). - size_t capacity() const { return impl.capacity(); } - - // Don't just call |impl.sizeOfExcludingThis()| because there's no - // guarantee that |impl| is the first field in HashMap. - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return impl.sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + impl.sizeOfExcludingThis(mallocSizeOf); - } - - Generation generation() const { - return impl.generation(); - } - - /************************************************** Shorthand operations */ - - bool has(const Lookup& l) const { - return impl.lookup(l).found(); - } - - // Overwrite existing value with v. Return false on oom. - template - MOZ_MUST_USE bool put(KeyInput&& k, ValueInput&& v) { - AddPtr p = lookupForAdd(k); - if (p) { - p->value() = mozilla::Forward(v); - return true; - } - return add(p, mozilla::Forward(k), mozilla::Forward(v)); - } - - // Like put, but assert that the given key is not already present. - template - MOZ_MUST_USE bool putNew(KeyInput&& k, ValueInput&& v) { - return impl.putNew(k, mozilla::Forward(k), mozilla::Forward(v)); - } - - // Only call this to populate an empty map after reserving space with init(). - template - void putNewInfallible(KeyInput&& k, ValueInput&& v) { - impl.putNewInfallible(k, mozilla::Forward(k), mozilla::Forward(v)); - } - - // Add (k,defaultValue) if |k| is not found. Return a false-y Ptr on oom. - Ptr lookupWithDefault(const Key& k, const Value& defaultValue) { - AddPtr p = lookupForAdd(k); - if (p) - return p; - bool ok = add(p, k, defaultValue); - MOZ_ASSERT_IF(!ok, !p); // p is left false-y on oom. - (void)ok; - return p; - } - - // Remove if present. - void remove(const Lookup& l) { - if (Ptr p = lookup(l)) - remove(p); - } - - // Infallibly rekey one entry, if necessary. - // Requires template parameters Key and HashPolicy::Lookup to be the same type. - void rekeyIfMoved(const Key& old_key, const Key& new_key) { - if (old_key != new_key) - rekeyAs(old_key, new_key, new_key); - } - - // Infallibly rekey one entry if present, and return whether that happened. - bool rekeyAs(const Lookup& old_lookup, const Lookup& new_lookup, const Key& new_key) { - if (Ptr p = lookup(old_lookup)) { - impl.rekeyAndMaybeRehash(p, new_lookup, new_key); - return true; - } - return false; - } - - // HashMap is movable - HashMap(HashMap&& rhs) : impl(mozilla::Move(rhs.impl)) {} - void operator=(HashMap&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - impl = mozilla::Move(rhs.impl); - } - - private: - // HashMap is not copyable or assignable - HashMap(const HashMap& hm) = delete; - HashMap& operator=(const HashMap& hm) = delete; - - friend class Impl::Enum; -}; - -/*****************************************************************************/ - -// A JS-friendly, STL-like container providing a hash-based set of values. In -// particular, HashSet calls constructors and destructors of all objects added -// so non-PODs may be used safely. -// -// T requirements: -// - movable, destructible, assignable -// HashPolicy requirements: -// - see Hash Policy section below -// AllocPolicy: -// - see jsalloc.h -// -// Note: -// - HashSet is not reentrant: T/HashPolicy/AllocPolicy members called by -// HashSet must not call back into the same HashSet object. -// - Due to the lack of exception handling, the user must call |init()|. -template , - class AllocPolicy = TempAllocPolicy> -class HashSet -{ - struct SetOps : HashPolicy - { - using Base = HashPolicy; - typedef T KeyType; - static const KeyType& getKey(const T& t) { return t; } - static void setKey(T& t, KeyType& k) { HashPolicy::rekey(t, k); } - }; - - typedef detail::HashTable Impl; - Impl impl; - - public: - typedef typename HashPolicy::Lookup Lookup; - typedef T Entry; - - // HashSet construction is fallible (due to OOM); thus the user must call - // init after constructing a HashSet and check the return value. - explicit HashSet(AllocPolicy a = AllocPolicy()) : impl(a) {} - MOZ_MUST_USE bool init(uint32_t len = 16) { return impl.init(len); } - bool initialized() const { return impl.initialized(); } - - // Return whether the given lookup value is present in the map. E.g.: - // - // typedef HashSet HS; - // HS h; - // if (HS::Ptr p = h.lookup(3)) { - // assert(*p == 3); // p acts like a pointer to int - // } - // - // Also see the definition of Ptr in HashTable above. - typedef typename Impl::Ptr Ptr; - Ptr lookup(const Lookup& l) const { return impl.lookup(l); } - - // Like lookup, but does not assert if two threads call lookup at the same - // time. Only use this method when none of the threads will modify the map. - Ptr readonlyThreadsafeLookup(const Lookup& l) const { return impl.readonlyThreadsafeLookup(l); } - - // Assuming |p.found()|, remove |*p|. - void remove(Ptr p) { impl.remove(p); } - - // Like |lookup(l)|, but on miss, |p = lookupForAdd(l)| allows efficient - // insertion of T value |t| (where |HashPolicy::match(t,l) == true|) using - // |add(p,t)|. After |add(p,t)|, |p| points to the new element. E.g.: - // - // typedef HashSet HS; - // HS h; - // HS::AddPtr p = h.lookupForAdd(3); - // if (!p) { - // if (!h.add(p, 3)) - // return false; - // } - // assert(*p == 3); // p acts like a pointer to int - // - // Also see the definition of AddPtr in HashTable above. - // - // N.B. The caller must ensure that no mutating hash table operations - // occur between a pair of |lookupForAdd| and |add| calls. To avoid - // looking up the key a second time, the caller may use the more efficient - // relookupOrAdd method. This method reuses part of the hashing computation - // to more efficiently insert the key if it has not been added. For - // example, a mutation-handling version of the previous example: - // - // HS::AddPtr p = h.lookupForAdd(3); - // if (!p) { - // call_that_may_mutate_h(); - // if (!h.relookupOrAdd(p, 3, 3)) - // return false; - // } - // assert(*p == 3); - // - // Note that relookupOrAdd(p,l,t) performs Lookup using |l| and adds the - // entry |t|, where the caller ensures match(l,t). - typedef typename Impl::AddPtr AddPtr; - AddPtr lookupForAdd(const Lookup& l) const { return impl.lookupForAdd(l); } - - template - MOZ_MUST_USE bool add(AddPtr& p, U&& u) { - return impl.add(p, mozilla::Forward(u)); - } - - template - MOZ_MUST_USE bool relookupOrAdd(AddPtr& p, const Lookup& l, U&& u) { - return impl.relookupOrAdd(p, l, mozilla::Forward(u)); - } - - // |all()| returns a Range containing |count()| elements: - // - // typedef HashSet HS; - // HS h; - // for (HS::Range r = h.all(); !r.empty(); r.popFront()) - // int i = r.front(); - // - // Also see the definition of Range in HashTable above. - typedef typename Impl::Range Range; - Range all() const { return impl.all(); } - - // Typedef for the enumeration class. An Enum may be used to examine and - // remove table entries: - // - // typedef HashSet HS; - // HS s; - // for (HS::Enum e(s); !e.empty(); e.popFront()) - // if (e.front() == 42) - // e.removeFront(); - // - // Table resize may occur in Enum's destructor. Also see the definition of - // Enum in HashTable above. - typedef typename Impl::Enum Enum; - - // Remove all entries. This does not shrink the table. For that consider - // using the finish() method. - void clear() { impl.clear(); } - - // Remove all the entries and release all internal buffers. The set must - // be initialized again before any use. - void finish() { impl.finish(); } - - // Does the table contain any entries? - bool empty() const { return impl.empty(); } - - // Number of live elements in the map. - uint32_t count() const { return impl.count(); } - - // Total number of allocation in the dynamic table. Note: resize will - // happen well before count() == capacity(). - size_t capacity() const { return impl.capacity(); } - - // Don't just call |impl.sizeOfExcludingThis()| because there's no - // guarantee that |impl| is the first field in HashSet. - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return impl.sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + impl.sizeOfExcludingThis(mallocSizeOf); - } - - Generation generation() const { - return impl.generation(); - } - - /************************************************** Shorthand operations */ - - bool has(const Lookup& l) const { - return impl.lookup(l).found(); - } - - // Add |u| if it is not present already. Return false on oom. - template - MOZ_MUST_USE bool put(U&& u) { - AddPtr p = lookupForAdd(u); - return p ? true : add(p, mozilla::Forward(u)); - } - - // Like put, but assert that the given key is not already present. - template - MOZ_MUST_USE bool putNew(U&& u) { - return impl.putNew(u, mozilla::Forward(u)); - } - - template - MOZ_MUST_USE bool putNew(const Lookup& l, U&& u) { - return impl.putNew(l, mozilla::Forward(u)); - } - - // Only call this to populate an empty set after reserving space with init(). - template - void putNewInfallible(const Lookup& l, U&& u) { - impl.putNewInfallible(l, mozilla::Forward(u)); - } - - void remove(const Lookup& l) { - if (Ptr p = lookup(l)) - remove(p); - } - - // Infallibly rekey one entry, if present. - // Requires template parameters T and HashPolicy::Lookup to be the same type. - void rekeyIfMoved(const Lookup& old_value, const T& new_value) { - if (old_value != new_value) - rekeyAs(old_value, new_value, new_value); - } - - // Infallibly rekey one entry if present, and return whether that happened. - bool rekeyAs(const Lookup& old_lookup, const Lookup& new_lookup, const T& new_value) { - if (Ptr p = lookup(old_lookup)) { - impl.rekeyAndMaybeRehash(p, new_lookup, new_value); - return true; - } - return false; - } - - // Infallibly replace the current key at |p| with an equivalent key. - // Specifically, both HashPolicy::hash and HashPolicy::match must return - // identical results for the new and old key when applied against all - // possible matching values. - void replaceKey(Ptr p, const T& new_value) { - MOZ_ASSERT(p.found()); - MOZ_ASSERT(*p != new_value); - MOZ_ASSERT(HashPolicy::hash(*p) == HashPolicy::hash(new_value)); - MOZ_ASSERT(HashPolicy::match(*p, new_value)); - const_cast(*p) = new_value; - } - - // HashSet is movable - HashSet(HashSet&& rhs) : impl(mozilla::Move(rhs.impl)) {} - void operator=(HashSet&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - impl = mozilla::Move(rhs.impl); - } - - private: - // HashSet is not copyable or assignable - HashSet(const HashSet& hs) = delete; - HashSet& operator=(const HashSet& hs) = delete; - - friend class Impl::Enum; -}; - -/*****************************************************************************/ - -// Hash Policy -// -// A hash policy P for a hash table with key-type Key must provide: -// - a type |P::Lookup| to use to lookup table entries; -// - a static member function |P::hash| with signature -// -// static js::HashNumber hash(Lookup) -// -// to use to hash the lookup type; and -// - a static member function |P::match| with signature -// -// static bool match(Key, Lookup) -// -// to use to test equality of key and lookup values. -// -// Normally, Lookup = Key. In general, though, different values and types of -// values can be used to lookup and store. If a Lookup value |l| is != to the -// added Key value |k|, the user must ensure that |P::match(k,l)|. E.g.: -// -// js::HashSet::AddPtr p = h.lookup(l); -// if (!p) { -// assert(P::match(k, l)); // must hold -// h.add(p, k); -// } - -// Pointer hashing policy that strips the lowest zeroBits when calculating the -// hash to improve key distribution. -template -struct PointerHasher -{ - typedef Key Lookup; - static HashNumber hash(const Lookup& l) { - size_t word = reinterpret_cast(l) >> zeroBits; - static_assert(sizeof(HashNumber) == 4, - "subsequent code assumes a four-byte hash"); -#if JS_BITS_PER_WORD == 32 - return HashNumber(word); -#else - static_assert(sizeof(word) == 8, - "unexpected word size, new hashing strategy required to " - "properly incorporate all bits"); - return HashNumber((word >> 32) ^ word); -#endif - } - static bool match(const Key& k, const Lookup& l) { - return k == l; - } - static void rekey(Key& k, const Key& newKey) { - k = newKey; - } -}; - -// Default hash policy: just use the 'lookup' value. This of course only -// works if the lookup value is integral. HashTable applies ScrambleHashCode to -// the result of the 'hash' which means that it is 'ok' if the lookup value is -// not well distributed over the HashNumber domain. -template -struct DefaultHasher -{ - typedef Key Lookup; - static HashNumber hash(const Lookup& l) { - // Hash if can implicitly cast to hash number type. - return l; - } - static bool match(const Key& k, const Lookup& l) { - // Use builtin or overloaded operator==. - return k == l; - } - static void rekey(Key& k, const Key& newKey) { - k = newKey; - } -}; - -// Specialize hashing policy for pointer types. It assumes that the type is -// at least word-aligned. For types with smaller size use PointerHasher. -template -struct DefaultHasher : PointerHasher::value> -{}; - -// Specialize hashing policy for mozilla::UniquePtr to proxy the UniquePtr's -// raw pointer to PointerHasher. -template -struct DefaultHasher> -{ - using Lookup = mozilla::UniquePtr; - using PtrHasher = PointerHasher::value>; - - static HashNumber hash(const Lookup& l) { - return PtrHasher::hash(l.get()); - } - static bool match(const mozilla::UniquePtr& k, const Lookup& l) { - return PtrHasher::match(k.get(), l.get()); - } - static void rekey(mozilla::UniquePtr& k, mozilla::UniquePtr&& newKey) { - k = mozilla::Move(newKey); - } -}; - -// For doubles, we can xor the two uint32s. -template <> -struct DefaultHasher -{ - typedef double Lookup; - static HashNumber hash(double d) { - static_assert(sizeof(HashNumber) == 4, - "subsequent code assumes a four-byte hash"); - uint64_t u = mozilla::BitwiseCast(d); - return HashNumber(u ^ (u >> 32)); - } - static bool match(double lhs, double rhs) { - return mozilla::BitwiseCast(lhs) == mozilla::BitwiseCast(rhs); - } -}; - -template <> -struct DefaultHasher -{ - typedef float Lookup; - static HashNumber hash(float f) { - static_assert(sizeof(HashNumber) == 4, - "subsequent code assumes a four-byte hash"); - return HashNumber(mozilla::BitwiseCast(f)); - } - static bool match(float lhs, float rhs) { - return mozilla::BitwiseCast(lhs) == mozilla::BitwiseCast(rhs); - } -}; - -// A hash policy that compares C strings. -struct CStringHasher -{ - typedef const char* Lookup; - static js::HashNumber hash(Lookup l) { - return mozilla::HashString(l); - } - static bool match(const char* key, Lookup lookup) { - return strcmp(key, lookup) == 0; - } -}; - -// Fallible hashing interface. -// -// Most of the time generating a hash code is infallible so this class provides -// default methods that always succeed. Specialize this class for your own hash -// policy to provide fallible hashing. -// -// This is used by MovableCellHasher to handle the fact that generating a unique -// ID for cell pointer may fail due to OOM. -template -struct FallibleHashMethods -{ - // Return true if a hashcode is already available for its argument. Once - // this returns true for a specific argument it must continue to do so. - template static bool hasHash(Lookup&& l) { return true; } - - // Fallible method to ensure a hashcode exists for its argument and create - // one if not. Returns false on error, e.g. out of memory. - template static bool ensureHash(Lookup&& l) { return true; } -}; - -template -static bool -HasHash(Lookup&& l) { - return FallibleHashMethods::hasHash(mozilla::Forward(l)); -} - -template -static bool -EnsureHash(Lookup&& l) { - return FallibleHashMethods::ensureHash(mozilla::Forward(l)); -} - -/*****************************************************************************/ - -// Both HashMap and HashSet are implemented by a single HashTable that is even -// more heavily parameterized than the other two. This leaves HashTable gnarly -// and extremely coupled to HashMap and HashSet; thus code should not use -// HashTable directly. - -template -class HashMapEntry -{ - Key key_; - Value value_; - - template friend class detail::HashTable; - template friend class detail::HashTableEntry; - template friend class HashMap; - - public: - template - HashMapEntry(KeyInput&& k, ValueInput&& v) - : key_(mozilla::Forward(k)), - value_(mozilla::Forward(v)) - {} - - HashMapEntry(HashMapEntry&& rhs) - : key_(mozilla::Move(rhs.key_)), - value_(mozilla::Move(rhs.value_)) - {} - - void operator=(HashMapEntry&& rhs) { - key_ = mozilla::Move(rhs.key_); - value_ = mozilla::Move(rhs.value_); - } - - typedef Key KeyType; - typedef Value ValueType; - - const Key& key() const { return key_; } - Key& mutableKey() { return key_; } - const Value& value() const { return value_; } - Value& value() { return value_; } - - private: - HashMapEntry(const HashMapEntry&) = delete; - void operator=(const HashMapEntry&) = delete; -}; - -} // namespace js - -namespace mozilla { - -template -struct IsPod > : IsPod {}; - -template -struct IsPod > - : IntegralConstant::value && IsPod::value> -{}; - -} // namespace mozilla - -namespace js { - -namespace detail { - -template -class HashTable; - -template -class HashTableEntry -{ - template friend class HashTable; - typedef typename mozilla::RemoveConst::Type NonConstT; - - HashNumber keyHash; - mozilla::AlignedStorage2 mem; - - static const HashNumber sFreeKey = 0; - static const HashNumber sRemovedKey = 1; - static const HashNumber sCollisionBit = 1; - - static bool isLiveHash(HashNumber hash) - { - return hash > sRemovedKey; - } - - HashTableEntry(const HashTableEntry&) = delete; - void operator=(const HashTableEntry&) = delete; - ~HashTableEntry() = delete; - - public: - // NB: HashTableEntry is treated as a POD: no constructor or destructor calls. - - void destroyIfLive() { - if (isLive()) - mem.addr()->~T(); - } - - void destroy() { - MOZ_ASSERT(isLive()); - mem.addr()->~T(); - } - - void swap(HashTableEntry* other) { - if (this == other) - return; - MOZ_ASSERT(isLive()); - if (other->isLive()) { - mozilla::Swap(*mem.addr(), *other->mem.addr()); - } else { - *other->mem.addr() = mozilla::Move(*mem.addr()); - destroy(); - } - mozilla::Swap(keyHash, other->keyHash); - } - - T& get() { MOZ_ASSERT(isLive()); return *mem.addr(); } - NonConstT& getMutable() { MOZ_ASSERT(isLive()); return *mem.addr(); } - - bool isFree() const { return keyHash == sFreeKey; } - void clearLive() { MOZ_ASSERT(isLive()); keyHash = sFreeKey; mem.addr()->~T(); } - void clear() { if (isLive()) mem.addr()->~T(); keyHash = sFreeKey; } - bool isRemoved() const { return keyHash == sRemovedKey; } - void removeLive() { MOZ_ASSERT(isLive()); keyHash = sRemovedKey; mem.addr()->~T(); } - bool isLive() const { return isLiveHash(keyHash); } - void setCollision() { MOZ_ASSERT(isLive()); keyHash |= sCollisionBit; } - void unsetCollision() { keyHash &= ~sCollisionBit; } - bool hasCollision() const { return keyHash & sCollisionBit; } - bool matchHash(HashNumber hn) { return (keyHash & ~sCollisionBit) == hn; } - HashNumber getKeyHash() const { return keyHash & ~sCollisionBit; } - - template - void setLive(HashNumber hn, Args&&... args) - { - MOZ_ASSERT(!isLive()); - keyHash = hn; - new(mem.addr()) T(mozilla::Forward(args)...); - MOZ_ASSERT(isLive()); - } -}; - -template -class HashTable : private AllocPolicy -{ - friend class mozilla::ReentrancyGuard; - - typedef typename mozilla::RemoveConst::Type NonConstT; - typedef typename HashPolicy::KeyType Key; - typedef typename HashPolicy::Lookup Lookup; - - public: - typedef HashTableEntry Entry; - - // A nullable pointer to a hash table element. A Ptr |p| can be tested - // either explicitly |if (p.found()) p->...| or using boolean conversion - // |if (p) p->...|. Ptr objects must not be used after any mutating hash - // table operations unless |generation()| is tested. - class Ptr - { - friend class HashTable; - - Entry* entry_; -#ifdef JS_DEBUG - const HashTable* table_; - Generation generation; -#endif - - protected: - Ptr(Entry& entry, const HashTable& tableArg) - : entry_(&entry) -#ifdef JS_DEBUG - , table_(&tableArg) - , generation(tableArg.generation()) -#endif - {} - - public: - Ptr() - : entry_(nullptr) -#ifdef JS_DEBUG - , table_(nullptr) - , generation(0) -#endif - {} - - bool isValid() const { - return !entry_; - } - - bool found() const { - if (isValid()) - return false; -#ifdef JS_DEBUG - MOZ_ASSERT(generation == table_->generation()); -#endif - return entry_->isLive(); - } - - explicit operator bool() const { - return found(); - } - - bool operator==(const Ptr& rhs) const { - MOZ_ASSERT(found() && rhs.found()); - return entry_ == rhs.entry_; - } - - bool operator!=(const Ptr& rhs) const { -#ifdef JS_DEBUG - MOZ_ASSERT(generation == table_->generation()); -#endif - return !(*this == rhs); - } - - T& operator*() const { -#ifdef JS_DEBUG - MOZ_ASSERT(found()); - MOZ_ASSERT(generation == table_->generation()); -#endif - return entry_->get(); - } - - T* operator->() const { -#ifdef JS_DEBUG - MOZ_ASSERT(found()); - MOZ_ASSERT(generation == table_->generation()); -#endif - return &entry_->get(); - } - }; - - // A Ptr that can be used to add a key after a failed lookup. - class AddPtr : public Ptr - { - friend class HashTable; - HashNumber keyHash; -#ifdef JS_DEBUG - uint64_t mutationCount; -#endif - - AddPtr(Entry& entry, const HashTable& tableArg, HashNumber hn) - : Ptr(entry, tableArg) - , keyHash(hn) -#ifdef JS_DEBUG - , mutationCount(tableArg.mutationCount) -#endif - {} - - public: - AddPtr() : keyHash(0) {} - }; - - // A collection of hash table entries. The collection is enumerated by - // calling |front()| followed by |popFront()| as long as |!empty()|. As - // with Ptr/AddPtr, Range objects must not be used after any mutating hash - // table operation unless the |generation()| is tested. - class Range - { - protected: - friend class HashTable; - - Range(const HashTable& tableArg, Entry* c, Entry* e) - : cur(c) - , end(e) -#ifdef JS_DEBUG - , table_(&tableArg) - , mutationCount(tableArg.mutationCount) - , generation(tableArg.generation()) - , validEntry(true) -#endif - { - while (cur < end && !cur->isLive()) - ++cur; - } - - Entry* cur; - Entry* end; -#ifdef JS_DEBUG - const HashTable* table_; - uint64_t mutationCount; - Generation generation; - bool validEntry; -#endif - - public: - Range() - : cur(nullptr) - , end(nullptr) -#ifdef JS_DEBUG - , table_(nullptr) - , mutationCount(0) - , generation(0) - , validEntry(false) -#endif - {} - - bool empty() const { -#ifdef JS_DEBUG - MOZ_ASSERT(generation == table_->generation()); - MOZ_ASSERT(mutationCount == table_->mutationCount); -#endif - return cur == end; - } - - T& front() const { - MOZ_ASSERT(!empty()); -#ifdef JS_DEBUG - MOZ_ASSERT(validEntry); - MOZ_ASSERT(generation == table_->generation()); - MOZ_ASSERT(mutationCount == table_->mutationCount); -#endif - return cur->get(); - } - - void popFront() { - MOZ_ASSERT(!empty()); -#ifdef JS_DEBUG - MOZ_ASSERT(generation == table_->generation()); - MOZ_ASSERT(mutationCount == table_->mutationCount); -#endif - while (++cur < end && !cur->isLive()) - continue; -#ifdef JS_DEBUG - validEntry = true; -#endif - } - }; - - // A Range whose lifetime delimits a mutating enumeration of a hash table. - // Since rehashing when elements were removed during enumeration would be - // bad, it is postponed until the Enum is destructed. Since the Enum's - // destructor touches the hash table, the user must ensure that the hash - // table is still alive when the destructor runs. - class Enum : public Range - { - friend class HashTable; - - HashTable& table_; - bool rekeyed; - bool removed; - - /* Not copyable. */ - Enum(const Enum&) = delete; - void operator=(const Enum&) = delete; - - public: - template explicit - Enum(Map& map) : Range(map.all()), table_(map.impl), rekeyed(false), removed(false) {} - - // Removes the |front()| element from the table, leaving |front()| - // invalid until the next call to |popFront()|. For example: - // - // HashSet s; - // for (HashSet::Enum e(s); !e.empty(); e.popFront()) - // if (e.front() == 42) - // e.removeFront(); - void removeFront() { - table_.remove(*this->cur); - removed = true; -#ifdef JS_DEBUG - this->validEntry = false; - this->mutationCount = table_.mutationCount; -#endif - } - - NonConstT& mutableFront() { - MOZ_ASSERT(!this->empty()); -#ifdef JS_DEBUG - MOZ_ASSERT(this->validEntry); - MOZ_ASSERT(this->generation == this->Range::table_->generation()); - MOZ_ASSERT(this->mutationCount == this->Range::table_->mutationCount); -#endif - return this->cur->getMutable(); - } - - // Removes the |front()| element and re-inserts it into the table with - // a new key at the new Lookup position. |front()| is invalid after - // this operation until the next call to |popFront()|. - void rekeyFront(const Lookup& l, const Key& k) { - MOZ_ASSERT(&k != &HashPolicy::getKey(this->cur->get())); - Ptr p(*this->cur, table_); - table_.rekeyWithoutRehash(p, l, k); - rekeyed = true; -#ifdef JS_DEBUG - this->validEntry = false; - this->mutationCount = table_.mutationCount; -#endif - } - - void rekeyFront(const Key& k) { - rekeyFront(k, k); - } - - // Potentially rehashes the table. - ~Enum() { - if (rekeyed) { - table_.gen++; - table_.checkOverRemoved(); - } - - if (removed) - table_.compactIfUnderloaded(); - } - }; - - // HashTable is movable - HashTable(HashTable&& rhs) - : AllocPolicy(rhs) - { - mozilla::PodAssign(this, &rhs); - rhs.table = nullptr; - } - void operator=(HashTable&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - if (table) - destroyTable(*this, table, capacity()); - mozilla::PodAssign(this, &rhs); - rhs.table = nullptr; - } - - private: - // HashTable is not copyable or assignable - HashTable(const HashTable&) = delete; - void operator=(const HashTable&) = delete; - - private: - static const size_t CAP_BITS = 30; - - public: - uint64_t gen:56; // entry storage generation number - uint64_t hashShift:8; // multiplicative hash shift - Entry* table; // entry storage - uint32_t entryCount; // number of entries in table - uint32_t removedCount; // removed entry sentinels in table - -#ifdef JS_DEBUG - uint64_t mutationCount; - mutable bool mEntered; - // Note that some updates to these stats are not thread-safe. See the - // comment on the three-argument overloading of HashTable::lookup(). - mutable struct Stats - { - uint32_t searches; // total number of table searches - uint32_t steps; // hash chain links traversed - uint32_t hits; // searches that found key - uint32_t misses; // searches that didn't find key - uint32_t addOverRemoved; // adds that recycled a removed entry - uint32_t removes; // calls to remove - uint32_t removeFrees; // calls to remove that freed the entry - uint32_t grows; // table expansions - uint32_t shrinks; // table contractions - uint32_t compresses; // table compressions - uint32_t rehashes; // tombstone decontaminations - } stats; -# define METER(x) x -#else -# define METER(x) -#endif - - // The default initial capacity is 32 (enough to hold 16 elements), but it - // can be as low as 4. - static const unsigned sMinCapacityLog2 = 2; - static const unsigned sMinCapacity = 1 << sMinCapacityLog2; - static const unsigned sMaxInit = JS_BIT(CAP_BITS - 1); - static const unsigned sMaxCapacity = JS_BIT(CAP_BITS); - static const unsigned sHashBits = mozilla::tl::BitSize::value; - - // Hash-table alpha is conceptually a fraction, but to avoid floating-point - // math we implement it as a ratio of integers. - static const uint8_t sAlphaDenominator = 4; - static const uint8_t sMinAlphaNumerator = 1; // min alpha: 1/4 - static const uint8_t sMaxAlphaNumerator = 3; // max alpha: 3/4 - - static const HashNumber sFreeKey = Entry::sFreeKey; - static const HashNumber sRemovedKey = Entry::sRemovedKey; - static const HashNumber sCollisionBit = Entry::sCollisionBit; - - void setTableSizeLog2(unsigned sizeLog2) - { - hashShift = sHashBits - sizeLog2; - } - - static bool isLiveHash(HashNumber hash) - { - return Entry::isLiveHash(hash); - } - - static HashNumber prepareHash(const Lookup& l) - { - HashNumber keyHash = ScrambleHashCode(HashPolicy::hash(l)); - - // Avoid reserved hash codes. - if (!isLiveHash(keyHash)) - keyHash -= (sRemovedKey + 1); - return keyHash & ~sCollisionBit; - } - - enum FailureBehavior { DontReportFailure = false, ReportFailure = true }; - - static Entry* createTable(AllocPolicy& alloc, uint32_t capacity, - FailureBehavior reportFailure = ReportFailure) - { - static_assert(sFreeKey == 0, - "newly-calloc'd tables have to be considered empty"); - if (reportFailure) - return alloc.template pod_calloc(capacity); - - return alloc.template maybe_pod_calloc(capacity); - } - - static Entry* maybeCreateTable(AllocPolicy& alloc, uint32_t capacity) - { - static_assert(sFreeKey == 0, - "newly-calloc'd tables have to be considered empty"); - return alloc.template maybe_pod_calloc(capacity); - } - - static void destroyTable(AllocPolicy& alloc, Entry* oldTable, uint32_t capacity) - { - Entry* end = oldTable + capacity; - for (Entry* e = oldTable; e < end; ++e) - e->destroyIfLive(); - alloc.free_(oldTable); - } - - public: - explicit HashTable(AllocPolicy ap) - : AllocPolicy(ap) - , gen(0) - , hashShift(sHashBits) - , table(nullptr) - , entryCount(0) - , removedCount(0) -#ifdef JS_DEBUG - , mutationCount(0) - , mEntered(false) -#endif - {} - - MOZ_MUST_USE bool init(uint32_t length) - { - MOZ_ASSERT(!initialized()); - - // Reject all lengths whose initial computed capacity would exceed - // sMaxCapacity. Round that maximum length down to the nearest power - // of two for speedier code. - if (MOZ_UNLIKELY(length > sMaxInit)) { - this->reportAllocOverflow(); - return false; - } - - static_assert((sMaxInit * sAlphaDenominator) / sAlphaDenominator == sMaxInit, - "multiplication in numerator below could overflow"); - static_assert(sMaxInit * sAlphaDenominator <= UINT32_MAX - sMaxAlphaNumerator, - "numerator calculation below could potentially overflow"); - - // Compute the smallest capacity allowing |length| elements to be - // inserted without rehashing: ceil(length / max-alpha). (Ceiling - // integral division: .) - uint32_t newCapacity = - (length * sAlphaDenominator + sMaxAlphaNumerator - 1) / sMaxAlphaNumerator; - if (newCapacity < sMinCapacity) - newCapacity = sMinCapacity; - - // FIXME: use JS_CEILING_LOG2 when PGO stops crashing (bug 543034). - uint32_t roundUp = sMinCapacity, roundUpLog2 = sMinCapacityLog2; - while (roundUp < newCapacity) { - roundUp <<= 1; - ++roundUpLog2; - } - - newCapacity = roundUp; - MOZ_ASSERT(newCapacity >= length); - MOZ_ASSERT(newCapacity <= sMaxCapacity); - - table = createTable(*this, newCapacity); - if (!table) - return false; - - setTableSizeLog2(roundUpLog2); - METER(memset(&stats, 0, sizeof(stats))); - return true; - } - - bool initialized() const - { - return !!table; - } - - ~HashTable() - { - if (table) - destroyTable(*this, table, capacity()); - } - - private: - HashNumber hash1(HashNumber hash0) const - { - return hash0 >> hashShift; - } - - struct DoubleHash - { - HashNumber h2; - HashNumber sizeMask; - }; - - DoubleHash hash2(HashNumber curKeyHash) const - { - unsigned sizeLog2 = sHashBits - hashShift; - DoubleHash dh = { - ((curKeyHash << sizeLog2) >> hashShift) | 1, - (HashNumber(1) << sizeLog2) - 1 - }; - return dh; - } - - static HashNumber applyDoubleHash(HashNumber h1, const DoubleHash& dh) - { - return (h1 - dh.h2) & dh.sizeMask; - } - - bool overloaded() - { - static_assert(sMaxCapacity <= UINT32_MAX / sMaxAlphaNumerator, - "multiplication below could overflow"); - return entryCount + removedCount >= - capacity() * sMaxAlphaNumerator / sAlphaDenominator; - } - - // Would the table be underloaded if it had the given capacity and entryCount? - static bool wouldBeUnderloaded(uint32_t capacity, uint32_t entryCount) - { - static_assert(sMaxCapacity <= UINT32_MAX / sMinAlphaNumerator, - "multiplication below could overflow"); - return capacity > sMinCapacity && - entryCount <= capacity * sMinAlphaNumerator / sAlphaDenominator; - } - - bool underloaded() - { - return wouldBeUnderloaded(capacity(), entryCount); - } - - static bool match(Entry& e, const Lookup& l) - { - return HashPolicy::match(HashPolicy::getKey(e.get()), l); - } - - // Warning: in order for readonlyThreadsafeLookup() to be safe this - // function must not modify the table in any way when |collisionBit| is 0. - // (The use of the METER() macro to increment stats violates this - // restriction but we will live with that for now because it's enabled so - // rarely.) - Entry& lookup(const Lookup& l, HashNumber keyHash, unsigned collisionBit) const - { - MOZ_ASSERT(isLiveHash(keyHash)); - MOZ_ASSERT(!(keyHash & sCollisionBit)); - MOZ_ASSERT(collisionBit == 0 || collisionBit == sCollisionBit); - MOZ_ASSERT(table); - METER(stats.searches++); - - // Compute the primary hash address. - HashNumber h1 = hash1(keyHash); - Entry* entry = &table[h1]; - - // Miss: return space for a new entry. - if (entry->isFree()) { - METER(stats.misses++); - return *entry; - } - - // Hit: return entry. - if (entry->matchHash(keyHash) && match(*entry, l)) { - METER(stats.hits++); - return *entry; - } - - // Collision: double hash. - DoubleHash dh = hash2(keyHash); - - // Save the first removed entry pointer so we can recycle later. - Entry* firstRemoved = nullptr; - - while (true) { - if (MOZ_UNLIKELY(entry->isRemoved())) { - if (!firstRemoved) - firstRemoved = entry; - } else { - if (collisionBit == sCollisionBit) - entry->setCollision(); - } - - METER(stats.steps++); - h1 = applyDoubleHash(h1, dh); - - entry = &table[h1]; - if (entry->isFree()) { - METER(stats.misses++); - return firstRemoved ? *firstRemoved : *entry; - } - - if (entry->matchHash(keyHash) && match(*entry, l)) { - METER(stats.hits++); - return *entry; - } - } - } - - // This is a copy of lookup hardcoded to the assumptions: - // 1. the lookup is a lookupForAdd - // 2. the key, whose |keyHash| has been passed is not in the table, - // 3. no entries have been removed from the table. - // This specialized search avoids the need for recovering lookup values - // from entries, which allows more flexible Lookup/Key types. - Entry& findFreeEntry(HashNumber keyHash) - { - MOZ_ASSERT(!(keyHash & sCollisionBit)); - MOZ_ASSERT(table); - METER(stats.searches++); - - // We assume 'keyHash' has already been distributed. - - // Compute the primary hash address. - HashNumber h1 = hash1(keyHash); - Entry* entry = &table[h1]; - - // Miss: return space for a new entry. - if (!entry->isLive()) { - METER(stats.misses++); - return *entry; - } - - // Collision: double hash. - DoubleHash dh = hash2(keyHash); - - while (true) { - MOZ_ASSERT(!entry->isRemoved()); - entry->setCollision(); - - METER(stats.steps++); - h1 = applyDoubleHash(h1, dh); - - entry = &table[h1]; - if (!entry->isLive()) { - METER(stats.misses++); - return *entry; - } - } - } - - enum RebuildStatus { NotOverloaded, Rehashed, RehashFailed }; - - RebuildStatus changeTableSize(int deltaLog2, FailureBehavior reportFailure = ReportFailure) - { - // Look, but don't touch, until we succeed in getting new entry store. - Entry* oldTable = table; - uint32_t oldCap = capacity(); - uint32_t newLog2 = sHashBits - hashShift + deltaLog2; - uint32_t newCapacity = JS_BIT(newLog2); - if (MOZ_UNLIKELY(newCapacity > sMaxCapacity)) { - if (reportFailure) - this->reportAllocOverflow(); - return RehashFailed; - } - - Entry* newTable = createTable(*this, newCapacity, reportFailure); - if (!newTable) - return RehashFailed; - - // We can't fail from here on, so update table parameters. - setTableSizeLog2(newLog2); - removedCount = 0; - gen++; - table = newTable; - - // Copy only live entries, leaving removed ones behind. - Entry* end = oldTable + oldCap; - for (Entry* src = oldTable; src < end; ++src) { - if (src->isLive()) { - HashNumber hn = src->getKeyHash(); - findFreeEntry(hn).setLive( - hn, mozilla::Move(const_cast(src->get()))); - src->destroy(); - } - } - - // All entries have been destroyed, no need to destroyTable. - this->free_(oldTable); - return Rehashed; - } - - bool shouldCompressTable() - { - // Compress if a quarter or more of all entries are removed. - return removedCount >= (capacity() >> 2); - } - - RebuildStatus checkOverloaded(FailureBehavior reportFailure = ReportFailure) - { - if (!overloaded()) - return NotOverloaded; - - int deltaLog2; - if (shouldCompressTable()) { - METER(stats.compresses++); - deltaLog2 = 0; - } else { - METER(stats.grows++); - deltaLog2 = 1; - } - - return changeTableSize(deltaLog2, reportFailure); - } - - // Infallibly rehash the table if we are overloaded with removals. - void checkOverRemoved() - { - if (overloaded()) { - if (checkOverloaded(DontReportFailure) == RehashFailed) - rehashTableInPlace(); - } - } - - void remove(Entry& e) - { - MOZ_ASSERT(table); - METER(stats.removes++); - - if (e.hasCollision()) { - e.removeLive(); - removedCount++; - } else { - METER(stats.removeFrees++); - e.clearLive(); - } - entryCount--; -#ifdef JS_DEBUG - mutationCount++; -#endif - } - - void checkUnderloaded() - { - if (underloaded()) { - METER(stats.shrinks++); - (void) changeTableSize(-1, DontReportFailure); - } - } - - // Resize the table down to the largest capacity which doesn't underload the - // table. Since we call checkUnderloaded() on every remove, you only need - // to call this after a bulk removal of items done without calling remove(). - void compactIfUnderloaded() - { - int32_t resizeLog2 = 0; - uint32_t newCapacity = capacity(); - while (wouldBeUnderloaded(newCapacity, entryCount)) { - newCapacity = newCapacity >> 1; - resizeLog2--; - } - - if (resizeLog2 != 0) - (void) changeTableSize(resizeLog2, DontReportFailure); - } - - // This is identical to changeTableSize(currentSize), but without requiring - // a second table. We do this by recycling the collision bits to tell us if - // the element is already inserted or still waiting to be inserted. Since - // already-inserted elements win any conflicts, we get the same table as we - // would have gotten through random insertion order. - void rehashTableInPlace() - { - METER(stats.rehashes++); - removedCount = 0; - for (size_t i = 0; i < capacity(); ++i) - table[i].unsetCollision(); - - for (size_t i = 0; i < capacity();) { - Entry* src = &table[i]; - - if (!src->isLive() || src->hasCollision()) { - ++i; - continue; - } - - HashNumber keyHash = src->getKeyHash(); - HashNumber h1 = hash1(keyHash); - DoubleHash dh = hash2(keyHash); - Entry* tgt = &table[h1]; - while (true) { - if (!tgt->hasCollision()) { - src->swap(tgt); - tgt->setCollision(); - break; - } - - h1 = applyDoubleHash(h1, dh); - tgt = &table[h1]; - } - } - - // TODO: this algorithm leaves collision bits on *all* elements, even if - // they are on no collision path. We have the option of setting the - // collision bits correctly on a subsequent pass or skipping the rehash - // unless we are totally filled with tombstones: benchmark to find out - // which approach is best. - } - - // Note: |l| may be a reference to a piece of |u|, so this function - // must take care not to use |l| after moving |u|. - // - // Prefer to use putNewInfallible; this function does not check - // invariants. - template - void putNewInfallibleInternal(const Lookup& l, Args&&... args) - { - MOZ_ASSERT(table); - - HashNumber keyHash = prepareHash(l); - Entry* entry = &findFreeEntry(keyHash); - MOZ_ASSERT(entry); - - if (entry->isRemoved()) { - METER(stats.addOverRemoved++); - removedCount--; - keyHash |= sCollisionBit; - } - - entry->setLive(keyHash, mozilla::Forward(args)...); - entryCount++; -#ifdef JS_DEBUG - mutationCount++; -#endif - } - - public: - void clear() - { - if (mozilla::IsPod::value) { - memset(table, 0, sizeof(*table) * capacity()); - } else { - uint32_t tableCapacity = capacity(); - Entry* end = table + tableCapacity; - for (Entry* e = table; e < end; ++e) - e->clear(); - } - removedCount = 0; - entryCount = 0; -#ifdef JS_DEBUG - mutationCount++; -#endif - } - - void finish() - { -#ifdef JS_DEBUG - MOZ_ASSERT(!mEntered); -#endif - if (!table) - return; - - destroyTable(*this, table, capacity()); - table = nullptr; - gen++; - entryCount = 0; - removedCount = 0; -#ifdef JS_DEBUG - mutationCount++; -#endif - } - - Range all() const - { - MOZ_ASSERT(table); - return Range(*this, table, table + capacity()); - } - - bool empty() const - { - MOZ_ASSERT(table); - return !entryCount; - } - - uint32_t count() const - { - MOZ_ASSERT(table); - return entryCount; - } - - uint32_t capacity() const - { - MOZ_ASSERT(table); - return JS_BIT(sHashBits - hashShift); - } - - Generation generation() const - { - MOZ_ASSERT(table); - return Generation(gen); - } - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const - { - return mallocSizeOf(table); - } - - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const - { - return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf); - } - - Ptr lookup(const Lookup& l) const - { - mozilla::ReentrancyGuard g(*this); - if (!HasHash(l)) - return Ptr(); - HashNumber keyHash = prepareHash(l); - return Ptr(lookup(l, keyHash, 0), *this); - } - - Ptr readonlyThreadsafeLookup(const Lookup& l) const - { - if (!HasHash(l)) - return Ptr(); - HashNumber keyHash = prepareHash(l); - return Ptr(lookup(l, keyHash, 0), *this); - } - - AddPtr lookupForAdd(const Lookup& l) const - { - mozilla::ReentrancyGuard g(*this); - if (!EnsureHash(l)) - return AddPtr(); - HashNumber keyHash = prepareHash(l); - Entry& entry = lookup(l, keyHash, sCollisionBit); - AddPtr p(entry, *this, keyHash); - return p; - } - - template - MOZ_MUST_USE bool add(AddPtr& p, Args&&... args) - { - mozilla::ReentrancyGuard g(*this); - MOZ_ASSERT(table); - MOZ_ASSERT(!p.found()); - MOZ_ASSERT(!(p.keyHash & sCollisionBit)); - - // Check for error from ensureHash() here. - if (p.isValid()) - return false; - - // Changing an entry from removed to live does not affect whether we - // are overloaded and can be handled separately. - if (p.entry_->isRemoved()) { - if (!this->checkSimulatedOOM()) - return false; - METER(stats.addOverRemoved++); - removedCount--; - p.keyHash |= sCollisionBit; - } else { - // Preserve the validity of |p.entry_|. - RebuildStatus status = checkOverloaded(); - if (status == RehashFailed) - return false; - if (status == NotOverloaded && !this->checkSimulatedOOM()) - return false; - if (status == Rehashed) - p.entry_ = &findFreeEntry(p.keyHash); - } - - p.entry_->setLive(p.keyHash, mozilla::Forward(args)...); - entryCount++; -#ifdef JS_DEBUG - mutationCount++; - p.generation = generation(); - p.mutationCount = mutationCount; -#endif - return true; - } - - // Note: |l| may be a reference to a piece of |u|, so this function - // must take care not to use |l| after moving |u|. - template - void putNewInfallible(const Lookup& l, Args&&... args) - { - MOZ_ASSERT(!lookup(l).found()); - mozilla::ReentrancyGuard g(*this); - putNewInfallibleInternal(l, mozilla::Forward(args)...); - } - - // Note: |l| may be alias arguments in |args|, so this function must take - // care not to use |l| after moving |args|. - template - MOZ_MUST_USE bool putNew(const Lookup& l, Args&&... args) - { - if (!this->checkSimulatedOOM()) - return false; - - if (!EnsureHash(l)) - return false; - - if (checkOverloaded() == RehashFailed) - return false; - - putNewInfallible(l, mozilla::Forward(args)...); - return true; - } - - // Note: |l| may be a reference to a piece of |u|, so this function - // must take care not to use |l| after moving |u|. - template - MOZ_MUST_USE bool relookupOrAdd(AddPtr& p, const Lookup& l, Args&&... args) - { - // Check for error from ensureHash() here. - if (p.isValid()) - return false; - -#ifdef JS_DEBUG - p.generation = generation(); - p.mutationCount = mutationCount; -#endif - { - mozilla::ReentrancyGuard g(*this); - MOZ_ASSERT(prepareHash(l) == p.keyHash); // l has not been destroyed - p.entry_ = &lookup(l, p.keyHash, sCollisionBit); - } - return p.found() || add(p, mozilla::Forward(args)...); - } - - void remove(Ptr p) - { - MOZ_ASSERT(table); - mozilla::ReentrancyGuard g(*this); - MOZ_ASSERT(p.found()); - remove(*p.entry_); - checkUnderloaded(); - } - - void rekeyWithoutRehash(Ptr p, const Lookup& l, const Key& k) - { - MOZ_ASSERT(table); - mozilla::ReentrancyGuard g(*this); - MOZ_ASSERT(p.found()); - typename HashTableEntry::NonConstT t(mozilla::Move(*p)); - HashPolicy::setKey(t, const_cast(k)); - remove(*p.entry_); - putNewInfallibleInternal(l, mozilla::Move(t)); - } - - void rekeyAndMaybeRehash(Ptr p, const Lookup& l, const Key& k) - { - rekeyWithoutRehash(p, l, k); - checkOverRemoved(); - } - -#undef METER -}; - -} // namespace detail -} // namespace js - -#endif /* js_HashTable_h */ diff --git a/android/x86/include/spidermonkey/js/HeapAPI.h b/android/x86/include/spidermonkey/js/HeapAPI.h deleted file mode 100644 index e37d13e9..00000000 --- a/android/x86/include/spidermonkey/js/HeapAPI.h +++ /dev/null @@ -1,406 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_HeapAPI_h -#define js_HeapAPI_h - -#include - -#include "jspubtd.h" - -#include "js/TraceKind.h" -#include "js/Utility.h" - -/* These values are private to the JS engine. */ -namespace js { - -JS_FRIEND_API(bool) -CurrentThreadCanAccessZone(JS::Zone* zone); - -namespace gc { - -struct Cell; - -const size_t ArenaShift = 12; -const size_t ArenaSize = size_t(1) << ArenaShift; -const size_t ArenaMask = ArenaSize - 1; - -#ifdef JS_GC_SMALL_CHUNK_SIZE -const size_t ChunkShift = 18; -#else -const size_t ChunkShift = 20; -#endif -const size_t ChunkSize = size_t(1) << ChunkShift; -const size_t ChunkMask = ChunkSize - 1; - -const size_t CellShift = 3; -const size_t CellSize = size_t(1) << CellShift; -const size_t CellMask = CellSize - 1; - -/* These are magic constants derived from actual offsets in gc/Heap.h. */ -#ifdef JS_GC_SMALL_CHUNK_SIZE -const size_t ChunkMarkBitmapOffset = 258104; -const size_t ChunkMarkBitmapBits = 31744; -#else -const size_t ChunkMarkBitmapOffset = 1032352; -const size_t ChunkMarkBitmapBits = 129024; -#endif -const size_t ChunkRuntimeOffset = ChunkSize - sizeof(void*); -const size_t ChunkTrailerSize = 2 * sizeof(uintptr_t) + sizeof(uint64_t); -const size_t ChunkLocationOffset = ChunkSize - ChunkTrailerSize; -const size_t ArenaZoneOffset = sizeof(size_t); -const size_t ArenaHeaderSize = sizeof(size_t) + 2 * sizeof(uintptr_t) + - sizeof(size_t) + sizeof(uintptr_t); - -/* - * Live objects are marked black. How many other additional colors are available - * depends on the size of the GCThing. Objects marked gray are eligible for - * cycle collection. - */ -static const uint32_t BLACK = 0; -static const uint32_t GRAY = 1; - -/* - * The "location" field in the Chunk trailer is a enum indicating various roles - * of the chunk. - */ -enum class ChunkLocation : uint32_t -{ - Invalid = 0, - Nursery = 1, - TenuredHeap = 2 -}; - -#ifdef JS_DEBUG -/* When downcasting, ensure we are actually the right type. */ -extern JS_FRIEND_API(void) -AssertGCThingHasType(js::gc::Cell* cell, JS::TraceKind kind); -#else -inline void -AssertGCThingHasType(js::gc::Cell* cell, JS::TraceKind kind) {} -#endif - -MOZ_ALWAYS_INLINE bool IsInsideNursery(const js::gc::Cell* cell); - -} /* namespace gc */ -} /* namespace js */ - -namespace JS { -struct Zone; - -/* Default size for the generational nursery in bytes. */ -const uint32_t DefaultNurseryBytes = 16 * js::gc::ChunkSize; - -/* Default maximum heap size in bytes to pass to JS_NewRuntime(). */ -const uint32_t DefaultHeapMaxBytes = 32 * 1024 * 1024; - -namespace shadow { - -struct Zone -{ - protected: - JSRuntime* const runtime_; - JSTracer* const barrierTracer_; // A pointer to the JSRuntime's |gcMarker|. - - public: - // Stack GC roots for Rooted GC pointers. - js::RootedListHeads stackRoots_; - template friend class JS::Rooted; - - bool needsIncrementalBarrier_; - - Zone(JSRuntime* runtime, JSTracer* barrierTracerArg) - : runtime_(runtime), - barrierTracer_(barrierTracerArg), - needsIncrementalBarrier_(false) - { - for (auto& stackRootPtr : stackRoots_) - stackRootPtr = nullptr; - } - - bool needsIncrementalBarrier() const { - return needsIncrementalBarrier_; - } - - JSTracer* barrierTracer() { - MOZ_ASSERT(needsIncrementalBarrier_); - MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_)); - return barrierTracer_; - } - - JSRuntime* runtimeFromMainThread() const { - MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_)); - return runtime_; - } - - // Note: Unrestricted access to the zone's runtime from an arbitrary - // thread can easily lead to races. Use this method very carefully. - JSRuntime* runtimeFromAnyThread() const { - return runtime_; - } - - static MOZ_ALWAYS_INLINE JS::shadow::Zone* asShadowZone(JS::Zone* zone) { - return reinterpret_cast(zone); - } -}; - -} /* namespace shadow */ - -/** - * A GC pointer, tagged with the trace kind. - * - * In general, a GC pointer should be stored with an exact type. This class - * is for use when that is not possible because a single pointer must point - * to several kinds of GC thing. - */ -class JS_FRIEND_API(GCCellPtr) -{ - public: - // Construction from a void* and trace kind. - GCCellPtr(void* gcthing, JS::TraceKind traceKind) : ptr(checkedCast(gcthing, traceKind)) {} - - // Automatically construct a null GCCellPtr from nullptr. - MOZ_IMPLICIT GCCellPtr(decltype(nullptr)) : ptr(checkedCast(nullptr, JS::TraceKind::Null)) {} - - // Construction from an explicit type. - template - explicit GCCellPtr(T* p) : ptr(checkedCast(p, JS::MapTypeToTraceKind::kind)) { } - explicit GCCellPtr(JSFunction* p) : ptr(checkedCast(p, JS::TraceKind::Object)) { } - explicit GCCellPtr(JSFlatString* str) : ptr(checkedCast(str, JS::TraceKind::String)) { } - explicit GCCellPtr(const Value& v); - - JS::TraceKind kind() const { - JS::TraceKind traceKind = JS::TraceKind(ptr & OutOfLineTraceKindMask); - if (uintptr_t(traceKind) != OutOfLineTraceKindMask) - return traceKind; - return outOfLineKind(); - } - - // Allow GCCellPtr to be used in a boolean context. - explicit operator bool() const { - MOZ_ASSERT(bool(asCell()) == (kind() != JS::TraceKind::Null)); - return asCell(); - } - - // Simplify checks to the kind. - template - bool is() const { return kind() == JS::MapTypeToTraceKind::kind; } - - // Conversions to more specific types must match the kind. Access to - // further refined types is not allowed directly from a GCCellPtr. - template - T& as() const { - MOZ_ASSERT(kind() == JS::MapTypeToTraceKind::kind); - // We can't use static_cast here, because the fact that JSObject - // inherits from js::gc::Cell is not part of the public API. - return *reinterpret_cast(asCell()); - } - - // Return a pointer to the cell this |GCCellPtr| refers to, or |nullptr|. - // (It would be more symmetrical with |to| for this to return a |Cell&|, but - // the result can be |nullptr|, and null references are undefined behavior.) - js::gc::Cell* asCell() const { - return reinterpret_cast(ptr & ~OutOfLineTraceKindMask); - } - - // The CC's trace logger needs an identity that is XPIDL serializable. - uint64_t unsafeAsInteger() const { - return static_cast(unsafeAsUIntPtr()); - } - // Inline mark bitmap access requires direct pointer arithmetic. - uintptr_t unsafeAsUIntPtr() const { - MOZ_ASSERT(asCell()); - MOZ_ASSERT(!js::gc::IsInsideNursery(asCell())); - return reinterpret_cast(asCell()); - } - - bool mayBeOwnedByOtherRuntime() const; - - private: - static uintptr_t checkedCast(void* p, JS::TraceKind traceKind) { - js::gc::Cell* cell = static_cast(p); - MOZ_ASSERT((uintptr_t(p) & OutOfLineTraceKindMask) == 0); - AssertGCThingHasType(cell, traceKind); - // Note: the OutOfLineTraceKindMask bits are set on all out-of-line kinds - // so that we can mask instead of branching. - MOZ_ASSERT_IF(uintptr_t(traceKind) >= OutOfLineTraceKindMask, - (uintptr_t(traceKind) & OutOfLineTraceKindMask) == OutOfLineTraceKindMask); - return uintptr_t(p) | (uintptr_t(traceKind) & OutOfLineTraceKindMask); - } - - JS::TraceKind outOfLineKind() const; - - uintptr_t ptr; -}; - -inline bool -operator==(const GCCellPtr& ptr1, const GCCellPtr& ptr2) -{ - return ptr1.asCell() == ptr2.asCell(); -} - -inline bool -operator!=(const GCCellPtr& ptr1, const GCCellPtr& ptr2) -{ - return !(ptr1 == ptr2); -} - -// Unwraps the given GCCellPtr and calls the given functor with a template -// argument of the actual type of the pointer. -template -auto -DispatchTyped(F f, GCCellPtr thing, Args&&... args) - -> decltype(f(static_cast(nullptr), mozilla::Forward(args)...)) -{ - switch (thing.kind()) { -#define JS_EXPAND_DEF(name, type, _) \ - case JS::TraceKind::name: \ - return f(&thing.as(), mozilla::Forward(args)...); - JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF); -#undef JS_EXPAND_DEF - default: - MOZ_CRASH("Invalid trace kind in DispatchTyped for GCCellPtr."); - } -} - -} /* namespace JS */ - -namespace js { -namespace gc { -namespace detail { - -static MOZ_ALWAYS_INLINE uintptr_t* -GetGCThingMarkBitmap(const uintptr_t addr) -{ - MOZ_ASSERT(addr); - const uintptr_t bmap_addr = (addr & ~ChunkMask) | ChunkMarkBitmapOffset; - return reinterpret_cast(bmap_addr); -} - -static MOZ_ALWAYS_INLINE void -GetGCThingMarkWordAndMask(const uintptr_t addr, uint32_t color, - uintptr_t** wordp, uintptr_t* maskp) -{ - MOZ_ASSERT(addr); - const size_t bit = (addr & js::gc::ChunkMask) / js::gc::CellSize + color; - MOZ_ASSERT(bit < js::gc::ChunkMarkBitmapBits); - uintptr_t* bitmap = GetGCThingMarkBitmap(addr); - const uintptr_t nbits = sizeof(*bitmap) * CHAR_BIT; - *maskp = uintptr_t(1) << (bit % nbits); - *wordp = &bitmap[bit / nbits]; -} - -static MOZ_ALWAYS_INLINE JS::Zone* -GetGCThingZone(const uintptr_t addr) -{ - MOZ_ASSERT(addr); - const uintptr_t zone_addr = (addr & ~ArenaMask) | ArenaZoneOffset; - return *reinterpret_cast(zone_addr); - -} - -static MOZ_ALWAYS_INLINE JS::shadow::Runtime* -GetCellRuntime(const Cell* cell) -{ - MOZ_ASSERT(cell); - const uintptr_t addr = uintptr_t(cell); - const uintptr_t rt_addr = (addr & ~ChunkMask) | ChunkRuntimeOffset; - return *reinterpret_cast(rt_addr); -} - -static MOZ_ALWAYS_INLINE bool -CellIsMarkedGray(const Cell* cell) -{ - MOZ_ASSERT(cell); - if (js::gc::IsInsideNursery(cell)) - return false; - - uintptr_t* word, mask; - js::gc::detail::GetGCThingMarkWordAndMask(uintptr_t(cell), js::gc::GRAY, &word, &mask); - return *word & mask; -} - -extern JS_PUBLIC_API(bool) -CellIsMarkedGrayIfKnown(const Cell* cell); - -} /* namespace detail */ - -MOZ_ALWAYS_INLINE bool -IsInsideNursery(const js::gc::Cell* cell) -{ - if (!cell) - return false; - uintptr_t addr = uintptr_t(cell); - addr &= ~js::gc::ChunkMask; - addr |= js::gc::ChunkLocationOffset; - auto location = *reinterpret_cast(addr); - MOZ_ASSERT(location == ChunkLocation::Nursery || location == ChunkLocation::TenuredHeap); - return location == ChunkLocation::Nursery; -} - -} /* namespace gc */ -} /* namespace js */ - -namespace JS { - -static MOZ_ALWAYS_INLINE Zone* -GetTenuredGCThingZone(GCCellPtr thing) -{ - MOZ_ASSERT(!js::gc::IsInsideNursery(thing.asCell())); - return js::gc::detail::GetGCThingZone(thing.unsafeAsUIntPtr()); -} - -static MOZ_ALWAYS_INLINE Zone* -GetStringZone(JSString* str) -{ - return js::gc::detail::GetGCThingZone(uintptr_t(str)); -} - -extern JS_PUBLIC_API(Zone*) -GetObjectZone(JSObject* obj); - -static MOZ_ALWAYS_INLINE bool -GCThingIsMarkedGray(GCCellPtr thing) -{ - if (thing.mayBeOwnedByOtherRuntime()) - return false; - return js::gc::detail::CellIsMarkedGrayIfKnown(thing.asCell()); -} - -extern JS_PUBLIC_API(JS::TraceKind) -GCThingTraceKind(void* thing); - -} /* namespace JS */ - -namespace js { -namespace gc { - -static MOZ_ALWAYS_INLINE bool -IsIncrementalBarrierNeededOnTenuredGCThing(JS::shadow::Runtime* rt, const JS::GCCellPtr thing) -{ - MOZ_ASSERT(thing); - MOZ_ASSERT(!js::gc::IsInsideNursery(thing.asCell())); - - // TODO: I'd like to assert !isHeapBusy() here but this gets called while we - // are tracing the heap, e.g. during memory reporting (see bug 1313318). - MOZ_ASSERT(!rt->isHeapCollecting()); - - JS::Zone* zone = JS::GetTenuredGCThingZone(thing); - return JS::shadow::Zone::asShadowZone(zone)->needsIncrementalBarrier(); -} - -/** - * Create an object providing access to the garbage collector's internal notion - * of the current state of memory (both GC heap memory and GCthing-controlled - * malloc memory. - */ -extern JS_PUBLIC_API(JSObject*) -NewMemoryInfoObject(JSContext* cx); - -} /* namespace gc */ -} /* namespace js */ - -#endif /* js_HeapAPI_h */ diff --git a/android/x86/include/spidermonkey/js/Id.h b/android/x86/include/spidermonkey/js/Id.h deleted file mode 100644 index d474e784..00000000 --- a/android/x86/include/spidermonkey/js/Id.h +++ /dev/null @@ -1,207 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_Id_h -#define js_Id_h - -// A jsid is an identifier for a property or method of an object which is -// either a 31-bit unsigned integer, interned string or symbol. -// -// Also, there is an additional jsid value, JSID_VOID, which does not occur in -// JS scripts but may be used to indicate the absence of a valid jsid. A void -// jsid is not a valid id and only arises as an exceptional API return value, -// such as in JS_NextProperty. Embeddings must not pass JSID_VOID into JSAPI -// entry points expecting a jsid and do not need to handle JSID_VOID in hooks -// receiving a jsid except when explicitly noted in the API contract. -// -// A jsid is not implicitly convertible to or from a Value; JS_ValueToId or -// JS_IdToValue must be used instead. - -#include "jstypes.h" - -#include "js/HeapAPI.h" -#include "js/RootingAPI.h" -#include "js/TypeDecls.h" -#include "js/Utility.h" - -struct jsid -{ - size_t asBits; - bool operator==(const jsid& rhs) const { return asBits == rhs.asBits; } - bool operator!=(const jsid& rhs) const { return asBits != rhs.asBits; } -} JS_HAZ_GC_POINTER; -#define JSID_BITS(id) (id.asBits) - -#define JSID_TYPE_STRING 0x0 -#define JSID_TYPE_INT 0x1 -#define JSID_TYPE_VOID 0x2 -#define JSID_TYPE_SYMBOL 0x4 -#define JSID_TYPE_MASK 0x7 - -// Avoid using canonical 'id' for jsid parameters since this is a magic word in -// Objective-C++ which, apparently, wants to be able to #include jsapi.h. -#define id iden - -static MOZ_ALWAYS_INLINE bool -JSID_IS_STRING(jsid id) -{ - return (JSID_BITS(id) & JSID_TYPE_MASK) == 0; -} - -static MOZ_ALWAYS_INLINE JSString* -JSID_TO_STRING(jsid id) -{ - MOZ_ASSERT(JSID_IS_STRING(id)); - return (JSString*)JSID_BITS(id); -} - -/** - * Only JSStrings that have been interned via the JSAPI can be turned into - * jsids by API clients. - * - * N.B. if a jsid is backed by a string which has not been interned, that - * string must be appropriately rooted to avoid being collected by the GC. - */ -JS_PUBLIC_API(jsid) -INTERNED_STRING_TO_JSID(JSContext* cx, JSString* str); - -static MOZ_ALWAYS_INLINE bool -JSID_IS_INT(jsid id) -{ - return !!(JSID_BITS(id) & JSID_TYPE_INT); -} - -static MOZ_ALWAYS_INLINE int32_t -JSID_TO_INT(jsid id) -{ - MOZ_ASSERT(JSID_IS_INT(id)); - return ((uint32_t)JSID_BITS(id)) >> 1; -} - -#define JSID_INT_MIN 0 -#define JSID_INT_MAX INT32_MAX - -static MOZ_ALWAYS_INLINE bool -INT_FITS_IN_JSID(int32_t i) -{ - return i >= 0; -} - -static MOZ_ALWAYS_INLINE jsid -INT_TO_JSID(int32_t i) -{ - jsid id; - MOZ_ASSERT(INT_FITS_IN_JSID(i)); - JSID_BITS(id) = ((i << 1) | JSID_TYPE_INT); - return id; -} - -static MOZ_ALWAYS_INLINE bool -JSID_IS_SYMBOL(jsid id) -{ - return (JSID_BITS(id) & JSID_TYPE_MASK) == JSID_TYPE_SYMBOL && - JSID_BITS(id) != JSID_TYPE_SYMBOL; -} - -static MOZ_ALWAYS_INLINE JS::Symbol* -JSID_TO_SYMBOL(jsid id) -{ - MOZ_ASSERT(JSID_IS_SYMBOL(id)); - return (JS::Symbol*)(JSID_BITS(id) & ~(size_t)JSID_TYPE_MASK); -} - -static MOZ_ALWAYS_INLINE jsid -SYMBOL_TO_JSID(JS::Symbol* sym) -{ - jsid id; - MOZ_ASSERT(sym != nullptr); - MOZ_ASSERT((size_t(sym) & JSID_TYPE_MASK) == 0); - MOZ_ASSERT(!js::gc::IsInsideNursery(reinterpret_cast(sym))); - JSID_BITS(id) = (size_t(sym) | JSID_TYPE_SYMBOL); - return id; -} - -static MOZ_ALWAYS_INLINE bool -JSID_IS_GCTHING(jsid id) -{ - return JSID_IS_STRING(id) || JSID_IS_SYMBOL(id); -} - -static MOZ_ALWAYS_INLINE JS::GCCellPtr -JSID_TO_GCTHING(jsid id) -{ - void* thing = (void*)(JSID_BITS(id) & ~(size_t)JSID_TYPE_MASK); - if (JSID_IS_STRING(id)) - return JS::GCCellPtr(thing, JS::TraceKind::String); - MOZ_ASSERT(JSID_IS_SYMBOL(id)); - return JS::GCCellPtr(thing, JS::TraceKind::Symbol); -} - -static MOZ_ALWAYS_INLINE bool -JSID_IS_VOID(const jsid id) -{ - MOZ_ASSERT_IF(((size_t)JSID_BITS(id) & JSID_TYPE_MASK) == JSID_TYPE_VOID, - JSID_BITS(id) == JSID_TYPE_VOID); - return (size_t)JSID_BITS(id) == JSID_TYPE_VOID; -} - -static MOZ_ALWAYS_INLINE bool -JSID_IS_EMPTY(const jsid id) -{ - return (size_t)JSID_BITS(id) == JSID_TYPE_SYMBOL; -} - -extern JS_PUBLIC_DATA(const jsid) JSID_VOID; -extern JS_PUBLIC_DATA(const jsid) JSID_EMPTY; - -extern JS_PUBLIC_DATA(const JS::HandleId) JSID_VOIDHANDLE; -extern JS_PUBLIC_DATA(const JS::HandleId) JSID_EMPTYHANDLE; - -namespace JS { - -template <> -struct GCPolicy -{ - static jsid initial() { return JSID_VOID; } - static void trace(JSTracer* trc, jsid* idp, const char* name) { - js::UnsafeTraceManuallyBarrieredEdge(trc, idp, name); - } -}; - -} // namespace JS - -namespace js { - -template <> -struct BarrierMethods -{ - static void postBarrier(jsid* idp, jsid prev, jsid next) {} - static void exposeToJS(jsid id) { - if (JSID_IS_GCTHING(id)) - js::gc::ExposeGCThingToActiveJS(JSID_TO_GCTHING(id)); - } -}; - -// If the jsid is a GC pointer type, convert to that type and call |f| with -// the pointer. If the jsid is not a GC type, calls F::defaultValue. -template -auto -DispatchTyped(F f, const jsid& id, Args&&... args) - -> decltype(f(static_cast(nullptr), mozilla::Forward(args)...)) -{ - if (JSID_IS_STRING(id)) - return f(JSID_TO_STRING(id), mozilla::Forward(args)...); - if (JSID_IS_SYMBOL(id)) - return f(JSID_TO_SYMBOL(id), mozilla::Forward(args)...); - MOZ_ASSERT(!JSID_IS_GCTHING(id)); - return F::defaultValue(id); -} - -#undef id - -} // namespace js - -#endif /* js_Id_h */ diff --git a/android/x86/include/spidermonkey/js/Initialization.h b/android/x86/include/spidermonkey/js/Initialization.h deleted file mode 100644 index 8a1cf910..00000000 --- a/android/x86/include/spidermonkey/js/Initialization.h +++ /dev/null @@ -1,125 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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/. */ - -/* SpiderMonkey initialization and shutdown APIs. */ - -#ifndef js_Initialization_h -#define js_Initialization_h - -#include "jstypes.h" - -namespace JS { -namespace detail { - -enum class InitState { Uninitialized = 0, Running, ShutDown }; - -/** - * SpiderMonkey's initialization status is tracked here, and it controls things - * that should happen only once across all runtimes. It's an API requirement - * that JS_Init (and JS_ShutDown, if called) be called in a thread-aware - * manner, so this (internal -- embedders, don't use!) variable doesn't need to - * be atomic. - */ -extern JS_PUBLIC_DATA(InitState) -libraryInitState; - -extern JS_PUBLIC_API(const char*) -InitWithFailureDiagnostic(bool isDebugBuild); - -} // namespace detail -} // namespace JS - -// These are equivalent to ICU's |UMemAllocFn|, |UMemReallocFn|, and -// |UMemFreeFn| types. The first argument (called |context| in the ICU docs) -// will always be nullptr and should be ignored. -typedef void* (*JS_ICUAllocFn)(const void*, size_t size); -typedef void* (*JS_ICUReallocFn)(const void*, void* p, size_t size); -typedef void (*JS_ICUFreeFn)(const void*, void* p); - -/** - * This function can be used to track memory used by ICU. If it is called, it - * *must* be called before JS_Init. Don't use it unless you know what you're - * doing! - */ -extern JS_PUBLIC_API(bool) -JS_SetICUMemoryFunctions(JS_ICUAllocFn allocFn, - JS_ICUReallocFn reallocFn, - JS_ICUFreeFn freeFn); - -/** - * Initialize SpiderMonkey, returning true only if initialization succeeded. - * Once this method has succeeded, it is safe to call JS_NewRuntime and other - * JSAPI methods. - * - * This method must be called before any other JSAPI method is used on any - * thread. Once it has been used, it is safe to call any JSAPI method, and it - * remains safe to do so until JS_ShutDown is correctly called. - * - * It is currently not possible to initialize SpiderMonkey multiple times (that - * is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so - * again). This restriction may eventually be lifted. - */ -inline bool -JS_Init(void) -{ -#ifdef DEBUG - return !JS::detail::InitWithFailureDiagnostic(true); -#else - return !JS::detail::InitWithFailureDiagnostic(false); -#endif -} - -/** - * A variant of JS_Init. On success it returns nullptr. On failure it returns a - * pointer to a string literal that describes how initialization failed, which - * can be useful for debugging purposes. - */ -inline const char* -JS_InitWithFailureDiagnostic(void) -{ -#ifdef DEBUG - return JS::detail::InitWithFailureDiagnostic(true); -#else - return JS::detail::InitWithFailureDiagnostic(false); -#endif -} - -/* - * Returns true if SpiderMonkey has been initialized successfully, even if it has - * possibly been shut down. - * - * Note that it is the responsibility of the embedder to call JS_Init() and - * JS_ShutDown() at the correct times, and therefore this API should ideally not - * be necessary to use. This is only intended to be used in cases where the - * embedder isn't in full control of deciding whether to initialize SpiderMonkey - * or hand off the task to another consumer. - */ -inline bool -JS_IsInitialized(void) -{ - return JS::detail::libraryInitState != JS::detail::InitState::Uninitialized; -} - -/** - * Destroy free-standing resources allocated by SpiderMonkey, not associated - * with any runtime, context, or other structure. - * - * This method should be called after all other JSAPI data has been properly - * cleaned up: every new runtime must have been destroyed, every new context - * must have been destroyed, and so on. Calling this method before all other - * resources have been destroyed has undefined behavior. - * - * Failure to call this method, at present, has no adverse effects other than - * leaking memory. This may not always be the case; it's recommended that all - * embedders call this method when all other JSAPI operations have completed. - * - * It is currently not possible to initialize SpiderMonkey multiple times (that - * is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so - * again). This restriction may eventually be lifted. - */ -extern JS_PUBLIC_API(void) -JS_ShutDown(void); - -#endif /* js_Initialization_h */ diff --git a/android/x86/include/spidermonkey/js/LegacyIntTypes.h b/android/x86/include/spidermonkey/js/LegacyIntTypes.h deleted file mode 100644 index 2c8498c8..00000000 --- a/android/x86/include/spidermonkey/js/LegacyIntTypes.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* - * This section typedefs the old 'native' types to the new types. - * These redefinitions are provided solely to allow JSAPI users to more easily - * transition to types. They are not to be used in the JSAPI, and - * new JSAPI user code should not use them. This mapping file may eventually - * be removed from SpiderMonkey, so don't depend on it in the long run. - */ - -/* - * BEWARE: Comity with other implementers of these types is not guaranteed. - * Indeed, if you use this header and third-party code defining these - * types, *expect* to encounter either compile errors or link errors, - * depending how these types are used and on the order of inclusion. - * It is safest to use only the types. - */ -#ifndef js_LegacyIntTypes_h -#define js_LegacyIntTypes_h - -#include - -#include "js-config.h" - -typedef uint8_t uint8; -typedef uint16_t uint16; -typedef uint32_t uint32; -typedef uint64_t uint64; - -/* - * On AIX 4.3, sys/inttypes.h (which is included by sys/types.h, a very - * common header file) defines the types int8, int16, int32, and int64. - * So we don't define these four types here to avoid conflicts in case - * the code also includes sys/types.h. - */ -#if defined(AIX) && defined(HAVE_SYS_INTTYPES_H) -#include -#else -typedef int8_t int8; -typedef int16_t int16; -typedef int32_t int32; -typedef int64_t int64; -#endif /* AIX && HAVE_SYS_INTTYPES_H */ - -typedef uint8_t JSUint8; -typedef uint16_t JSUint16; -typedef uint32_t JSUint32; -typedef uint64_t JSUint64; - -typedef int8_t JSInt8; -typedef int16_t JSInt16; -typedef int32_t JSInt32; -typedef int64_t JSInt64; - -#endif /* js_LegacyIntTypes_h */ diff --git a/android/x86/include/spidermonkey/js/MemoryMetrics.h b/android/x86/include/spidermonkey/js/MemoryMetrics.h deleted file mode 100644 index 9b5caa24..00000000 --- a/android/x86/include/spidermonkey/js/MemoryMetrics.h +++ /dev/null @@ -1,971 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_MemoryMetrics_h -#define js_MemoryMetrics_h - -// These declarations are highly likely to change in the future. Depend on them -// at your own risk. - -#include "mozilla/MemoryReporting.h" -#include "mozilla/PodOperations.h" -#include "mozilla/TypeTraits.h" - -#include - -#include "jsalloc.h" -#include "jspubtd.h" - -#include "js/HashTable.h" -#include "js/TracingAPI.h" -#include "js/Utility.h" -#include "js/Vector.h" - -class nsISupports; // Needed for ObjectPrivateVisitor. - -namespace JS { - -struct TabSizes -{ - enum Kind { - Objects, - Strings, - Private, - Other - }; - - TabSizes() { mozilla::PodZero(this); } - - void add(Kind kind, size_t n) { - switch (kind) { - case Objects: objects += n; break; - case Strings: strings += n; break; - case Private: private_ += n; break; - case Other: other += n; break; - default: MOZ_CRASH("bad TabSizes kind"); - } - } - - size_t objects; - size_t strings; - size_t private_; - size_t other; -}; - -/** These are the measurements used by Servo. */ -struct ServoSizes -{ - enum Kind { - GCHeapUsed, - GCHeapUnused, - GCHeapAdmin, - GCHeapDecommitted, - MallocHeap, - NonHeap, - Ignore - }; - - ServoSizes() { mozilla::PodZero(this); } - - void add(Kind kind, size_t n) { - switch (kind) { - case GCHeapUsed: gcHeapUsed += n; break; - case GCHeapUnused: gcHeapUnused += n; break; - case GCHeapAdmin: gcHeapAdmin += n; break; - case GCHeapDecommitted: gcHeapDecommitted += n; break; - case MallocHeap: mallocHeap += n; break; - case NonHeap: nonHeap += n; break; - case Ignore: /* do nothing */ break; - default: MOZ_CRASH("bad ServoSizes kind"); - } - } - - size_t gcHeapUsed; - size_t gcHeapUnused; - size_t gcHeapAdmin; - size_t gcHeapDecommitted; - size_t mallocHeap; - size_t nonHeap; -}; - -} // namespace JS - -namespace js { - -/** - * In memory reporting, we have concept of "sundries", line items which are too - * small to be worth reporting individually. Under some circumstances, a memory - * reporter gets tossed into the sundries bucket if it's smaller than - * MemoryReportingSundriesThreshold() bytes. - * - * We need to define this value here, rather than in the code which actually - * generates the memory reports, because NotableStringInfo uses this value. - */ -JS_FRIEND_API(size_t) MemoryReportingSundriesThreshold(); - -/** - * This hash policy avoids flattening ropes (which perturbs the site being - * measured and requires a JSContext) at the expense of doing a FULL ROPE COPY - * on every hash and match! Beware. - */ -struct InefficientNonFlatteningStringHashPolicy -{ - typedef JSString* Lookup; - static HashNumber hash(const Lookup& l); - static bool match(const JSString* const& k, const Lookup& l); -}; - -struct CStringHashPolicy -{ - typedef const char* Lookup; - static HashNumber hash(const Lookup& l); - static bool match(const char* const& k, const Lookup& l); -}; - -// This file features many classes with numerous size_t fields, and each such -// class has one or more methods that need to operate on all of these fields. -// Writing these individually is error-prone -- it's easy to add a new field -// without updating all the required methods. So we define a single macro list -// in each class to name the fields (and notable characteristics of them), and -// then use the following macros to transform those lists into the required -// methods. -// -// - The |tabKind| value is used when measuring TabSizes. -// -// - The |servoKind| value is used when measuring ServoSizes and also for -// the various sizeOfLiveGCThings() methods. -// -// In some classes, one or more of the macro arguments aren't used. We use '_' -// for those. -// -#define DECL_SIZE(tabKind, servoKind, mSize) size_t mSize; -#define ZERO_SIZE(tabKind, servoKind, mSize) mSize(0), -#define COPY_OTHER_SIZE(tabKind, servoKind, mSize) mSize(other.mSize), -#define ADD_OTHER_SIZE(tabKind, servoKind, mSize) mSize += other.mSize; -#define SUB_OTHER_SIZE(tabKind, servoKind, mSize) \ - MOZ_ASSERT(mSize >= other.mSize); \ - mSize -= other.mSize; -#define ADD_SIZE_TO_N(tabKind, servoKind, mSize) n += mSize; -#define ADD_SIZE_TO_N_IF_LIVE_GC_THING(tabKind, servoKind, mSize) \ - /* Avoid self-comparison warnings by comparing enums indirectly. */ \ - n += (mozilla::IsSame::value) \ - ? mSize \ - : 0; -#define ADD_TO_TAB_SIZES(tabKind, servoKind, mSize) sizes->add(JS::TabSizes::tabKind, mSize); -#define ADD_TO_SERVO_SIZES(tabKind, servoKind, mSize) sizes->add(JS::ServoSizes::servoKind, mSize); - -} // namespace js - -namespace JS { - -struct ClassInfo -{ -#define FOR_EACH_SIZE(macro) \ - macro(Objects, GCHeapUsed, objectsGCHeap) \ - macro(Objects, MallocHeap, objectsMallocHeapSlots) \ - macro(Objects, MallocHeap, objectsMallocHeapElementsNormal) \ - macro(Objects, MallocHeap, objectsMallocHeapElementsAsmJS) \ - macro(Objects, MallocHeap, objectsMallocHeapMisc) \ - macro(Objects, NonHeap, objectsNonHeapElementsNormal) \ - macro(Objects, NonHeap, objectsNonHeapElementsShared) \ - macro(Objects, NonHeap, objectsNonHeapElementsWasm) \ - macro(Objects, NonHeap, objectsNonHeapCodeWasm) - - ClassInfo() - : FOR_EACH_SIZE(ZERO_SIZE) - wasmGuardPages(0) - {} - - void add(const ClassInfo& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE) - } - - void subtract(const ClassInfo& other) { - FOR_EACH_SIZE(SUB_OTHER_SIZE) - } - - size_t sizeOfAllThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N) - return n; - } - - bool isNotable() const { - static const size_t NotabilityThreshold = 16 * 1024; - return sizeOfAllThings() >= NotabilityThreshold; - } - - size_t sizeOfLiveGCThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) - return n; - } - - void addToTabSizes(TabSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_TAB_SIZES) - } - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - size_t wasmGuardPages; - -#undef FOR_EACH_SIZE -}; - -struct ShapeInfo -{ -#define FOR_EACH_SIZE(macro) \ - macro(Other, GCHeapUsed, shapesGCHeapTree) \ - macro(Other, GCHeapUsed, shapesGCHeapDict) \ - macro(Other, GCHeapUsed, shapesGCHeapBase) \ - macro(Other, MallocHeap, shapesMallocHeapTreeTables) \ - macro(Other, MallocHeap, shapesMallocHeapDictTables) \ - macro(Other, MallocHeap, shapesMallocHeapTreeKids) - - ShapeInfo() - : FOR_EACH_SIZE(ZERO_SIZE) - dummy() - {} - - void add(const ShapeInfo& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE) - } - - void subtract(const ShapeInfo& other) { - FOR_EACH_SIZE(SUB_OTHER_SIZE) - } - - size_t sizeOfAllThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N) - return n; - } - - size_t sizeOfLiveGCThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) - return n; - } - - void addToTabSizes(TabSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_TAB_SIZES) - } - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE) - -#undef FOR_EACH_SIZE -}; - -/** - * Holds data about a notable class (one whose combined object and shape - * instances use more than a certain amount of memory) so we can report it - * individually. - * - * The only difference between this class and ClassInfo is that this class - * holds a copy of the filename. - */ -struct NotableClassInfo : public ClassInfo -{ - NotableClassInfo(); - NotableClassInfo(const char* className, const ClassInfo& info); - NotableClassInfo(NotableClassInfo&& info); - NotableClassInfo& operator=(NotableClassInfo&& info); - - ~NotableClassInfo() { - js_free(className_); - } - - char* className_; - - private: - NotableClassInfo(const NotableClassInfo& info) = delete; -}; - -/** Data for tracking JIT-code memory usage. */ -struct CodeSizes -{ -#define FOR_EACH_SIZE(macro) \ - macro(_, NonHeap, ion) \ - macro(_, NonHeap, baseline) \ - macro(_, NonHeap, regexp) \ - macro(_, NonHeap, other) \ - macro(_, NonHeap, unused) - - CodeSizes() - : FOR_EACH_SIZE(ZERO_SIZE) - dummy() - {} - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE) - -#undef FOR_EACH_SIZE -}; - -/** Data for tracking GC memory usage. */ -struct GCSizes -{ - // |nurseryDecommitted| is marked as NonHeap rather than GCHeapDecommitted - // because we don't consider the nursery to be part of the GC heap. -#define FOR_EACH_SIZE(macro) \ - macro(_, MallocHeap, marker) \ - macro(_, NonHeap, nurseryCommitted) \ - macro(_, MallocHeap, nurseryMallocedBuffers) \ - macro(_, MallocHeap, storeBufferVals) \ - macro(_, MallocHeap, storeBufferCells) \ - macro(_, MallocHeap, storeBufferSlots) \ - macro(_, MallocHeap, storeBufferWholeCells) \ - macro(_, MallocHeap, storeBufferGenerics) - - GCSizes() - : FOR_EACH_SIZE(ZERO_SIZE) - dummy() - {} - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE) - -#undef FOR_EACH_SIZE -}; - -/** - * This class holds information about the memory taken up by identical copies of - * a particular string. Multiple JSStrings may have their sizes aggregated - * together into one StringInfo object. Note that two strings with identical - * chars will not be aggregated together if one is a short string and the other - * is not. - */ -struct StringInfo -{ -#define FOR_EACH_SIZE(macro) \ - macro(Strings, GCHeapUsed, gcHeapLatin1) \ - macro(Strings, GCHeapUsed, gcHeapTwoByte) \ - macro(Strings, MallocHeap, mallocHeapLatin1) \ - macro(Strings, MallocHeap, mallocHeapTwoByte) - - StringInfo() - : FOR_EACH_SIZE(ZERO_SIZE) - numCopies(0) - {} - - void add(const StringInfo& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE); - numCopies++; - } - - void subtract(const StringInfo& other) { - FOR_EACH_SIZE(SUB_OTHER_SIZE); - numCopies--; - } - - bool isNotable() const { - static const size_t NotabilityThreshold = 16 * 1024; - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N) - return n >= NotabilityThreshold; - } - - size_t sizeOfLiveGCThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) - return n; - } - - void addToTabSizes(TabSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_TAB_SIZES) - } - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - uint32_t numCopies; // How many copies of the string have we seen? - -#undef FOR_EACH_SIZE -}; - -/** - * Holds data about a notable string (one which, counting all duplicates, uses - * more than a certain amount of memory) so we can report it individually. - * - * The only difference between this class and StringInfo is that - * NotableStringInfo holds a copy of some or all of the string's chars. - */ -struct NotableStringInfo : public StringInfo -{ - static const size_t MAX_SAVED_CHARS = 1024; - - NotableStringInfo(); - NotableStringInfo(JSString* str, const StringInfo& info); - NotableStringInfo(NotableStringInfo&& info); - NotableStringInfo& operator=(NotableStringInfo&& info); - - ~NotableStringInfo() { - js_free(buffer); - } - - char* buffer; - size_t length; - - private: - NotableStringInfo(const NotableStringInfo& info) = delete; -}; - -/** - * This class holds information about the memory taken up by script sources - * from a particular file. - */ -struct ScriptSourceInfo -{ -#define FOR_EACH_SIZE(macro) \ - macro(_, MallocHeap, misc) - - ScriptSourceInfo() - : FOR_EACH_SIZE(ZERO_SIZE) - numScripts(0) - {} - - void add(const ScriptSourceInfo& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE) - numScripts++; - } - - void subtract(const ScriptSourceInfo& other) { - FOR_EACH_SIZE(SUB_OTHER_SIZE) - numScripts--; - } - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - bool isNotable() const { - static const size_t NotabilityThreshold = 16 * 1024; - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N) - return n >= NotabilityThreshold; - } - - FOR_EACH_SIZE(DECL_SIZE) - uint32_t numScripts; // How many ScriptSources come from this file? (It - // can be more than one in XML files that have - // multiple scripts in CDATA sections.) -#undef FOR_EACH_SIZE -}; - -/** - * Holds data about a notable script source file (one whose combined - * script sources use more than a certain amount of memory) so we can report it - * individually. - * - * The only difference between this class and ScriptSourceInfo is that this - * class holds a copy of the filename. - */ -struct NotableScriptSourceInfo : public ScriptSourceInfo -{ - NotableScriptSourceInfo(); - NotableScriptSourceInfo(const char* filename, const ScriptSourceInfo& info); - NotableScriptSourceInfo(NotableScriptSourceInfo&& info); - NotableScriptSourceInfo& operator=(NotableScriptSourceInfo&& info); - - ~NotableScriptSourceInfo() { - js_free(filename_); - } - - char* filename_; - - private: - NotableScriptSourceInfo(const NotableScriptSourceInfo& info) = delete; -}; - -/** - * These measurements relate directly to the JSRuntime, and not to zones and - * compartments within it. - */ -struct RuntimeSizes -{ -#define FOR_EACH_SIZE(macro) \ - macro(_, MallocHeap, object) \ - macro(_, MallocHeap, atomsTable) \ - macro(_, MallocHeap, contexts) \ - macro(_, MallocHeap, temporary) \ - macro(_, MallocHeap, interpreterStack) \ - macro(_, MallocHeap, mathCache) \ - macro(_, MallocHeap, sharedImmutableStringsCache) \ - macro(_, MallocHeap, sharedIntlData) \ - macro(_, MallocHeap, uncompressedSourceCache) \ - macro(_, MallocHeap, scriptData) - - RuntimeSizes() - : FOR_EACH_SIZE(ZERO_SIZE) - scriptSourceInfo(), - code(), - gc(), - notableScriptSources() - { - allScriptSources = js_new(); - if (!allScriptSources || !allScriptSources->init()) - MOZ_CRASH("oom"); - } - - ~RuntimeSizes() { - // |allScriptSources| is usually deleted and set to nullptr before this - // destructor runs. But there are failure cases due to OOMs that may - // prevent that, so it doesn't hurt to try again here. - js_delete(allScriptSources); - } - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - scriptSourceInfo.addToServoSizes(sizes); - code.addToServoSizes(sizes); - gc.addToServoSizes(sizes); - } - - // The script source measurements in |scriptSourceInfo| are initially for - // all script sources. At the end, if the measurement granularity is - // FineGrained, we subtract the measurements of the notable script sources - // and move them into |notableScriptSources|. - FOR_EACH_SIZE(DECL_SIZE) - ScriptSourceInfo scriptSourceInfo; - CodeSizes code; - GCSizes gc; - - typedef js::HashMap ScriptSourcesHashMap; - - // |allScriptSources| is only used transiently. During the reporting phase - // it is filled with info about every script source in the runtime. It's - // then used to fill in |notableScriptSources| (which actually gets - // reported), and immediately discarded afterwards. - ScriptSourcesHashMap* allScriptSources; - js::Vector notableScriptSources; - -#undef FOR_EACH_SIZE -}; - -struct UnusedGCThingSizes -{ -#define FOR_EACH_SIZE(macro) \ - macro(Other, GCHeapUnused, object) \ - macro(Other, GCHeapUnused, script) \ - macro(Other, GCHeapUnused, lazyScript) \ - macro(Other, GCHeapUnused, shape) \ - macro(Other, GCHeapUnused, baseShape) \ - macro(Other, GCHeapUnused, objectGroup) \ - macro(Other, GCHeapUnused, string) \ - macro(Other, GCHeapUnused, symbol) \ - macro(Other, GCHeapUnused, jitcode) \ - macro(Other, GCHeapUnused, scope) - - UnusedGCThingSizes() - : FOR_EACH_SIZE(ZERO_SIZE) - dummy() - {} - - UnusedGCThingSizes(UnusedGCThingSizes&& other) - : FOR_EACH_SIZE(COPY_OTHER_SIZE) - dummy() - {} - - void addToKind(JS::TraceKind kind, intptr_t n) { - switch (kind) { - case JS::TraceKind::Object: object += n; break; - case JS::TraceKind::String: string += n; break; - case JS::TraceKind::Symbol: symbol += n; break; - case JS::TraceKind::Script: script += n; break; - case JS::TraceKind::Shape: shape += n; break; - case JS::TraceKind::BaseShape: baseShape += n; break; - case JS::TraceKind::JitCode: jitcode += n; break; - case JS::TraceKind::LazyScript: lazyScript += n; break; - case JS::TraceKind::ObjectGroup: objectGroup += n; break; - case JS::TraceKind::Scope: scope += n; break; - default: - MOZ_CRASH("Bad trace kind for UnusedGCThingSizes"); - } - } - - void addSizes(const UnusedGCThingSizes& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE) - } - - size_t totalSize() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N) - return n; - } - - void addToTabSizes(JS::TabSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_TAB_SIZES) - } - - void addToServoSizes(JS::ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - } - - FOR_EACH_SIZE(DECL_SIZE) - int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE) - -#undef FOR_EACH_SIZE -}; - -struct ZoneStats -{ -#define FOR_EACH_SIZE(macro) \ - macro(Other, GCHeapUsed, symbolsGCHeap) \ - macro(Other, GCHeapAdmin, gcHeapArenaAdmin) \ - macro(Other, GCHeapUsed, lazyScriptsGCHeap) \ - macro(Other, MallocHeap, lazyScriptsMallocHeap) \ - macro(Other, GCHeapUsed, jitCodesGCHeap) \ - macro(Other, GCHeapUsed, objectGroupsGCHeap) \ - macro(Other, MallocHeap, objectGroupsMallocHeap) \ - macro(Other, GCHeapUsed, scopesGCHeap) \ - macro(Other, MallocHeap, scopesMallocHeap) \ - macro(Other, MallocHeap, typePool) \ - macro(Other, MallocHeap, baselineStubsOptimized) \ - macro(Other, MallocHeap, uniqueIdMap) \ - macro(Other, MallocHeap, shapeTables) - - ZoneStats() - : FOR_EACH_SIZE(ZERO_SIZE) - unusedGCThings(), - stringInfo(), - shapeInfo(), - extra(), - allStrings(nullptr), - notableStrings(), - isTotals(true) - {} - - ZoneStats(ZoneStats&& other) - : FOR_EACH_SIZE(COPY_OTHER_SIZE) - unusedGCThings(mozilla::Move(other.unusedGCThings)), - stringInfo(mozilla::Move(other.stringInfo)), - shapeInfo(mozilla::Move(other.shapeInfo)), - extra(other.extra), - allStrings(other.allStrings), - notableStrings(mozilla::Move(other.notableStrings)), - isTotals(other.isTotals) - { - other.allStrings = nullptr; - MOZ_ASSERT(!other.isTotals); - } - - ~ZoneStats() { - // |allStrings| is usually deleted and set to nullptr before this - // destructor runs. But there are failure cases due to OOMs that may - // prevent that, so it doesn't hurt to try again here. - js_delete(allStrings); - } - - bool initStrings(JSRuntime* rt); - - void addSizes(const ZoneStats& other) { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_OTHER_SIZE) - unusedGCThings.addSizes(other.unusedGCThings); - stringInfo.add(other.stringInfo); - shapeInfo.add(other.shapeInfo); - } - - size_t sizeOfLiveGCThings() const { - MOZ_ASSERT(isTotals); - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) - n += stringInfo.sizeOfLiveGCThings(); - n += shapeInfo.sizeOfLiveGCThings(); - return n; - } - - void addToTabSizes(JS::TabSizes* sizes) const { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_TO_TAB_SIZES) - unusedGCThings.addToTabSizes(sizes); - stringInfo.addToTabSizes(sizes); - shapeInfo.addToTabSizes(sizes); - } - - void addToServoSizes(JS::ServoSizes *sizes) const { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - unusedGCThings.addToServoSizes(sizes); - stringInfo.addToServoSizes(sizes); - shapeInfo.addToServoSizes(sizes); - } - - // These string measurements are initially for all strings. At the end, - // if the measurement granularity is FineGrained, we subtract the - // measurements of the notable script sources and move them into - // |notableStrings|. - FOR_EACH_SIZE(DECL_SIZE) - UnusedGCThingSizes unusedGCThings; - StringInfo stringInfo; - ShapeInfo shapeInfo; - void* extra; // This field can be used by embedders. - - typedef js::HashMap StringsHashMap; - - // |allStrings| is only used transiently. During the zone traversal it is - // filled with info about every string in the zone. It's then used to fill - // in |notableStrings| (which actually gets reported), and immediately - // discarded afterwards. - StringsHashMap* allStrings; - js::Vector notableStrings; - bool isTotals; - -#undef FOR_EACH_SIZE -}; - -struct CompartmentStats -{ - // We assume that |objectsPrivate| is on the malloc heap, but it's not - // actually guaranteed. But for Servo, at least, it's a moot point because - // it doesn't provide an ObjectPrivateVisitor so the value will always be - // zero. -#define FOR_EACH_SIZE(macro) \ - macro(Private, MallocHeap, objectsPrivate) \ - macro(Other, GCHeapUsed, scriptsGCHeap) \ - macro(Other, MallocHeap, scriptsMallocHeapData) \ - macro(Other, MallocHeap, baselineData) \ - macro(Other, MallocHeap, baselineStubsFallback) \ - macro(Other, MallocHeap, ionData) \ - macro(Other, MallocHeap, typeInferenceTypeScripts) \ - macro(Other, MallocHeap, typeInferenceAllocationSiteTables) \ - macro(Other, MallocHeap, typeInferenceArrayTypeTables) \ - macro(Other, MallocHeap, typeInferenceObjectTypeTables) \ - macro(Other, MallocHeap, compartmentObject) \ - macro(Other, MallocHeap, compartmentTables) \ - macro(Other, MallocHeap, innerViewsTable) \ - macro(Other, MallocHeap, lazyArrayBuffersTable) \ - macro(Other, MallocHeap, objectMetadataTable) \ - macro(Other, MallocHeap, crossCompartmentWrappersTable) \ - macro(Other, MallocHeap, regexpCompartment) \ - macro(Other, MallocHeap, savedStacksSet) \ - macro(Other, MallocHeap, varNamesSet) \ - macro(Other, MallocHeap, nonSyntacticLexicalScopesTable) \ - macro(Other, MallocHeap, jitCompartment) \ - macro(Other, MallocHeap, privateData) - - CompartmentStats() - : FOR_EACH_SIZE(ZERO_SIZE) - classInfo(), - extra(), - allClasses(nullptr), - notableClasses(), - isTotals(true) - {} - - CompartmentStats(CompartmentStats&& other) - : FOR_EACH_SIZE(COPY_OTHER_SIZE) - classInfo(mozilla::Move(other.classInfo)), - extra(other.extra), - allClasses(other.allClasses), - notableClasses(mozilla::Move(other.notableClasses)), - isTotals(other.isTotals) - { - other.allClasses = nullptr; - MOZ_ASSERT(!other.isTotals); - } - - CompartmentStats(const CompartmentStats&) = delete; // disallow copying - - ~CompartmentStats() { - // |allClasses| is usually deleted and set to nullptr before this - // destructor runs. But there are failure cases due to OOMs that may - // prevent that, so it doesn't hurt to try again here. - js_delete(allClasses); - } - - bool initClasses(JSRuntime* rt); - - void addSizes(const CompartmentStats& other) { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_OTHER_SIZE) - classInfo.add(other.classInfo); - } - - size_t sizeOfLiveGCThings() const { - MOZ_ASSERT(isTotals); - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) - n += classInfo.sizeOfLiveGCThings(); - return n; - } - - void addToTabSizes(TabSizes* sizes) const { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_TO_TAB_SIZES); - classInfo.addToTabSizes(sizes); - } - - void addToServoSizes(ServoSizes *sizes) const { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES); - classInfo.addToServoSizes(sizes); - } - - // The class measurements in |classInfo| are initially for all classes. At - // the end, if the measurement granularity is FineGrained, we subtract the - // measurements of the notable classes and move them into |notableClasses|. - FOR_EACH_SIZE(DECL_SIZE) - ClassInfo classInfo; - void* extra; // This field can be used by embedders. - - typedef js::HashMap ClassesHashMap; - - // These are similar to |allStrings| and |notableStrings| in ZoneStats. - ClassesHashMap* allClasses; - js::Vector notableClasses; - bool isTotals; - -#undef FOR_EACH_SIZE -}; - -typedef js::Vector CompartmentStatsVector; -typedef js::Vector ZoneStatsVector; - -struct RuntimeStats -{ - // |gcHeapChunkTotal| is ignored because it's the sum of all the other - // values. |gcHeapGCThings| is ignored because it's the sum of some of the - // values from the zones and compartments. Both of those values are not - // reported directly, but are just present for sanity-checking other - // values. -#define FOR_EACH_SIZE(macro) \ - macro(_, Ignore, gcHeapChunkTotal) \ - macro(_, GCHeapDecommitted, gcHeapDecommittedArenas) \ - macro(_, GCHeapUnused, gcHeapUnusedChunks) \ - macro(_, GCHeapUnused, gcHeapUnusedArenas) \ - macro(_, GCHeapAdmin, gcHeapChunkAdmin) \ - macro(_, Ignore, gcHeapGCThings) - - explicit RuntimeStats(mozilla::MallocSizeOf mallocSizeOf) - : FOR_EACH_SIZE(ZERO_SIZE) - runtime(), - cTotals(), - zTotals(), - compartmentStatsVector(), - zoneStatsVector(), - currZoneStats(nullptr), - mallocSizeOf_(mallocSizeOf) - {} - - // Here's a useful breakdown of the GC heap. - // - // - rtStats.gcHeapChunkTotal - // - decommitted bytes - // - rtStats.gcHeapDecommittedArenas (decommitted arenas in non-empty chunks) - // - unused bytes - // - rtStats.gcHeapUnusedChunks (empty chunks) - // - rtStats.gcHeapUnusedArenas (empty arenas within non-empty chunks) - // - rtStats.zTotals.unusedGCThings.totalSize() (empty GC thing slots within non-empty arenas) - // - used bytes - // - rtStats.gcHeapChunkAdmin - // - rtStats.zTotals.gcHeapArenaAdmin - // - rtStats.gcHeapGCThings (in-use GC things) - // == rtStats.zTotals.sizeOfLiveGCThings() + rtStats.cTotals.sizeOfLiveGCThings() - // - // It's possible that some arenas in empty chunks may be decommitted, but - // we don't count those under rtStats.gcHeapDecommittedArenas because (a) - // it's rare, and (b) this means that rtStats.gcHeapUnusedChunks is a - // multiple of the chunk size, which is good. - - void addToServoSizes(ServoSizes *sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES) - runtime.addToServoSizes(sizes); - } - - FOR_EACH_SIZE(DECL_SIZE) - - RuntimeSizes runtime; - - CompartmentStats cTotals; // The sum of this runtime's compartments' measurements. - ZoneStats zTotals; // The sum of this runtime's zones' measurements. - - CompartmentStatsVector compartmentStatsVector; - ZoneStatsVector zoneStatsVector; - - ZoneStats* currZoneStats; - - mozilla::MallocSizeOf mallocSizeOf_; - - virtual void initExtraCompartmentStats(JSCompartment* c, CompartmentStats* cstats) = 0; - virtual void initExtraZoneStats(JS::Zone* zone, ZoneStats* zstats) = 0; - -#undef FOR_EACH_SIZE -}; - -class ObjectPrivateVisitor -{ - public: - // Within CollectRuntimeStats, this method is called for each JS object - // that has an nsISupports pointer. - virtual size_t sizeOfIncludingThis(nsISupports* aSupports) = 0; - - // A callback that gets a JSObject's nsISupports pointer, if it has one. - // Note: this function does *not* addref |iface|. - typedef bool(*GetISupportsFun)(JSObject* obj, nsISupports** iface); - GetISupportsFun getISupports_; - - explicit ObjectPrivateVisitor(GetISupportsFun getISupports) - : getISupports_(getISupports) - {} -}; - -extern JS_PUBLIC_API(bool) -CollectRuntimeStats(JSContext* cx, RuntimeStats* rtStats, ObjectPrivateVisitor* opv, bool anonymize); - -extern JS_PUBLIC_API(size_t) -SystemCompartmentCount(JSContext* cx); - -extern JS_PUBLIC_API(size_t) -UserCompartmentCount(JSContext* cx); - -extern JS_PUBLIC_API(size_t) -PeakSizeOfTemporary(const JSContext* cx); - -extern JS_PUBLIC_API(bool) -AddSizeOfTab(JSContext* cx, JS::HandleObject obj, mozilla::MallocSizeOf mallocSizeOf, - ObjectPrivateVisitor* opv, TabSizes* sizes); - -extern JS_PUBLIC_API(bool) -AddServoSizeOf(JSContext* cx, mozilla::MallocSizeOf mallocSizeOf, - ObjectPrivateVisitor *opv, ServoSizes *sizes); - -} // namespace JS - -#undef DECL_SIZE -#undef ZERO_SIZE -#undef COPY_OTHER_SIZE -#undef ADD_OTHER_SIZE -#undef SUB_OTHER_SIZE -#undef ADD_SIZE_TO_N -#undef ADD_SIZE_TO_N_IF_LIVE_GC_THING -#undef ADD_TO_TAB_SIZES - -#endif /* js_MemoryMetrics_h */ diff --git a/android/x86/include/spidermonkey/js/Principals.h b/android/x86/include/spidermonkey/js/Principals.h deleted file mode 100644 index cf6c813a..00000000 --- a/android/x86/include/spidermonkey/js/Principals.h +++ /dev/null @@ -1,132 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* JSPrincipals and related interfaces. */ - -#ifndef js_Principals_h -#define js_Principals_h - -#include "mozilla/Atomics.h" - -#include - -#include "jspubtd.h" - -#include "js/StructuredClone.h" - -namespace js { - struct PerformanceGroup; -} // namespace js - -struct JSPrincipals { - /* Don't call "destroy"; use reference counting macros below. */ - mozilla::Atomic refcount; - -#ifdef JS_DEBUG - /* A helper to facilitate principals debugging. */ - uint32_t debugToken; -#endif - - JSPrincipals() : refcount(0) {} - - void setDebugToken(uint32_t token) { -# ifdef JS_DEBUG - debugToken = token; -# endif - } - - /* - * Write the principals with the given |writer|. Return false on failure, - * true on success. - */ - virtual bool write(JSContext* cx, JSStructuredCloneWriter* writer) = 0; - - /* - * This is not defined by the JS engine but should be provided by the - * embedding. - */ - JS_PUBLIC_API(void) dump(); -}; - -extern JS_PUBLIC_API(void) -JS_HoldPrincipals(JSPrincipals* principals); - -extern JS_PUBLIC_API(void) -JS_DropPrincipals(JSContext* cx, JSPrincipals* principals); - -// Return whether the first principal subsumes the second. The exact meaning of -// 'subsumes' is left up to the browser. Subsumption is checked inside the JS -// engine when determining, e.g., which stack frames to display in a backtrace. -typedef bool -(* JSSubsumesOp)(JSPrincipals* first, JSPrincipals* second); - -/* - * Used to check if a CSP instance wants to disable eval() and friends. - * See js_CheckCSPPermitsJSAction() in jsobj. - */ -typedef bool -(* JSCSPEvalChecker)(JSContext* cx); - -struct JSSecurityCallbacks { - JSCSPEvalChecker contentSecurityPolicyAllows; - JSSubsumesOp subsumes; -}; - -extern JS_PUBLIC_API(void) -JS_SetSecurityCallbacks(JSContext* cx, const JSSecurityCallbacks* callbacks); - -extern JS_PUBLIC_API(const JSSecurityCallbacks*) -JS_GetSecurityCallbacks(JSContext* cx); - -/* - * Code running with "trusted" principals will be given a deeper stack - * allocation than ordinary scripts. This allows trusted script to run after - * untrusted script has exhausted the stack. This function sets the - * runtime-wide trusted principal. - * - * This principals is not held (via JS_HoldPrincipals/JS_DropPrincipals). - * Instead, the caller must ensure that the given principals stays valid for as - * long as 'cx' may point to it. If the principals would be destroyed before - * 'cx', JS_SetTrustedPrincipals must be called again, passing nullptr for - * 'prin'. - */ -extern JS_PUBLIC_API(void) -JS_SetTrustedPrincipals(JSContext* cx, JSPrincipals* prin); - -typedef void -(* JSDestroyPrincipalsOp)(JSPrincipals* principals); - -/* - * Initialize the callback that is called to destroy JSPrincipals instance - * when its reference counter drops to zero. The initialization can be done - * only once per JS runtime. - */ -extern JS_PUBLIC_API(void) -JS_InitDestroyPrincipalsCallback(JSContext* cx, JSDestroyPrincipalsOp destroyPrincipals); - -/* - * Read a JSPrincipals instance from the given |reader| and initialize the out - * paratemer |outPrincipals| to the JSPrincipals instance read. - * - * Return false on failure, true on success. The |outPrincipals| parameter - * should not be modified if false is returned. - * - * The caller is not responsible for calling JS_HoldPrincipals on the resulting - * JSPrincipals instance, the JSReadPrincipalsOp must increment the refcount of - * the resulting JSPrincipals on behalf of the caller. - */ -using JSReadPrincipalsOp = bool (*)(JSContext* cx, JSStructuredCloneReader* reader, - JSPrincipals** outPrincipals); - -/* - * Initialize the callback that is called to read JSPrincipals instances from a - * buffer. The initialization can be done only once per JS runtime. - */ -extern JS_PUBLIC_API(void) -JS_InitReadPrincipalsCallback(JSContext* cx, JSReadPrincipalsOp read); - - -#endif /* js_Principals_h */ diff --git a/android/x86/include/spidermonkey/js/ProfilingFrameIterator.h b/android/x86/include/spidermonkey/js/ProfilingFrameIterator.h deleted file mode 100644 index d082213d..00000000 --- a/android/x86/include/spidermonkey/js/ProfilingFrameIterator.h +++ /dev/null @@ -1,203 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_ProfilingFrameIterator_h -#define js_ProfilingFrameIterator_h - -#include "mozilla/Alignment.h" -#include "mozilla/Maybe.h" - -#include "jsbytecode.h" -#include "js/GCAPI.h" -#include "js/TypeDecls.h" -#include "js/Utility.h" - -struct JSContext; -struct JSRuntime; -class JSScript; - -namespace js { - class Activation; - namespace jit { - class JitActivation; - class JitProfilingFrameIterator; - class JitcodeGlobalEntry; - } // namespace jit - namespace wasm { - class ProfilingFrameIterator; - } // namespace wasm -} // namespace js - -namespace JS { - -struct ForEachTrackedOptimizationAttemptOp; -struct ForEachTrackedOptimizationTypeInfoOp; - -// This iterator can be used to walk the stack of a thread suspended at an -// arbitrary pc. To provide acurate results, profiling must have been enabled -// (via EnableRuntimeProfilingStack) before executing the callstack being -// unwound. -// -// Note that the caller must not do anything that could cause GC to happen while -// the iterator is alive, since this could invalidate Ion code and cause its -// contents to become out of date. -class JS_PUBLIC_API(ProfilingFrameIterator) -{ - JSRuntime* rt_; - uint32_t sampleBufferGen_; - js::Activation* activation_; - - // When moving past a JitActivation, we need to save the prevJitTop - // from it to use as the exit-frame pointer when the next caller jit - // activation (if any) comes around. - void* savedPrevJitTop_; - - JS::AutoCheckCannotGC nogc_; - - static const unsigned StorageSpace = 8 * sizeof(void*); - mozilla::AlignedStorage storage_; - js::wasm::ProfilingFrameIterator& wasmIter() { - MOZ_ASSERT(!done()); - MOZ_ASSERT(isWasm()); - return *reinterpret_cast(storage_.addr()); - } - const js::wasm::ProfilingFrameIterator& wasmIter() const { - MOZ_ASSERT(!done()); - MOZ_ASSERT(isWasm()); - return *reinterpret_cast(storage_.addr()); - } - - js::jit::JitProfilingFrameIterator& jitIter() { - MOZ_ASSERT(!done()); - MOZ_ASSERT(isJit()); - return *reinterpret_cast(storage_.addr()); - } - - const js::jit::JitProfilingFrameIterator& jitIter() const { - MOZ_ASSERT(!done()); - MOZ_ASSERT(isJit()); - return *reinterpret_cast(storage_.addr()); - } - - void settle(); - - bool hasSampleBufferGen() const { - return sampleBufferGen_ != UINT32_MAX; - } - - public: - struct RegisterState - { - RegisterState() : pc(nullptr), sp(nullptr), lr(nullptr) {} - void* pc; - void* sp; - void* lr; - }; - - ProfilingFrameIterator(JSContext* cx, const RegisterState& state, - uint32_t sampleBufferGen = UINT32_MAX); - ~ProfilingFrameIterator(); - void operator++(); - bool done() const { return !activation_; } - - // Assuming the stack grows down (we do), the return value: - // - always points into the stack - // - is weakly monotonically increasing (may be equal for successive frames) - // - will compare greater than newer native and psuedo-stack frame addresses - // and less than older native and psuedo-stack frame addresses - void* stackAddress() const; - - enum FrameKind - { - Frame_Baseline, - Frame_Ion, - Frame_Wasm - }; - - struct Frame - { - FrameKind kind; - void* stackAddress; - void* returnAddress; - void* activation; - UniqueChars label; - }; - - bool isWasm() const; - bool isJit() const; - - uint32_t extractStack(Frame* frames, uint32_t offset, uint32_t end) const; - - mozilla::Maybe getPhysicalFrameWithoutLabel() const; - - private: - mozilla::Maybe getPhysicalFrameAndEntry(js::jit::JitcodeGlobalEntry* entry) const; - - void iteratorConstruct(const RegisterState& state); - void iteratorConstruct(); - void iteratorDestroy(); - bool iteratorDone(); -}; - -JS_FRIEND_API(bool) -IsProfilingEnabledForContext(JSContext* cx); - -/** - * After each sample run, this method should be called with the latest sample - * buffer generation, and the lapCount. It will update corresponding fields on - * JSRuntime. - * - * See fields |profilerSampleBufferGen|, |profilerSampleBufferLapCount| on - * JSRuntime for documentation about what these values are used for. - */ -JS_FRIEND_API(void) -UpdateJSContextProfilerSampleBufferGen(JSContext* cx, uint32_t generation, - uint32_t lapCount); - -struct ForEachProfiledFrameOp -{ - // A handle to the underlying JitcodeGlobalEntry, so as to avoid repeated - // lookups on JitcodeGlobalTable. - class MOZ_STACK_CLASS FrameHandle - { - friend JS_PUBLIC_API(void) ForEachProfiledFrame(JSContext* cx, void* addr, - ForEachProfiledFrameOp& op); - - JSRuntime* rt_; - js::jit::JitcodeGlobalEntry& entry_; - void* addr_; - void* canonicalAddr_; - const char* label_; - uint32_t depth_; - mozilla::Maybe optsIndex_; - - FrameHandle(JSRuntime* rt, js::jit::JitcodeGlobalEntry& entry, void* addr, - const char* label, uint32_t depth); - - void updateHasTrackedOptimizations(); - - public: - const char* label() const { return label_; } - uint32_t depth() const { return depth_; } - bool hasTrackedOptimizations() const { return optsIndex_.isSome(); } - void* canonicalAddress() const { return canonicalAddr_; } - - ProfilingFrameIterator::FrameKind frameKind() const; - void forEachOptimizationAttempt(ForEachTrackedOptimizationAttemptOp& op, - JSScript** scriptOut, jsbytecode** pcOut) const; - void forEachOptimizationTypeInfo(ForEachTrackedOptimizationTypeInfoOp& op) const; - }; - - // Called once per frame. - virtual void operator()(const FrameHandle& frame) = 0; -}; - -JS_PUBLIC_API(void) -ForEachProfiledFrame(JSContext* cx, void* addr, ForEachProfiledFrameOp& op); - -} // namespace JS - -#endif /* js_ProfilingFrameIterator_h */ diff --git a/android/x86/include/spidermonkey/js/ProfilingStack.h b/android/x86/include/spidermonkey/js/ProfilingStack.h deleted file mode 100644 index 6b6c9701..00000000 --- a/android/x86/include/spidermonkey/js/ProfilingStack.h +++ /dev/null @@ -1,208 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_ProfilingStack_h -#define js_ProfilingStack_h - -#include "jsbytecode.h" -#include "jstypes.h" -#include "js/TypeDecls.h" - -#include "js/Utility.h" - -struct JSRuntime; -class JSTracer; - -namespace js { - -// A call stack can be specified to the JS engine such that all JS entry/exits -// to functions push/pop an entry to/from the specified stack. -// -// For more detailed information, see vm/SPSProfiler.h. -// -class ProfileEntry -{ - // All fields are marked volatile to prevent the compiler from re-ordering - // instructions. Namely this sequence: - // - // entry[size] = ...; - // size++; - // - // If the size modification were somehow reordered before the stores, then - // if a sample were taken it would be examining bogus information. - // - // A ProfileEntry represents both a C++ profile entry and a JS one. - - // Descriptive string of this entry. - const char * volatile string; - - // Stack pointer for non-JS entries, the script pointer otherwise. - void * volatile spOrScript; - - // Line number for non-JS entries, the bytecode offset otherwise. - int32_t volatile lineOrPcOffset; - - // General purpose storage describing this frame. - uint32_t volatile flags_; - - public: - // These traits are bit masks. Make sure they're powers of 2. - enum Flags : uint32_t { - // Indicate whether a profile entry represents a CPP frame. If not set, - // a JS frame is assumed by default. You're not allowed to publicly - // change the frame type. Instead, initialize the ProfileEntry as either - // a JS or CPP frame with `initJsFrame` or `initCppFrame` respectively. - IS_CPP_ENTRY = 0x01, - - // Indicate that copying the frame label is not necessary when taking a - // sample of the pseudostack. - FRAME_LABEL_COPY = 0x02, - - // This ProfileEntry is a dummy entry indicating the start of a run - // of JS pseudostack entries. - BEGIN_PSEUDO_JS = 0x04, - - // This flag is used to indicate that an interpreter JS entry has OSR-ed - // into baseline. - OSR = 0x08, - - // Union of all flags. - ALL = IS_CPP_ENTRY|FRAME_LABEL_COPY|BEGIN_PSEUDO_JS|OSR, - - // Mask for removing all flags except the category information. - CATEGORY_MASK = ~ALL - }; - - // Keep these in sync with devtools/client/performance/modules/categories.js - enum class Category : uint32_t { - OTHER = 0x10, - CSS = 0x20, - JS = 0x40, - GC = 0x80, - CC = 0x100, - NETWORK = 0x200, - GRAPHICS = 0x400, - STORAGE = 0x800, - EVENTS = 0x1000, - - FIRST = OTHER, - LAST = EVENTS - }; - - static_assert((static_cast(Category::FIRST) & Flags::ALL) == 0, - "The category bitflags should not intersect with the other flags!"); - - // All of these methods are marked with the 'volatile' keyword because SPS's - // representation of the stack is stored such that all ProfileEntry - // instances are volatile. These methods would not be available unless they - // were marked as volatile as well. - - bool isCpp() const volatile { return hasFlag(IS_CPP_ENTRY); } - bool isJs() const volatile { return !isCpp(); } - - bool isCopyLabel() const volatile { return hasFlag(FRAME_LABEL_COPY); } - - void setLabel(const char* aString) volatile { string = aString; } - const char* label() const volatile { return string; } - - void initJsFrame(JSScript* aScript, jsbytecode* aPc) volatile { - flags_ = 0; - spOrScript = aScript; - setPC(aPc); - } - void initCppFrame(void* aSp, uint32_t aLine) volatile { - flags_ = IS_CPP_ENTRY; - spOrScript = aSp; - lineOrPcOffset = static_cast(aLine); - } - - void setFlag(uint32_t flag) volatile { - MOZ_ASSERT(flag != IS_CPP_ENTRY); - flags_ |= flag; - } - void unsetFlag(uint32_t flag) volatile { - MOZ_ASSERT(flag != IS_CPP_ENTRY); - flags_ &= ~flag; - } - bool hasFlag(uint32_t flag) const volatile { - return bool(flags_ & flag); - } - - uint32_t flags() const volatile { - return flags_; - } - - uint32_t category() const volatile { - return flags_ & CATEGORY_MASK; - } - void setCategory(Category c) volatile { - MOZ_ASSERT(c >= Category::FIRST); - MOZ_ASSERT(c <= Category::LAST); - flags_ &= ~CATEGORY_MASK; - setFlag(static_cast(c)); - } - - void setOSR() volatile { - MOZ_ASSERT(isJs()); - setFlag(OSR); - } - void unsetOSR() volatile { - MOZ_ASSERT(isJs()); - unsetFlag(OSR); - } - bool isOSR() const volatile { - return hasFlag(OSR); - } - - void* stackAddress() const volatile { - MOZ_ASSERT(!isJs()); - return spOrScript; - } - JSScript* script() const volatile; - uint32_t line() const volatile { - MOZ_ASSERT(!isJs()); - return static_cast(lineOrPcOffset); - } - - // Note that the pointer returned might be invalid. - JSScript* rawScript() const volatile { - MOZ_ASSERT(isJs()); - return (JSScript*)spOrScript; - } - - // We can't know the layout of JSScript, so look in vm/SPSProfiler.cpp. - JS_FRIEND_API(jsbytecode*) pc() const volatile; - JS_FRIEND_API(void) setPC(jsbytecode* pc) volatile; - - void trace(JSTracer* trc); - - // The offset of a pc into a script's code can actually be 0, so to - // signify a nullptr pc, use a -1 index. This is checked against in - // pc() and setPC() to set/get the right pc. - static const int32_t NullPCOffset = -1; - - static size_t offsetOfLabel() { return offsetof(ProfileEntry, string); } - static size_t offsetOfSpOrScript() { return offsetof(ProfileEntry, spOrScript); } - static size_t offsetOfLineOrPcOffset() { return offsetof(ProfileEntry, lineOrPcOffset); } - static size_t offsetOfFlags() { return offsetof(ProfileEntry, flags_); } -}; - -JS_FRIEND_API(void) -SetContextProfilingStack(JSContext* cx, ProfileEntry* stack, uint32_t* size, - uint32_t max); - -JS_FRIEND_API(void) -EnableContextProfilingStack(JSContext* cx, bool enabled); - -JS_FRIEND_API(void) -RegisterContextProfilingEventMarker(JSContext* cx, void (*fn)(const char*)); - -JS_FRIEND_API(jsbytecode*) -ProfilingGetPC(JSContext* cx, JSScript* script, void* ip); - -} // namespace js - -#endif /* js_ProfilingStack_h */ diff --git a/android/x86/include/spidermonkey/js/Proxy.h b/android/x86/include/spidermonkey/js/Proxy.h deleted file mode 100644 index 3e95538d..00000000 --- a/android/x86/include/spidermonkey/js/Proxy.h +++ /dev/null @@ -1,632 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_Proxy_h -#define js_Proxy_h - -#include "mozilla/Maybe.h" - -#include "jsfriendapi.h" - -#include "js/CallNonGenericMethod.h" -#include "js/Class.h" - -namespace js { - -using JS::AutoIdVector; -using JS::CallArgs; -using JS::Handle; -using JS::HandleId; -using JS::HandleObject; -using JS::HandleValue; -using JS::IsAcceptableThis; -using JS::MutableHandle; -using JS::MutableHandleObject; -using JS::MutableHandleValue; -using JS::NativeImpl; -using JS::ObjectOpResult; -using JS::PrivateValue; -using JS::PropertyDescriptor; -using JS::Value; - -class RegExpGuard; -class JS_FRIEND_API(Wrapper); - -/* - * A proxy is a JSObject with highly customizable behavior. ES6 specifies a - * single kind of proxy, but the customization mechanisms we use to implement - * ES6 Proxy objects are also useful wherever an object with weird behavior is - * wanted. Proxies are used to implement: - * - * - the scope objects used by the Debugger's frame.eval() method - * (see js::GetDebugScopeForFunction) - * - * - the khuey hack, whereby a whole compartment can be blown away - * even if other compartments hold references to objects in it - * (see js::NukeCrossCompartmentWrappers) - * - * - XPConnect security wrappers, which protect chrome from malicious content - * (js/xpconnect/wrappers) - * - * - DOM objects with special property behavior, like named getters - * (dom/bindings/Codegen.py generates these proxies from WebIDL) - * - * - semi-transparent use of objects that live in other processes - * (CPOWs, implemented in js/ipc) - * - * ### Proxies and internal methods - * - * ES2016 specifies 13 internal methods. The runtime semantics of just - * about everything a script can do to an object is specified in terms - * of these internal methods. For example: - * - * JS code ES6 internal method that gets called - * --------------------------- -------------------------------- - * obj.prop obj.[[Get]](obj, "prop") - * "prop" in obj obj.[[HasProperty]]("prop") - * new obj() obj.[[Construct]]() - * - * With regard to the implementation of these internal methods, there are three - * very different kinds of object in SpiderMonkey. - * - * 1. Native objects' internal methods are implemented in vm/NativeObject.cpp, - * with duplicate (but functionally identical) implementations scattered - * through the ICs and JITs. - * - * 2. Certain non-native objects have internal methods that are implemented as - * magical js::ObjectOps hooks. We're trying to get rid of these. - * - * 3. All other objects are proxies. A proxy's internal methods are - * implemented in C++, as the virtual methods of a C++ object stored on the - * proxy, known as its handler. - * - * This means that just about anything you do to a proxy will end up going - * through a C++ virtual method call. Possibly several. There's no reason the - * JITs and ICs can't specialize for particular proxies, based on the handler; - * but currently we don't do much of this, so the virtual method overhead - * typically is actually incurred. - * - * ### The proxy handler hierarchy - * - * A major use case for proxies is to forward each internal method call to - * another object, known as its target. The target can be an arbitrary JS - * object. Not every proxy has the notion of a target, however. - * - * To minimize code duplication, a set of abstract proxy handler classes is - * provided, from which other handlers may inherit. These abstract classes are - * organized in the following hierarchy: - * - * BaseProxyHandler - * | - * Wrapper // has a target, can be unwrapped to reveal - * | // target (see js::CheckedUnwrap) - * | - * CrossCompartmentWrapper // target is in another compartment; - * // implements membrane between compartments - * - * Example: Some DOM objects (including all the arraylike DOM objects) are - * implemented as proxies. Since these objects don't need to forward operations - * to any underlying JS object, DOMJSProxyHandler directly subclasses - * BaseProxyHandler. - * - * Gecko's security wrappers are examples of cross-compartment wrappers. - * - * ### Proxy prototype chains - * - * In addition to the normal methods, there are two models for proxy prototype - * chains. - * - * 1. Proxies can use the standard prototype mechanism used throughout the - * engine. To do so, simply pass a prototype to NewProxyObject() at - * creation time. All prototype accesses will then "just work" to treat the - * proxy as a "normal" object. - * - * 2. A proxy can implement more complicated prototype semantics (if, for - * example, it wants to delegate the prototype lookup to a wrapped object) - * by passing Proxy::LazyProto as the prototype at create time. This - * guarantees that the getPrototype() handler method will be called every - * time the object's prototype chain is accessed. - * - * This system is implemented with two methods: {get,set}Prototype. The - * default implementation of setPrototype throws a TypeError. Since it is - * not possible to create an object without a sense of prototype chain, - * handlers must implement getPrototype if opting in to the dynamic - * prototype system. - */ - -/* - * BaseProxyHandler is the most generic kind of proxy handler. It does not make - * any assumptions about the target. Consequently, it does not provide any - * default implementation for most methods. As a convenience, a few high-level - * methods, like get() and set(), are given default implementations that work by - * calling the low-level methods, like getOwnPropertyDescriptor(). - * - * Important: If you add a method here, you should probably also add a - * Proxy::foo entry point with an AutoEnterPolicy. If you don't, you need an - * explicit override for the method in SecurityWrapper. See bug 945826 comment 0. - */ -class JS_FRIEND_API(BaseProxyHandler) -{ - /* - * Sometimes it's desirable to designate groups of proxy handlers as "similar". - * For this, we use the notion of a "family": A consumer-provided opaque pointer - * that designates the larger group to which this proxy belongs. - * - * If it will never be important to differentiate this proxy from others as - * part of a distinct group, nullptr may be used instead. - */ - const void* mFamily; - - /* - * Proxy handlers can use mHasPrototype to request the following special - * treatment from the JS engine: - * - * - When mHasPrototype is true, the engine never calls these methods: - * getPropertyDescriptor, has, set, enumerate, iterate. Instead, for - * these operations, it calls the "own" methods like - * getOwnPropertyDescriptor, hasOwn, defineProperty, - * getOwnEnumerablePropertyKeys, etc., and consults the prototype chain - * if needed. - * - * - When mHasPrototype is true, the engine calls handler->get() only if - * handler->hasOwn() says an own property exists on the proxy. If not, - * it consults the prototype chain. - * - * This is useful because it frees the ProxyHandler from having to implement - * any behavior having to do with the prototype chain. - */ - bool mHasPrototype; - - /* - * All proxies indicate whether they have any sort of interesting security - * policy that might prevent the caller from doing something it wants to - * the object. In the case of wrappers, this distinction is used to - * determine whether the caller may strip off the wrapper if it so desires. - */ - bool mHasSecurityPolicy; - - public: - explicit constexpr BaseProxyHandler(const void* aFamily, bool aHasPrototype = false, - bool aHasSecurityPolicy = false) - : mFamily(aFamily), - mHasPrototype(aHasPrototype), - mHasSecurityPolicy(aHasSecurityPolicy) - { } - - bool hasPrototype() const { - return mHasPrototype; - } - - bool hasSecurityPolicy() const { - return mHasSecurityPolicy; - } - - inline const void* family() const { - return mFamily; - } - static size_t offsetOfFamily() { - return offsetof(BaseProxyHandler, mFamily); - } - - virtual bool finalizeInBackground(const Value& priv) const { - /* - * Called on creation of a proxy to determine whether its finalize - * method can be finalized on the background thread. - */ - return true; - } - - virtual bool canNurseryAllocate() const { - /* - * Nursery allocation is allowed if and only if it is safe to not - * run |finalize| when the ProxyObject dies. - */ - return false; - } - - /* Policy enforcement methods. - * - * enter() allows the policy to specify whether the caller may perform |act| - * on the proxy's |id| property. In the case when |act| is CALL, |id| is - * generally JSID_VOID. - * - * The |act| parameter to enter() specifies the action being performed. - * If |bp| is false, the method suggests that the caller throw (though it - * may still decide to squelch the error). - * - * We make these OR-able so that assertEnteredPolicy can pass a union of them. - * For example, get{,Own}PropertyDescriptor is invoked by calls to ::get() - * ::set(), in addition to being invoked on its own, so there are several - * valid Actions that could have been entered. - */ - typedef uint32_t Action; - enum { - NONE = 0x00, - GET = 0x01, - SET = 0x02, - CALL = 0x04, - ENUMERATE = 0x08, - GET_PROPERTY_DESCRIPTOR = 0x10 - }; - - virtual bool enter(JSContext* cx, HandleObject wrapper, HandleId id, Action act, - bool* bp) const; - - /* Standard internal methods. */ - virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id, - MutableHandle desc) const = 0; - virtual bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id, - Handle desc, - ObjectOpResult& result) const = 0; - virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy, - AutoIdVector& props) const = 0; - virtual bool delete_(JSContext* cx, HandleObject proxy, HandleId id, - ObjectOpResult& result) const = 0; - - /* - * These methods are standard, but the engine does not normally call them. - * They're opt-in. See "Proxy prototype chains" above. - * - * getPrototype() crashes if called. setPrototype() throws a TypeError. - */ - virtual bool getPrototype(JSContext* cx, HandleObject proxy, MutableHandleObject protop) const; - virtual bool setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto, - ObjectOpResult& result) const; - - /* Non-standard but conceptual kin to {g,s}etPrototype, so these live here. */ - virtual bool getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy, bool* isOrdinary, - MutableHandleObject protop) const = 0; - virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy, bool* succeeded) const; - - virtual bool preventExtensions(JSContext* cx, HandleObject proxy, - ObjectOpResult& result) const = 0; - virtual bool isExtensible(JSContext* cx, HandleObject proxy, bool* extensible) const = 0; - - /* - * These standard internal methods are implemented, as a convenience, so - * that ProxyHandler subclasses don't have to provide every single method. - * - * The base-class implementations work by calling getPropertyDescriptor(). - * They do not follow any standard. When in doubt, override them. - */ - virtual bool has(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const; - virtual bool get(JSContext* cx, HandleObject proxy, HandleValue receiver, - HandleId id, MutableHandleValue vp) const; - virtual bool set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v, - HandleValue receiver, ObjectOpResult& result) const; - - /* - * [[Call]] and [[Construct]] are standard internal methods but according - * to the spec, they are not present on every object. - * - * SpiderMonkey never calls a proxy's call()/construct() internal method - * unless isCallable()/isConstructor() returns true for that proxy. - * - * BaseProxyHandler::isCallable()/isConstructor() always return false, and - * BaseProxyHandler::call()/construct() crash if called. So if you're - * creating a kind of that is never callable, you don't have to override - * anything, but otherwise you probably want to override all four. - */ - virtual bool call(JSContext* cx, HandleObject proxy, const CallArgs& args) const; - virtual bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const; - - /* SpiderMonkey extensions. */ - virtual bool enumerate(JSContext* cx, HandleObject proxy, MutableHandleObject objp) const; - virtual bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id, - MutableHandle desc) const; - virtual bool hasOwn(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const; - virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject proxy, - AutoIdVector& props) const; - virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl, - const CallArgs& args) const; - virtual bool hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v, bool* bp) const; - virtual bool getBuiltinClass(JSContext* cx, HandleObject proxy, - ESClass* cls) const; - virtual bool isArray(JSContext* cx, HandleObject proxy, JS::IsArrayAnswer* answer) const; - virtual const char* className(JSContext* cx, HandleObject proxy) const; - virtual JSString* fun_toString(JSContext* cx, HandleObject proxy, unsigned indent) const; - virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const; - virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const; - virtual void trace(JSTracer* trc, JSObject* proxy) const; - virtual void finalize(JSFreeOp* fop, JSObject* proxy) const; - virtual void objectMoved(JSObject* proxy, const JSObject* old) const; - - // Allow proxies, wrappers in particular, to specify callability at runtime. - // Note: These do not take const JSObject*, but they do in spirit. - // We are not prepared to do this, as there's little const correctness - // in the external APIs that handle proxies. - virtual bool isCallable(JSObject* obj) const; - virtual bool isConstructor(JSObject* obj) const; - - // These two hooks must be overridden, or not overridden, in tandem -- no - // overriding just one! - virtual bool watch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, - JS::HandleObject callable) const; - virtual bool unwatch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id) const; - - virtual bool getElements(JSContext* cx, HandleObject proxy, uint32_t begin, uint32_t end, - ElementAdder* adder) const; - - /* See comment for weakmapKeyDelegateOp in js/Class.h. */ - virtual JSObject* weakmapKeyDelegate(JSObject* proxy) const; - virtual bool isScripted() const { return false; } -}; - -extern JS_FRIEND_DATA(const js::Class* const) ProxyClassPtr; - -inline bool IsProxy(const JSObject* obj) -{ - return GetObjectClass(obj)->isProxy(); -} - -namespace detail { -const uint32_t PROXY_EXTRA_SLOTS = 2; - -// Layout of the values stored by a proxy. Note that API clients require the -// private slot to be the first slot in the proxy's values, so that the private -// slot can be accessed in the same fashion as the first reserved slot, via -// {Get,Set}ReservedOrProxyPrivateSlot. - -struct ProxyValueArray -{ - Value privateSlot; - Value extraSlots[PROXY_EXTRA_SLOTS]; - - ProxyValueArray() - : privateSlot(JS::UndefinedValue()) - { - for (size_t i = 0; i < PROXY_EXTRA_SLOTS; i++) - extraSlots[i] = JS::UndefinedValue(); - } -}; - -// All proxies share the same data layout. Following the object's shape and -// type, the proxy has a ProxyDataLayout structure with a pointer to an array -// of values and the proxy's handler. This is designed both so that proxies can -// be easily swapped with other objects (via RemapWrapper) and to mimic the -// layout of other objects (proxies and other objects have the same size) so -// that common code can access either type of object. -// -// See GetReservedOrProxyPrivateSlot below. -struct ProxyDataLayout -{ - ProxyValueArray* values; - const BaseProxyHandler* handler; -}; - -const uint32_t ProxyDataOffset = 2 * sizeof(void*); - -inline ProxyDataLayout* -GetProxyDataLayout(JSObject* obj) -{ - MOZ_ASSERT(IsProxy(obj)); - return reinterpret_cast(reinterpret_cast(obj) + ProxyDataOffset); -} - -inline const ProxyDataLayout* -GetProxyDataLayout(const JSObject* obj) -{ - MOZ_ASSERT(IsProxy(obj)); - return reinterpret_cast(reinterpret_cast(obj) + - ProxyDataOffset); -} -} // namespace detail - -inline const BaseProxyHandler* -GetProxyHandler(const JSObject* obj) -{ - return detail::GetProxyDataLayout(obj)->handler; -} - -inline const Value& -GetProxyPrivate(const JSObject* obj) -{ - return detail::GetProxyDataLayout(obj)->values->privateSlot; -} - -inline JSObject* -GetProxyTargetObject(JSObject* obj) -{ - return GetProxyPrivate(obj).toObjectOrNull(); -} - -inline const Value& -GetProxyExtra(const JSObject* obj, size_t n) -{ - MOZ_ASSERT(n < detail::PROXY_EXTRA_SLOTS); - return detail::GetProxyDataLayout(obj)->values->extraSlots[n]; -} - -inline void -SetProxyHandler(JSObject* obj, const BaseProxyHandler* handler) -{ - detail::GetProxyDataLayout(obj)->handler = handler; -} - -JS_FRIEND_API(void) -SetValueInProxy(Value* slot, const Value& value); - -inline void -SetProxyExtra(JSObject* obj, size_t n, const Value& extra) -{ - MOZ_ASSERT(n < detail::PROXY_EXTRA_SLOTS); - Value* vp = &detail::GetProxyDataLayout(obj)->values->extraSlots[n]; - - // Trigger a barrier before writing the slot. - if (vp->isMarkable() || extra.isMarkable()) - SetValueInProxy(vp, extra); - else - *vp = extra; -} - -inline bool -IsScriptedProxy(const JSObject* obj) -{ - return IsProxy(obj) && GetProxyHandler(obj)->isScripted(); -} - -inline const Value& -GetReservedOrProxyPrivateSlot(const JSObject* obj, size_t slot) -{ - MOZ_ASSERT(slot == 0); - MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj)) || IsProxy(obj)); - return reinterpret_cast(obj)->slotRef(slot); -} - -inline void -SetReservedOrProxyPrivateSlot(JSObject* obj, size_t slot, const Value& value) -{ - MOZ_ASSERT(slot == 0); - MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj)) || IsProxy(obj)); - shadow::Object* sobj = reinterpret_cast(obj); - if (sobj->slotRef(slot).isMarkable() || value.isMarkable()) - SetReservedOrProxyPrivateSlotWithBarrier(obj, slot, value); - else - sobj->slotRef(slot) = value; -} - -class MOZ_STACK_CLASS ProxyOptions { - protected: - /* protected constructor for subclass */ - explicit ProxyOptions(bool singletonArg, bool lazyProtoArg = false) - : singleton_(singletonArg), - lazyProto_(lazyProtoArg), - clasp_(ProxyClassPtr) - {} - - public: - ProxyOptions() : singleton_(false), - lazyProto_(false), - clasp_(ProxyClassPtr) - {} - - bool singleton() const { return singleton_; } - ProxyOptions& setSingleton(bool flag) { - singleton_ = flag; - return *this; - } - - bool lazyProto() const { return lazyProto_; } - ProxyOptions& setLazyProto(bool flag) { - lazyProto_ = flag; - return *this; - } - - const Class* clasp() const { - return clasp_; - } - ProxyOptions& setClass(const Class* claspArg) { - clasp_ = claspArg; - return *this; - } - - private: - bool singleton_; - bool lazyProto_; - const Class* clasp_; -}; - -JS_FRIEND_API(JSObject*) -NewProxyObject(JSContext* cx, const BaseProxyHandler* handler, HandleValue priv, - JSObject* proto, const ProxyOptions& options = ProxyOptions()); - -JSObject* -RenewProxyObject(JSContext* cx, JSObject* obj, BaseProxyHandler* handler, const Value& priv); - -class JS_FRIEND_API(AutoEnterPolicy) -{ - public: - typedef BaseProxyHandler::Action Action; - AutoEnterPolicy(JSContext* cx, const BaseProxyHandler* handler, - HandleObject wrapper, HandleId id, Action act, bool mayThrow) -#ifdef JS_DEBUG - : context(nullptr) -#endif - { - allow = handler->hasSecurityPolicy() ? handler->enter(cx, wrapper, id, act, &rv) - : true; - recordEnter(cx, wrapper, id, act); - // We want to throw an exception if all of the following are true: - // * The policy disallowed access. - // * The policy set rv to false, indicating that we should throw. - // * The caller did not instruct us to ignore exceptions. - // * The policy did not throw itself. - if (!allow && !rv && mayThrow) - reportErrorIfExceptionIsNotPending(cx, id); - } - - virtual ~AutoEnterPolicy() { recordLeave(); } - inline bool allowed() { return allow; } - inline bool returnValue() { MOZ_ASSERT(!allowed()); return rv; } - - protected: - // no-op constructor for subclass - AutoEnterPolicy() -#ifdef JS_DEBUG - : context(nullptr) - , enteredAction(BaseProxyHandler::NONE) -#endif - {} - void reportErrorIfExceptionIsNotPending(JSContext* cx, jsid id); - bool allow; - bool rv; - -#ifdef JS_DEBUG - JSContext* context; - mozilla::Maybe enteredProxy; - mozilla::Maybe enteredId; - Action enteredAction; - - // NB: We explicitly don't track the entered action here, because sometimes - // set() methods do an implicit get() during their implementation, leading - // to spurious assertions. - AutoEnterPolicy* prev; - void recordEnter(JSContext* cx, HandleObject proxy, HandleId id, Action act); - void recordLeave(); - - friend JS_FRIEND_API(void) assertEnteredPolicy(JSContext* cx, JSObject* proxy, jsid id, Action act); -#else - inline void recordEnter(JSContext* cx, JSObject* proxy, jsid id, Action act) {} - inline void recordLeave() {} -#endif - -}; - -#ifdef JS_DEBUG -class JS_FRIEND_API(AutoWaivePolicy) : public AutoEnterPolicy { -public: - AutoWaivePolicy(JSContext* cx, HandleObject proxy, HandleId id, - BaseProxyHandler::Action act) - { - allow = true; - recordEnter(cx, proxy, id, act); - } -}; -#else -class JS_FRIEND_API(AutoWaivePolicy) { - public: - AutoWaivePolicy(JSContext* cx, HandleObject proxy, HandleId id, - BaseProxyHandler::Action act) - {} -}; -#endif - -#ifdef JS_DEBUG -extern JS_FRIEND_API(void) -assertEnteredPolicy(JSContext* cx, JSObject* obj, jsid id, - BaseProxyHandler::Action act); -#else -inline void assertEnteredPolicy(JSContext* cx, JSObject* obj, jsid id, - BaseProxyHandler::Action act) -{} -#endif - -extern JS_FRIEND_API(JSObject*) -InitProxyClass(JSContext* cx, JS::HandleObject obj); - -} /* namespace js */ - -#endif /* js_Proxy_h */ diff --git a/android/x86/include/spidermonkey/js/Realm.h b/android/x86/include/spidermonkey/js/Realm.h deleted file mode 100644 index 13a22c70..00000000 --- a/android/x86/include/spidermonkey/js/Realm.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* - * Ways to get various per-Realm objects. All the getters declared in this - * header operate on the Realm corresponding to the current compartment on the - * JSContext. - */ - -#ifndef js_Realm_h -#define js_Realm_h - -#include "jstypes.h" - -struct JSContext; -class JSObject; - -namespace JS { - -extern JS_PUBLIC_API(JSObject*) -GetRealmObjectPrototype(JSContext* cx); - -extern JS_PUBLIC_API(JSObject*) -GetRealmFunctionPrototype(JSContext* cx); - -extern JS_PUBLIC_API(JSObject*) -GetRealmArrayPrototype(JSContext* cx); - -extern JS_PUBLIC_API(JSObject*) -GetRealmErrorPrototype(JSContext* cx); - -extern JS_PUBLIC_API(JSObject*) -GetRealmIteratorPrototype(JSContext* cx); - -} // namespace JS - -#endif // js_Realm_h - - diff --git a/android/x86/include/spidermonkey/js/RequiredDefines.h b/android/x86/include/spidermonkey/js/RequiredDefines.h deleted file mode 100644 index 308fd7d6..00000000 --- a/android/x86/include/spidermonkey/js/RequiredDefines.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* - * Various #defines required to build SpiderMonkey. Embedders should add this - * file to the start of the command line via -include or a similar mechanism, - * or SpiderMonkey public headers may not work correctly. - */ - -#ifndef js_RequiredDefines_h -#define js_RequiredDefines_h - -/* - * The c99 defining the limit macros (UINT32_MAX for example), says: - * - * C++ implementations should define these macros only when - * __STDC_LIMIT_MACROS is defined before is included. - * - * The same also occurs with __STDC_CONSTANT_MACROS for the constant macros - * (INT8_C for example) used to specify a literal constant of the proper type, - * and with __STDC_FORMAT_MACROS for the format macros (PRId32 for example) used - * with the fprintf function family. - */ -#define __STDC_LIMIT_MACROS -#define __STDC_CONSTANT_MACROS -#define __STDC_FORMAT_MACROS - -/* Also define a char16_t type if not provided by the compiler. */ -#include "mozilla/Char16.h" - -#endif /* js_RequiredDefines_h */ diff --git a/android/x86/include/spidermonkey/js/RootingAPI.h b/android/x86/include/spidermonkey/js/RootingAPI.h deleted file mode 100644 index a99ac4ec..00000000 --- a/android/x86/include/spidermonkey/js/RootingAPI.h +++ /dev/null @@ -1,1308 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_RootingAPI_h -#define js_RootingAPI_h - -#include "mozilla/Attributes.h" -#include "mozilla/DebugOnly.h" -#include "mozilla/GuardObjects.h" -#include "mozilla/LinkedList.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -#include - -#include "jspubtd.h" - -#include "js/GCAnnotations.h" -#include "js/GCAPI.h" -#include "js/GCPolicyAPI.h" -#include "js/HeapAPI.h" -#include "js/TypeDecls.h" -#include "js/UniquePtr.h" -#include "js/Utility.h" - -/* - * Moving GC Stack Rooting - * - * A moving GC may change the physical location of GC allocated things, even - * when they are rooted, updating all pointers to the thing to refer to its new - * location. The GC must therefore know about all live pointers to a thing, - * not just one of them, in order to behave correctly. - * - * The |Rooted| and |Handle| classes below are used to root stack locations - * whose value may be held live across a call that can trigger GC. For a - * code fragment such as: - * - * JSObject* obj = NewObject(cx); - * DoSomething(cx); - * ... = obj->lastProperty(); - * - * If |DoSomething()| can trigger a GC, the stack location of |obj| must be - * rooted to ensure that the GC does not move the JSObject referred to by - * |obj| without updating |obj|'s location itself. This rooting must happen - * regardless of whether there are other roots which ensure that the object - * itself will not be collected. - * - * If |DoSomething()| cannot trigger a GC, and the same holds for all other - * calls made between |obj|'s definitions and its last uses, then no rooting - * is required. - * - * SpiderMonkey can trigger a GC at almost any time and in ways that are not - * always clear. For example, the following innocuous-looking actions can - * cause a GC: allocation of any new GC thing; JSObject::hasProperty; - * JS_ReportError and friends; and ToNumber, among many others. The following - * dangerous-looking actions cannot trigger a GC: js_malloc, cx->malloc_, - * rt->malloc_, and friends and JS_ReportOutOfMemory. - * - * The following family of three classes will exactly root a stack location. - * Incorrect usage of these classes will result in a compile error in almost - * all cases. Therefore, it is very hard to be incorrectly rooted if you use - * these classes exclusively. These classes are all templated on the type T of - * the value being rooted. - * - * - Rooted declares a variable of type T, whose value is always rooted. - * Rooted may be automatically coerced to a Handle, below. Rooted - * should be used whenever a local variable's value may be held live across a - * call which can trigger a GC. - * - * - Handle is a const reference to a Rooted. Functions which take GC - * things or values as arguments and need to root those arguments should - * generally use handles for those arguments and avoid any explicit rooting. - * This has two benefits. First, when several such functions call each other - * then redundant rooting of multiple copies of the GC thing can be avoided. - * Second, if the caller does not pass a rooted value a compile error will be - * generated, which is quicker and easier to fix than when relying on a - * separate rooting analysis. - * - * - MutableHandle is a non-const reference to Rooted. It is used in the - * same way as Handle and includes a |set(const T& v)| method to allow - * updating the value of the referenced Rooted. A MutableHandle can be - * created with an implicit cast from a Rooted*. - * - * In some cases the small performance overhead of exact rooting (measured to - * be a few nanoseconds on desktop) is too much. In these cases, try the - * following: - * - * - Move all Rooted above inner loops: this allows you to re-use the root - * on each iteration of the loop. - * - * - Pass Handle through your hot call stack to avoid re-rooting costs at - * every invocation. - * - * The following diagram explains the list of supported, implicit type - * conversions between classes of this family: - * - * Rooted ----> Handle - * | ^ - * | | - * | | - * +---> MutableHandle - * (via &) - * - * All of these types have an implicit conversion to raw pointers. - */ - -namespace js { - -template -struct BarrierMethods { -}; - -template -class RootedBase {}; - -template -class HandleBase {}; - -template -class MutableHandleBase {}; - -template -class HeapBase {}; - -// Cannot use FOR_EACH_HEAP_ABLE_GC_POINTER_TYPE, as this would import too many macros into scope -template struct IsHeapConstructibleType { static constexpr bool value = false; }; -#define DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE(T) \ - template <> struct IsHeapConstructibleType { static constexpr bool value = true; }; -FOR_EACH_PUBLIC_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE) -FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE) -#undef DECLARE_IS_HEAP_CONSTRUCTIBLE_TYPE - -template -class PersistentRootedBase {}; - -static void* const ConstNullValue = nullptr; - -namespace gc { -struct Cell; -template -struct PersistentRootedMarker; -} /* namespace gc */ - -#define DECLARE_POINTER_COMPARISON_OPS(T) \ - bool operator==(const T& other) const { return get() == other; } \ - bool operator!=(const T& other) const { return get() != other; } - -// Important: Return a reference so passing a Rooted, etc. to -// something that takes a |const T&| is not a GC hazard. -#define DECLARE_POINTER_CONSTREF_OPS(T) \ - operator const T&() const { return get(); } \ - const T& operator->() const { return get(); } - -// Assignment operators on a base class are hidden by the implicitly defined -// operator= on the derived class. Thus, define the operator= directly on the -// class as we would need to manually pass it through anyway. -#define DECLARE_POINTER_ASSIGN_OPS(Wrapper, T) \ - Wrapper& operator=(const T& p) { \ - set(p); \ - return *this; \ - } \ - Wrapper& operator=(const Wrapper& other) { \ - set(other.get()); \ - return *this; \ - } \ - -#define DELETE_ASSIGNMENT_OPS(Wrapper, T) \ - template Wrapper& operator=(S) = delete; \ - Wrapper& operator=(const Wrapper&) = delete; - -#define DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr) \ - const T* address() const { return &(ptr); } \ - const T& get() const { return (ptr); } \ - -#define DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr) \ - T* address() { return &(ptr); } \ - T& get() { return (ptr); } \ - -} /* namespace js */ - -namespace JS { - -template class Rooted; -template class PersistentRooted; - -/* This is exposing internal state of the GC for inlining purposes. */ -JS_FRIEND_API(bool) isGCEnabled(); - -JS_FRIEND_API(void) HeapObjectPostBarrier(JSObject** objp, JSObject* prev, JSObject* next); - -#ifdef JS_DEBUG -/** - * For generational GC, assert that an object is in the tenured generation as - * opposed to being in the nursery. - */ -extern JS_FRIEND_API(void) -AssertGCThingMustBeTenured(JSObject* obj); -extern JS_FRIEND_API(void) -AssertGCThingIsNotAnObjectSubclass(js::gc::Cell* cell); -#else -inline void -AssertGCThingMustBeTenured(JSObject* obj) {} -inline void -AssertGCThingIsNotAnObjectSubclass(js::gc::Cell* cell) {} -#endif - -/** - * The Heap class is a heap-stored reference to a JS GC thing. All members of - * heap classes that refer to GC things should use Heap (or possibly - * TenuredHeap, described below). - * - * Heap is an abstraction that hides some of the complexity required to - * maintain GC invariants for the contained reference. It uses operator - * overloading to provide a normal pointer interface, but notifies the GC every - * time the value it contains is updated. This is necessary for generational GC, - * which keeps track of all pointers into the nursery. - * - * Heap instances must be traced when their containing object is traced to - * keep the pointed-to GC thing alive. - * - * Heap objects should only be used on the heap. GC references stored on the - * C/C++ stack must use Rooted/Handle/MutableHandle instead. - * - * Type T must be a public GC pointer type. - */ -template -class Heap : public js::HeapBase -{ - // Please note: this can actually also be used by nsXBLMaybeCompiled, for legacy reasons. - static_assert(js::IsHeapConstructibleType::value, - "Type T must be a public GC pointer type"); - public: - Heap() { - static_assert(sizeof(T) == sizeof(Heap), - "Heap must be binary compatible with T."); - init(GCPolicy::initial()); - } - explicit Heap(const T& p) { init(p); } - - /* - * For Heap, move semantics are equivalent to copy semantics. In C++, a - * copy constructor taking const-ref is the way to get a single function - * that will be used for both lvalue and rvalue copies, so we can simply - * omit the rvalue variant. - */ - explicit Heap(const Heap& p) { init(p.ptr); } - - ~Heap() { - post(ptr, GCPolicy::initial()); - } - - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_POINTER_ASSIGN_OPS(Heap, T); - - const T* address() const { return &ptr; } - - void exposeToActiveJS() const { - js::BarrierMethods::exposeToJS(ptr); - } - const T& get() const { - exposeToActiveJS(); - return ptr; - } - const T& unbarrieredGet() const { - return ptr; - } - - T* unsafeGet() { return &ptr; } - - explicit operator bool() const { - return bool(js::BarrierMethods::asGCThingOrNull(ptr)); - } - explicit operator bool() { - return bool(js::BarrierMethods::asGCThingOrNull(ptr)); - } - - private: - void init(const T& newPtr) { - ptr = newPtr; - post(GCPolicy::initial(), ptr); - } - - void set(const T& newPtr) { - T tmp = ptr; - ptr = newPtr; - post(tmp, ptr); - } - - void post(const T& prev, const T& next) { - js::BarrierMethods::postBarrier(&ptr, prev, next); - } - - T ptr; -}; - -static MOZ_ALWAYS_INLINE bool -ObjectIsTenured(JSObject* obj) -{ - return !js::gc::IsInsideNursery(reinterpret_cast(obj)); -} - -static MOZ_ALWAYS_INLINE bool -ObjectIsTenured(const Heap& obj) -{ - return ObjectIsTenured(obj.unbarrieredGet()); -} - -static MOZ_ALWAYS_INLINE bool -ObjectIsMarkedGray(JSObject* obj) -{ - auto cell = reinterpret_cast(obj); - return js::gc::detail::CellIsMarkedGrayIfKnown(cell); -} - -static MOZ_ALWAYS_INLINE bool -ObjectIsMarkedGray(const JS::Heap& obj) -{ - return ObjectIsMarkedGray(obj.unbarrieredGet()); -} - -static MOZ_ALWAYS_INLINE bool -ScriptIsMarkedGray(JSScript* script) -{ - auto cell = reinterpret_cast(script); - return js::gc::detail::CellIsMarkedGrayIfKnown(cell); -} - -static MOZ_ALWAYS_INLINE bool -ScriptIsMarkedGray(const Heap& script) -{ - return ScriptIsMarkedGray(script.unbarrieredGet()); -} - -/** - * The TenuredHeap class is similar to the Heap class above in that it - * encapsulates the GC concerns of an on-heap reference to a JS object. However, - * it has two important differences: - * - * 1) Pointers which are statically known to only reference "tenured" objects - * can avoid the extra overhead of SpiderMonkey's write barriers. - * - * 2) Objects in the "tenured" heap have stronger alignment restrictions than - * those in the "nursery", so it is possible to store flags in the lower - * bits of pointers known to be tenured. TenuredHeap wraps a normal tagged - * pointer with a nice API for accessing the flag bits and adds various - * assertions to ensure that it is not mis-used. - * - * GC things are said to be "tenured" when they are located in the long-lived - * heap: e.g. they have gained tenure as an object by surviving past at least - * one GC. For performance, SpiderMonkey allocates some things which are known - * to normally be long lived directly into the tenured generation; for example, - * global objects. Additionally, SpiderMonkey does not visit individual objects - * when deleting non-tenured objects, so object with finalizers are also always - * tenured; for instance, this includes most DOM objects. - * - * The considerations to keep in mind when using a TenuredHeap vs a normal - * Heap are: - * - * - It is invalid for a TenuredHeap to refer to a non-tenured thing. - * - It is however valid for a Heap to refer to a tenured thing. - * - It is not possible to store flag bits in a Heap. - */ -template -class TenuredHeap : public js::HeapBase -{ - public: - TenuredHeap() : bits(0) { - static_assert(sizeof(T) == sizeof(TenuredHeap), - "TenuredHeap must be binary compatible with T."); - } - explicit TenuredHeap(T p) : bits(0) { setPtr(p); } - explicit TenuredHeap(const TenuredHeap& p) : bits(0) { setPtr(p.getPtr()); } - - bool operator==(const TenuredHeap& other) { return bits == other.bits; } - bool operator!=(const TenuredHeap& other) { return bits != other.bits; } - - void setPtr(T newPtr) { - MOZ_ASSERT((reinterpret_cast(newPtr) & flagsMask) == 0); - if (newPtr) - AssertGCThingMustBeTenured(newPtr); - bits = (bits & flagsMask) | reinterpret_cast(newPtr); - } - - void setFlags(uintptr_t flagsToSet) { - MOZ_ASSERT((flagsToSet & ~flagsMask) == 0); - bits |= flagsToSet; - } - - void unsetFlags(uintptr_t flagsToUnset) { - MOZ_ASSERT((flagsToUnset & ~flagsMask) == 0); - bits &= ~flagsToUnset; - } - - bool hasFlag(uintptr_t flag) const { - MOZ_ASSERT((flag & ~flagsMask) == 0); - return (bits & flag) != 0; - } - - T unbarrieredGetPtr() const { return reinterpret_cast(bits & ~flagsMask); } - uintptr_t getFlags() const { return bits & flagsMask; } - - void exposeToActiveJS() const { - js::BarrierMethods::exposeToJS(unbarrieredGetPtr()); - } - T getPtr() const { - exposeToActiveJS(); - return unbarrieredGetPtr(); - } - - operator T() const { return getPtr(); } - T operator->() const { return getPtr(); } - - explicit operator bool() const { - return bool(js::BarrierMethods::asGCThingOrNull(unbarrieredGetPtr())); - } - explicit operator bool() { - return bool(js::BarrierMethods::asGCThingOrNull(unbarrieredGetPtr())); - } - - TenuredHeap& operator=(T p) { - setPtr(p); - return *this; - } - - TenuredHeap& operator=(const TenuredHeap& other) { - bits = other.bits; - return *this; - } - - private: - enum { - maskBits = 3, - flagsMask = (1 << maskBits) - 1, - }; - - uintptr_t bits; -}; - -/** - * Reference to a T that has been rooted elsewhere. This is most useful - * as a parameter type, which guarantees that the T lvalue is properly - * rooted. See "Move GC Stack Rooting" above. - * - * If you want to add additional methods to Handle for a specific - * specialization, define a HandleBase specialization containing them. - */ -template -class MOZ_NONHEAP_CLASS Handle : public js::HandleBase -{ - friend class JS::MutableHandle; - - public: - /* Creates a handle from a handle of a type convertible to T. */ - template - MOZ_IMPLICIT Handle(Handle handle, - typename mozilla::EnableIf::value, int>::Type dummy = 0) - { - static_assert(sizeof(Handle) == sizeof(T*), - "Handle must be binary compatible with T*."); - ptr = reinterpret_cast(handle.address()); - } - - MOZ_IMPLICIT Handle(decltype(nullptr)) { - static_assert(mozilla::IsPointer::value, - "nullptr_t overload not valid for non-pointer types"); - ptr = reinterpret_cast(&js::ConstNullValue); - } - - MOZ_IMPLICIT Handle(MutableHandle handle) { - ptr = handle.address(); - } - - /* - * Take care when calling this method! - * - * This creates a Handle from the raw location of a T. - * - * It should be called only if the following conditions hold: - * - * 1) the location of the T is guaranteed to be marked (for some reason - * other than being a Rooted), e.g., if it is guaranteed to be reachable - * from an implicit root. - * - * 2) the contents of the location are immutable, or at least cannot change - * for the lifetime of the handle, as its users may not expect its value - * to change underneath them. - */ - static constexpr Handle fromMarkedLocation(const T* p) { - return Handle(p, DeliberatelyChoosingThisOverload, - ImUsingThisOnlyInFromFromMarkedLocation); - } - - /* - * Construct a handle from an explicitly rooted location. This is the - * normal way to create a handle, and normally happens implicitly. - */ - template - inline - MOZ_IMPLICIT Handle(const Rooted& root, - typename mozilla::EnableIf::value, int>::Type dummy = 0); - - template - inline - MOZ_IMPLICIT Handle(const PersistentRooted& root, - typename mozilla::EnableIf::value, int>::Type dummy = 0); - - /* Construct a read only handle from a mutable handle. */ - template - inline - MOZ_IMPLICIT Handle(MutableHandle& root, - typename mozilla::EnableIf::value, int>::Type dummy = 0); - - DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr); - - private: - Handle() {} - DELETE_ASSIGNMENT_OPS(Handle, T); - - enum Disambiguator { DeliberatelyChoosingThisOverload = 42 }; - enum CallerIdentity { ImUsingThisOnlyInFromFromMarkedLocation = 17 }; - constexpr Handle(const T* p, Disambiguator, CallerIdentity) : ptr(p) {} - - const T* ptr; -}; - -/** - * Similar to a handle, but the underlying storage can be changed. This is - * useful for outparams. - * - * If you want to add additional methods to MutableHandle for a specific - * specialization, define a MutableHandleBase specialization containing - * them. - */ -template -class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase -{ - public: - inline MOZ_IMPLICIT MutableHandle(Rooted* root); - inline MOZ_IMPLICIT MutableHandle(PersistentRooted* root); - - private: - // Disallow nullptr for overloading purposes. - MutableHandle(decltype(nullptr)) = delete; - - public: - void set(const T& v) { - *ptr = v; - } - - /* - * This may be called only if the location of the T is guaranteed - * to be marked (for some reason other than being a Rooted), - * e.g., if it is guaranteed to be reachable from an implicit root. - * - * Create a MutableHandle from a raw location of a T. - */ - static MutableHandle fromMarkedLocation(T* p) { - MutableHandle h; - h.ptr = p; - return h; - } - - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr); - DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(*ptr); - - private: - MutableHandle() {} - DELETE_ASSIGNMENT_OPS(MutableHandle, T); - - T* ptr; -}; - -} /* namespace JS */ - -namespace js { - -template -struct BarrierMethods -{ - static T* initial() { return nullptr; } - static gc::Cell* asGCThingOrNull(T* v) { - if (!v) - return nullptr; - MOZ_ASSERT(uintptr_t(v) > 32); - return reinterpret_cast(v); - } - static void postBarrier(T** vp, T* prev, T* next) { - if (next) - JS::AssertGCThingIsNotAnObjectSubclass(reinterpret_cast(next)); - } - static void exposeToJS(T* t) { - if (t) - js::gc::ExposeGCThingToActiveJS(JS::GCCellPtr(t)); - } -}; - -template <> -struct BarrierMethods -{ - static JSObject* initial() { return nullptr; } - static gc::Cell* asGCThingOrNull(JSObject* v) { - if (!v) - return nullptr; - MOZ_ASSERT(uintptr_t(v) > 32); - return reinterpret_cast(v); - } - static void postBarrier(JSObject** vp, JSObject* prev, JSObject* next) { - JS::HeapObjectPostBarrier(vp, prev, next); - } - static void exposeToJS(JSObject* obj) { - if (obj) - JS::ExposeObjectToActiveJS(obj); - } -}; - -template <> -struct BarrierMethods -{ - static JSFunction* initial() { return nullptr; } - static gc::Cell* asGCThingOrNull(JSFunction* v) { - if (!v) - return nullptr; - MOZ_ASSERT(uintptr_t(v) > 32); - return reinterpret_cast(v); - } - static void postBarrier(JSFunction** vp, JSFunction* prev, JSFunction* next) { - JS::HeapObjectPostBarrier(reinterpret_cast(vp), - reinterpret_cast(prev), - reinterpret_cast(next)); - } - static void exposeToJS(JSFunction* fun) { - if (fun) - JS::ExposeObjectToActiveJS(reinterpret_cast(fun)); - } -}; - -// Provide hash codes for Cell kinds that may be relocated and, thus, not have -// a stable address to use as the base for a hash code. Instead of the address, -// this hasher uses Cell::getUniqueId to provide exact matches and as a base -// for generating hash codes. -// -// Note: this hasher, like PointerHasher can "hash" a nullptr. While a nullptr -// would not likely be a useful key, there are some cases where being able to -// hash a nullptr is useful, either on purpose or because of bugs: -// (1) existence checks where the key may happen to be null and (2) some -// aggregate Lookup kinds embed a JSObject* that is frequently null and do not -// null test before dispatching to the hasher. -template -struct JS_PUBLIC_API(MovableCellHasher) -{ - using Key = T; - using Lookup = T; - - static bool hasHash(const Lookup& l); - static bool ensureHash(const Lookup& l); - static HashNumber hash(const Lookup& l); - static bool match(const Key& k, const Lookup& l); - static void rekey(Key& k, const Key& newKey) { k = newKey; } -}; - -template -struct JS_PUBLIC_API(MovableCellHasher>) -{ - using Key = JS::Heap; - using Lookup = T; - - static bool hasHash(const Lookup& l) { return MovableCellHasher::hasHash(l); } - static bool ensureHash(const Lookup& l) { return MovableCellHasher::ensureHash(l); } - static HashNumber hash(const Lookup& l) { return MovableCellHasher::hash(l); } - static bool match(const Key& k, const Lookup& l) { - return MovableCellHasher::match(k.unbarrieredGet(), l); - } - static void rekey(Key& k, const Key& newKey) { k.unsafeSet(newKey); } -}; - -template -struct FallibleHashMethods> -{ - template static bool hasHash(Lookup&& l) { - return MovableCellHasher::hasHash(mozilla::Forward(l)); - } - template static bool ensureHash(Lookup&& l) { - return MovableCellHasher::ensureHash(mozilla::Forward(l)); - } -}; - -} /* namespace js */ - -namespace js { - -// The alignment must be set because the Rooted and PersistentRooted ptr fields -// may be accessed through reinterpret_cast*>, and -// the compiler may choose a different alignment for the ptr field when it -// knows the actual type stored in DispatchWrapper. -// -// It would make more sense to align only those specific fields of type -// DispatchWrapper, rather than DispatchWrapper itself, but that causes MSVC to -// fail when Rooted is used in an IsConvertible test. -template -class alignas(8) DispatchWrapper -{ - static_assert(JS::MapTypeToRootKind::kind == JS::RootKind::Traceable, - "DispatchWrapper is intended only for usage with a Traceable"); - - using TraceFn = void (*)(JSTracer*, T*, const char*); - TraceFn tracer; - alignas(gc::CellSize) T storage; - - public: - template - MOZ_IMPLICIT DispatchWrapper(U&& initial) - : tracer(&JS::GCPolicy::trace), - storage(mozilla::Forward(initial)) - { } - - // Mimic a pointer type, so that we can drop into Rooted. - T* operator &() { return &storage; } - const T* operator &() const { return &storage; } - operator T&() { return storage; } - operator const T&() const { return storage; } - - // Trace the contained storage (of unknown type) using the trace function - // we set aside when we did know the type. - static void TraceWrapped(JSTracer* trc, T* thingp, const char* name) { - auto wrapper = reinterpret_cast( - uintptr_t(thingp) - offsetof(DispatchWrapper, storage)); - wrapper->tracer(trc, &wrapper->storage, name); - } -}; - -} /* namespace js */ - -namespace JS { - -/** - * Local variable of type T whose value is always rooted. This is typically - * used for local variables, or for non-rooted values being passed to a - * function that requires a handle, e.g. Foo(Root(cx, x)). - * - * If you want to add additional methods to Rooted for a specific - * specialization, define a RootedBase specialization containing them. - */ -template -class MOZ_RAII Rooted : public js::RootedBase -{ - inline void registerWithRootLists(js::RootedListHeads& roots) { - this->stack = &roots[JS::MapTypeToRootKind::kind]; - this->prev = *stack; - *stack = reinterpret_cast*>(this); - } - - inline js::RootedListHeads& rootLists(JS::RootingContext* cx) { - return rootLists(static_cast(cx)); - } - inline js::RootedListHeads& rootLists(js::ContextFriendFields* cx) { - if (JS::Zone* zone = cx->zone_) - return JS::shadow::Zone::asShadowZone(zone)->stackRoots_; - MOZ_ASSERT(cx->isJSContext); - return cx->roots.stackRoots_; - } - inline js::RootedListHeads& rootLists(JSContext* cx) { - return rootLists(js::ContextFriendFields::get(cx)); - } - - public: - template - explicit Rooted(const RootingContext& cx) - : ptr(GCPolicy::initial()) - { - registerWithRootLists(rootLists(cx)); - } - - template - Rooted(const RootingContext& cx, S&& initial) - : ptr(mozilla::Forward(initial)) - { - registerWithRootLists(rootLists(cx)); - } - - ~Rooted() { - MOZ_ASSERT(*stack == reinterpret_cast*>(this)); - *stack = prev; - } - - Rooted* previous() { return reinterpret_cast*>(prev); } - - /* - * This method is public for Rooted so that Codegen.py can use a Rooted - * interchangeably with a MutableHandleValue. - */ - void set(const T& value) { - ptr = value; - } - - DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_POINTER_ASSIGN_OPS(Rooted, T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr); - DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr); - - private: - /* - * These need to be templated on void* to avoid aliasing issues between, for - * example, Rooted and Rooted, which use the same - * stack head pointer for different classes. - */ - Rooted** stack; - Rooted* prev; - - /* - * For pointer types, the TraceKind for tracing is based on the list it is - * in (selected via MapTypeToRootKind), so no additional storage is - * required here. Non-pointer types, however, share the same list, so the - * function to call for tracing is stored adjacent to the struct. Since C++ - * cannot templatize on storage class, this is implemented via the wrapper - * class DispatchWrapper. - */ - using MaybeWrapped = typename mozilla::Conditional< - MapTypeToRootKind::kind == JS::RootKind::Traceable, - js::DispatchWrapper, - T>::Type; - MaybeWrapped ptr; - - Rooted(const Rooted&) = delete; -} JS_HAZ_ROOTED; - -} /* namespace JS */ - -namespace js { - -/** - * Augment the generic Rooted interface when T = JSObject* with - * class-querying and downcasting operations. - * - * Given a Rooted obj, one can view - * Handle h = obj.as(); - * as an optimization of - * Rooted rooted(cx, &obj->as()); - * Handle h = rooted; - */ -template <> -class RootedBase -{ - public: - template - JS::Handle as() const; -}; - -/** - * Augment the generic Handle interface when T = JSObject* with - * downcasting operations. - * - * Given a Handle obj, one can view - * Handle h = obj.as(); - * as an optimization of - * Rooted rooted(cx, &obj->as()); - * Handle h = rooted; - */ -template <> -class HandleBase -{ - public: - template - JS::Handle as() const; -}; - -/** Interface substitute for Rooted which does not root the variable's memory. */ -template -class MOZ_RAII FakeRooted : public RootedBase -{ - public: - template - explicit FakeRooted(CX* cx) : ptr(JS::GCPolicy::initial()) {} - - template - FakeRooted(CX* cx, T initial) : ptr(initial) {} - - DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_POINTER_ASSIGN_OPS(FakeRooted, T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr); - DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr); - - private: - T ptr; - - void set(const T& value) { - ptr = value; - } - - FakeRooted(const FakeRooted&) = delete; -}; - -/** Interface substitute for MutableHandle which is not required to point to rooted memory. */ -template -class FakeMutableHandle : public js::MutableHandleBase -{ - public: - MOZ_IMPLICIT FakeMutableHandle(T* t) { - ptr = t; - } - - MOZ_IMPLICIT FakeMutableHandle(FakeRooted* root) { - ptr = root->address(); - } - - void set(const T& v) { - *ptr = v; - } - - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr); - DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(*ptr); - - private: - FakeMutableHandle() {} - DELETE_ASSIGNMENT_OPS(FakeMutableHandle, T); - - T* ptr; -}; - -/** - * Types for a variable that either should or shouldn't be rooted, depending on - * the template parameter allowGC. Used for implementing functions that can - * operate on either rooted or unrooted data. - * - * The toHandle() and toMutableHandle() functions are for calling functions - * which require handle types and are only called in the CanGC case. These - * allow the calling code to type check. - */ -enum AllowGC { - NoGC = 0, - CanGC = 1 -}; -template -class MaybeRooted -{ -}; - -template class MaybeRooted -{ - public: - typedef JS::Handle HandleType; - typedef JS::Rooted RootType; - typedef JS::MutableHandle MutableHandleType; - - static inline JS::Handle toHandle(HandleType v) { - return v; - } - - static inline JS::MutableHandle toMutableHandle(MutableHandleType v) { - return v; - } - - template - static inline JS::Handle downcastHandle(HandleType v) { - return v.template as(); - } -}; - -template class MaybeRooted -{ - public: - typedef const T& HandleType; - typedef FakeRooted RootType; - typedef FakeMutableHandle MutableHandleType; - - static JS::Handle toHandle(HandleType v) { - MOZ_CRASH("Bad conversion"); - } - - static JS::MutableHandle toMutableHandle(MutableHandleType v) { - MOZ_CRASH("Bad conversion"); - } - - template - static inline T2* downcastHandle(HandleType v) { - return &v->template as(); - } -}; - -} /* namespace js */ - -namespace JS { - -template template -inline -Handle::Handle(const Rooted& root, - typename mozilla::EnableIf::value, int>::Type dummy) -{ - ptr = reinterpret_cast(root.address()); -} - -template template -inline -Handle::Handle(const PersistentRooted& root, - typename mozilla::EnableIf::value, int>::Type dummy) -{ - ptr = reinterpret_cast(root.address()); -} - -template template -inline -Handle::Handle(MutableHandle& root, - typename mozilla::EnableIf::value, int>::Type dummy) -{ - ptr = reinterpret_cast(root.address()); -} - -template -inline -MutableHandle::MutableHandle(Rooted* root) -{ - static_assert(sizeof(MutableHandle) == sizeof(T*), - "MutableHandle must be binary compatible with T*."); - ptr = root->address(); -} - -template -inline -MutableHandle::MutableHandle(PersistentRooted* root) -{ - static_assert(sizeof(MutableHandle) == sizeof(T*), - "MutableHandle must be binary compatible with T*."); - ptr = root->address(); -} - -/** - * A copyable, assignable global GC root type with arbitrary lifetime, an - * infallible constructor, and automatic unrooting on destruction. - * - * These roots can be used in heap-allocated data structures, so they are not - * associated with any particular JSContext or stack. They are registered with - * the JSRuntime itself, without locking, so they require a full JSContext to be - * initialized, not one of its more restricted superclasses. Initialization may - * take place on construction, or in two phases if the no-argument constructor - * is called followed by init(). - * - * Note that you must not use an PersistentRooted in an object owned by a JS - * object: - * - * Whenever one object whose lifetime is decided by the GC refers to another - * such object, that edge must be traced only if the owning JS object is traced. - * This applies not only to JS objects (which obviously are managed by the GC) - * but also to C++ objects owned by JS objects. - * - * If you put a PersistentRooted in such a C++ object, that is almost certainly - * a leak. When a GC begins, the referent of the PersistentRooted is treated as - * live, unconditionally (because a PersistentRooted is a *root*), even if the - * JS object that owns it is unreachable. If there is any path from that - * referent back to the JS object, then the C++ object containing the - * PersistentRooted will not be destructed, and the whole blob of objects will - * not be freed, even if there are no references to them from the outside. - * - * In the context of Firefox, this is a severe restriction: almost everything in - * Firefox is owned by some JS object or another, so using PersistentRooted in - * such objects would introduce leaks. For these kinds of edges, Heap or - * TenuredHeap would be better types. It's up to the implementor of the type - * containing Heap or TenuredHeap members to make sure their referents get - * marked when the object itself is marked. - */ -template -class PersistentRooted : public js::PersistentRootedBase, - private mozilla::LinkedListElement> -{ - using ListBase = mozilla::LinkedListElement>; - - friend class mozilla::LinkedList; - friend class mozilla::LinkedListElement; - - void registerWithRootLists(js::RootLists& roots) { - MOZ_ASSERT(!initialized()); - JS::RootKind kind = JS::MapTypeToRootKind::kind; - roots.heapRoots_[kind].insertBack(reinterpret_cast*>(this)); - } - - js::RootLists& rootLists(JSContext* cx) { - return rootLists(JS::RootingContext::get(cx)); - } - js::RootLists& rootLists(JS::RootingContext* cx) { - MOZ_ASSERT(cx->isJSContext); - return cx->roots; - } - - // Disallow ExclusiveContext*. - js::RootLists& rootLists(js::ContextFriendFields* cx) = delete; - - public: - PersistentRooted() : ptr(GCPolicy::initial()) {} - - template - explicit PersistentRooted(const RootingContext& cx) - : ptr(GCPolicy::initial()) - { - registerWithRootLists(rootLists(cx)); - } - - template - PersistentRooted(const RootingContext& cx, U&& initial) - : ptr(mozilla::Forward(initial)) - { - registerWithRootLists(rootLists(cx)); - } - - PersistentRooted(const PersistentRooted& rhs) - : mozilla::LinkedListElement>(), - ptr(rhs.ptr) - { - /* - * Copy construction takes advantage of the fact that the original - * is already inserted, and simply adds itself to whatever list the - * original was on - no JSRuntime pointer needed. - * - * This requires mutating rhs's links, but those should be 'mutable' - * anyway. C++ doesn't let us declare mutable base classes. - */ - const_cast(rhs).setNext(this); - } - - bool initialized() { - return ListBase::isInList(); - } - - template - void init(const RootingContext& cx) { - init(cx, GCPolicy::initial()); - } - - template - void init(const RootingContext& cx, U&& initial) { - ptr = mozilla::Forward(initial); - registerWithRootLists(rootLists(cx)); - } - - void reset() { - if (initialized()) { - set(GCPolicy::initial()); - ListBase::remove(); - } - } - - DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_POINTER_ASSIGN_OPS(PersistentRooted, T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr); - - // These are the same as DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS, except - // they check that |this| is initialized in case the caller later stores - // something in |ptr|. - T* address() { - MOZ_ASSERT(initialized()); - return &ptr; - } - T& get() { - MOZ_ASSERT(initialized()); - return ptr; - } - - private: - template - void set(U&& value) { - MOZ_ASSERT(initialized()); - ptr = mozilla::Forward(value); - } - - // See the comment above Rooted::ptr. - using MaybeWrapped = typename mozilla::Conditional< - MapTypeToRootKind::kind == JS::RootKind::Traceable, - js::DispatchWrapper, - T>::Type; - MaybeWrapped ptr; -} JS_HAZ_ROOTED; - -class JS_PUBLIC_API(ObjectPtr) -{ - Heap value; - - public: - ObjectPtr() : value(nullptr) {} - - explicit ObjectPtr(JSObject* obj) : value(obj) {} - - /* Always call finalize before the destructor. */ - ~ObjectPtr() { MOZ_ASSERT(!value); } - - void finalize(JSRuntime* rt); - void finalize(JSContext* cx); - - void init(JSObject* obj) { value = obj; } - - JSObject* get() const { return value; } - JSObject* unbarrieredGet() const { return value.unbarrieredGet(); } - - void writeBarrierPre(JSContext* cx) { - IncrementalObjectBarrier(value); - } - - void updateWeakPointerAfterGC(); - - ObjectPtr& operator=(JSObject* obj) { - IncrementalObjectBarrier(value); - value = obj; - return *this; - } - - void trace(JSTracer* trc, const char* name); - - JSObject& operator*() const { return *value; } - JSObject* operator->() const { return value; } - operator JSObject*() const { return value; } - - explicit operator bool() const { return value.unbarrieredGet(); } - explicit operator bool() { return value.unbarrieredGet(); } -}; - -} /* namespace JS */ - -namespace js { - -template -class UniquePtrOperations -{ - const UniquePtr& uniquePtr() const { return static_cast(this)->get(); } - - public: - explicit operator bool() const { return !!uniquePtr(); } -}; - -template -class MutableUniquePtrOperations : public UniquePtrOperations -{ - UniquePtr& uniquePtr() { return static_cast(this)->get(); } - - public: - MOZ_MUST_USE typename UniquePtr::Pointer release() { return uniquePtr().release(); } -}; - -template -class RootedBase> - : public MutableUniquePtrOperations>, T, D> -{ }; - -template -class MutableHandleBase> - : public MutableUniquePtrOperations>, T, D> -{ }; - -template -class HandleBase> - : public UniquePtrOperations>, T, D> -{ }; - -template -class PersistentRootedBase> - : public MutableUniquePtrOperations>, T, D> -{ }; - -namespace gc { - -template -void -CallTraceCallbackOnNonHeap(T* v, const TraceCallbacks& aCallbacks, const char* aName, void* aClosure) -{ - static_assert(sizeof(T) == sizeof(JS::Heap), "T and Heap must be compatible."); - MOZ_ASSERT(v); - mozilla::DebugOnly cell = BarrierMethods::asGCThingOrNull(*v); - MOZ_ASSERT(cell); - MOZ_ASSERT(!IsInsideNursery(cell)); - JS::Heap* asHeapT = reinterpret_cast*>(v); - aCallbacks.Trace(asHeapT, aName, aClosure); -} - -} /* namespace gc */ -} /* namespace js */ - -// mozilla::Swap uses a stack temporary, which prevents classes like Heap -// from being declared MOZ_HEAP_CLASS. -namespace mozilla { - -template -inline void -Swap(JS::Heap& aX, JS::Heap& aY) -{ - T tmp = aX; - aX = aY; - aY = tmp; -} - -template -inline void -Swap(JS::TenuredHeap& aX, JS::TenuredHeap& aY) -{ - T tmp = aX; - aX = aY; - aY = tmp; -} - -} /* namespace mozilla */ - -#undef DELETE_ASSIGNMENT_OPS - -#endif /* js_RootingAPI_h */ diff --git a/android/x86/include/spidermonkey/js/SliceBudget.h b/android/x86/include/spidermonkey/js/SliceBudget.h deleted file mode 100644 index 78982df0..00000000 --- a/android/x86/include/spidermonkey/js/SliceBudget.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_SliceBudget_h -#define js_SliceBudget_h - -#include - -namespace js { - -struct JS_PUBLIC_API(TimeBudget) -{ - int64_t budget; - - explicit TimeBudget(int64_t milliseconds) { budget = milliseconds; } -}; - -struct JS_PUBLIC_API(WorkBudget) -{ - int64_t budget; - - explicit WorkBudget(int64_t work) { budget = work; } -}; - -/* - * This class records how much work has been done in a given collection slice, - * so that we can return before pausing for too long. Some slices are allowed - * to run for unlimited time, and others are bounded. To reduce the number of - * gettimeofday calls, we only check the time every 1000 operations. - */ -class JS_PUBLIC_API(SliceBudget) -{ - static const int64_t unlimitedDeadline = INT64_MAX; - static const intptr_t unlimitedStartCounter = INTPTR_MAX; - - bool checkOverBudget(); - - SliceBudget(); - - public: - // Memory of the originally requested budget. If isUnlimited, neither of - // these are in use. If deadline==0, then workBudget is valid. Otherwise - // timeBudget is valid. - TimeBudget timeBudget; - WorkBudget workBudget; - - int64_t deadline; /* in microseconds */ - intptr_t counter; - - static const intptr_t CounterReset = 1000; - - static const int64_t UnlimitedTimeBudget = -1; - static const int64_t UnlimitedWorkBudget = -1; - - /* Use to create an unlimited budget. */ - static SliceBudget unlimited() { return SliceBudget(); } - - /* Instantiate as SliceBudget(TimeBudget(n)). */ - explicit SliceBudget(TimeBudget time); - - /* Instantiate as SliceBudget(WorkBudget(n)). */ - explicit SliceBudget(WorkBudget work); - - void makeUnlimited() { - deadline = unlimitedDeadline; - counter = unlimitedStartCounter; - } - - void step(intptr_t amt = 1) { - counter -= amt; - } - - bool isOverBudget() { - if (counter > 0) - return false; - return checkOverBudget(); - } - - bool isWorkBudget() const { return deadline == 0; } - bool isTimeBudget() const { return deadline > 0 && !isUnlimited(); } - bool isUnlimited() const { return deadline == unlimitedDeadline; } - - int describe(char* buffer, size_t maxlen) const; -}; - -} // namespace js - -#endif /* js_SliceBudget_h */ diff --git a/android/x86/include/spidermonkey/js/StructuredClone.h b/android/x86/include/spidermonkey/js/StructuredClone.h deleted file mode 100644 index e10a3073..00000000 --- a/android/x86/include/spidermonkey/js/StructuredClone.h +++ /dev/null @@ -1,358 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_StructuredClone_h -#define js_StructuredClone_h - -#include "mozilla/Attributes.h" -#include "mozilla/BufferList.h" - -#include - -#include "jstypes.h" - -#include "js/RootingAPI.h" -#include "js/TypeDecls.h" -#include "js/Value.h" - -struct JSRuntime; -struct JSStructuredCloneReader; -struct JSStructuredCloneWriter; - -// API for the HTML5 internal structured cloning algorithm. - -namespace JS { - -enum class StructuredCloneScope : uint32_t { - SameProcessSameThread, - SameProcessDifferentThread, - DifferentProcess -}; - -enum TransferableOwnership { - /** Transferable data has not been filled in yet */ - SCTAG_TMO_UNFILLED = 0, - - /** Structured clone buffer does not yet own the data */ - SCTAG_TMO_UNOWNED = 1, - - /** All values at least this large are owned by the clone buffer */ - SCTAG_TMO_FIRST_OWNED = 2, - - /** Data is a pointer that can be freed */ - SCTAG_TMO_ALLOC_DATA = 2, - - /** Data is a memory mapped pointer */ - SCTAG_TMO_MAPPED_DATA = 3, - - /** - * Data is embedding-specific. The engine can free it by calling the - * freeTransfer op. The embedding can also use SCTAG_TMO_USER_MIN and - * greater, up to 32 bits, to distinguish specific ownership variants. - */ - SCTAG_TMO_CUSTOM = 4, - - SCTAG_TMO_USER_MIN -}; - -class CloneDataPolicy -{ - bool sharedArrayBuffer_; - - public: - // The default is to allow all policy-controlled aspects. - - CloneDataPolicy() : - sharedArrayBuffer_(true) - {} - - // In the JS engine, SharedArrayBuffers can only be cloned intra-process - // because the shared memory areas are allocated in process-private memory. - // Clients should therefore deny SharedArrayBuffers when cloning data that - // are to be transmitted inter-process. - // - // Clients should also deny SharedArrayBuffers when cloning data that are to - // be transmitted intra-process if policy needs dictate such denial. - - CloneDataPolicy& denySharedArrayBuffer() { - sharedArrayBuffer_ = false; - return *this; - } - - bool isSharedArrayBufferAllowed() const { - return sharedArrayBuffer_; - } -}; - -} /* namespace JS */ - -/** - * Read structured data from the reader r. This hook is used to read a value - * previously serialized by a call to the WriteStructuredCloneOp hook. - * - * tag and data are the pair of uint32_t values from the header. The callback - * may use the JS_Read* APIs to read any other relevant parts of the object - * from the reader r. closure is any value passed to the JS_ReadStructuredClone - * function. Return the new object on success, nullptr on error/exception. - */ -typedef JSObject* (*ReadStructuredCloneOp)(JSContext* cx, JSStructuredCloneReader* r, - uint32_t tag, uint32_t data, void* closure); - -/** - * Structured data serialization hook. The engine can write primitive values, - * Objects, Arrays, Dates, RegExps, TypedArrays, ArrayBuffers, Sets, Maps, - * and SharedTypedArrays. Any other type of object requires application support. - * This callback must first use the JS_WriteUint32Pair API to write an object - * header, passing a value greater than JS_SCTAG_USER to the tag parameter. - * Then it can use the JS_Write* APIs to write any other relevant parts of - * the value v to the writer w. closure is any value passed to the - * JS_WriteStructuredClone function. - * - * Return true on success, false on error/exception. - */ -typedef bool (*WriteStructuredCloneOp)(JSContext* cx, JSStructuredCloneWriter* w, - JS::HandleObject obj, void* closure); - -/** - * This is called when JS_WriteStructuredClone is given an invalid transferable. - * To follow HTML5, the application must throw a DATA_CLONE_ERR DOMException - * with error set to one of the JS_SCERR_* values. - */ -typedef void (*StructuredCloneErrorOp)(JSContext* cx, uint32_t errorid); - -/** - * This is called when JS_ReadStructuredClone receives a transferable object - * not known to the engine. If this hook does not exist or returns false, the - * JS engine calls the reportError op if set, otherwise it throws a - * DATA_CLONE_ERR DOM Exception. This method is called before any other - * callback and must return a non-null object in returnObject on success. - */ -typedef bool (*ReadTransferStructuredCloneOp)(JSContext* cx, JSStructuredCloneReader* r, - uint32_t tag, void* content, uint64_t extraData, - void* closure, - JS::MutableHandleObject returnObject); - -/** - * Called when JS_WriteStructuredClone receives a transferable object not - * handled by the engine. If this hook does not exist or returns false, the JS - * engine will call the reportError hook or fall back to throwing a - * DATA_CLONE_ERR DOM Exception. This method is called before any other - * callback. - * - * tag: indicates what type of transferable this is. Must be greater than - * 0xFFFF0201 (value of the internal SCTAG_TRANSFER_MAP_PENDING_ENTRY) - * - * ownership: see TransferableOwnership, above. Used to communicate any needed - * ownership info to the FreeTransferStructuredCloneOp. - * - * content, extraData: what the ReadTransferStructuredCloneOp will receive - */ -typedef bool (*TransferStructuredCloneOp)(JSContext* cx, - JS::Handle obj, - void* closure, - // Output: - uint32_t* tag, - JS::TransferableOwnership* ownership, - void** content, - uint64_t* extraData); - -/** - * Called when freeing an unknown transferable object. Note that it - * should never trigger a garbage collection (and will assert in a - * debug build if it does.) - */ -typedef void (*FreeTransferStructuredCloneOp)(uint32_t tag, JS::TransferableOwnership ownership, - void* content, uint64_t extraData, void* closure); - -// The maximum supported structured-clone serialization format version. -// Increment this when anything at all changes in the serialization format. -// (Note that this does not need to be bumped for Transferable-only changes, -// since they are never saved to persistent storage.) -#define JS_STRUCTURED_CLONE_VERSION 8 - -struct JSStructuredCloneCallbacks { - ReadStructuredCloneOp read; - WriteStructuredCloneOp write; - StructuredCloneErrorOp reportError; - ReadTransferStructuredCloneOp readTransfer; - TransferStructuredCloneOp writeTransfer; - FreeTransferStructuredCloneOp freeTransfer; -}; - -enum OwnTransferablePolicy { - OwnsTransferablesIfAny, - IgnoreTransferablesIfAny, - NoTransferables -}; - -class MOZ_NON_MEMMOVABLE JSStructuredCloneData : public mozilla::BufferList -{ - typedef js::SystemAllocPolicy AllocPolicy; - typedef mozilla::BufferList BufferList; - - static const size_t kInitialSize = 0; - static const size_t kInitialCapacity = 4096; - static const size_t kStandardCapacity = 4096; - - const JSStructuredCloneCallbacks* callbacks_; - void* closure_; - OwnTransferablePolicy ownTransferables_; - - void setOptionalCallbacks(const JSStructuredCloneCallbacks* callbacks, - void* closure, - OwnTransferablePolicy policy) { - callbacks_ = callbacks; - closure_ = closure; - ownTransferables_ = policy; - } - - friend struct JSStructuredCloneWriter; - friend class JS_PUBLIC_API(JSAutoStructuredCloneBuffer); - -public: - explicit JSStructuredCloneData(AllocPolicy aAP = AllocPolicy()) - : BufferList(kInitialSize, kInitialCapacity, kStandardCapacity, aAP) - , callbacks_(nullptr) - , closure_(nullptr) - , ownTransferables_(OwnTransferablePolicy::NoTransferables) - {} - MOZ_IMPLICIT JSStructuredCloneData(BufferList&& buffers) - : BufferList(Move(buffers)) - , callbacks_(nullptr) - , closure_(nullptr) - , ownTransferables_(OwnTransferablePolicy::NoTransferables) - {} - JSStructuredCloneData(JSStructuredCloneData&& other) = default; - JSStructuredCloneData& operator=(JSStructuredCloneData&& other) = default; - ~JSStructuredCloneData(); - - using BufferList::BufferList; -}; - -/** Note: if the *data contains transferable objects, it can be read only once. */ -JS_PUBLIC_API(bool) -JS_ReadStructuredClone(JSContext* cx, JSStructuredCloneData& data, uint32_t version, - JS::StructuredCloneScope scope, - JS::MutableHandleValue vp, - const JSStructuredCloneCallbacks* optionalCallbacks, void* closure); - -JS_PUBLIC_API(bool) -JS_WriteStructuredClone(JSContext* cx, JS::HandleValue v, JSStructuredCloneData* data, - JS::StructuredCloneScope scope, - JS::CloneDataPolicy cloneDataPolicy, - const JSStructuredCloneCallbacks* optionalCallbacks, - void* closure, JS::HandleValue transferable); - -JS_PUBLIC_API(bool) -JS_StructuredCloneHasTransferables(JSStructuredCloneData& data, bool* hasTransferable); - -JS_PUBLIC_API(bool) -JS_StructuredClone(JSContext* cx, JS::HandleValue v, JS::MutableHandleValue vp, - const JSStructuredCloneCallbacks* optionalCallbacks, void* closure); - -/** RAII sugar for JS_WriteStructuredClone. */ -class JS_PUBLIC_API(JSAutoStructuredCloneBuffer) { - const JS::StructuredCloneScope scope_; - JSStructuredCloneData data_; - uint32_t version_; - - public: - JSAutoStructuredCloneBuffer(JS::StructuredCloneScope scope, - const JSStructuredCloneCallbacks* callbacks, void* closure) - : scope_(scope), version_(JS_STRUCTURED_CLONE_VERSION) - { - data_.setOptionalCallbacks(callbacks, closure, OwnTransferablePolicy::NoTransferables); - } - - JSAutoStructuredCloneBuffer(JSAutoStructuredCloneBuffer&& other); - JSAutoStructuredCloneBuffer& operator=(JSAutoStructuredCloneBuffer&& other); - - ~JSAutoStructuredCloneBuffer() { clear(); } - - JSStructuredCloneData& data() { return data_; } - bool empty() const { return !data_.Size(); } - - void clear(const JSStructuredCloneCallbacks* optionalCallbacks=nullptr, void* closure=nullptr); - - /** Copy some memory. It will be automatically freed by the destructor. */ - bool copy(const JSStructuredCloneData& data, uint32_t version=JS_STRUCTURED_CLONE_VERSION, - const JSStructuredCloneCallbacks* callbacks=nullptr, void* closure=nullptr); - - /** - * Adopt some memory. It will be automatically freed by the destructor. - * data must have been allocated by the JS engine (e.g., extracted via - * JSAutoStructuredCloneBuffer::steal). - */ - void adopt(JSStructuredCloneData&& data, uint32_t version=JS_STRUCTURED_CLONE_VERSION, - const JSStructuredCloneCallbacks* callbacks=nullptr, void* closure=nullptr); - - /** - * Release the buffer and transfer ownership to the caller. - */ - void steal(JSStructuredCloneData* data, uint32_t* versionp=nullptr, - const JSStructuredCloneCallbacks** callbacks=nullptr, void** closure=nullptr); - - /** - * Abandon ownership of any transferable objects stored in the buffer, - * without freeing the buffer itself. Useful when copying the data out into - * an external container, though note that you will need to use adopt() to - * properly release that data eventually. - */ - void abandon() { data_.ownTransferables_ = OwnTransferablePolicy::IgnoreTransferablesIfAny; } - - bool read(JSContext* cx, JS::MutableHandleValue vp, - const JSStructuredCloneCallbacks* optionalCallbacks=nullptr, void* closure=nullptr); - - bool write(JSContext* cx, JS::HandleValue v, - const JSStructuredCloneCallbacks* optionalCallbacks=nullptr, void* closure=nullptr); - - bool write(JSContext* cx, JS::HandleValue v, JS::HandleValue transferable, - JS::CloneDataPolicy cloneDataPolicy, - const JSStructuredCloneCallbacks* optionalCallbacks=nullptr, void* closure=nullptr); - - private: - // Copy and assignment are not supported. - JSAutoStructuredCloneBuffer(const JSAutoStructuredCloneBuffer& other) = delete; - JSAutoStructuredCloneBuffer& operator=(const JSAutoStructuredCloneBuffer& other) = delete; -}; - -// The range of tag values the application may use for its own custom object types. -#define JS_SCTAG_USER_MIN ((uint32_t) 0xFFFF8000) -#define JS_SCTAG_USER_MAX ((uint32_t) 0xFFFFFFFF) - -#define JS_SCERR_RECURSION 0 -#define JS_SCERR_TRANSFERABLE 1 -#define JS_SCERR_DUP_TRANSFERABLE 2 -#define JS_SCERR_UNSUPPORTED_TYPE 3 - -JS_PUBLIC_API(bool) -JS_ReadUint32Pair(JSStructuredCloneReader* r, uint32_t* p1, uint32_t* p2); - -JS_PUBLIC_API(bool) -JS_ReadBytes(JSStructuredCloneReader* r, void* p, size_t len); - -JS_PUBLIC_API(bool) -JS_ReadTypedArray(JSStructuredCloneReader* r, JS::MutableHandleValue vp); - -JS_PUBLIC_API(bool) -JS_WriteUint32Pair(JSStructuredCloneWriter* w, uint32_t tag, uint32_t data); - -JS_PUBLIC_API(bool) -JS_WriteBytes(JSStructuredCloneWriter* w, const void* p, size_t len); - -JS_PUBLIC_API(bool) -JS_WriteString(JSStructuredCloneWriter* w, JS::HandleString str); - -JS_PUBLIC_API(bool) -JS_WriteTypedArray(JSStructuredCloneWriter* w, JS::HandleValue v); - -JS_PUBLIC_API(bool) -JS_ObjectNotWritten(JSStructuredCloneWriter* w, JS::HandleObject obj); - -JS_PUBLIC_API(JS::StructuredCloneScope) -JS_GetStructuredCloneScope(JSStructuredCloneWriter* w); - -#endif /* js_StructuredClone_h */ diff --git a/android/x86/include/spidermonkey/js/SweepingAPI.h b/android/x86/include/spidermonkey/js/SweepingAPI.h deleted file mode 100644 index 0eb29ae4..00000000 --- a/android/x86/include/spidermonkey/js/SweepingAPI.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_SweepingAPI_h -#define js_SweepingAPI_h - -#include "js/HeapAPI.h" - -namespace js { -template -class WeakCacheBase {}; -} // namespace js - -namespace JS { -template class WeakCache; - -namespace shadow { -JS_PUBLIC_API(void) -RegisterWeakCache(JS::Zone* zone, JS::WeakCache* cachep); -} // namespace shadow - -// A WeakCache stores the given Sweepable container and links itself into a -// list of such caches that are swept during each GC. -template -class WeakCache : public js::WeakCacheBase, - private mozilla::LinkedListElement> -{ - friend class mozilla::LinkedListElement>; - friend class mozilla::LinkedList>; - - WeakCache() = delete; - WeakCache(const WeakCache&) = delete; - - using SweepFn = void (*)(T*); - SweepFn sweeper; - T cache; - - public: - using Type = T; - - template - WeakCache(Zone* zone, U&& initial) - : cache(mozilla::Forward(initial)) - { - sweeper = GCPolicy::sweep; - shadow::RegisterWeakCache(zone, reinterpret_cast*>(this)); - } - WeakCache(WeakCache&& other) - : sweeper(other.sweeper), - cache(mozilla::Move(other.cache)) - { - } - - const T& get() const { return cache; } - T& get() { return cache; } - - void sweep() { sweeper(&cache); } -}; - -} // namespace JS - -#endif // js_SweepingAPI_h diff --git a/android/x86/include/spidermonkey/js/TraceKind.h b/android/x86/include/spidermonkey/js/TraceKind.h deleted file mode 100644 index 2eda9cb2..00000000 --- a/android/x86/include/spidermonkey/js/TraceKind.h +++ /dev/null @@ -1,212 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_TraceKind_h -#define js_TraceKind_h - -#include "mozilla/UniquePtr.h" - -#include "js/TypeDecls.h" - -// Forward declarations of all the types a TraceKind can denote. -namespace js { -class BaseShape; -class LazyScript; -class ObjectGroup; -class Shape; -class Scope; -namespace jit { -class JitCode; -} // namespace jit -} // namespace js - -namespace JS { - -// When tracing a thing, the GC needs to know about the layout of the object it -// is looking at. There are a fixed number of different layouts that the GC -// knows about. The "trace kind" is a static map which tells which layout a GC -// thing has. -// -// Although this map is public, the details are completely hidden. Not all of -// the matching C++ types are exposed, and those that are, are opaque. -// -// See Value::gcKind() and JSTraceCallback in Tracer.h for more details. -enum class TraceKind -{ - // These trace kinds have a publicly exposed, although opaque, C++ type. - // Note: The order here is determined by our Value packing. Other users - // should sort alphabetically, for consistency. - Object = 0x00, - String = 0x01, - Symbol = 0x02, - Script = 0x03, - - // Shape details are exposed through JS_TraceShapeCycleCollectorChildren. - Shape = 0x04, - - // ObjectGroup details are exposed through JS_TraceObjectGroupCycleCollectorChildren. - ObjectGroup = 0x05, - - // The kind associated with a nullptr. - Null = 0x06, - - // The following kinds do not have an exposed C++ idiom. - BaseShape = 0x0F, - JitCode = 0x1F, - LazyScript = 0x2F, - Scope = 0x3F -}; -const static uintptr_t OutOfLineTraceKindMask = 0x07; -static_assert(uintptr_t(JS::TraceKind::BaseShape) & OutOfLineTraceKindMask, "mask bits are set"); -static_assert(uintptr_t(JS::TraceKind::JitCode) & OutOfLineTraceKindMask, "mask bits are set"); -static_assert(uintptr_t(JS::TraceKind::LazyScript) & OutOfLineTraceKindMask, "mask bits are set"); -static_assert(uintptr_t(JS::TraceKind::Scope) & OutOfLineTraceKindMask, "mask bits are set"); - -// When this header is imported inside SpiderMonkey, the class definitions are -// available and we can query those definitions to find the correct kind -// directly from the class hierarchy. -template -struct MapTypeToTraceKind { - static const JS::TraceKind kind = T::TraceKind; -}; - -// When this header is used outside SpiderMonkey, the class definitions are not -// available, so the following table containing all public GC types is used. -#define JS_FOR_EACH_TRACEKIND(D) \ - /* PrettyName TypeName AddToCCKind */ \ - D(BaseShape, js::BaseShape, true) \ - D(JitCode, js::jit::JitCode, true) \ - D(LazyScript, js::LazyScript, true) \ - D(Scope, js::Scope, true) \ - D(Object, JSObject, true) \ - D(ObjectGroup, js::ObjectGroup, true) \ - D(Script, JSScript, true) \ - D(Shape, js::Shape, true) \ - D(String, JSString, false) \ - D(Symbol, JS::Symbol, false) - -// Map from all public types to their trace kind. -#define JS_EXPAND_DEF(name, type, _) \ - template <> struct MapTypeToTraceKind { \ - static const JS::TraceKind kind = JS::TraceKind::name; \ - }; -JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF); -#undef JS_EXPAND_DEF - -// RootKind is closely related to TraceKind. Whereas TraceKind's indices are -// laid out for convenient embedding as a pointer tag, the indicies of RootKind -// are designed for use as array keys via EnumeratedArray. -enum class RootKind : int8_t -{ - // These map 1:1 with trace kinds. -#define EXPAND_ROOT_KIND(name, _0, _1) \ - name, -JS_FOR_EACH_TRACEKIND(EXPAND_ROOT_KIND) -#undef EXPAND_ROOT_KIND - - // These tagged pointers are special-cased for performance. - Id, - Value, - - // Everything else. - Traceable, - - Limit -}; - -// Most RootKind correspond directly to a trace kind. -template struct MapTraceKindToRootKind {}; -#define JS_EXPAND_DEF(name, _0, _1) \ - template <> struct MapTraceKindToRootKind { \ - static const JS::RootKind kind = JS::RootKind::name; \ - }; -JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF) -#undef JS_EXPAND_DEF - -// Specify the RootKind for all types. Value and jsid map to special cases; -// pointer types we can derive directly from the TraceKind; everything else -// should go in the Traceable list and use GCPolicy::trace for tracing. -template -struct MapTypeToRootKind { - static const JS::RootKind kind = JS::RootKind::Traceable; -}; -template -struct MapTypeToRootKind { - static const JS::RootKind kind = - JS::MapTraceKindToRootKind::kind>::kind; -}; -template -struct MapTypeToRootKind> { - static const JS::RootKind kind = JS::MapTypeToRootKind::kind; -}; -template <> struct MapTypeToRootKind { - static const JS::RootKind kind = JS::RootKind::Value; -}; -template <> struct MapTypeToRootKind { - static const JS::RootKind kind = JS::RootKind::Id; -}; -template <> struct MapTypeToRootKind : public MapTypeToRootKind {}; - -// Fortunately, few places in the system need to deal with fully abstract -// cells. In those places that do, we generally want to move to a layout -// templated function as soon as possible. This template wraps the upcast -// for that dispatch. -// -// Given a call: -// -// DispatchTraceKindTyped(f, thing, traceKind, ... args) -// -// Downcast the |void *thing| to the specific type designated by |traceKind|, -// and pass it to the functor |f| along with |... args|, forwarded. Pass the -// type designated by |traceKind| as the functor's template argument. The -// |thing| parameter is optional; without it, we simply pass through |... args|. - -// GCC and Clang require an explicit template declaration in front of the -// specialization of operator() because it is a dependent template. MSVC, on -// the other hand, gets very confused if we have a |template| token there. -// The clang-cl front end defines _MSC_VER, but still requires the explicit -// template declaration, so we must test for __clang__ here as well. -#if defined(_MSC_VER) && !defined(__clang__) -# define JS_DEPENDENT_TEMPLATE_HINT -#else -# define JS_DEPENDENT_TEMPLATE_HINT template -#endif -template -auto -DispatchTraceKindTyped(F f, JS::TraceKind traceKind, Args&&... args) - -> decltype(f. JS_DEPENDENT_TEMPLATE_HINT operator()(mozilla::Forward(args)...)) -{ - switch (traceKind) { -#define JS_EXPAND_DEF(name, type, _) \ - case JS::TraceKind::name: \ - return f. JS_DEPENDENT_TEMPLATE_HINT operator()(mozilla::Forward(args)...); - JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF); -#undef JS_EXPAND_DEF - default: - MOZ_CRASH("Invalid trace kind in DispatchTraceKindTyped."); - } -} -#undef JS_DEPENDENT_TEMPLATE_HINT - -template -auto -DispatchTraceKindTyped(F f, void* thing, JS::TraceKind traceKind, Args&&... args) - -> decltype(f(static_cast(nullptr), mozilla::Forward(args)...)) -{ - switch (traceKind) { -#define JS_EXPAND_DEF(name, type, _) \ - case JS::TraceKind::name: \ - return f(static_cast(thing), mozilla::Forward(args)...); - JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF); -#undef JS_EXPAND_DEF - default: - MOZ_CRASH("Invalid trace kind in DispatchTraceKindTyped."); - } -} - -} // namespace JS - -#endif // js_TraceKind_h diff --git a/android/x86/include/spidermonkey/js/TracingAPI.h b/android/x86/include/spidermonkey/js/TracingAPI.h deleted file mode 100644 index 37c69aca..00000000 --- a/android/x86/include/spidermonkey/js/TracingAPI.h +++ /dev/null @@ -1,403 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_TracingAPI_h -#define js_TracingAPI_h - -#include "jsalloc.h" - -#include "js/HashTable.h" -#include "js/HeapAPI.h" -#include "js/TraceKind.h" - -class JS_PUBLIC_API(JSTracer); - -namespace JS { -class JS_PUBLIC_API(CallbackTracer); -template class Heap; -template class TenuredHeap; - -/** Returns a static string equivalent of |kind|. */ -JS_FRIEND_API(const char*) -GCTraceKindToAscii(JS::TraceKind kind); - -} // namespace JS - -enum WeakMapTraceKind { - /** - * Do not trace into weak map keys or values during traversal. Users must - * handle weak maps manually. - */ - DoNotTraceWeakMaps, - - /** - * Do true ephemeron marking with a weak key lookup marking phase. This is - * the default for GCMarker. - */ - ExpandWeakMaps, - - /** - * Trace through to all values, irrespective of whether the keys are live - * or not. Used for non-marking tracers. - */ - TraceWeakMapValues, - - /** - * Trace through to all keys and values, irrespective of whether the keys - * are live or not. Used for non-marking tracers. - */ - TraceWeakMapKeysValues -}; - -class JS_PUBLIC_API(JSTracer) -{ - public: - // Return the runtime set on the tracer. - JSRuntime* runtime() const { return runtime_; } - - // Return the weak map tracing behavior currently set on this tracer. - WeakMapTraceKind weakMapAction() const { return weakMapAction_; } - - enum class TracerKindTag { - // Marking path: a tracer used only for marking liveness of cells, not - // for moving them. The kind will transition to WeakMarking after - // everything reachable by regular edges has been marked. - Marking, - - // Same as Marking, except we have now moved on to the "weak marking - // phase", in which every marked obj/script is immediately looked up to - // see if it is a weak map key (and therefore might require marking its - // weak map value). - WeakMarking, - - // A tracer that traverses the graph for the purposes of moving objects - // from the nursery to the tenured area. - Tenuring, - - // General-purpose traversal that invokes a callback on each cell. - // Traversing children is the responsibility of the callback. - Callback - }; - bool isMarkingTracer() const { return tag_ == TracerKindTag::Marking || tag_ == TracerKindTag::WeakMarking; } - bool isWeakMarkingTracer() const { return tag_ == TracerKindTag::WeakMarking; } - bool isTenuringTracer() const { return tag_ == TracerKindTag::Tenuring; } - bool isCallbackTracer() const { return tag_ == TracerKindTag::Callback; } - inline JS::CallbackTracer* asCallbackTracer(); -#ifdef DEBUG - bool checkEdges() { return checkEdges_; } -#endif - - protected: - JSTracer(JSRuntime* rt, TracerKindTag tag, - WeakMapTraceKind weakTraceKind = TraceWeakMapValues) - : runtime_(rt) - , weakMapAction_(weakTraceKind) -#ifdef DEBUG - , checkEdges_(true) -#endif - , tag_(tag) - {} - -#ifdef DEBUG - // Set whether to check edges are valid in debug builds. - void setCheckEdges(bool check) { - checkEdges_ = check; - } -#endif - - private: - JSRuntime* runtime_; - WeakMapTraceKind weakMapAction_; -#ifdef DEBUG - bool checkEdges_; -#endif - - protected: - TracerKindTag tag_; -}; - -namespace JS { - -class AutoTracingName; -class AutoTracingIndex; -class AutoTracingCallback; - -class JS_PUBLIC_API(CallbackTracer) : public JSTracer -{ - public: - CallbackTracer(JSRuntime* rt, WeakMapTraceKind weakTraceKind = TraceWeakMapValues) - : JSTracer(rt, JSTracer::TracerKindTag::Callback, weakTraceKind), - contextName_(nullptr), contextIndex_(InvalidIndex), contextFunctor_(nullptr) - {} - CallbackTracer(JSContext* cx, WeakMapTraceKind weakTraceKind = TraceWeakMapValues); - - // Override these methods to receive notification when an edge is visited - // with the type contained in the callback. The default implementation - // dispatches to the fully-generic onChild implementation, so for cases that - // do not care about boxing overhead and do not need the actual edges, - // just override the generic onChild. - virtual void onObjectEdge(JSObject** objp) { onChild(JS::GCCellPtr(*objp)); } - virtual void onStringEdge(JSString** strp) { onChild(JS::GCCellPtr(*strp)); } - virtual void onSymbolEdge(JS::Symbol** symp) { onChild(JS::GCCellPtr(*symp)); } - virtual void onScriptEdge(JSScript** scriptp) { onChild(JS::GCCellPtr(*scriptp)); } - virtual void onShapeEdge(js::Shape** shapep) { - onChild(JS::GCCellPtr(*shapep, JS::TraceKind::Shape)); - } - virtual void onObjectGroupEdge(js::ObjectGroup** groupp) { - onChild(JS::GCCellPtr(*groupp, JS::TraceKind::ObjectGroup)); - } - virtual void onBaseShapeEdge(js::BaseShape** basep) { - onChild(JS::GCCellPtr(*basep, JS::TraceKind::BaseShape)); - } - virtual void onJitCodeEdge(js::jit::JitCode** codep) { - onChild(JS::GCCellPtr(*codep, JS::TraceKind::JitCode)); - } - virtual void onLazyScriptEdge(js::LazyScript** lazyp) { - onChild(JS::GCCellPtr(*lazyp, JS::TraceKind::LazyScript)); - } - virtual void onScopeEdge(js::Scope** scopep) { - onChild(JS::GCCellPtr(*scopep, JS::TraceKind::Scope)); - } - - // Override this method to receive notification when a node in the GC - // heap graph is visited. - virtual void onChild(const JS::GCCellPtr& thing) = 0; - - // Access to the tracing context: - // When tracing with a JS::CallbackTracer, we invoke the callback with the - // edge location and the type of target. This is useful for operating on - // the edge in the abstract or on the target thing, satisfying most common - // use cases. However, some tracers need additional detail about the - // specific edge that is being traced in order to be useful. Unfortunately, - // the raw pointer to the edge that we provide is not enough information to - // infer much of anything useful about that edge. - // - // In order to better support use cases that care in particular about edges - // -- as opposed to the target thing -- tracing implementations are - // responsible for providing extra context information about each edge they - // trace, as it is traced. This contains, at a minimum, an edge name and, - // when tracing an array, the index. Further specialization can be achived - // (with some complexity), by associating a functor with the tracer so - // that, when requested, the user can generate totally custom edge - // descriptions. - - // Returns the current edge's name. It is only valid to call this when - // inside the trace callback, however, the edge name will always be set. - const char* contextName() const { MOZ_ASSERT(contextName_); return contextName_; } - - // Returns the current edge's index, if marked as part of an array of edges. - // This must be called only inside the trace callback. When not tracing an - // array, the value will be InvalidIndex. - const static size_t InvalidIndex = size_t(-1); - size_t contextIndex() const { return contextIndex_; } - - // Build a description of this edge in the heap graph. This call may invoke - // the context functor, if set, which may inspect arbitrary areas of the - // heap. On the other hand, the description provided by this method may be - // substantially more accurate and useful than those provided by only the - // contextName and contextIndex. - void getTracingEdgeName(char* buffer, size_t bufferSize); - - // The trace implementation may associate a callback with one or more edges - // using AutoTracingDetails. This functor is called by getTracingEdgeName - // and is responsible for providing a textual representation of the - // currently being traced edge. The callback has access to the full heap, - // including the currently set tracing context. - class ContextFunctor { - public: - virtual void operator()(CallbackTracer* trc, char* buf, size_t bufsize) = 0; - }; - -#ifdef DEBUG - enum class TracerKind { DoNotCare, Moving, GrayBuffering, VerifyTraceProtoAndIface }; - virtual TracerKind getTracerKind() const { return TracerKind::DoNotCare; } -#endif - - // In C++, overriding a method hides all methods in the base class with - // that name, not just methods with that signature. Thus, the typed edge - // methods have to have distinct names to allow us to override them - // individually, which is freqently useful if, for example, we only want to - // process only one type of edge. - void dispatchToOnEdge(JSObject** objp) { onObjectEdge(objp); } - void dispatchToOnEdge(JSString** strp) { onStringEdge(strp); } - void dispatchToOnEdge(JS::Symbol** symp) { onSymbolEdge(symp); } - void dispatchToOnEdge(JSScript** scriptp) { onScriptEdge(scriptp); } - void dispatchToOnEdge(js::Shape** shapep) { onShapeEdge(shapep); } - void dispatchToOnEdge(js::ObjectGroup** groupp) { onObjectGroupEdge(groupp); } - void dispatchToOnEdge(js::BaseShape** basep) { onBaseShapeEdge(basep); } - void dispatchToOnEdge(js::jit::JitCode** codep) { onJitCodeEdge(codep); } - void dispatchToOnEdge(js::LazyScript** lazyp) { onLazyScriptEdge(lazyp); } - void dispatchToOnEdge(js::Scope** scopep) { onScopeEdge(scopep); } - - private: - friend class AutoTracingName; - const char* contextName_; - - friend class AutoTracingIndex; - size_t contextIndex_; - - friend class AutoTracingDetails; - ContextFunctor* contextFunctor_; -}; - -// Set the name portion of the tracer's context for the current edge. -class MOZ_RAII AutoTracingName -{ - CallbackTracer* trc_; - const char* prior_; - - public: - AutoTracingName(CallbackTracer* trc, const char* name) : trc_(trc), prior_(trc->contextName_) { - MOZ_ASSERT(name); - trc->contextName_ = name; - } - ~AutoTracingName() { - MOZ_ASSERT(trc_->contextName_); - trc_->contextName_ = prior_; - } -}; - -// Set the index portion of the tracer's context for the current range. -class MOZ_RAII AutoTracingIndex -{ - CallbackTracer* trc_; - - public: - explicit AutoTracingIndex(JSTracer* trc, size_t initial = 0) : trc_(nullptr) { - if (trc->isCallbackTracer()) { - trc_ = trc->asCallbackTracer(); - MOZ_ASSERT(trc_->contextIndex_ == CallbackTracer::InvalidIndex); - trc_->contextIndex_ = initial; - } - } - ~AutoTracingIndex() { - if (trc_) { - MOZ_ASSERT(trc_->contextIndex_ != CallbackTracer::InvalidIndex); - trc_->contextIndex_ = CallbackTracer::InvalidIndex; - } - } - - void operator++() { - if (trc_) { - MOZ_ASSERT(trc_->contextIndex_ != CallbackTracer::InvalidIndex); - ++trc_->contextIndex_; - } - } -}; - -// Set a context callback for the trace callback to use, if it needs a detailed -// edge description. -class MOZ_RAII AutoTracingDetails -{ - CallbackTracer* trc_; - - public: - AutoTracingDetails(JSTracer* trc, CallbackTracer::ContextFunctor& func) : trc_(nullptr) { - if (trc->isCallbackTracer()) { - trc_ = trc->asCallbackTracer(); - MOZ_ASSERT(trc_->contextFunctor_ == nullptr); - trc_->contextFunctor_ = &func; - } - } - ~AutoTracingDetails() { - if (trc_) { - MOZ_ASSERT(trc_->contextFunctor_); - trc_->contextFunctor_ = nullptr; - } - } -}; - -} // namespace JS - -JS::CallbackTracer* -JSTracer::asCallbackTracer() -{ - MOZ_ASSERT(isCallbackTracer()); - return static_cast(this); -} - -namespace JS { - -// The JS::TraceEdge family of functions traces the given GC thing reference. -// This performs the tracing action configured on the given JSTracer: typically -// calling the JSTracer::callback or marking the thing as live. -// -// The argument to JS::TraceEdge is an in-out param: when the function returns, -// the garbage collector might have moved the GC thing. In this case, the -// reference passed to JS::TraceEdge will be updated to the thing's new -// location. Callers of this method are responsible for updating any state that -// is dependent on the object's address. For example, if the object's address -// is used as a key in a hashtable, then the object must be removed and -// re-inserted with the correct hash. -// -// Note that while |edgep| must never be null, it is fine for |*edgep| to be -// nullptr. -template -extern JS_PUBLIC_API(void) -TraceEdge(JSTracer* trc, JS::Heap* edgep, const char* name); - -extern JS_PUBLIC_API(void) -TraceEdge(JSTracer* trc, JS::TenuredHeap* edgep, const char* name); - -// Edges that are always traced as part of root marking do not require -// incremental barriers. This function allows for marking non-barriered -// pointers, but asserts that this happens during root marking. -// -// Note that while |edgep| must never be null, it is fine for |*edgep| to be -// nullptr. -template -extern JS_PUBLIC_API(void) -UnsafeTraceRoot(JSTracer* trc, T* edgep, const char* name); - -extern JS_PUBLIC_API(void) -TraceChildren(JSTracer* trc, GCCellPtr thing); - -using ZoneSet = js::HashSet, js::SystemAllocPolicy>; -using CompartmentSet = js::HashSet, - js::SystemAllocPolicy>; - -/** - * Trace every value within |compartments| that is wrapped by a - * cross-compartment wrapper from a compartment that is not an element of - * |compartments|. - */ -extern JS_PUBLIC_API(void) -TraceIncomingCCWs(JSTracer* trc, const JS::CompartmentSet& compartments); - -} // namespace JS - -extern JS_PUBLIC_API(void) -JS_GetTraceThingInfo(char* buf, size_t bufsize, JSTracer* trc, - void* thing, JS::TraceKind kind, bool includeDetails); - -namespace js { - -// Trace an edge that is not a GC root and is not wrapped in a barriered -// wrapper for some reason. -// -// This method does not check if |*edgep| is non-null before tracing through -// it, so callers must check any nullable pointer before calling this method. -template -extern JS_PUBLIC_API(void) -UnsafeTraceManuallyBarrieredEdge(JSTracer* trc, T* edgep, const char* name); - -namespace gc { - -// Return true if the given edge is not live and is about to be swept. -template -extern JS_PUBLIC_API(bool) -EdgeNeedsSweep(JS::Heap* edgep); - -// Not part of the public API, but declared here so we can use it in GCPolicy -// which is. -template -bool -IsAboutToBeFinalizedUnbarriered(T* thingp); - -} // namespace gc -} // namespace js - -#endif /* js_TracingAPI_h */ diff --git a/android/x86/include/spidermonkey/js/TrackedOptimizationInfo.h b/android/x86/include/spidermonkey/js/TrackedOptimizationInfo.h deleted file mode 100644 index b697765c..00000000 --- a/android/x86/include/spidermonkey/js/TrackedOptimizationInfo.h +++ /dev/null @@ -1,285 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_TrackedOptimizationInfo_h -#define js_TrackedOptimizationInfo_h - -#include "mozilla/Maybe.h" - -namespace JS { - -#define TRACKED_STRATEGY_LIST(_) \ - _(GetProp_ArgumentsLength) \ - _(GetProp_ArgumentsCallee) \ - _(GetProp_InferredConstant) \ - _(GetProp_Constant) \ - _(GetProp_NotDefined) \ - _(GetProp_StaticName) \ - _(GetProp_SimdGetter) \ - _(GetProp_TypedObject) \ - _(GetProp_DefiniteSlot) \ - _(GetProp_Unboxed) \ - _(GetProp_CommonGetter) \ - _(GetProp_InlineAccess) \ - _(GetProp_Innerize) \ - _(GetProp_InlineCache) \ - _(GetProp_SharedCache) \ - _(GetProp_ModuleNamespace) \ - \ - _(SetProp_CommonSetter) \ - _(SetProp_TypedObject) \ - _(SetProp_DefiniteSlot) \ - _(SetProp_Unboxed) \ - _(SetProp_InlineAccess) \ - _(SetProp_InlineCache) \ - \ - _(GetElem_TypedObject) \ - _(GetElem_Dense) \ - _(GetElem_TypedStatic) \ - _(GetElem_TypedArray) \ - _(GetElem_String) \ - _(GetElem_Arguments) \ - _(GetElem_ArgumentsInlined) \ - _(GetElem_InlineCache) \ - \ - _(SetElem_TypedObject) \ - _(SetElem_TypedStatic) \ - _(SetElem_TypedArray) \ - _(SetElem_Dense) \ - _(SetElem_Arguments) \ - _(SetElem_InlineCache) \ - \ - _(BinaryArith_Concat) \ - _(BinaryArith_SpecializedTypes) \ - _(BinaryArith_SpecializedOnBaselineTypes) \ - _(BinaryArith_SharedCache) \ - _(BinaryArith_Call) \ - \ - _(InlineCache_OptimizedStub) \ - \ - _(Call_Inline) - - -// Ordering is important below. All outcomes before GenericSuccess will be -// considered failures, and all outcomes after GenericSuccess will be -// considered successes. -#define TRACKED_OUTCOME_LIST(_) \ - _(GenericFailure) \ - _(Disabled) \ - _(NoTypeInfo) \ - _(NoAnalysisInfo) \ - _(NoShapeInfo) \ - _(UnknownObject) \ - _(UnknownProperties) \ - _(Singleton) \ - _(NotSingleton) \ - _(NotFixedSlot) \ - _(InconsistentFixedSlot) \ - _(NotObject) \ - _(NotStruct) \ - _(NotUnboxed) \ - _(NotUndefined) \ - _(UnboxedConvertedToNative) \ - _(StructNoField) \ - _(InconsistentFieldType) \ - _(InconsistentFieldOffset) \ - _(NeedsTypeBarrier) \ - _(InDictionaryMode) \ - _(NoProtoFound) \ - _(MultiProtoPaths) \ - _(NonWritableProperty) \ - _(ProtoIndexedProps) \ - _(ArrayBadFlags) \ - _(ArrayDoubleConversion) \ - _(ArrayRange) \ - _(ArraySeenNegativeIndex) \ - _(TypedObjectHasDetachedBuffer) \ - _(TypedObjectArrayRange) \ - _(AccessNotDense) \ - _(AccessNotSimdObject) \ - _(AccessNotTypedObject) \ - _(AccessNotTypedArray) \ - _(AccessNotString) \ - _(OperandNotString) \ - _(OperandNotNumber) \ - _(OperandNotStringOrNumber) \ - _(OperandNotSimpleArith) \ - _(StaticTypedArrayUint32) \ - _(StaticTypedArrayCantComputeMask) \ - _(OutOfBounds) \ - _(GetElemStringNotCached) \ - _(NonNativeReceiver) \ - _(IndexType) \ - _(SetElemNonDenseNonTANotCached) \ - _(NoSimdJitSupport) \ - _(SimdTypeNotOptimized) \ - _(UnknownSimdProperty) \ - _(NotModuleNamespace) \ - _(UnknownProperty) \ - \ - _(ICOptStub_GenericSuccess) \ - \ - _(ICGetPropStub_ReadSlot) \ - _(ICGetPropStub_CallGetter) \ - _(ICGetPropStub_ArrayLength) \ - _(ICGetPropStub_UnboxedRead) \ - _(ICGetPropStub_UnboxedReadExpando) \ - _(ICGetPropStub_UnboxedArrayLength) \ - _(ICGetPropStub_TypedArrayLength) \ - _(ICGetPropStub_DOMProxyShadowed) \ - _(ICGetPropStub_DOMProxyUnshadowed) \ - _(ICGetPropStub_GenericProxy) \ - _(ICGetPropStub_ArgumentsLength) \ - \ - _(ICSetPropStub_Slot) \ - _(ICSetPropStub_GenericProxy) \ - _(ICSetPropStub_DOMProxyShadowed) \ - _(ICSetPropStub_DOMProxyUnshadowed) \ - _(ICSetPropStub_CallSetter) \ - _(ICSetPropStub_AddSlot) \ - _(ICSetPropStub_SetUnboxed) \ - \ - _(ICGetElemStub_ReadSlot) \ - _(ICGetElemStub_CallGetter) \ - _(ICGetElemStub_ReadUnboxed) \ - _(ICGetElemStub_Dense) \ - _(ICGetElemStub_DenseHole) \ - _(ICGetElemStub_TypedArray) \ - _(ICGetElemStub_ArgsElementMapped) \ - _(ICGetElemStub_ArgsElementUnmapped) \ - \ - _(ICSetElemStub_Dense) \ - _(ICSetElemStub_TypedArray) \ - \ - _(ICNameStub_ReadSlot) \ - _(ICNameStub_CallGetter) \ - _(ICNameStub_TypeOfNoProperty) \ - \ - _(CantInlineGeneric) \ - _(CantInlineNoTarget) \ - _(CantInlineNotInterpreted) \ - _(CantInlineNoBaseline) \ - _(CantInlineLazy) \ - _(CantInlineNotConstructor) \ - _(CantInlineClassConstructor) \ - _(CantInlineDisabledIon) \ - _(CantInlineTooManyArgs) \ - _(CantInlineNeedsArgsObj) \ - _(CantInlineDebuggee) \ - _(CantInlineUnknownProps) \ - _(CantInlineExceededDepth) \ - _(CantInlineExceededTotalBytecodeLength) \ - _(CantInlineBigCaller) \ - _(CantInlineBigCallee) \ - _(CantInlineBigCalleeInlinedBytecodeLength) \ - _(CantInlineNotHot) \ - _(CantInlineNotInDispatch) \ - _(CantInlineUnreachable) \ - _(CantInlineNativeBadForm) \ - _(CantInlineNativeBadType) \ - _(CantInlineNativeNoTemplateObj) \ - _(CantInlineBound) \ - _(CantInlineNativeNoSpecialization) \ - _(HasCommonInliningPath) \ - \ - _(GenericSuccess) \ - _(Inlined) \ - _(DOM) \ - _(Monomorphic) \ - _(Polymorphic) - -#define TRACKED_TYPESITE_LIST(_) \ - _(Receiver) \ - _(Operand) \ - _(Index) \ - _(Value) \ - _(Call_Target) \ - _(Call_This) \ - _(Call_Arg) \ - _(Call_Return) - -enum class TrackedStrategy : uint32_t { -#define STRATEGY_OP(name) name, - TRACKED_STRATEGY_LIST(STRATEGY_OP) -#undef STRATEGY_OPT - - Count -}; - -enum class TrackedOutcome : uint32_t { -#define OUTCOME_OP(name) name, - TRACKED_OUTCOME_LIST(OUTCOME_OP) -#undef OUTCOME_OP - - Count -}; - -enum class TrackedTypeSite : uint32_t { -#define TYPESITE_OP(name) name, - TRACKED_TYPESITE_LIST(TYPESITE_OP) -#undef TYPESITE_OP - - Count -}; - -JS_PUBLIC_API(const char*) -TrackedStrategyString(TrackedStrategy strategy); - -JS_PUBLIC_API(const char*) -TrackedOutcomeString(TrackedOutcome outcome); - -JS_PUBLIC_API(const char*) -TrackedTypeSiteString(TrackedTypeSite site); - -struct ForEachTrackedOptimizationAttemptOp -{ - virtual void operator()(TrackedStrategy strategy, TrackedOutcome outcome) = 0; -}; - -struct ForEachTrackedOptimizationTypeInfoOp -{ - // Called 0+ times per entry, once for each type in the type set that Ion - // saw during MIR construction. readType is always called _before_ - // operator() on the same entry. - // - // The keyedBy parameter describes how the type is keyed: - // - "primitive" for primitive types - // - "constructor" for object types tied to a scripted constructor - // function. - // - "alloc site" for object types tied to an allocation site. - // - "prototype" for object types tied neither to a constructor nor - // to an allocation site, but to a prototype. - // - "singleton" for object types which only has a single value. - // - "function" for object types referring to scripted functions. - // - "native" for object types referring to native functions. - // - // The name parameter is the string representation of the type. If the - // type is keyed by "constructor", or if the type itself refers to a - // scripted function, the name is the function's displayAtom. If the type - // is keyed by "native", this is nullptr. - // - // The location parameter is the filename if the type is keyed by - // "constructor", "alloc site", or if the type itself refers to a scripted - // function. If the type is keyed by "native", it is the offset of the - // native function, suitable for use with addr2line on Linux or atos on OS - // X. Otherwise it is nullptr. - // - // The lineno parameter is the line number if the type is keyed by - // "constructor", "alloc site", or if the type itself refers to a scripted - // function. Otherwise it is Nothing(). - // - // The location parameter is the only one that may need escaping if being - // quoted. - virtual void readType(const char* keyedBy, const char* name, - const char* location, mozilla::Maybe lineno) = 0; - - // Called once per entry. - virtual void operator()(TrackedTypeSite site, const char* mirType) = 0; -}; - -} // namespace JS - -#endif // js_TrackedOptimizationInfo_h diff --git a/android/x86/include/spidermonkey/js/TypeDecls.h b/android/x86/include/spidermonkey/js/TypeDecls.h deleted file mode 100644 index acb93f97..00000000 --- a/android/x86/include/spidermonkey/js/TypeDecls.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -// This file contains public type declarations that are used *frequently*. If -// it doesn't occur at least 10 times in Gecko, it probably shouldn't be in -// here. -// -// It includes only: -// - forward declarations of structs and classes; -// - typedefs; -// - enums (maybe). -// It does *not* contain any struct or class definitions. - -#ifndef js_TypeDecls_h -#define js_TypeDecls_h - -#include -#include - -#include "js-config.h" - -struct JSContext; -class JSFunction; -class JSObject; -class JSScript; -class JSString; -class JSAddonId; - -struct jsid; - -namespace JS { - -typedef unsigned char Latin1Char; - -class Symbol; -class Value; -template class Handle; -template class MutableHandle; -template class Rooted; -template class PersistentRooted; - -typedef Handle HandleFunction; -typedef Handle HandleId; -typedef Handle HandleObject; -typedef Handle HandleScript; -typedef Handle HandleString; -typedef Handle HandleSymbol; -typedef Handle HandleValue; - -typedef MutableHandle MutableHandleFunction; -typedef MutableHandle MutableHandleId; -typedef MutableHandle MutableHandleObject; -typedef MutableHandle MutableHandleScript; -typedef MutableHandle MutableHandleString; -typedef MutableHandle MutableHandleSymbol; -typedef MutableHandle MutableHandleValue; - -typedef Rooted RootedObject; -typedef Rooted RootedFunction; -typedef Rooted RootedScript; -typedef Rooted RootedString; -typedef Rooted RootedSymbol; -typedef Rooted RootedId; -typedef Rooted RootedValue; - -typedef PersistentRooted PersistentRootedFunction; -typedef PersistentRooted PersistentRootedId; -typedef PersistentRooted PersistentRootedObject; -typedef PersistentRooted PersistentRootedScript; -typedef PersistentRooted PersistentRootedString; -typedef PersistentRooted PersistentRootedSymbol; -typedef PersistentRooted PersistentRootedValue; - -} // namespace JS - -#endif /* js_TypeDecls_h */ diff --git a/android/x86/include/spidermonkey/js/UbiNode.h b/android/x86/include/spidermonkey/js/UbiNode.h deleted file mode 100644 index c8742f33..00000000 --- a/android/x86/include/spidermonkey/js/UbiNode.h +++ /dev/null @@ -1,1144 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNode_h -#define js_UbiNode_h - -#include "mozilla/Alignment.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Maybe.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" -#include "mozilla/RangedPtr.h" -#include "mozilla/TypeTraits.h" -#include "mozilla/Variant.h" - -#include "jspubtd.h" - -#include "js/GCAPI.h" -#include "js/HashTable.h" -#include "js/RootingAPI.h" -#include "js/TracingAPI.h" -#include "js/TypeDecls.h" -#include "js/UniquePtr.h" -#include "js/Value.h" -#include "js/Vector.h" - -// JS::ubi::Node -// -// JS::ubi::Node is a pointer-like type designed for internal use by heap -// analysis tools. A ubi::Node can refer to: -// -// - a JS value, like a string, object, or symbol; -// - an internal SpiderMonkey structure, like a shape or a scope chain object -// - an instance of some embedding-provided type: in Firefox, an XPCOM -// object, or an internal DOM node class instance -// -// A ubi::Node instance provides metadata about its referent, and can -// enumerate its referent's outgoing edges, so you can implement heap analysis -// algorithms that walk the graph - finding paths between objects, or -// computing heap dominator trees, say - using ubi::Node, while remaining -// ignorant of the details of the types you're operating on. -// -// Of course, when it comes to presenting the results in a developer-facing -// tool, you'll need to stop being ignorant of those details, because you have -// to discuss the ubi::Nodes' referents with the developer. Here, ubi::Node -// can hand you dynamically checked, properly typed pointers to the original -// objects via the as method, or generate descriptions of the referent -// itself. -// -// ubi::Node instances are lightweight (two-word) value types. Instances: -// - compare equal if and only if they refer to the same object; -// - have hash values that respect their equality relation; and -// - have serializations that are only equal if the ubi::Nodes are equal. -// -// A ubi::Node is only valid for as long as its referent is alive; if its -// referent goes away, the ubi::Node becomes a dangling pointer. A ubi::Node -// that refers to a GC-managed object is not automatically a GC root; if the -// GC frees or relocates its referent, the ubi::Node becomes invalid. A -// ubi::Node that refers to a reference-counted object does not bump the -// reference count. -// -// ubi::Node values require no supporting data structures, making them -// feasible for use in memory-constrained devices --- ideally, the memory -// requirements of the algorithm which uses them will be the limiting factor, -// not the demands of ubi::Node itself. -// -// One can construct a ubi::Node value given a pointer to a type that ubi::Node -// supports. In the other direction, one can convert a ubi::Node back to a -// pointer; these downcasts are checked dynamically. In particular, one can -// convert a 'JSContext*' to a ubi::Node, yielding a node with an outgoing edge -// for every root registered with the runtime; starting from this, one can walk -// the entire heap. (Of course, one could also start traversal at any other kind -// of type to which one has a pointer.) -// -// -// Extending ubi::Node To Handle Your Embedding's Types -// -// To add support for a new ubi::Node referent type R, you must define a -// specialization of the ubi::Concrete template, ubi::Concrete, which -// inherits from ubi::Base. ubi::Node itself uses the specialization for -// compile-time information (i.e. the checked conversions between R * and -// ubi::Node), and the inheritance for run-time dispatching. -// -// -// ubi::Node Exposes Implementation Details -// -// In many cases, a JavaScript developer's view of their data differs -// substantially from its actual implementation. For example, while the -// ECMAScript specification describes objects as maps from property names to -// sets of attributes (like ECMAScript's [[Value]]), in practice many objects -// have only a pointer to a shape, shared with other similar objects, and -// indexed slots that contain the [[Value]] attributes. As another example, a -// string produced by concatenating two other strings may sometimes be -// represented by a "rope", a structure that points to the two original -// strings. -// -// We intend to use ubi::Node to write tools that report memory usage, so it's -// important that ubi::Node accurately portray how much memory nodes consume. -// Thus, for example, when data that apparently belongs to multiple nodes is -// in fact shared in a common structure, ubi::Node's graph uses a separate -// node for that shared structure, and presents edges to it from the data's -// apparent owners. For example, ubi::Node exposes SpiderMonkey objects' -// shapes and base shapes, and exposes rope string and substring structure, -// because these optimizations become visible when a tool reports how much -// memory a structure consumes. -// -// However, fine granularity is not a goal. When a particular object is the -// exclusive owner of a separate block of memory, ubi::Node may present the -// object and its block as a single node, and add their sizes together when -// reporting the node's size, as there is no meaningful loss of data in this -// case. Thus, for example, a ubi::Node referring to a JavaScript object, when -// asked for the object's size in bytes, includes the object's slot and -// element arrays' sizes in the total. There is no separate ubi::Node value -// representing the slot and element arrays, since they are owned exclusively -// by the object. -// -// -// Presenting Analysis Results To JavaScript Developers -// -// If an analysis provides its results in terms of ubi::Node values, a user -// interface presenting those results will generally need to clean them up -// before they can be understood by JavaScript developers. For example, -// JavaScript developers should not need to understand shapes, only JavaScript -// objects. Similarly, they should not need to understand the distinction -// between DOM nodes and the JavaScript shadow objects that represent them. -// -// -// Rooting Restrictions -// -// At present there is no way to root ubi::Node instances, so instances can't be -// live across any operation that might GC. Analyses using ubi::Node must either -// run to completion and convert their results to some other rootable type, or -// save their intermediate state in some rooted structure if they must GC before -// they complete. (For algorithms like path-finding and dominator tree -// computation, we implement the algorithm avoiding any operation that could -// cause a GC --- and use AutoCheckCannotGC to verify this.) -// -// If this restriction prevents us from implementing interesting tools, we may -// teach the GC how to root ubi::Nodes, fix up hash tables that use them as -// keys, etc. -// -// -// Hostile Graph Structure -// -// Analyses consuming ubi::Node graphs must be robust when presented with graphs -// that are deliberately constructed to exploit their weaknesses. When operating -// on live graphs, web content has control over the object graph, and less -// direct control over shape and string structure, and analyses should be -// prepared to handle extreme cases gracefully. For example, if an analysis were -// to use the C++ stack in a depth-first traversal, carefully constructed -// content could cause the analysis to overflow the stack. -// -// When ubi::Nodes refer to nodes deserialized from a heap snapshot, analyses -// must be even more careful: since snapshots often come from potentially -// compromised e10s content processes, even properties normally guaranteed by -// the platform (the proper linking of DOM nodes, for example) might be -// corrupted. While it is the deserializer's responsibility to check the basic -// structure of the snapshot file, the analyses should be prepared for ubi::Node -// graphs constructed from snapshots to be even more bizarre. - -class JSAtom; - -namespace JS { -namespace ubi { - -class Edge; -class EdgeRange; -class StackFrame; - -} // namespace ubi -} // namespace JS - -namespace JS { -namespace ubi { - -using mozilla::Forward; -using mozilla::Maybe; -using mozilla::Move; -using mozilla::RangedPtr; -using mozilla::Variant; - -template -using Vector = mozilla::Vector; - -/*** ubi::StackFrame ******************************************************************************/ - -// Concrete JS::ubi::StackFrame instances backed by a live SavedFrame object -// store their strings as JSAtom*, while deserialized stack frames from offline -// heap snapshots store their strings as const char16_t*. In order to provide -// zero-cost accessors to these strings in a single interface that works with -// both cases, we use this variant type. -class AtomOrTwoByteChars : public Variant { - using Base = Variant; - - public: - template - MOZ_IMPLICIT AtomOrTwoByteChars(T&& rhs) : Base(Forward(rhs)) { } - - template - AtomOrTwoByteChars& operator=(T&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move disallowed"); - this->~AtomOrTwoByteChars(); - new (this) AtomOrTwoByteChars(Forward(rhs)); - return *this; - } - - // Return the length of the given AtomOrTwoByteChars string. - size_t length(); - - // Copy the given AtomOrTwoByteChars string into the destination buffer, - // inflating if necessary. Does NOT null terminate. Returns the number of - // characters written to destination. - size_t copyToBuffer(RangedPtr destination, size_t length); -}; - -// The base class implemented by each ConcreteStackFrame type. Subclasses -// must not add data members to this class. -class BaseStackFrame { - friend class StackFrame; - - BaseStackFrame(const StackFrame&) = delete; - BaseStackFrame& operator=(const StackFrame&) = delete; - - protected: - void* ptr; - explicit BaseStackFrame(void* ptr) : ptr(ptr) { } - - public: - // This is a value type that should not have a virtual destructor. Don't add - // destructors in subclasses! - - // Get a unique identifier for this StackFrame. The identifier is not valid - // across garbage collections. - virtual uint64_t identifier() const { return uint64_t(uintptr_t(ptr)); } - - // Get this frame's parent frame. - virtual StackFrame parent() const = 0; - - // Get this frame's line number. - virtual uint32_t line() const = 0; - - // Get this frame's column number. - virtual uint32_t column() const = 0; - - // Get this frame's source name. Never null. - virtual AtomOrTwoByteChars source() const = 0; - - // Return this frame's function name if named, otherwise the inferred - // display name. Can be null. - virtual AtomOrTwoByteChars functionDisplayName() const = 0; - - // Returns true if this frame's function is system JavaScript running with - // trusted principals, false otherwise. - virtual bool isSystem() const = 0; - - // Return true if this frame's function is a self-hosted JavaScript builtin, - // false otherwise. - virtual bool isSelfHosted(JSContext* cx) const = 0; - - // Construct a SavedFrame stack for the stack starting with this frame and - // containing all of its parents. The SavedFrame objects will be placed into - // cx's current compartment. - // - // Note that the process of - // - // SavedFrame - // | - // V - // JS::ubi::StackFrame - // | - // V - // offline heap snapshot - // | - // V - // JS::ubi::StackFrame - // | - // V - // SavedFrame - // - // is lossy because we cannot serialize and deserialize the SavedFrame's - // principals in the offline heap snapshot, so JS::ubi::StackFrame - // simplifies the principals check into the boolean isSystem() state. This - // is fine because we only expose JS::ubi::Stack to devtools and chrome - // code, and not to the web platform. - virtual MOZ_MUST_USE bool constructSavedFrameStack(JSContext* cx, - MutableHandleObject outSavedFrameStack) - const = 0; - - // Trace the concrete implementation of JS::ubi::StackFrame. - virtual void trace(JSTracer* trc) = 0; -}; - -// A traits template with a specialization for each backing type that implements -// the ubi::BaseStackFrame interface. Each specialization must be the a subclass -// of ubi::BaseStackFrame. -template class ConcreteStackFrame; - -// A JS::ubi::StackFrame represents a frame in a recorded stack. It can be -// backed either by a live SavedFrame object or by a structure deserialized from -// an offline heap snapshot. -// -// It is a value type that may be memcpy'd hither and thither without worrying -// about constructors or destructors, similar to POD types. -// -// Its lifetime is the same as the lifetime of the graph that is being analyzed -// by the JS::ubi::Node that the JS::ubi::StackFrame came from. That is, if the -// graph being analyzed is the live heap graph, the JS::ubi::StackFrame is only -// valid within the scope of an AutoCheckCannotGC; if the graph being analyzed -// is an offline heap snapshot, the JS::ubi::StackFrame is valid as long as the -// offline heap snapshot is alive. -class StackFrame { - // Storage in which we allocate BaseStackFrame subclasses. - mozilla::AlignedStorage2 storage; - - BaseStackFrame* base() { return storage.addr(); } - const BaseStackFrame* base() const { return storage.addr(); } - - template - void construct(T* ptr) { - static_assert(mozilla::IsBaseOf>::value, - "ConcreteStackFrame must inherit from BaseStackFrame"); - static_assert(sizeof(ConcreteStackFrame) == sizeof(*base()), - "ubi::ConcreteStackFrame specializations must be the same size as " - "ubi::BaseStackFrame"); - ConcreteStackFrame::construct(base(), ptr); - } - struct ConstructFunctor; - - public: - StackFrame() { construct(nullptr); } - - template - MOZ_IMPLICIT StackFrame(T* ptr) { - construct(ptr); - } - - template - StackFrame& operator=(T* ptr) { - construct(ptr); - return *this; - } - - // Constructors accepting SpiderMonkey's generic-pointer-ish types. - - template - explicit StackFrame(const JS::Handle& handle) { - construct(handle.get()); - } - - template - StackFrame& operator=(const JS::Handle& handle) { - construct(handle.get()); - return *this; - } - - template - explicit StackFrame(const JS::Rooted& root) { - construct(root.get()); - } - - template - StackFrame& operator=(const JS::Rooted& root) { - construct(root.get()); - return *this; - } - - // Because StackFrame is just a vtable pointer and an instance pointer, we - // can memcpy everything around instead of making concrete classes define - // virtual constructors. See the comment above Node's copy constructor for - // more details; that comment applies here as well. - StackFrame(const StackFrame& rhs) { - memcpy(storage.u.mBytes, rhs.storage.u.mBytes, sizeof(storage.u)); - } - - StackFrame& operator=(const StackFrame& rhs) { - memcpy(storage.u.mBytes, rhs.storage.u.mBytes, sizeof(storage.u)); - return *this; - } - - bool operator==(const StackFrame& rhs) const { return base()->ptr == rhs.base()->ptr; } - bool operator!=(const StackFrame& rhs) const { return !(*this == rhs); } - - explicit operator bool() const { - return base()->ptr != nullptr; - } - - // Copy this StackFrame's source name into the given |destination| - // buffer. Copy no more than |length| characters. The result is *not* null - // terminated. Returns how many characters were written into the buffer. - size_t source(RangedPtr destination, size_t length) const; - - // Copy this StackFrame's function display name into the given |destination| - // buffer. Copy no more than |length| characters. The result is *not* null - // terminated. Returns how many characters were written into the buffer. - size_t functionDisplayName(RangedPtr destination, size_t length) const; - - // Get the size of the respective strings. 0 is returned for null strings. - size_t sourceLength(); - size_t functionDisplayNameLength(); - - // Methods that forward to virtual calls through BaseStackFrame. - - void trace(JSTracer* trc) { base()->trace(trc); } - uint64_t identifier() const { - auto id = base()->identifier(); - MOZ_ASSERT(JS::Value::isNumberRepresentable(id)); - return id; - } - uint32_t line() const { return base()->line(); } - uint32_t column() const { return base()->column(); } - AtomOrTwoByteChars source() const { return base()->source(); } - AtomOrTwoByteChars functionDisplayName() const { return base()->functionDisplayName(); } - StackFrame parent() const { return base()->parent(); } - bool isSystem() const { return base()->isSystem(); } - bool isSelfHosted(JSContext* cx) const { return base()->isSelfHosted(cx); } - MOZ_MUST_USE bool constructSavedFrameStack(JSContext* cx, - MutableHandleObject outSavedFrameStack) const { - return base()->constructSavedFrameStack(cx, outSavedFrameStack); - } - - struct HashPolicy { - using Lookup = JS::ubi::StackFrame; - - static js::HashNumber hash(const Lookup& lookup) { - return lookup.identifier(); - } - - static bool match(const StackFrame& key, const Lookup& lookup) { - return key == lookup; - } - - static void rekey(StackFrame& k, const StackFrame& newKey) { - k = newKey; - } - }; -}; - -// The ubi::StackFrame null pointer. Any attempt to operate on a null -// ubi::StackFrame crashes. -template<> -class ConcreteStackFrame : public BaseStackFrame { - explicit ConcreteStackFrame(void* ptr) : BaseStackFrame(ptr) { } - - public: - static void construct(void* storage, void*) { new (storage) ConcreteStackFrame(nullptr); } - - uint64_t identifier() const override { return 0; } - void trace(JSTracer* trc) override { } - MOZ_MUST_USE bool constructSavedFrameStack(JSContext* cx, MutableHandleObject out) - const override - { - out.set(nullptr); - return true; - } - - uint32_t line() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - uint32_t column() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - AtomOrTwoByteChars source() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - AtomOrTwoByteChars functionDisplayName() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - StackFrame parent() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - bool isSystem() const override { MOZ_CRASH("null JS::ubi::StackFrame"); } - bool isSelfHosted(JSContext* cx) const override { MOZ_CRASH("null JS::ubi::StackFrame"); } -}; - -MOZ_MUST_USE bool ConstructSavedFrameStackSlow(JSContext* cx, JS::ubi::StackFrame& frame, - MutableHandleObject outSavedFrameStack); - - -/*** ubi::Node ************************************************************************************/ - -// A concrete node specialization can claim its referent is a member of a -// particular "coarse type" which is less specific than the actual -// implementation type but generally more palatable for web developers. For -// example, JitCode can be considered to have a coarse type of "Script". This is -// used by some analyses for putting nodes into different buckets. The default, -// if a concrete specialization does not provide its own mapping to a CoarseType -// variant, is "Other". -// -// NB: the values associated with a particular enum variant must not change or -// be reused for new variants. Doing so will cause inspecting ubi::Nodes backed -// by an offline heap snapshot from an older SpiderMonkey/Firefox version to -// break. Consider this enum append only. -enum class CoarseType: uint32_t { - Other = 0, - Object = 1, - Script = 2, - String = 3, - - FIRST = Other, - LAST = String -}; - -inline uint32_t -CoarseTypeToUint32(CoarseType type) -{ - return static_cast(type); -} - -inline bool -Uint32IsValidCoarseType(uint32_t n) -{ - auto first = static_cast(CoarseType::FIRST); - auto last = static_cast(CoarseType::LAST); - MOZ_ASSERT(first < last); - return first <= n && n <= last; -} - -inline CoarseType -Uint32ToCoarseType(uint32_t n) -{ - MOZ_ASSERT(Uint32IsValidCoarseType(n)); - return static_cast(n); -} - -// The base class implemented by each ubi::Node referent type. Subclasses must -// not add data members to this class. -class Base { - friend class Node; - - // For performance's sake, we'd prefer to avoid a virtual destructor; and - // an empty constructor seems consistent with the 'lightweight value type' - // visible behavior we're trying to achieve. But if the destructor isn't - // virtual, and a subclass overrides it, the subclass's destructor will be - // ignored. Is there a way to make the compiler catch that error? - - protected: - // Space for the actual pointer. Concrete subclasses should define a - // properly typed 'get' member function to access this. - void* ptr; - - explicit Base(void* ptr) : ptr(ptr) { } - - public: - bool operator==(const Base& rhs) const { - // Some compilers will indeed place objects of different types at - // the same address, so technically, we should include the vtable - // in this comparison. But it seems unlikely to cause problems in - // practice. - return ptr == rhs.ptr; - } - bool operator!=(const Base& rhs) const { return !(*this == rhs); } - - // An identifier for this node, guaranteed to be stable and unique for as - // long as this ubi::Node's referent is alive and at the same address. - // - // This is probably suitable for use in serializations, as it is an integral - // type. It may also help save memory when constructing HashSets of - // ubi::Nodes: since a uint64_t will always be smaller-or-equal-to the size - // of a ubi::Node, a HashSet may use less space per element - // than a HashSet. - // - // (Note that 'unique' only means 'up to equality on ubi::Node'; see the - // caveats about multiple objects allocated at the same address for - // 'ubi::Node::operator=='.) - using Id = uint64_t; - virtual Id identifier() const { return Id(uintptr_t(ptr)); } - - // Returns true if this node is pointing to something on the live heap, as - // opposed to something from a deserialized core dump. Returns false, - // otherwise. - virtual bool isLive() const { return true; }; - - // Return the coarse-grained type-of-thing that this node represents. - virtual CoarseType coarseType() const { return CoarseType::Other; } - - // Return a human-readable name for the referent's type. The result should - // be statically allocated. (You can use u"strings" for this.) - // - // This must always return Concrete::concreteTypeName; we use that - // pointer as a tag for this particular referent type. - virtual const char16_t* typeName() const = 0; - - // Return the size of this node, in bytes. Include any structures that this - // node owns exclusively that are not exposed as their own ubi::Nodes. - // |mallocSizeOf| should be a malloc block sizing function; see - // |mfbt/MemoryReporting.h|. - // - // Because we can use |JS::ubi::Node|s backed by a snapshot that was taken - // on a 64-bit platform when we are currently on a 32-bit platform, we - // cannot rely on |size_t| for node sizes. Instead, |Size| is uint64_t on - // all platforms. - using Size = uint64_t; - virtual Size size(mozilla::MallocSizeOf mallocSizeof) const { return 1; } - - // Return an EdgeRange that initially contains all the referent's outgoing - // edges. The caller takes ownership of the EdgeRange. - // - // If wantNames is true, compute names for edges. Doing so can be expensive - // in time and memory. - virtual js::UniquePtr edges(JSContext* cx, bool wantNames) const = 0; - - // Return the Zone to which this node's referent belongs, or nullptr if the - // referent is not of a type allocated in SpiderMonkey Zones. - virtual JS::Zone* zone() const { return nullptr; } - - // Return the compartment for this node. Some ubi::Node referents are not - // associated with JSCompartments, such as JSStrings (which are associated - // with Zones). When the referent is not associated with a compartment, - // nullptr is returned. - virtual JSCompartment* compartment() const { return nullptr; } - - // Return whether this node's referent's allocation stack was captured. - virtual bool hasAllocationStack() const { return false; } - - // Get the stack recorded at the time this node's referent was - // allocated. This must only be called when hasAllocationStack() is true. - virtual StackFrame allocationStack() const { - MOZ_CRASH("Concrete classes that have an allocation stack must override both " - "hasAllocationStack and allocationStack."); - } - - // Methods for JSObject Referents - // - // These methods are only semantically valid if the referent is either a - // JSObject in the live heap, or represents a previously existing JSObject - // from some deserialized heap snapshot. - - // Return the object's [[Class]]'s name. - virtual const char* jsObjectClassName() const { return nullptr; } - - // If this object was constructed with `new` and we have the data available, - // place the contructor function's display name in the out parameter. - // Otherwise, place nullptr in the out parameter. Caller maintains ownership - // of the out parameter. True is returned on success, false is returned on - // OOM. - virtual MOZ_MUST_USE bool jsObjectConstructorName(JSContext* cx, UniqueTwoByteChars& outName) - const - { - outName.reset(nullptr); - return true; - } - - // Methods for CoarseType::Script referents - - // Return the script's source's filename if available. If unavailable, - // return nullptr. - virtual const char* scriptFilename() const { return nullptr; } - - private: - Base(const Base& rhs) = delete; - Base& operator=(const Base& rhs) = delete; -}; - -// A traits template with a specialization for each referent type that -// ubi::Node supports. The specialization must be the concrete subclass of Base -// that represents a pointer to the referent type. It must include these -// members: -// -// // The specific char16_t array returned by Concrete::typeName(). -// static const char16_t concreteTypeName[]; -// -// // Construct an instance of this concrete class in |storage| referring -// // to |referent|. Implementations typically use a placement 'new'. -// // -// // In some cases, |referent| will contain dynamic type information that -// // identifies it a some more specific subclass of |Referent|. For -// // example, when |Referent| is |JSObject|, then |referent->getClass()| -// // could tell us that it's actually a JSFunction. Similarly, if -// // |Referent| is |nsISupports|, we would like a ubi::Node that knows its -// // final implementation type. -// // -// // So we delegate the actual construction to this specialization, which -// // knows Referent's details. -// static void construct(void* storage, Referent* referent); -template -class Concrete; - -// A container for a Base instance; all members simply forward to the contained -// instance. This container allows us to pass ubi::Node instances by value. -class Node { - // Storage in which we allocate Base subclasses. - mozilla::AlignedStorage2 storage; - Base* base() { return storage.addr(); } - const Base* base() const { return storage.addr(); } - - template - void construct(T* ptr) { - static_assert(sizeof(Concrete) == sizeof(*base()), - "ubi::Base specializations must be the same size as ubi::Base"); - static_assert(mozilla::IsBaseOf>::value, - "ubi::Concrete must inherit from ubi::Base"); - Concrete::construct(base(), ptr); - } - struct ConstructFunctor; - - public: - Node() { construct(nullptr); } - - template - MOZ_IMPLICIT Node(T* ptr) { - construct(ptr); - } - template - Node& operator=(T* ptr) { - construct(ptr); - return *this; - } - - // We can construct and assign from rooted forms of pointers. - template - MOZ_IMPLICIT Node(const Rooted& root) { - construct(root.get()); - } - template - Node& operator=(const Rooted& root) { - construct(root.get()); - return *this; - } - - // Constructors accepting SpiderMonkey's other generic-pointer-ish types. - // Note that we *do* want an implicit constructor here: JS::Value and - // JS::ubi::Node are both essentially tagged references to other sorts of - // objects, so letting conversions happen automatically is appropriate. - MOZ_IMPLICIT Node(JS::HandleValue value); - explicit Node(const JS::GCCellPtr& thing); - - // copy construction and copy assignment just use memcpy, since we know - // instances contain nothing but a vtable pointer and a data pointer. - // - // To be completely correct, concrete classes could provide a virtual - // 'construct' member function, which we could invoke on rhs to construct an - // instance in our storage. But this is good enough; there's no need to jump - // through vtables for copying and assignment that are just going to move - // two words around. The compiler knows how to optimize memcpy. - Node(const Node& rhs) { - memcpy(storage.u.mBytes, rhs.storage.u.mBytes, sizeof(storage.u)); - } - - Node& operator=(const Node& rhs) { - memcpy(storage.u.mBytes, rhs.storage.u.mBytes, sizeof(storage.u)); - return *this; - } - - bool operator==(const Node& rhs) const { return *base() == *rhs.base(); } - bool operator!=(const Node& rhs) const { return *base() != *rhs.base(); } - - explicit operator bool() const { - return base()->ptr != nullptr; - } - - bool isLive() const { return base()->isLive(); } - - // Get the canonical type name for the given type T. - template - static const char16_t* canonicalTypeName() { return Concrete::concreteTypeName; } - - template - bool is() const { - return base()->typeName() == canonicalTypeName(); - } - - template - T* as() const { - MOZ_ASSERT(isLive()); - MOZ_ASSERT(is()); - return static_cast(base()->ptr); - } - - template - T* asOrNull() const { - MOZ_ASSERT(isLive()); - return is() ? static_cast(base()->ptr) : nullptr; - } - - // If this node refers to something that can be represented as a JavaScript - // value that is safe to expose to JavaScript code, return that value. - // Otherwise return UndefinedValue(). JSStrings, JS::Symbols, and some (but - // not all!) JSObjects can be exposed. - JS::Value exposeToJS() const; - - CoarseType coarseType() const { return base()->coarseType(); } - const char16_t* typeName() const { return base()->typeName(); } - JS::Zone* zone() const { return base()->zone(); } - JSCompartment* compartment() const { return base()->compartment(); } - const char* jsObjectClassName() const { return base()->jsObjectClassName(); } - MOZ_MUST_USE bool jsObjectConstructorName(JSContext* cx, UniqueTwoByteChars& outName) const { - return base()->jsObjectConstructorName(cx, outName); - } - - const char* scriptFilename() const { return base()->scriptFilename(); } - - using Size = Base::Size; - Size size(mozilla::MallocSizeOf mallocSizeof) const { - auto size = base()->size(mallocSizeof); - MOZ_ASSERT(size > 0, - "C++ does not have zero-sized types! Choose 1 if you just need a " - "conservative default."); - return size; - } - - js::UniquePtr edges(JSContext* cx, bool wantNames = true) const { - return base()->edges(cx, wantNames); - } - - bool hasAllocationStack() const { return base()->hasAllocationStack(); } - StackFrame allocationStack() const { - return base()->allocationStack(); - } - - using Id = Base::Id; - Id identifier() const { - auto id = base()->identifier(); - MOZ_ASSERT(JS::Value::isNumberRepresentable(id)); - return id; - } - - // A hash policy for ubi::Nodes. - // This simply uses the stock PointerHasher on the ubi::Node's pointer. - // We specialize DefaultHasher below to make this the default. - class HashPolicy { - typedef js::PointerHasher::value> PtrHash; - - public: - typedef Node Lookup; - - static js::HashNumber hash(const Lookup& l) { return PtrHash::hash(l.base()->ptr); } - static bool match(const Node& k, const Lookup& l) { return k == l; } - static void rekey(Node& k, const Node& newKey) { k = newKey; } - }; -}; - -using NodeSet = js::HashSet, js::SystemAllocPolicy>; -using NodeSetPtr = mozilla::UniquePtr>; - -/*** Edge and EdgeRange ***************************************************************************/ - -using EdgeName = UniqueTwoByteChars; - -// An outgoing edge to a referent node. -class Edge { - public: - Edge() : name(nullptr), referent() { } - - // Construct an initialized Edge, taking ownership of |name|. - Edge(char16_t* name, const Node& referent) - : name(name) - , referent(referent) - { } - - // Move construction and assignment. - Edge(Edge&& rhs) - : name(mozilla::Move(rhs.name)) - , referent(rhs.referent) - { } - - Edge& operator=(Edge&& rhs) { - MOZ_ASSERT(&rhs != this); - this->~Edge(); - new (this) Edge(mozilla::Move(rhs)); - return *this; - } - - Edge(const Edge&) = delete; - Edge& operator=(const Edge&) = delete; - - // This edge's name. This may be nullptr, if Node::edges was called with - // false as the wantNames parameter. - // - // The storage is owned by this Edge, and will be freed when this Edge is - // destructed. You may take ownership of the name by `mozilla::Move`ing it - // out of the edge; it is just a UniquePtr. - // - // (In real life we'll want a better representation for names, to avoid - // creating tons of strings when the names follow a pattern; and we'll need - // to think about lifetimes carefully to ensure traversal stays cheap.) - EdgeName name; - - // This edge's referent. - Node referent; -}; - -// EdgeRange is an abstract base class for iterating over a node's outgoing -// edges. (This is modeled after js::HashTable::Range.) -// -// Concrete instances of this class need not be as lightweight as Node itself, -// since they're usually only instantiated while iterating over a particular -// object's edges. For example, a dumb implementation for JS Cells might use -// JS::TraceChildren to to get the outgoing edges, and then store them in an -// array internal to the EdgeRange. -class EdgeRange { - protected: - // The current front edge of this range, or nullptr if this range is empty. - Edge* front_; - - EdgeRange() : front_(nullptr) { } - - public: - virtual ~EdgeRange() { } - - // True if there are no more edges in this range. - bool empty() const { return !front_; } - - // The front edge of this range. This is owned by the EdgeRange, and is - // only guaranteed to live until the next call to popFront, or until - // the EdgeRange is destructed. - const Edge& front() const { return *front_; } - Edge& front() { return *front_; } - - // Remove the front edge from this range. This should only be called if - // !empty(). - virtual void popFront() = 0; - - private: - EdgeRange(const EdgeRange&) = delete; - EdgeRange& operator=(const EdgeRange&) = delete; -}; - - -typedef mozilla::Vector EdgeVector; - -// An EdgeRange concrete class that holds a pre-existing vector of -// Edges. A PreComputedEdgeRange does not take ownership of its -// EdgeVector; it is up to the PreComputedEdgeRange's consumer to manage -// that lifetime. -class PreComputedEdgeRange : public EdgeRange { - EdgeVector& edges; - size_t i; - - void settle() { - front_ = i < edges.length() ? &edges[i] : nullptr; - } - - public: - explicit PreComputedEdgeRange(EdgeVector& edges) - : edges(edges), - i(0) - { - settle(); - } - - void popFront() override { - MOZ_ASSERT(!empty()); - i++; - settle(); - } -}; - -/*** RootList *************************************************************************************/ - -// RootList is a class that can be pointed to by a |ubi::Node|, creating a -// fictional root-of-roots which has edges to every GC root in the JS -// runtime. Having a single root |ubi::Node| is useful for algorithms written -// with the assumption that there aren't multiple roots (such as computing -// dominator trees) and you want a single point of entry. It also ensures that -// the roots themselves get visited by |ubi::BreadthFirst| (they would otherwise -// only be used as starting points). -// -// RootList::init itself causes a minor collection, but once the list of roots -// has been created, GC must not occur, as the referent ubi::Nodes are not -// stable across GC. The init calls emplace on |noGC|'s AutoCheckCannotGC, whose -// lifetime must extend at least as long as the RootList itself. -// -// Example usage: -// -// { -// mozilla::Maybe maybeNoGC; -// JS::ubi::RootList rootList(cx, maybeNoGC); -// if (!rootList.init()) -// return false; -// -// // The AutoCheckCannotGC is guaranteed to exist if init returned true. -// MOZ_ASSERT(maybeNoGC.isSome()); -// -// JS::ubi::Node root(&rootList); -// -// ... -// } -class MOZ_STACK_CLASS RootList { - Maybe& noGC; - - public: - JSContext* cx; - EdgeVector edges; - bool wantNames; - - RootList(JSContext* cx, Maybe& noGC, bool wantNames = false); - - // Find all GC roots. - MOZ_MUST_USE bool init(); - // Find only GC roots in the provided set of |JSCompartment|s. - MOZ_MUST_USE bool init(CompartmentSet& debuggees); - // Find only GC roots in the given Debugger object's set of debuggee - // compartments. - MOZ_MUST_USE bool init(HandleObject debuggees); - - // Returns true if the RootList has been initialized successfully, false - // otherwise. - bool initialized() { return noGC.isSome(); } - - // Explicitly add the given Node as a root in this RootList. If wantNames is - // true, you must pass an edgeName. The RootList does not take ownership of - // edgeName. - MOZ_MUST_USE bool addRoot(Node node, const char16_t* edgeName = nullptr); -}; - - -/*** Concrete classes for ubi::Node referent types ************************************************/ - -template<> -class Concrete : public Base { - protected: - explicit Concrete(RootList* ptr) : Base(ptr) { } - RootList& get() const { return *static_cast(ptr); } - - public: - static void construct(void* storage, RootList* ptr) { new (storage) Concrete(ptr); } - - js::UniquePtr edges(JSContext* cx, bool wantNames) const override; - - const char16_t* typeName() const override { return concreteTypeName; } - static const char16_t concreteTypeName[]; -}; - -// A reusable ubi::Concrete specialization base class for types supported by -// JS::TraceChildren. -template -class TracerConcrete : public Base { - js::UniquePtr edges(JSContext* cx, bool wantNames) const override; - JS::Zone* zone() const override; - - protected: - explicit TracerConcrete(Referent* ptr) : Base(ptr) { } - Referent& get() const { return *static_cast(ptr); } -}; - -// For JS::TraceChildren-based types that have a 'compartment' method. -template -class TracerConcreteWithCompartment : public TracerConcrete { - typedef TracerConcrete TracerBase; - JSCompartment* compartment() const override; - - protected: - explicit TracerConcreteWithCompartment(Referent* ptr) : TracerBase(ptr) { } -}; - -// Define specializations for some commonly-used public JSAPI types. -// These can use the generic templates above. -template<> -class Concrete : TracerConcrete { - protected: - explicit Concrete(JS::Symbol* ptr) : TracerConcrete(ptr) { } - - public: - static void construct(void* storage, JS::Symbol* ptr) { - new (storage) Concrete(ptr); - } - - Size size(mozilla::MallocSizeOf mallocSizeOf) const override; - - const char16_t* typeName() const override { return concreteTypeName; } - static const char16_t concreteTypeName[]; -}; - -template<> -class Concrete : TracerConcreteWithCompartment { - protected: - explicit Concrete(JSScript *ptr) : TracerConcreteWithCompartment(ptr) { } - - public: - static void construct(void *storage, JSScript *ptr) { new (storage) Concrete(ptr); } - - CoarseType coarseType() const final { return CoarseType::Script; } - Size size(mozilla::MallocSizeOf mallocSizeOf) const override; - const char* scriptFilename() const final; - - const char16_t* typeName() const override { return concreteTypeName; } - static const char16_t concreteTypeName[]; -}; - -// The JSObject specialization. -template<> -class Concrete : public TracerConcreteWithCompartment { - protected: - explicit Concrete(JSObject* ptr) : TracerConcreteWithCompartment(ptr) { } - - public: - static void construct(void* storage, JSObject* ptr) { - new (storage) Concrete(ptr); - } - - const char* jsObjectClassName() const override; - MOZ_MUST_USE bool jsObjectConstructorName(JSContext* cx, UniqueTwoByteChars& outName) - const override; - Size size(mozilla::MallocSizeOf mallocSizeOf) const override; - - bool hasAllocationStack() const override; - StackFrame allocationStack() const override; - - CoarseType coarseType() const final { return CoarseType::Object; } - - const char16_t* typeName() const override { return concreteTypeName; } - static const char16_t concreteTypeName[]; -}; - -// For JSString, we extend the generic template with a 'size' implementation. -template<> -class Concrete : TracerConcrete { - protected: - explicit Concrete(JSString *ptr) : TracerConcrete(ptr) { } - - public: - static void construct(void *storage, JSString *ptr) { new (storage) Concrete(ptr); } - - Size size(mozilla::MallocSizeOf mallocSizeOf) const override; - - CoarseType coarseType() const final { return CoarseType::String; } - - const char16_t* typeName() const override { return concreteTypeName; } - static const char16_t concreteTypeName[]; -}; - -// The ubi::Node null pointer. Any attempt to operate on a null ubi::Node asserts. -template<> -class Concrete : public Base { - const char16_t* typeName() const override; - Size size(mozilla::MallocSizeOf mallocSizeOf) const override; - js::UniquePtr edges(JSContext* cx, bool wantNames) const override; - JS::Zone* zone() const override; - JSCompartment* compartment() const override; - CoarseType coarseType() const final; - - explicit Concrete(void* ptr) : Base(ptr) { } - - public: - static void construct(void* storage, void* ptr) { new (storage) Concrete(ptr); } -}; - - -} // namespace ubi -} // namespace JS - -namespace js { - -// Make ubi::Node::HashPolicy the default hash policy for ubi::Node. -template<> struct DefaultHasher : JS::ubi::Node::HashPolicy { }; -template<> struct DefaultHasher : JS::ubi::StackFrame::HashPolicy { }; - -} // namespace js - -#endif // js_UbiNode_h diff --git a/android/x86/include/spidermonkey/js/UbiNodeBreadthFirst.h b/android/x86/include/spidermonkey/js/UbiNodeBreadthFirst.h deleted file mode 100644 index 8446dbc6..00000000 --- a/android/x86/include/spidermonkey/js/UbiNodeBreadthFirst.h +++ /dev/null @@ -1,244 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNodeBreadthFirst_h -#define js_UbiNodeBreadthFirst_h - -#include "js/UbiNode.h" -#include "js/Utility.h" -#include "js/Vector.h" - -namespace JS { -namespace ubi { - -// A breadth-first traversal template for graphs of ubi::Nodes. -// -// No GC may occur while an instance of this template is live. -// -// The provided Handler type should have two members: -// -// typename NodeData; -// -// The value type of |BreadthFirst::visited|, the HashMap of -// ubi::Nodes that have been visited so far. Since the algorithm needs a -// hash table like this for its own use anyway, it is simple to let -// Handler store its own metadata about each node in the same table. -// -// For example, if you want to find a shortest path to each node from any -// traversal starting point, your |NodeData| type could record the first -// edge to reach each node, and the node from which it originates. Then, -// when the traversal is complete, you can walk backwards from any node -// to some starting point, and the path recorded will be a shortest path. -// -// This type must have a default constructor. If this type owns any other -// resources, move constructors and assignment operators are probably a -// good idea, too. -// -// bool operator() (BreadthFirst& traversal, -// Node origin, const Edge& edge, -// Handler::NodeData* referentData, bool first); -// -// The visitor function, called to report that we have traversed -// |edge| from |origin|. This is called once for each edge we traverse. -// As this is a breadth-first search, any prior calls to the visitor function -// were for origin nodes not further from the start nodes than |origin|. -// -// |traversal| is this traversal object, passed along for convenience. -// -// |referentData| is a pointer to the value of the entry in -// |traversal.visited| for |edge.referent|; the visitor function can -// store whatever metadata it likes about |edge.referent| there. -// -// |first| is true if this is the first time we have visited an edge -// leading to |edge.referent|. This could be stored in NodeData, but -// the algorithm knows whether it has just created the entry in -// |traversal.visited|, so it passes it along for convenience. -// -// The visitor function may call |traversal.abandonReferent()| if it -// doesn't want to traverse the outgoing edges of |edge.referent|. You can -// use this to limit the traversal to a given portion of the graph: it will -// never visit nodes reachable only through nodes that you have abandoned. -// Note that |abandonReferent| must be called the first time the given node -// is reached; that is, |first| must be true. -// -// The visitor function may call |traversal.stop()| if it doesn't want -// to visit any more nodes at all. -// -// The visitor function may consult |traversal.visited| for information -// about other nodes, but it should not add or remove entries. -// -// The visitor function should return true on success, or false if an -// error occurs. A false return value terminates the traversal -// immediately, and causes BreadthFirst::traverse to return -// false. -template -struct BreadthFirst { - - // Construct a breadth-first traversal object that reports the nodes it - // reaches to |handler|. The traversal asserts that no GC happens in its - // runtime during its lifetime. - // - // We do nothing with noGC, other than require it to exist, with a lifetime - // that encloses our own. - BreadthFirst(JSContext* cx, Handler& handler, const JS::AutoCheckCannotGC& noGC) - : wantNames(true), cx(cx), visited(), handler(handler), pending(), - traversalBegun(false), stopRequested(false), abandonRequested(false) - { } - - // Initialize this traversal object. Return false on OOM. - bool init() { return visited.init(); } - - // Add |node| as a starting point for the traversal. You may add - // as many starting points as you like. Return false on OOM. - bool addStart(Node node) { return pending.append(node); } - - // Add |node| as a starting point for the traversal (see addStart) and also - // add it to the |visited| set. Return false on OOM. - bool addStartVisited(Node node) { - typename NodeMap::AddPtr ptr = visited.lookupForAdd(node); - if (!ptr && !visited.add(ptr, node, typename Handler::NodeData())) - return false; - return addStart(node); - } - - // True if the handler wants us to compute edge names; doing so can be - // expensive in time and memory. True by default. - bool wantNames; - - // Traverse the graph in breadth-first order, starting at the given - // start nodes, applying |handler::operator()| for each edge traversed - // as described above. - // - // This should be called only once per instance of this class. - // - // Return false on OOM or error return from |handler::operator()|. - bool traverse() - { - MOZ_ASSERT(!traversalBegun); - traversalBegun = true; - - // While there are pending nodes, visit them. - while (!pending.empty()) { - Node origin = pending.front(); - pending.popFront(); - - // Get a range containing all origin's outgoing edges. - auto range = origin.edges(cx, wantNames); - if (!range) - return false; - - // Traverse each edge. - for (; !range->empty(); range->popFront()) { - MOZ_ASSERT(!stopRequested); - - Edge& edge = range->front(); - typename NodeMap::AddPtr a = visited.lookupForAdd(edge.referent); - bool first = !a; - - if (first) { - // This is the first time we've reached |edge.referent|. - // Mark it as visited. - if (!visited.add(a, edge.referent, typename Handler::NodeData())) - return false; - } - - MOZ_ASSERT(a); - - // Report this edge to the visitor function. - if (!handler(*this, origin, edge, &a->value(), first)) - return false; - - if (stopRequested) - return true; - - // Arrange to traverse this edge's referent's outgoing edges - // later --- unless |handler| asked us not to. - if (abandonRequested) { - // Skip the enqueue; reset flag for future iterations. - abandonRequested = false; - } else if (first) { - if (!pending.append(edge.referent)) - return false; - } - } - } - - return true; - } - - // Stop traversal, and return true from |traverse| without visiting any - // more nodes. Only |handler::operator()| should call this function; it - // may do so to stop the traversal early, without returning false and - // then making |traverse|'s caller disambiguate that result from a real - // error. - void stop() { stopRequested = true; } - - // Request that the current edge's referent's outgoing edges not be - // traversed. This must be called the first time that referent is reached. - // Other edges *to* that referent will still be traversed. - void abandonReferent() { abandonRequested = true; } - - // The context with which we were constructed. - JSContext* cx; - - // A map associating each node N that we have reached with a - // Handler::NodeData, for |handler|'s use. This is public, so that - // |handler| can access it to see the traversal thus far. - using NodeMap = js::HashMap, - js::SystemAllocPolicy>; - NodeMap visited; - - private: - // Our handler object. - Handler& handler; - - // A queue template. Appending and popping the front are constant time. - // Wasted space is never more than some recent actual population plus the - // current population. - template - class Queue { - js::Vector head, tail; - size_t frontIndex; - public: - Queue() : head(), tail(), frontIndex(0) { } - bool empty() { return frontIndex >= head.length(); } - T& front() { - MOZ_ASSERT(!empty()); - return head[frontIndex]; - } - void popFront() { - MOZ_ASSERT(!empty()); - frontIndex++; - if (frontIndex >= head.length()) { - head.clearAndFree(); - head.swap(tail); - frontIndex = 0; - } - } - bool append(const T& elt) { - return frontIndex == 0 ? head.append(elt) : tail.append(elt); - } - }; - - // A queue of nodes that we have reached, but whose outgoing edges we - // have not yet traversed. Nodes reachable in fewer edges are enqueued - // earlier. - Queue pending; - - // True if our traverse function has been called. - bool traversalBegun; - - // True if we've been asked to stop the traversal. - bool stopRequested; - - // True if we've been asked to abandon the current edge's referent. - bool abandonRequested; -}; - -} // namespace ubi -} // namespace JS - -#endif // js_UbiNodeBreadthFirst_h diff --git a/android/x86/include/spidermonkey/js/UbiNodeCensus.h b/android/x86/include/spidermonkey/js/UbiNodeCensus.h deleted file mode 100644 index c0859ec5..00000000 --- a/android/x86/include/spidermonkey/js/UbiNodeCensus.h +++ /dev/null @@ -1,251 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNodeCensus_h -#define js_UbiNodeCensus_h - -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" - -#include - -#include "jsapi.h" - -#include "js/UbiNode.h" -#include "js/UbiNodeBreadthFirst.h" - -// A census is a ubi::Node traversal that assigns each node to one or more -// buckets, and returns a report with the size of each bucket. -// -// We summarize the results of a census with counts broken down according to -// criteria selected by the API consumer code that is requesting the census. For -// example, the following breakdown might give an interesting overview of the -// heap: -// -// - all nodes -// - objects -// - objects with a specific [[Class]] * -// - strings -// - scripts -// - all other Node types -// - nodes with a specific ubi::Node::typeName * -// -// Obviously, the parts of this tree marked with * represent many separate -// counts, depending on how many distinct [[Class]] values and ubi::Node type -// names we encounter. -// -// The supported types of breakdowns are documented in -// js/src/doc/Debugger/Debugger.Memory.md. -// -// When we parse the 'breakdown' argument to takeCensus, we build a tree of -// CountType nodes. For example, for the breakdown shown in the -// Debugger.Memory.prototype.takeCensus, documentation: -// -// { -// by: "coarseType", -// objects: { by: "objectClass" }, -// other: { by: "internalType" } -// } -// -// we would build the following tree of CountType subclasses: -// -// ByCoarseType -// objects: ByObjectClass -// each class: SimpleCount -// scripts: SimpleCount -// strings: SimpleCount -// other: ByUbinodeType -// each type: SimpleCount -// -// The interior nodes are all breakdown types that categorize nodes according to -// one characteristic or another; and the leaf nodes are all SimpleType. -// -// Each CountType has its own concrete C++ type that holds the counts it -// produces. SimpleCount::Count just holds totals. ByObjectClass::Count has a -// hash table whose keys are object class names and whose values are counts of -// some other type (in the example above, SimpleCount). -// -// To keep actual count nodes small, they have no vtable. Instead, each count -// points to its CountType, which knows how to carry out all the operations we -// need on a Count. A CountType can produce new count nodes; process nodes as we -// visit them; build a JS object reporting the results; and destruct count -// nodes. - - -namespace JS { -namespace ubi { - -struct Census; - -class CountBase; - -struct CountDeleter { - void operator()(CountBase*); -}; - -using CountBasePtr = js::UniquePtr; - -// Abstract base class for CountType nodes. -struct CountType { - explicit CountType() { } - virtual ~CountType() { } - - // Destruct a count tree node that this type instance constructed. - virtual void destructCount(CountBase& count) = 0; - - // Return a fresh node for the count tree that categorizes nodes according - // to this type. Return a nullptr on OOM. - virtual CountBasePtr makeCount() = 0; - - // Trace |count| and all its children, for garbage collection. - virtual void traceCount(CountBase& count, JSTracer* trc) = 0; - - // Implement the 'count' method for counts returned by this CountType - // instance's 'newCount' method. - virtual MOZ_MUST_USE bool count(CountBase& count, - mozilla::MallocSizeOf mallocSizeOf, - const Node& node) = 0; - - // Implement the 'report' method for counts returned by this CountType - // instance's 'newCount' method. - virtual MOZ_MUST_USE bool report(JSContext* cx, CountBase& count, - MutableHandleValue report) = 0; -}; - -using CountTypePtr = js::UniquePtr; - -// An abstract base class for count tree nodes. -class CountBase { - // In lieu of a vtable, each CountBase points to its type, which - // carries not only the implementations of the CountBase methods, but also - // additional parameters for the type's behavior, as specified in the - // breakdown argument passed to takeCensus. - CountType& type; - - protected: - ~CountBase() { } - - public: - explicit CountBase(CountType& type) - : type(type) - , total_(0) - , smallestNodeIdCounted_(SIZE_MAX) - { } - - // Categorize and count |node| as appropriate for this count's type. - MOZ_MUST_USE bool count(mozilla::MallocSizeOf mallocSizeOf, const Node& node) { - total_++; - - auto id = node.identifier(); - if (id < smallestNodeIdCounted_) { - smallestNodeIdCounted_ = id; - } - -#ifdef DEBUG - size_t oldTotal = total_; -#endif - - bool ret = type.count(*this, mallocSizeOf, node); - - MOZ_ASSERT(total_ == oldTotal, - "CountType::count should not increment total_, CountBase::count handles that"); - - return ret; - } - - // Construct a JavaScript object reporting the counts recorded in this - // count, and store it in |report|. Return true on success, or false on - // failure. - MOZ_MUST_USE bool report(JSContext* cx, MutableHandleValue report) { - return type.report(cx, *this, report); - } - - // Down-cast this CountBase to its true type, based on its 'type' member, - // and run its destructor. - void destruct() { return type.destructCount(*this); } - - // Trace this count for garbage collection. - void trace(JSTracer* trc) { type.traceCount(*this, trc); } - - size_t total_; - - // The smallest JS::ubi::Node::identifier() passed to this instance's - // count() method. This provides a stable way to sort sets. - Node::Id smallestNodeIdCounted_; -}; - -class RootedCount : JS::CustomAutoRooter { - CountBasePtr count; - - void trace(JSTracer* trc) override { count->trace(trc); } - - public: - RootedCount(JSContext* cx, CountBasePtr&& count) - : CustomAutoRooter(cx), - count(Move(count)) - { } - CountBase* operator->() const { return count.get(); } - explicit operator bool() const { return count.get(); } - operator CountBasePtr&() { return count; } -}; - -// Common data for a census traversal, shared across all CountType nodes. -struct Census { - JSContext* const cx; - // If the targetZones set is non-empty, then only consider nodes whose zone - // is an element of the set. If the targetZones set is empty, then nodes in - // all zones are considered. - JS::ZoneSet targetZones; - Zone* atomsZone; - - explicit Census(JSContext* cx) : cx(cx), atomsZone(nullptr) { } - - MOZ_MUST_USE bool init(); -}; - -// A BreadthFirst handler type that conducts a census, using a CountBase to -// categorize and count each node. -class CensusHandler { - Census& census; - CountBasePtr& rootCount; - mozilla::MallocSizeOf mallocSizeOf; - - public: - CensusHandler(Census& census, CountBasePtr& rootCount, mozilla::MallocSizeOf mallocSizeOf) - : census(census), - rootCount(rootCount), - mallocSizeOf(mallocSizeOf) - { } - - MOZ_MUST_USE bool report(JSContext* cx, MutableHandleValue report) { - return rootCount->report(cx, report); - } - - // This class needs to retain no per-node data. - class NodeData { }; - - MOZ_MUST_USE bool operator() (BreadthFirst& traversal, - Node origin, const Edge& edge, - NodeData* referentData, bool first); -}; - -using CensusTraversal = BreadthFirst; - -// Examine the census options supplied by the API consumer, and (among other -// things) use that to build a CountType tree. -MOZ_MUST_USE bool ParseCensusOptions(JSContext* cx, Census& census, HandleObject options, - CountTypePtr& outResult); - -// Parse the breakdown language (as described in -// js/src/doc/Debugger/Debugger.Memory.md) into a CountTypePtr. A null pointer -// is returned on error and is reported to the cx. -CountTypePtr ParseBreakdown(JSContext* cx, HandleValue breakdownValue); - - -} // namespace ubi -} // namespace JS - -#endif // js_UbiNodeCensus_h diff --git a/android/x86/include/spidermonkey/js/UbiNodeDominatorTree.h b/android/x86/include/spidermonkey/js/UbiNodeDominatorTree.h deleted file mode 100644 index 3422b76b..00000000 --- a/android/x86/include/spidermonkey/js/UbiNodeDominatorTree.h +++ /dev/null @@ -1,677 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNodeDominatorTree_h -#define js_UbiNodeDominatorTree_h - -#include "mozilla/Attributes.h" -#include "mozilla/DebugOnly.h" -#include "mozilla/Maybe.h" -#include "mozilla/Move.h" -#include "mozilla/UniquePtr.h" - -#include "jsalloc.h" - -#include "js/UbiNode.h" -#include "js/UbiNodePostOrder.h" -#include "js/Utility.h" -#include "js/Vector.h" - -namespace JS { -namespace ubi { - -/** - * In a directed graph with a root node `R`, a node `A` is said to "dominate" a - * node `B` iff every path from `R` to `B` contains `A`. A node `A` is said to - * be the "immediate dominator" of a node `B` iff it dominates `B`, is not `B` - * itself, and does not dominate any other nodes which also dominate `B` in - * turn. - * - * If we take every node from a graph `G` and create a new graph `T` with edges - * to each node from its immediate dominator, then `T` is a tree (each node has - * only one immediate dominator, or none if it is the root). This tree is called - * a "dominator tree". - * - * This class represents a dominator tree constructed from a `JS::ubi::Node` - * heap graph. The domination relationship and dominator trees are useful tools - * for analyzing heap graphs because they tell you: - * - * - Exactly what could be reclaimed by the GC if some node `A` became - * unreachable: those nodes which are dominated by `A`, - * - * - The "retained size" of a node in the heap graph, in contrast to its - * "shallow size". The "shallow size" is the space taken by a node itself, - * not counting anything it references. The "retained size" of a node is its - * shallow size plus the size of all the things that would be collected if - * the original node wasn't (directly or indirectly) referencing them. In - * other words, the retained size is the shallow size of a node plus the - * shallow sizes of every other node it dominates. For example, the root - * node in a binary tree might have a small shallow size that does not take - * up much space itself, but it dominates the rest of the binary tree and - * its retained size is therefore significant (assuming no external - * references into the tree). - * - * The simple, engineered algorithm presented in "A Simple, Fast Dominance - * Algorithm" by Cooper el al[0] is used to find dominators and construct the - * dominator tree. This algorithm runs in O(n^2) time, but is faster in practice - * than alternative algorithms with better theoretical running times, such as - * Lengauer-Tarjan which runs in O(e * log(n)). The big caveat to that statement - * is that Cooper et al found it is faster in practice *on control flow graphs* - * and I'm not convinced that this property also holds on *heap* graphs. That - * said, the implementation of this algorithm is *much* simpler than - * Lengauer-Tarjan and has been found to be fast enough at least for the time - * being. - * - * [0]: http://www.cs.rice.edu/~keith/EMBED/dom.pdf - */ -class JS_PUBLIC_API(DominatorTree) -{ - private: - // Types. - - using PredecessorSets = js::HashMap, - js::SystemAllocPolicy>; - using NodeToIndexMap = js::HashMap, - js::SystemAllocPolicy>; - class DominatedSets; - - public: - class DominatedSetRange; - - /** - * A pointer to an immediately dominated node. - * - * Don't use this type directly; it is no safer than regular pointers. This - * is only for use indirectly with range-based for loops and - * `DominatedSetRange`. - * - * @see JS::ubi::DominatorTree::getDominatedSet - */ - class DominatedNodePtr - { - friend class DominatedSetRange; - - const JS::ubi::Vector& postOrder; - const uint32_t* ptr; - - DominatedNodePtr(const JS::ubi::Vector& postOrder, const uint32_t* ptr) - : postOrder(postOrder) - , ptr(ptr) - { } - - public: - bool operator!=(const DominatedNodePtr& rhs) const { return ptr != rhs.ptr; } - void operator++() { ptr++; } - const Node& operator*() const { return postOrder[*ptr]; } - }; - - /** - * A range of immediately dominated `JS::ubi::Node`s for use with - * range-based for loops. - * - * @see JS::ubi::DominatorTree::getDominatedSet - */ - class DominatedSetRange - { - friend class DominatedSets; - - const JS::ubi::Vector& postOrder; - const uint32_t* beginPtr; - const uint32_t* endPtr; - - DominatedSetRange(JS::ubi::Vector& postOrder, const uint32_t* begin, const uint32_t* end) - : postOrder(postOrder) - , beginPtr(begin) - , endPtr(end) - { - MOZ_ASSERT(begin <= end); - } - - public: - DominatedNodePtr begin() const { - MOZ_ASSERT(beginPtr <= endPtr); - return DominatedNodePtr(postOrder, beginPtr); - } - - DominatedNodePtr end() const { - return DominatedNodePtr(postOrder, endPtr); - } - - size_t length() const { - MOZ_ASSERT(beginPtr <= endPtr); - return endPtr - beginPtr; - } - - /** - * Safely skip ahead `n` dominators in the range, in O(1) time. - * - * Example usage: - * - * mozilla::Maybe range = myDominatorTree.getDominatedSet(myNode); - * if (range.isNothing()) { - * // Handle unknown nodes however you see fit... - * return false; - * } - * - * // Don't care about the first ten, for whatever reason. - * range->skip(10); - * for (const JS::ubi::Node& dominatedNode : *range) { - * // ... - * } - */ - void skip(size_t n) { - beginPtr += n; - if (beginPtr > endPtr) - beginPtr = endPtr; - } - }; - - private: - /** - * The set of all dominated sets in a dominator tree. - * - * Internally stores the sets in a contiguous array, with a side table of - * indices into that contiguous array to denote the start index of each - * individual set. - */ - class DominatedSets - { - JS::ubi::Vector dominated; - JS::ubi::Vector indices; - - DominatedSets(JS::ubi::Vector&& dominated, JS::ubi::Vector&& indices) - : dominated(mozilla::Move(dominated)) - , indices(mozilla::Move(indices)) - { } - - public: - // DominatedSets is not copy-able. - DominatedSets(const DominatedSets& rhs) = delete; - DominatedSets& operator=(const DominatedSets& rhs) = delete; - - // DominatedSets is move-able. - DominatedSets(DominatedSets&& rhs) - : dominated(mozilla::Move(rhs.dominated)) - , indices(mozilla::Move(rhs.indices)) - { - MOZ_ASSERT(this != &rhs, "self-move not allowed"); - } - DominatedSets& operator=(DominatedSets&& rhs) { - this->~DominatedSets(); - new (this) DominatedSets(mozilla::Move(rhs)); - return *this; - } - - /** - * Create the DominatedSets given the mapping of a node index to its - * immediate dominator. Returns `Some` on success, `Nothing` on OOM - * failure. - */ - static mozilla::Maybe Create(const JS::ubi::Vector& doms) { - auto length = doms.length(); - MOZ_ASSERT(length < UINT32_MAX); - - // Create a vector `dominated` holding a flattened set of buckets of - // immediately dominated children nodes, with a lookup table - // `indices` mapping from each node to the beginning of its bucket. - // - // This has three phases: - // - // 1. Iterate over the full set of nodes and count up the size of - // each bucket. These bucket sizes are temporarily stored in the - // `indices` vector. - // - // 2. Convert the `indices` vector to store the cumulative sum of - // the sizes of all buckets before each index, resulting in a - // mapping from node index to one past the end of that node's - // bucket. - // - // 3. Iterate over the full set of nodes again, filling in bucket - // entries from the end of the bucket's range to its - // beginning. This decrements each index as a bucket entry is - // filled in. After having filled in all of a bucket's entries, - // the index points to the start of the bucket. - - JS::ubi::Vector dominated; - JS::ubi::Vector indices; - if (!dominated.growBy(length) || !indices.growBy(length)) - return mozilla::Nothing(); - - // 1 - memset(indices.begin(), 0, length * sizeof(uint32_t)); - for (uint32_t i = 0; i < length; i++) - indices[doms[i]]++; - - // 2 - uint32_t sumOfSizes = 0; - for (uint32_t i = 0; i < length; i++) { - sumOfSizes += indices[i]; - MOZ_ASSERT(sumOfSizes <= length); - indices[i] = sumOfSizes; - } - - // 3 - for (uint32_t i = 0; i < length; i++) { - auto idxOfDom = doms[i]; - indices[idxOfDom]--; - dominated[indices[idxOfDom]] = i; - } - -#ifdef DEBUG - // Assert that our buckets are non-overlapping and don't run off the - // end of the vector. - uint32_t lastIndex = 0; - for (uint32_t i = 0; i < length; i++) { - MOZ_ASSERT(indices[i] >= lastIndex); - MOZ_ASSERT(indices[i] < length); - lastIndex = indices[i]; - } -#endif - - return mozilla::Some(DominatedSets(mozilla::Move(dominated), mozilla::Move(indices))); - } - - /** - * Get the set of nodes immediately dominated by the node at - * `postOrder[nodeIndex]`. - */ - DominatedSetRange dominatedSet(JS::ubi::Vector& postOrder, uint32_t nodeIndex) const { - MOZ_ASSERT(postOrder.length() == indices.length()); - MOZ_ASSERT(nodeIndex < indices.length()); - auto end = nodeIndex == indices.length() - 1 - ? dominated.end() - : &dominated[indices[nodeIndex + 1]]; - return DominatedSetRange(postOrder, &dominated[indices[nodeIndex]], end); - } - }; - - private: - // Data members. - JS::ubi::Vector postOrder; - NodeToIndexMap nodeToPostOrderIndex; - JS::ubi::Vector doms; - DominatedSets dominatedSets; - mozilla::Maybe> retainedSizes; - - private: - // We use `UNDEFINED` as a sentinel value in the `doms` vector to signal - // that we haven't found any dominators for the node at the corresponding - // index in `postOrder` yet. - static const uint32_t UNDEFINED = UINT32_MAX; - - DominatorTree(JS::ubi::Vector&& postOrder, NodeToIndexMap&& nodeToPostOrderIndex, - JS::ubi::Vector&& doms, DominatedSets&& dominatedSets) - : postOrder(mozilla::Move(postOrder)) - , nodeToPostOrderIndex(mozilla::Move(nodeToPostOrderIndex)) - , doms(mozilla::Move(doms)) - , dominatedSets(mozilla::Move(dominatedSets)) - , retainedSizes(mozilla::Nothing()) - { } - - static uint32_t intersect(JS::ubi::Vector& doms, uint32_t finger1, uint32_t finger2) { - while (finger1 != finger2) { - if (finger1 < finger2) - finger1 = doms[finger1]; - else if (finger2 < finger1) - finger2 = doms[finger2]; - } - return finger1; - } - - // Do the post order traversal of the heap graph and populate our - // predecessor sets. - static MOZ_MUST_USE bool doTraversal(JSContext* cx, AutoCheckCannotGC& noGC, const Node& root, - JS::ubi::Vector& postOrder, - PredecessorSets& predecessorSets) { - uint32_t nodeCount = 0; - auto onNode = [&](const Node& node) { - nodeCount++; - if (MOZ_UNLIKELY(nodeCount == UINT32_MAX)) - return false; - return postOrder.append(node); - }; - - auto onEdge = [&](const Node& origin, const Edge& edge) { - auto p = predecessorSets.lookupForAdd(edge.referent); - if (!p) { - mozilla::UniquePtr> set(js_new()); - if (!set || - !set->init() || - !predecessorSets.add(p, edge.referent, mozilla::Move(set))) - { - return false; - } - } - MOZ_ASSERT(p && p->value()); - return p->value()->put(origin); - }; - - PostOrder traversal(cx, noGC); - return traversal.init() && - traversal.addStart(root) && - traversal.traverse(onNode, onEdge); - } - - // Populates the given `map` with an entry for each node to its index in - // `postOrder`. - static MOZ_MUST_USE bool mapNodesToTheirIndices(JS::ubi::Vector& postOrder, - NodeToIndexMap& map) { - MOZ_ASSERT(!map.initialized()); - MOZ_ASSERT(postOrder.length() < UINT32_MAX); - uint32_t length = postOrder.length(); - if (!map.init(length)) - return false; - for (uint32_t i = 0; i < length; i++) - map.putNewInfallible(postOrder[i], i); - return true; - } - - // Convert the Node -> NodeSet predecessorSets to a index -> Vector - // form. - static MOZ_MUST_USE bool convertPredecessorSetsToVectors( - const Node& root, - JS::ubi::Vector& postOrder, - PredecessorSets& predecessorSets, - NodeToIndexMap& nodeToPostOrderIndex, - JS::ubi::Vector>& predecessorVectors) - { - MOZ_ASSERT(postOrder.length() < UINT32_MAX); - uint32_t length = postOrder.length(); - - MOZ_ASSERT(predecessorVectors.length() == 0); - if (!predecessorVectors.growBy(length)) - return false; - - for (uint32_t i = 0; i < length - 1; i++) { - auto& node = postOrder[i]; - MOZ_ASSERT(node != root, - "Only the last node should be root, since this was a post order traversal."); - - auto ptr = predecessorSets.lookup(node); - MOZ_ASSERT(ptr, - "Because this isn't the root, it had better have predecessors, or else how " - "did we even find it."); - - auto& predecessors = ptr->value(); - if (!predecessorVectors[i].reserve(predecessors->count())) - return false; - for (auto range = predecessors->all(); !range.empty(); range.popFront()) { - auto ptr = nodeToPostOrderIndex.lookup(range.front()); - MOZ_ASSERT(ptr); - predecessorVectors[i].infallibleAppend(ptr->value()); - } - } - predecessorSets.finish(); - return true; - } - - // Initialize `doms` such that the immediate dominator of the `root` is the - // `root` itself and all others are `UNDEFINED`. - static MOZ_MUST_USE bool initializeDominators(JS::ubi::Vector& doms, - uint32_t length) { - MOZ_ASSERT(doms.length() == 0); - if (!doms.growByUninitialized(length)) - return false; - doms[length - 1] = length - 1; - for (uint32_t i = 0; i < length - 1; i++) - doms[i] = UNDEFINED; - return true; - } - - void assertSanity() const { - MOZ_ASSERT(postOrder.length() == doms.length()); - MOZ_ASSERT(postOrder.length() == nodeToPostOrderIndex.count()); - MOZ_ASSERT_IF(retainedSizes.isSome(), postOrder.length() == retainedSizes->length()); - } - - MOZ_MUST_USE bool computeRetainedSizes(mozilla::MallocSizeOf mallocSizeOf) { - MOZ_ASSERT(retainedSizes.isNothing()); - auto length = postOrder.length(); - - retainedSizes.emplace(); - if (!retainedSizes->growBy(length)) { - retainedSizes = mozilla::Nothing(); - return false; - } - - // Iterate in forward order so that we know all of a node's children in - // the dominator tree have already had their retained size - // computed. Then we can simply say that the retained size of a node is - // its shallow size (JS::ubi::Node::size) plus the retained sizes of its - // immediate children in the tree. - - for (uint32_t i = 0; i < length; i++) { - auto size = postOrder[i].size(mallocSizeOf); - - for (const auto& dominated : dominatedSets.dominatedSet(postOrder, i)) { - // The root node dominates itself, but shouldn't contribute to - // its own retained size. - if (dominated == postOrder[length - 1]) { - MOZ_ASSERT(i == length - 1); - continue; - } - - auto ptr = nodeToPostOrderIndex.lookup(dominated); - MOZ_ASSERT(ptr); - auto idxOfDominated = ptr->value(); - MOZ_ASSERT(idxOfDominated < i); - size += retainedSizes.ref()[idxOfDominated]; - } - - retainedSizes.ref()[i] = size; - } - - return true; - } - - public: - // DominatorTree is not copy-able. - DominatorTree(const DominatorTree&) = delete; - DominatorTree& operator=(const DominatorTree&) = delete; - - // DominatorTree is move-able. - DominatorTree(DominatorTree&& rhs) - : postOrder(mozilla::Move(rhs.postOrder)) - , nodeToPostOrderIndex(mozilla::Move(rhs.nodeToPostOrderIndex)) - , doms(mozilla::Move(rhs.doms)) - , dominatedSets(mozilla::Move(rhs.dominatedSets)) - , retainedSizes(mozilla::Move(rhs.retainedSizes)) - { - MOZ_ASSERT(this != &rhs, "self-move is not allowed"); - } - DominatorTree& operator=(DominatorTree&& rhs) { - this->~DominatorTree(); - new (this) DominatorTree(mozilla::Move(rhs)); - return *this; - } - - /** - * Construct a `DominatorTree` of the heap graph visible from `root`. The - * `root` is also used as the root of the resulting dominator tree. - * - * The resulting `DominatorTree` instance must not outlive the - * `JS::ubi::Node` graph it was constructed from. - * - * - For `JS::ubi::Node` graphs backed by the live heap graph, this means - * that the `DominatorTree`'s lifetime _must_ be contained within the - * scope of the provided `AutoCheckCannotGC` reference because a GC will - * invalidate the nodes. - * - * - For `JS::ubi::Node` graphs backed by some other offline structure - * provided by the embedder, the resulting `DominatorTree`'s lifetime is - * bounded by that offline structure's lifetime. - * - * In practice, this means that within SpiderMonkey we must treat - * `DominatorTree` as if it were backed by the live heap graph and trust - * that embedders with knowledge of the graph's implementation will do the - * Right Thing. - * - * Returns `mozilla::Nothing()` on OOM failure. It is the caller's - * responsibility to handle and report the OOM. - */ - static mozilla::Maybe - Create(JSContext* cx, AutoCheckCannotGC& noGC, const Node& root) { - JS::ubi::Vector postOrder; - PredecessorSets predecessorSets; - if (!predecessorSets.init() || !doTraversal(cx, noGC, root, postOrder, predecessorSets)) - return mozilla::Nothing(); - - MOZ_ASSERT(postOrder.length() < UINT32_MAX); - uint32_t length = postOrder.length(); - MOZ_ASSERT(postOrder[length - 1] == root); - - // From here on out we wish to avoid hash table lookups, and we use - // indices into `postOrder` instead of actual nodes wherever - // possible. This greatly improves the performance of this - // implementation, but we have to pay a little bit of upfront cost to - // convert our data structures to play along first. - - NodeToIndexMap nodeToPostOrderIndex; - if (!mapNodesToTheirIndices(postOrder, nodeToPostOrderIndex)) - return mozilla::Nothing(); - - JS::ubi::Vector> predecessorVectors; - if (!convertPredecessorSetsToVectors(root, postOrder, predecessorSets, nodeToPostOrderIndex, - predecessorVectors)) - return mozilla::Nothing(); - - JS::ubi::Vector doms; - if (!initializeDominators(doms, length)) - return mozilla::Nothing(); - - bool changed = true; - while (changed) { - changed = false; - - // Iterate over the non-root nodes in reverse post order. - for (uint32_t indexPlusOne = length - 1; indexPlusOne > 0; indexPlusOne--) { - MOZ_ASSERT(postOrder[indexPlusOne - 1] != root); - - // Take the intersection of every predecessor's dominator set; - // that is the current best guess at the immediate dominator for - // this node. - - uint32_t newIDomIdx = UNDEFINED; - - auto& predecessors = predecessorVectors[indexPlusOne - 1]; - auto range = predecessors.all(); - for ( ; !range.empty(); range.popFront()) { - auto idx = range.front(); - if (doms[idx] != UNDEFINED) { - newIDomIdx = idx; - break; - } - } - - MOZ_ASSERT(newIDomIdx != UNDEFINED, - "Because the root is initialized to dominate itself and is the first " - "node in every path, there must exist a predecessor to this node that " - "also has a dominator."); - - for ( ; !range.empty(); range.popFront()) { - auto idx = range.front(); - if (doms[idx] != UNDEFINED) - newIDomIdx = intersect(doms, newIDomIdx, idx); - } - - // If the immediate dominator changed, we will have to do - // another pass of the outer while loop to continue the forward - // dataflow. - if (newIDomIdx != doms[indexPlusOne - 1]) { - doms[indexPlusOne - 1] = newIDomIdx; - changed = true; - } - } - } - - auto maybeDominatedSets = DominatedSets::Create(doms); - if (maybeDominatedSets.isNothing()) - return mozilla::Nothing(); - - return mozilla::Some(DominatorTree(mozilla::Move(postOrder), - mozilla::Move(nodeToPostOrderIndex), - mozilla::Move(doms), - mozilla::Move(*maybeDominatedSets))); - } - - /** - * Get the root node for this dominator tree. - */ - const Node& root() const { - return postOrder[postOrder.length() - 1]; - } - - /** - * Return the immediate dominator of the given `node`. If `node` was not - * reachable from the `root` that this dominator tree was constructed from, - * then return the null `JS::ubi::Node`. - */ - Node getImmediateDominator(const Node& node) const { - assertSanity(); - auto ptr = nodeToPostOrderIndex.lookup(node); - if (!ptr) - return Node(); - - auto idx = ptr->value(); - MOZ_ASSERT(idx < postOrder.length()); - return postOrder[doms[idx]]; - } - - /** - * Get the set of nodes immediately dominated by the given `node`. If `node` - * is not a member of this dominator tree, return `Nothing`. - * - * Example usage: - * - * mozilla::Maybe range = myDominatorTree.getDominatedSet(myNode); - * if (range.isNothing()) { - * // Handle unknown node however you see fit... - * return false; - * } - * - * for (const JS::ubi::Node& dominatedNode : *range) { - * // Do something with each immediately dominated node... - * } - */ - mozilla::Maybe getDominatedSet(const Node& node) { - assertSanity(); - auto ptr = nodeToPostOrderIndex.lookup(node); - if (!ptr) - return mozilla::Nothing(); - - auto idx = ptr->value(); - MOZ_ASSERT(idx < postOrder.length()); - return mozilla::Some(dominatedSets.dominatedSet(postOrder, idx)); - } - - /** - * Get the retained size of the given `node`. The size is placed in - * `outSize`, or 0 if `node` is not a member of the dominator tree. Returns - * false on OOM failure, leaving `outSize` unchanged. - */ - MOZ_MUST_USE bool getRetainedSize(const Node& node, mozilla::MallocSizeOf mallocSizeOf, - Node::Size& outSize) { - assertSanity(); - auto ptr = nodeToPostOrderIndex.lookup(node); - if (!ptr) { - outSize = 0; - return true; - } - - if (retainedSizes.isNothing() && !computeRetainedSizes(mallocSizeOf)) - return false; - - auto idx = ptr->value(); - MOZ_ASSERT(idx < postOrder.length()); - outSize = retainedSizes.ref()[idx]; - return true; - } -}; - -} // namespace ubi -} // namespace JS - -#endif // js_UbiNodeDominatorTree_h diff --git a/android/x86/include/spidermonkey/js/UbiNodePostOrder.h b/android/x86/include/spidermonkey/js/UbiNodePostOrder.h deleted file mode 100644 index a5042677..00000000 --- a/android/x86/include/spidermonkey/js/UbiNodePostOrder.h +++ /dev/null @@ -1,191 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNodePostOrder_h -#define js_UbiNodePostOrder_h - -#include "mozilla/Attributes.h" -#include "mozilla/Maybe.h" -#include "mozilla/Move.h" - -#include "jsalloc.h" - -#include "js/UbiNode.h" -#include "js/Utility.h" -#include "js/Vector.h" - -namespace JS { -namespace ubi { - -/** - * A post-order depth-first traversal of `ubi::Node` graphs. - * - * No GC may occur while an instance of `PostOrder` is live. - * - * The `NodeVisitor` type provided to `PostOrder::traverse` must have the - * following member: - * - * bool operator()(Node& node) - * - * The node visitor method. This method is called once for each `node` - * reachable from the start set in post-order. - * - * This visitor function should return true on success, or false if an error - * occurs. A false return value terminates the traversal immediately, and - * causes `PostOrder::traverse` to return false. - * - * The `EdgeVisitor` type provided to `PostOrder::traverse` must have the - * following member: - * - * bool operator()(Node& origin, Edge& edge) - * - * The edge visitor method. This method is called once for each outgoing - * `edge` from `origin` that is reachable from the start set. - * - * NB: UNLIKE NODES, THERE IS NO GUARANTEED ORDER IN WHICH EDGES AND THEIR - * ORIGINS ARE VISITED! - * - * This visitor function should return true on success, or false if an error - * occurs. A false return value terminates the traversal immediately, and - * causes `PostOrder::traverse` to return false. - */ -struct PostOrder { - private: - struct OriginAndEdges { - Node origin; - EdgeVector edges; - - OriginAndEdges(const Node& node, EdgeVector&& edges) - : origin(node) - , edges(mozilla::Move(edges)) - { } - - OriginAndEdges(const OriginAndEdges& rhs) = delete; - OriginAndEdges& operator=(const OriginAndEdges& rhs) = delete; - - OriginAndEdges(OriginAndEdges&& rhs) - : origin(rhs.origin) - , edges(mozilla::Move(rhs.edges)) - { - MOZ_ASSERT(&rhs != this, "self-move disallowed"); - } - - OriginAndEdges& operator=(OriginAndEdges&& rhs) { - this->~OriginAndEdges(); - new (this) OriginAndEdges(mozilla::Move(rhs)); - return *this; - } - }; - - using Stack = js::Vector; - using Set = js::HashSet, js::SystemAllocPolicy>; - - JSContext* cx; - Set seen; - Stack stack; -#ifdef DEBUG - bool traversed; -#endif - - private: - MOZ_MUST_USE bool fillEdgesFromRange(EdgeVector& edges, js::UniquePtr& range) { - MOZ_ASSERT(range); - for ( ; !range->empty(); range->popFront()) { - if (!edges.append(mozilla::Move(range->front()))) - return false; - } - return true; - } - - MOZ_MUST_USE bool pushForTraversing(const Node& node) { - EdgeVector edges; - auto range = node.edges(cx, /* wantNames */ false); - return range && - fillEdgesFromRange(edges, range) && - stack.append(OriginAndEdges(node, mozilla::Move(edges))); - } - - - public: - // Construct a post-order traversal object. - // - // The traversal asserts that no GC happens in its runtime during its - // lifetime via the `AutoCheckCannotGC&` parameter. We do nothing with it, - // other than require it to exist with a lifetime that encloses our own. - PostOrder(JSContext* cx, AutoCheckCannotGC&) - : cx(cx) - , seen() - , stack() -#ifdef DEBUG - , traversed(false) -#endif - { } - - // Initialize this traversal object. Return false on OOM. - MOZ_MUST_USE bool init() { return seen.init(); } - - // Add `node` as a starting point for the traversal. You may add - // as many starting points as you like. Returns false on OOM. - MOZ_MUST_USE bool addStart(const Node& node) { - if (!seen.put(node)) - return false; - return pushForTraversing(node); - } - - // Traverse the graph in post-order, starting with the set of nodes passed - // to `addStart` and applying `onNode::operator()` for each node in the - // graph and `onEdge::operator()` for each edge in the graph, as described - // above. - // - // This should be called only once per instance of this class. - // - // Return false on OOM or error return from `onNode::operator()` or - // `onEdge::operator()`. - template - MOZ_MUST_USE bool traverse(NodeVisitor onNode, EdgeVisitor onEdge) { -#ifdef DEBUG - MOZ_ASSERT(!traversed, "Can only traverse() once!"); - traversed = true; -#endif - - while (!stack.empty()) { - auto& origin = stack.back().origin; - auto& edges = stack.back().edges; - - if (edges.empty()) { - if (!onNode(origin)) - return false; - stack.popBack(); - continue; - } - - Edge edge = mozilla::Move(edges.back()); - edges.popBack(); - - if (!onEdge(origin, edge)) - return false; - - auto ptr = seen.lookupForAdd(edge.referent); - // We've already seen this node, don't follow its edges. - if (ptr) - continue; - - // Mark the referent as seen and follow its edges. - if (!seen.add(ptr, edge.referent) || - !pushForTraversing(edge.referent)) - { - return false; - } - } - - return true; - } -}; - -} // namespace ubi -} // namespace JS - -#endif // js_UbiNodePostOrder_h diff --git a/android/x86/include/spidermonkey/js/UbiNodeShortestPaths.h b/android/x86/include/spidermonkey/js/UbiNodeShortestPaths.h deleted file mode 100644 index edd5aebb..00000000 --- a/android/x86/include/spidermonkey/js/UbiNodeShortestPaths.h +++ /dev/null @@ -1,350 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UbiNodeShortestPaths_h -#define js_UbiNodeShortestPaths_h - -#include "mozilla/Attributes.h" -#include "mozilla/Maybe.h" -#include "mozilla/Move.h" - -#include "jsalloc.h" - -#include "js/UbiNodeBreadthFirst.h" -#include "js/Vector.h" - -namespace JS { -namespace ubi { - -/** - * A back edge along a path in the heap graph. - */ -struct JS_PUBLIC_API(BackEdge) -{ - private: - Node predecessor_; - EdgeName name_; - - public: - using Ptr = mozilla::UniquePtr>; - - BackEdge() : predecessor_(), name_(nullptr) { } - - MOZ_MUST_USE bool init(const Node& predecessor, Edge& edge) { - MOZ_ASSERT(!predecessor_); - MOZ_ASSERT(!name_); - - predecessor_ = predecessor; - name_ = mozilla::Move(edge.name); - return true; - } - - BackEdge(const BackEdge&) = delete; - BackEdge& operator=(const BackEdge&) = delete; - - BackEdge(BackEdge&& rhs) - : predecessor_(rhs.predecessor_) - , name_(mozilla::Move(rhs.name_)) - { - MOZ_ASSERT(&rhs != this); - } - - BackEdge& operator=(BackEdge&& rhs) { - this->~BackEdge(); - new(this) BackEdge(Move(rhs)); - return *this; - } - - Ptr clone() const; - - const EdgeName& name() const { return name_; } - EdgeName& name() { return name_; } - - const JS::ubi::Node& predecessor() const { return predecessor_; } -}; - -/** - * A path is a series of back edges from which we discovered a target node. - */ -using Path = JS::ubi::Vector; - -/** - * The `JS::ubi::ShortestPaths` type represents a collection of up to N shortest - * retaining paths for each of a target set of nodes, starting from the same - * root node. - */ -struct JS_PUBLIC_API(ShortestPaths) -{ - private: - // Types, type aliases, and data members. - - using BackEdgeVector = JS::ubi::Vector; - using NodeToBackEdgeVectorMap = js::HashMap, - js::SystemAllocPolicy>; - - struct Handler; - using Traversal = BreadthFirst; - - /** - * A `JS::ubi::BreadthFirst` traversal handler that records back edges for - * how we reached each node, allowing us to reconstruct the shortest - * retaining paths after the traversal. - */ - struct Handler - { - using NodeData = BackEdge; - - ShortestPaths& shortestPaths; - size_t totalMaxPathsToRecord; - size_t totalPathsRecorded; - - explicit Handler(ShortestPaths& shortestPaths) - : shortestPaths(shortestPaths) - , totalMaxPathsToRecord(shortestPaths.targets_.count() * shortestPaths.maxNumPaths_) - , totalPathsRecorded(0) - { - } - - bool - operator()(Traversal& traversal, JS::ubi::Node origin, JS::ubi::Edge& edge, - BackEdge* back, bool first) - { - MOZ_ASSERT(back); - MOZ_ASSERT(origin == shortestPaths.root_ || traversal.visited.has(origin)); - MOZ_ASSERT(totalPathsRecorded < totalMaxPathsToRecord); - - if (first && !back->init(origin, edge)) - return false; - - if (!shortestPaths.targets_.has(edge.referent)) - return true; - - // If `first` is true, then we moved the edge's name into `back` in - // the above call to `init`. So clone that back edge to get the - // correct edge name. If `first` is not true, then our edge name is - // still in `edge`. This accounts for the asymmetry between - // `back->clone()` in the first branch, and the `init` call in the - // second branch. - - if (first) { - BackEdgeVector paths; - if (!paths.reserve(shortestPaths.maxNumPaths_)) - return false; - auto cloned = back->clone(); - if (!cloned) - return false; - paths.infallibleAppend(mozilla::Move(cloned)); - if (!shortestPaths.paths_.putNew(edge.referent, mozilla::Move(paths))) - return false; - totalPathsRecorded++; - } else { - auto ptr = shortestPaths.paths_.lookup(edge.referent); - MOZ_ASSERT(ptr, - "This isn't the first time we have seen the target node `edge.referent`. " - "We should have inserted it into shortestPaths.paths_ the first time we " - "saw it."); - - if (ptr->value().length() < shortestPaths.maxNumPaths_) { - BackEdge::Ptr thisBackEdge(js_new()); - if (!thisBackEdge || !thisBackEdge->init(origin, edge)) - return false; - ptr->value().infallibleAppend(mozilla::Move(thisBackEdge)); - totalPathsRecorded++; - } - } - - MOZ_ASSERT(totalPathsRecorded <= totalMaxPathsToRecord); - if (totalPathsRecorded == totalMaxPathsToRecord) - traversal.stop(); - - return true; - } - - }; - - // The maximum number of paths to record for each node. - uint32_t maxNumPaths_; - - // The root node we are starting the search from. - Node root_; - - // The set of nodes we are searching for paths to. - NodeSet targets_; - - // The resulting paths. - NodeToBackEdgeVectorMap paths_; - - // Need to keep alive the traversal's back edges so we can walk them later - // when the traversal is over when recreating the shortest paths. - Traversal::NodeMap backEdges_; - - private: - // Private methods. - - ShortestPaths(uint32_t maxNumPaths, const Node& root, NodeSet&& targets) - : maxNumPaths_(maxNumPaths) - , root_(root) - , targets_(mozilla::Move(targets)) - , paths_() - , backEdges_() - { - MOZ_ASSERT(maxNumPaths_ > 0); - MOZ_ASSERT(root_); - MOZ_ASSERT(targets_.initialized()); - } - - bool initialized() const { - return targets_.initialized() && - paths_.initialized() && - backEdges_.initialized(); - } - - public: - // Public methods. - - ShortestPaths(ShortestPaths&& rhs) - : maxNumPaths_(rhs.maxNumPaths_) - , root_(rhs.root_) - , targets_(mozilla::Move(rhs.targets_)) - , paths_(mozilla::Move(rhs.paths_)) - , backEdges_(mozilla::Move(rhs.backEdges_)) - { - MOZ_ASSERT(this != &rhs, "self-move is not allowed"); - } - - ShortestPaths& operator=(ShortestPaths&& rhs) { - this->~ShortestPaths(); - new (this) ShortestPaths(mozilla::Move(rhs)); - return *this; - } - - ShortestPaths(const ShortestPaths&) = delete; - ShortestPaths& operator=(const ShortestPaths&) = delete; - - /** - * Construct a new `JS::ubi::ShortestPaths`, finding up to `maxNumPaths` - * shortest retaining paths for each target node in `targets` starting from - * `root`. - * - * The resulting `ShortestPaths` instance must not outlive the - * `JS::ubi::Node` graph it was constructed from. - * - * - For `JS::ubi::Node` graphs backed by the live heap graph, this means - * that the `ShortestPaths`'s lifetime _must_ be contained within the - * scope of the provided `AutoCheckCannotGC` reference because a GC will - * invalidate the nodes. - * - * - For `JS::ubi::Node` graphs backed by some other offline structure - * provided by the embedder, the resulting `ShortestPaths`'s lifetime is - * bounded by that offline structure's lifetime. - * - * Returns `mozilla::Nothing()` on OOM failure. It is the caller's - * responsibility to handle and report the OOM. - */ - static mozilla::Maybe - Create(JSContext* cx, AutoCheckCannotGC& noGC, uint32_t maxNumPaths, const Node& root, NodeSet&& targets) { - MOZ_ASSERT(targets.count() > 0); - MOZ_ASSERT(maxNumPaths > 0); - - size_t count = targets.count(); - ShortestPaths paths(maxNumPaths, root, mozilla::Move(targets)); - if (!paths.paths_.init(count)) - return mozilla::Nothing(); - - Handler handler(paths); - Traversal traversal(cx, handler, noGC); - traversal.wantNames = true; - if (!traversal.init() || !traversal.addStart(root) || !traversal.traverse()) - return mozilla::Nothing(); - - // Take ownership of the back edges we created while traversing the - // graph so that we can follow them from `paths_` and don't - // use-after-free. - paths.backEdges_ = mozilla::Move(traversal.visited); - - MOZ_ASSERT(paths.initialized()); - return mozilla::Some(mozilla::Move(paths)); - } - - /** - * Get a range that iterates over each target node we searched for retaining - * paths for. The returned range must not outlive the `ShortestPaths` - * instance. - */ - NodeSet::Range eachTarget() const { - MOZ_ASSERT(initialized()); - return targets_.all(); - } - - /** - * Invoke the provided functor/lambda/callable once for each retaining path - * discovered for `target`. The `func` is passed a single `JS::ubi::Path&` - * argument, which contains each edge along the path ordered starting from - * the root and ending at the target, and must not outlive the scope of the - * call. - * - * Note that it is possible that we did not find any paths from the root to - * the given target, in which case `func` will not be invoked. - */ - template - MOZ_MUST_USE bool forEachPath(const Node& target, Func func) { - MOZ_ASSERT(initialized()); - MOZ_ASSERT(targets_.has(target)); - - auto ptr = paths_.lookup(target); - - // We didn't find any paths to this target, so nothing to do here. - if (!ptr) - return true; - - MOZ_ASSERT(ptr->value().length() <= maxNumPaths_); - - Path path; - for (const auto& backEdge : ptr->value()) { - path.clear(); - - if (!path.append(backEdge.get())) - return false; - - Node here = backEdge->predecessor(); - MOZ_ASSERT(here); - - while (here != root_) { - auto p = backEdges_.lookup(here); - MOZ_ASSERT(p); - if (!path.append(&p->value())) - return false; - here = p->value().predecessor(); - MOZ_ASSERT(here); - } - - path.reverse(); - - if (!func(path)) - return false; - } - - return true; - } -}; - -#ifdef DEBUG -// A helper function to dump the first `maxNumPaths` shortest retaining paths to -// `node` from the GC roots. Useful when GC things you expect to have been -// reclaimed by the collector haven't been! -// -// Usage: -// -// JSObject* foo = ...; -// JS::ubi::dumpPaths(rt, JS::ubi::Node(foo)); -JS_PUBLIC_API(void) -dumpPaths(JSRuntime* rt, Node node, uint32_t maxNumPaths = 10); -#endif - -} // namespace ubi -} // namespace JS - -#endif // js_UbiNodeShortestPaths_h diff --git a/android/x86/include/spidermonkey/js/UniquePtr.h b/android/x86/include/spidermonkey/js/UniquePtr.h deleted file mode 100644 index 0236bab4..00000000 --- a/android/x86/include/spidermonkey/js/UniquePtr.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_UniquePtr_h -#define js_UniquePtr_h - -#include "mozilla/UniquePtr.h" - -#include "js/Utility.h" - -namespace js { - -// Replacement for mozilla::UniquePtr that defaults to js::DefaultDelete. -template > -using UniquePtr = mozilla::UniquePtr; - -namespace detail { - -template -struct UniqueSelector -{ - typedef UniquePtr SingleObject; -}; - -template -struct UniqueSelector -{ - typedef UniquePtr UnknownBound; -}; - -template -struct UniqueSelector -{ - typedef UniquePtr KnownBound; -}; - -} // namespace detail - -// Replacement for mozilla::MakeUnique that correctly calls js_new and produces -// a js::UniquePtr. -template -typename detail::UniqueSelector::SingleObject -MakeUnique(Args&&... aArgs) -{ - return UniquePtr(js_new(mozilla::Forward(aArgs)...)); -} - -template -typename detail::UniqueSelector::UnknownBound -MakeUnique(decltype(sizeof(int)) aN) = delete; - -template -typename detail::UniqueSelector::KnownBound -MakeUnique(Args&&... aArgs) = delete; - -} // namespace js - -#endif /* js_UniquePtr_h */ diff --git a/android/x86/include/spidermonkey/js/Utility.h b/android/x86/include/spidermonkey/js/Utility.h deleted file mode 100644 index 75214c32..00000000 --- a/android/x86/include/spidermonkey/js/Utility.h +++ /dev/null @@ -1,577 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_Utility_h -#define js_Utility_h - -#include "mozilla/Assertions.h" -#include "mozilla/Atomics.h" -#include "mozilla/Attributes.h" -#include "mozilla/Compiler.h" -#include "mozilla/Move.h" -#include "mozilla/Scoped.h" -#include "mozilla/TemplateLib.h" -#include "mozilla/UniquePtr.h" - -#include -#include - -#ifdef JS_OOM_DO_BACKTRACES -#include -#include -#endif - -#include "jstypes.h" - -/* The public JS engine namespace. */ -namespace JS {} - -/* The mozilla-shared reusable template/utility namespace. */ -namespace mozilla {} - -/* The private JS engine namespace. */ -namespace js {} - -#define JS_STATIC_ASSERT(cond) static_assert(cond, "JS_STATIC_ASSERT") -#define JS_STATIC_ASSERT_IF(cond, expr) MOZ_STATIC_ASSERT_IF(cond, expr, "JS_STATIC_ASSERT_IF") - -extern MOZ_NORETURN MOZ_COLD JS_PUBLIC_API(void) -JS_Assert(const char* s, const char* file, int ln); - -/* - * Custom allocator support for SpiderMonkey - */ -#if defined JS_USE_CUSTOM_ALLOCATOR -# include "jscustomallocator.h" -#else - -namespace js { -namespace oom { - -/* - * To make testing OOM in certain helper threads more effective, - * allow restricting the OOM testing to a certain helper thread - * type. This allows us to fail e.g. in off-thread script parsing - * without causing an OOM in the main thread first. - */ -enum ThreadType { - THREAD_TYPE_NONE = 0, // 0 - THREAD_TYPE_MAIN, // 1 - THREAD_TYPE_ASMJS, // 2 - THREAD_TYPE_ION, // 3 - THREAD_TYPE_PARSE, // 4 - THREAD_TYPE_COMPRESS, // 5 - THREAD_TYPE_GCHELPER, // 6 - THREAD_TYPE_GCPARALLEL, // 7 - THREAD_TYPE_PROMISE_TASK, // 8 - THREAD_TYPE_MAX // Used to check shell function arguments -}; - -/* - * Getter/Setter functions to encapsulate mozilla::ThreadLocal, - * implementation is in jsutil.cpp. - */ -# if defined(DEBUG) || defined(JS_OOM_BREAKPOINT) -extern bool InitThreadType(void); -extern void SetThreadType(ThreadType); -extern uint32_t GetThreadType(void); -# else -inline bool InitThreadType(void) { return true; } -inline void SetThreadType(ThreadType t) {}; -inline uint32_t GetThreadType(void) { return 0; } -# endif - -} /* namespace oom */ -} /* namespace js */ - -# if defined(DEBUG) || defined(JS_OOM_BREAKPOINT) - -#ifdef JS_OOM_BREAKPOINT -static MOZ_NEVER_INLINE void js_failedAllocBreakpoint() { asm(""); } -#define JS_OOM_CALL_BP_FUNC() js_failedAllocBreakpoint() -#else -#define JS_OOM_CALL_BP_FUNC() do {} while(0) -#endif - -namespace js { -namespace oom { - -/* - * Out of memory testing support. We provide various testing functions to - * simulate OOM conditions and so we can test that they are handled correctly. - */ - -extern JS_PUBLIC_DATA(uint32_t) targetThread; -extern JS_PUBLIC_DATA(uint64_t) maxAllocations; -extern JS_PUBLIC_DATA(uint64_t) counter; -extern JS_PUBLIC_DATA(bool) failAlways; - -extern void -SimulateOOMAfter(uint64_t allocations, uint32_t thread, bool always); - -extern void -ResetSimulatedOOM(); - -inline bool -IsThreadSimulatingOOM() -{ - return js::oom::targetThread && js::oom::targetThread == js::oom::GetThreadType(); -} - -inline bool -IsSimulatedOOMAllocation() -{ - return IsThreadSimulatingOOM() && - (counter == maxAllocations || (counter > maxAllocations && failAlways)); -} - -inline bool -ShouldFailWithOOM() -{ - if (!IsThreadSimulatingOOM()) - return false; - - counter++; - if (IsSimulatedOOMAllocation()) { - JS_OOM_CALL_BP_FUNC(); - return true; - } - return false; -} - -inline bool -HadSimulatedOOM() { - return counter >= maxAllocations; -} - -} /* namespace oom */ -} /* namespace js */ - -# define JS_OOM_POSSIBLY_FAIL() \ - do { \ - if (js::oom::ShouldFailWithOOM()) \ - return nullptr; \ - } while (0) - -# define JS_OOM_POSSIBLY_FAIL_BOOL() \ - do { \ - if (js::oom::ShouldFailWithOOM()) \ - return false; \ - } while (0) - -# else - -# define JS_OOM_POSSIBLY_FAIL() do {} while(0) -# define JS_OOM_POSSIBLY_FAIL_BOOL() do {} while(0) -namespace js { -namespace oom { -static inline bool IsSimulatedOOMAllocation() { return false; } -static inline bool ShouldFailWithOOM() { return false; } -} /* namespace oom */ -} /* namespace js */ - -# endif /* DEBUG || JS_OOM_BREAKPOINT */ - -namespace js { - -/* Disable OOM testing in sections which are not OOM safe. */ -struct MOZ_RAII AutoEnterOOMUnsafeRegion -{ - MOZ_NORETURN MOZ_COLD void crash(const char* reason); - MOZ_NORETURN MOZ_COLD void crash(size_t size, const char* reason); - - using AnnotateOOMAllocationSizeCallback = void(*)(size_t); - static AnnotateOOMAllocationSizeCallback annotateOOMSizeCallback; - static void setAnnotateOOMAllocationSizeCallback(AnnotateOOMAllocationSizeCallback callback) { - annotateOOMSizeCallback = callback; - } - -#if defined(DEBUG) || defined(JS_OOM_BREAKPOINT) - AutoEnterOOMUnsafeRegion() - : oomEnabled_(oom::IsThreadSimulatingOOM() && oom::maxAllocations != UINT64_MAX), - oomAfter_(0) - { - if (oomEnabled_) { - MOZ_ALWAYS_TRUE(owner_.compareExchange(nullptr, this)); - oomAfter_ = int64_t(oom::maxAllocations) - int64_t(oom::counter); - oom::maxAllocations = UINT64_MAX; - } - } - - ~AutoEnterOOMUnsafeRegion() { - if (oomEnabled_) { - MOZ_ASSERT(oom::maxAllocations == UINT64_MAX); - int64_t maxAllocations = int64_t(oom::counter) + oomAfter_; - MOZ_ASSERT(maxAllocations >= 0, - "alloc count + oom limit exceeds range, your oom limit is probably too large"); - oom::maxAllocations = uint64_t(maxAllocations); - MOZ_ALWAYS_TRUE(owner_.compareExchange(this, nullptr)); - } - } - - private: - // Used to catch concurrent use from other threads. - static mozilla::Atomic owner_; - - bool oomEnabled_; - int64_t oomAfter_; -#endif -}; - -} /* namespace js */ - -static inline void* js_malloc(size_t bytes) -{ - JS_OOM_POSSIBLY_FAIL(); - return malloc(bytes); -} - -static inline void* js_calloc(size_t bytes) -{ - JS_OOM_POSSIBLY_FAIL(); - return calloc(bytes, 1); -} - -static inline void* js_calloc(size_t nmemb, size_t size) -{ - JS_OOM_POSSIBLY_FAIL(); - return calloc(nmemb, size); -} - -static inline void* js_realloc(void* p, size_t bytes) -{ - // realloc() with zero size is not portable, as some implementations may - // return nullptr on success and free |p| for this. We assume nullptr - // indicates failure and that |p| is still valid. - MOZ_ASSERT(bytes != 0); - - JS_OOM_POSSIBLY_FAIL(); - return realloc(p, bytes); -} - -static inline void js_free(void* p) -{ - free(p); -} - -static inline char* js_strdup(const char* s) -{ - JS_OOM_POSSIBLY_FAIL(); - return strdup(s); -} -#endif/* JS_USE_CUSTOM_ALLOCATOR */ - -#include - -/* - * Low-level memory management in SpiderMonkey: - * - * ** Do not use the standard malloc/free/realloc: SpiderMonkey allows these - * to be redefined (via JS_USE_CUSTOM_ALLOCATOR) and Gecko even #define's - * these symbols. - * - * ** Do not use the builtin C++ operator new and delete: these throw on - * error and we cannot override them not to. - * - * Allocation: - * - * - If the lifetime of the allocation is tied to the lifetime of a GC-thing - * (that is, finalizing the GC-thing will free the allocation), call one of - * the following functions: - * - * JSContext::{malloc_,realloc_,calloc_,new_} - * JSRuntime::{malloc_,realloc_,calloc_,new_} - * - * These functions accumulate the number of bytes allocated which is used as - * part of the GC-triggering heuristic. - * - * The difference between the JSContext and JSRuntime versions is that the - * cx version reports an out-of-memory error on OOM. (This follows from the - * general SpiderMonkey idiom that a JSContext-taking function reports its - * own errors.) - * - * - Otherwise, use js_malloc/js_realloc/js_calloc/js_new - * - * Deallocation: - * - * - Ordinarily, use js_free/js_delete. - * - * - For deallocations during GC finalization, use one of the following - * operations on the FreeOp provided to the finalizer: - * - * FreeOp::{free_,delete_} - * - * The advantage of these operations is that the memory is batched and freed - * on another thread. - */ - -/* - * Given a class which should provide a 'new' method, add - * JS_DECLARE_NEW_METHODS (see js::MallocProvider for an example). - * - * Note: Do not add a ; at the end of a use of JS_DECLARE_NEW_METHODS, - * or the build will break. - */ -#define JS_DECLARE_NEW_METHODS(NEWNAME, ALLOCATOR, QUALIFIERS) \ - template \ - QUALIFIERS T * \ - NEWNAME(Args&&... args) MOZ_HEAP_ALLOCATOR { \ - void* memory = ALLOCATOR(sizeof(T)); \ - return MOZ_LIKELY(memory) \ - ? new(memory) T(mozilla::Forward(args)...) \ - : nullptr; \ - } - -/* - * Given a class which should provide 'make' methods, add - * JS_DECLARE_MAKE_METHODS (see js::MallocProvider for an example). This - * method is functionally the same as JS_DECLARE_NEW_METHODS: it just declares - * methods that return mozilla::UniquePtr instances that will singly-manage - * ownership of the created object. - * - * Note: Do not add a ; at the end of a use of JS_DECLARE_MAKE_METHODS, - * or the build will break. - */ -#define JS_DECLARE_MAKE_METHODS(MAKENAME, NEWNAME, QUALIFIERS)\ - template \ - QUALIFIERS mozilla::UniquePtr> \ - MAKENAME(Args&&... args) MOZ_HEAP_ALLOCATOR { \ - T* ptr = NEWNAME(mozilla::Forward(args)...); \ - return mozilla::UniquePtr>(ptr); \ - } - -JS_DECLARE_NEW_METHODS(js_new, js_malloc, static MOZ_ALWAYS_INLINE) - -namespace js { - -/* - * Calculate the number of bytes needed to allocate |numElems| contiguous - * instances of type |T|. Return false if the calculation overflowed. - */ -template -MOZ_MUST_USE inline bool -CalculateAllocSize(size_t numElems, size_t* bytesOut) -{ - *bytesOut = numElems * sizeof(T); - return (numElems & mozilla::tl::MulOverflowMask::value) == 0; -} - -/* - * Calculate the number of bytes needed to allocate a single instance of type - * |T| followed by |numExtra| contiguous instances of type |Extra|. Return - * false if the calculation overflowed. - */ -template -MOZ_MUST_USE inline bool -CalculateAllocSizeWithExtra(size_t numExtra, size_t* bytesOut) -{ - *bytesOut = sizeof(T) + numExtra * sizeof(Extra); - return (numExtra & mozilla::tl::MulOverflowMask::value) == 0 && - *bytesOut >= sizeof(T); -} - -} /* namespace js */ - -template -static MOZ_ALWAYS_INLINE void -js_delete(const T* p) -{ - if (p) { - p->~T(); - js_free(const_cast(p)); - } -} - -template -static MOZ_ALWAYS_INLINE void -js_delete_poison(const T* p) -{ - if (p) { - p->~T(); - memset(const_cast(p), 0x3B, sizeof(T)); - js_free(const_cast(p)); - } -} - -template -static MOZ_ALWAYS_INLINE T* -js_pod_malloc() -{ - return static_cast(js_malloc(sizeof(T))); -} - -template -static MOZ_ALWAYS_INLINE T* -js_pod_calloc() -{ - return static_cast(js_calloc(sizeof(T))); -} - -template -static MOZ_ALWAYS_INLINE T* -js_pod_malloc(size_t numElems) -{ - size_t bytes; - if (MOZ_UNLIKELY(!js::CalculateAllocSize(numElems, &bytes))) - return nullptr; - return static_cast(js_malloc(bytes)); -} - -template -static MOZ_ALWAYS_INLINE T* -js_pod_calloc(size_t numElems) -{ - size_t bytes; - if (MOZ_UNLIKELY(!js::CalculateAllocSize(numElems, &bytes))) - return nullptr; - return static_cast(js_calloc(bytes)); -} - -template -static MOZ_ALWAYS_INLINE T* -js_pod_realloc(T* prior, size_t oldSize, size_t newSize) -{ - MOZ_ASSERT(!(oldSize & mozilla::tl::MulOverflowMask::value)); - size_t bytes; - if (MOZ_UNLIKELY(!js::CalculateAllocSize(newSize, &bytes))) - return nullptr; - return static_cast(js_realloc(prior, bytes)); -} - -namespace js { - -template -struct ScopedFreePtrTraits -{ - typedef T* type; - static T* empty() { return nullptr; } - static void release(T* ptr) { js_free(ptr); } -}; -SCOPED_TEMPLATE(ScopedJSFreePtr, ScopedFreePtrTraits) - -template -struct ScopedDeletePtrTraits : public ScopedFreePtrTraits -{ - static void release(T* ptr) { js_delete(ptr); } -}; -SCOPED_TEMPLATE(ScopedJSDeletePtr, ScopedDeletePtrTraits) - -template -struct ScopedReleasePtrTraits : public ScopedFreePtrTraits -{ - static void release(T* ptr) { if (ptr) ptr->release(); } -}; -SCOPED_TEMPLATE(ScopedReleasePtr, ScopedReleasePtrTraits) - -} /* namespace js */ - -namespace JS { - -template -struct DeletePolicy -{ - constexpr DeletePolicy() {} - - template - MOZ_IMPLICIT DeletePolicy(DeletePolicy other, - typename mozilla::EnableIf::value, - int>::Type dummy = 0) - {} - - void operator()(const T* ptr) { - js_delete(const_cast(ptr)); - } -}; - -struct FreePolicy -{ - void operator()(const void* ptr) { - js_free(const_cast(ptr)); - } -}; - -typedef mozilla::UniquePtr UniqueChars; -typedef mozilla::UniquePtr UniqueTwoByteChars; - -} // namespace JS - -namespace js { - -/* Integral types for all hash functions. */ -typedef uint32_t HashNumber; -const unsigned HashNumberSizeBits = 32; - -namespace detail { - -/* - * Given a raw hash code, h, return a number that can be used to select a hash - * bucket. - * - * This function aims to produce as uniform an output distribution as possible, - * especially in the most significant (leftmost) bits, even though the input - * distribution may be highly nonrandom, given the constraints that this must - * be deterministic and quick to compute. - * - * Since the leftmost bits of the result are best, the hash bucket index is - * computed by doing ScrambleHashCode(h) / (2^32/N) or the equivalent - * right-shift, not ScrambleHashCode(h) % N or the equivalent bit-mask. - * - * FIXME: OrderedHashTable uses a bit-mask; see bug 775896. - */ -inline HashNumber -ScrambleHashCode(HashNumber h) -{ - /* - * Simply returning h would not cause any hash tables to produce wrong - * answers. But it can produce pathologically bad performance: The caller - * right-shifts the result, keeping only the highest bits. The high bits of - * hash codes are very often completely entropy-free. (So are the lowest - * bits.) - * - * So we use Fibonacci hashing, as described in Knuth, The Art of Computer - * Programming, 6.4. This mixes all the bits of the input hash code h. - * - * The value of goldenRatio is taken from the hex - * expansion of the golden ratio, which starts 1.9E3779B9.... - * This value is especially good if values with consecutive hash codes - * are stored in a hash table; see Knuth for details. - */ - static const HashNumber goldenRatio = 0x9E3779B9U; - return h * goldenRatio; -} - -} /* namespace detail */ - -} /* namespace js */ - -/* sixgill annotation defines */ -#ifndef HAVE_STATIC_ANNOTATIONS -# define HAVE_STATIC_ANNOTATIONS -# ifdef XGILL_PLUGIN -# define STATIC_PRECONDITION(COND) __attribute__((precondition(#COND))) -# define STATIC_PRECONDITION_ASSUME(COND) __attribute__((precondition_assume(#COND))) -# define STATIC_POSTCONDITION(COND) __attribute__((postcondition(#COND))) -# define STATIC_POSTCONDITION_ASSUME(COND) __attribute__((postcondition_assume(#COND))) -# define STATIC_INVARIANT(COND) __attribute__((invariant(#COND))) -# define STATIC_INVARIANT_ASSUME(COND) __attribute__((invariant_assume(#COND))) -# define STATIC_ASSUME(COND) \ - JS_BEGIN_MACRO \ - __attribute__((assume_static(#COND), unused)) \ - int STATIC_PASTE1(assume_static_, __COUNTER__); \ - JS_END_MACRO -# else /* XGILL_PLUGIN */ -# define STATIC_PRECONDITION(COND) /* nothing */ -# define STATIC_PRECONDITION_ASSUME(COND) /* nothing */ -# define STATIC_POSTCONDITION(COND) /* nothing */ -# define STATIC_POSTCONDITION_ASSUME(COND) /* nothing */ -# define STATIC_INVARIANT(COND) /* nothing */ -# define STATIC_INVARIANT_ASSUME(COND) /* nothing */ -# define STATIC_ASSUME(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO -# endif /* XGILL_PLUGIN */ -# define STATIC_SKIP_INFERENCE STATIC_INVARIANT(skip_inference()) -#endif /* HAVE_STATIC_ANNOTATIONS */ - -#endif /* js_Utility_h */ diff --git a/android/x86/include/spidermonkey/js/Value.h b/android/x86/include/spidermonkey/js/Value.h deleted file mode 100644 index 00fdad58..00000000 --- a/android/x86/include/spidermonkey/js/Value.h +++ /dev/null @@ -1,1509 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* JS::Value implementation. */ - -#ifndef js_Value_h -#define js_Value_h - -#include "mozilla/Attributes.h" -#include "mozilla/Casting.h" -#include "mozilla/FloatingPoint.h" -#include "mozilla/Likely.h" - -#include /* for std::numeric_limits */ - -#include "js-config.h" -#include "jstypes.h" - -#include "js/GCAPI.h" -#include "js/RootingAPI.h" -#include "js/Utility.h" - -namespace JS { class Value; } - -/* JS::Value can store a full int32_t. */ -#define JSVAL_INT_BITS 32 -#define JSVAL_INT_MIN ((int32_t)0x80000000) -#define JSVAL_INT_MAX ((int32_t)0x7fffffff) - -#if defined(JS_PUNBOX64) -# define JSVAL_TAG_SHIFT 47 -#endif - -// Use enums so that printing a JS::Value in the debugger shows nice -// symbolic type tags. - -#if defined(_MSC_VER) -# define JS_ENUM_HEADER(id, type) enum id : type -# define JS_ENUM_FOOTER(id) -#else -# define JS_ENUM_HEADER(id, type) enum id -# define JS_ENUM_FOOTER(id) __attribute__((packed)) -#endif - -/* Remember to propagate changes to the C defines below. */ -JS_ENUM_HEADER(JSValueType, uint8_t) -{ - JSVAL_TYPE_DOUBLE = 0x00, - JSVAL_TYPE_INT32 = 0x01, - JSVAL_TYPE_UNDEFINED = 0x02, - JSVAL_TYPE_BOOLEAN = 0x03, - JSVAL_TYPE_MAGIC = 0x04, - JSVAL_TYPE_STRING = 0x05, - JSVAL_TYPE_SYMBOL = 0x06, - JSVAL_TYPE_PRIVATE_GCTHING = 0x07, - JSVAL_TYPE_NULL = 0x08, - JSVAL_TYPE_OBJECT = 0x0c, - - /* These never appear in a jsval; they are only provided as an out-of-band value. */ - JSVAL_TYPE_UNKNOWN = 0x20, - JSVAL_TYPE_MISSING = 0x21 -} JS_ENUM_FOOTER(JSValueType); - -static_assert(sizeof(JSValueType) == 1, - "compiler typed enum support is apparently buggy"); - -#if defined(JS_NUNBOX32) - -/* Remember to propagate changes to the C defines below. */ -JS_ENUM_HEADER(JSValueTag, uint32_t) -{ - JSVAL_TAG_CLEAR = 0xFFFFFF80, - JSVAL_TAG_INT32 = JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32, - JSVAL_TAG_UNDEFINED = JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED, - JSVAL_TAG_STRING = JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING, - JSVAL_TAG_SYMBOL = JSVAL_TAG_CLEAR | JSVAL_TYPE_SYMBOL, - JSVAL_TAG_BOOLEAN = JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN, - JSVAL_TAG_MAGIC = JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC, - JSVAL_TAG_NULL = JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL, - JSVAL_TAG_OBJECT = JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT, - JSVAL_TAG_PRIVATE_GCTHING = JSVAL_TAG_CLEAR | JSVAL_TYPE_PRIVATE_GCTHING -} JS_ENUM_FOOTER(JSValueTag); - -static_assert(sizeof(JSValueTag) == sizeof(uint32_t), - "compiler typed enum support is apparently buggy"); - -#elif defined(JS_PUNBOX64) - -/* Remember to propagate changes to the C defines below. */ -JS_ENUM_HEADER(JSValueTag, uint32_t) -{ - JSVAL_TAG_MAX_DOUBLE = 0x1FFF0, - JSVAL_TAG_INT32 = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_INT32, - JSVAL_TAG_UNDEFINED = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_UNDEFINED, - JSVAL_TAG_STRING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_STRING, - JSVAL_TAG_SYMBOL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_SYMBOL, - JSVAL_TAG_BOOLEAN = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN, - JSVAL_TAG_MAGIC = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC, - JSVAL_TAG_NULL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL, - JSVAL_TAG_OBJECT = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT, - JSVAL_TAG_PRIVATE_GCTHING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_PRIVATE_GCTHING -} JS_ENUM_FOOTER(JSValueTag); - -static_assert(sizeof(JSValueTag) == sizeof(uint32_t), - "compiler typed enum support is apparently buggy"); - -JS_ENUM_HEADER(JSValueShiftedTag, uint64_t) -{ - JSVAL_SHIFTED_TAG_MAX_DOUBLE = ((((uint64_t)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF), - JSVAL_SHIFTED_TAG_INT32 = (((uint64_t)JSVAL_TAG_INT32) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_UNDEFINED = (((uint64_t)JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_STRING = (((uint64_t)JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_SYMBOL = (((uint64_t)JSVAL_TAG_SYMBOL) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_BOOLEAN = (((uint64_t)JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_MAGIC = (((uint64_t)JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_NULL = (((uint64_t)JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_OBJECT = (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_PRIVATE_GCTHING = (((uint64_t)JSVAL_TAG_PRIVATE_GCTHING) << JSVAL_TAG_SHIFT) -} JS_ENUM_FOOTER(JSValueShiftedTag); - -static_assert(sizeof(JSValueShiftedTag) == sizeof(uint64_t), - "compiler typed enum support is apparently buggy"); - -#endif - -/* - * All our supported compilers implement C++11 |enum Foo : T| syntax, so don't - * expose these macros. (This macro exists *only* because gcc bug 51242 - * makes bit-fields of - * typed enums trigger a warning that can't be turned off. Don't expose it - * beyond this file!) - */ -#undef JS_ENUM_HEADER -#undef JS_ENUM_FOOTER - -#if defined(JS_NUNBOX32) - -#define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_CLEAR | (type))) - -#define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET JSVAL_TAG_NULL -#define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET JSVAL_TAG_OBJECT -#define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32 -#define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET JSVAL_TAG_STRING - -#elif defined(JS_PUNBOX64) - -#define JSVAL_PAYLOAD_MASK 0x00007FFFFFFFFFFFLL -#define JSVAL_TAG_MASK 0xFFFF800000000000LL -#define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_MAX_DOUBLE | (type))) -#define JSVAL_TYPE_TO_SHIFTED_TAG(type) (((uint64_t)JSVAL_TYPE_TO_TAG(type)) << JSVAL_TAG_SHIFT) - -#define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET JSVAL_TAG_NULL -#define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET JSVAL_TAG_OBJECT -#define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32 -#define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET JSVAL_TAG_STRING - -#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET JSVAL_SHIFTED_TAG_NULL -#define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET JSVAL_SHIFTED_TAG_OBJECT -#define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET JSVAL_SHIFTED_TAG_UNDEFINED -#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET JSVAL_SHIFTED_TAG_STRING - -#endif /* JS_PUNBOX64 */ - -typedef enum JSWhyMagic -{ - /** a hole in a native object's elements */ - JS_ELEMENTS_HOLE, - - /** there is not a pending iterator value */ - JS_NO_ITER_VALUE, - - /** exception value thrown when closing a generator */ - JS_GENERATOR_CLOSING, - - /** compiler sentinel value */ - JS_NO_CONSTANT, - - /** used in debug builds to catch tracing errors */ - JS_THIS_POISON, - - /** used in debug builds to catch tracing errors */ - JS_ARG_POISON, - - /** an empty subnode in the AST serializer */ - JS_SERIALIZE_NO_NODE, - - /** lazy arguments value on the stack */ - JS_LAZY_ARGUMENTS, - - /** optimized-away 'arguments' value */ - JS_OPTIMIZED_ARGUMENTS, - - /** magic value passed to natives to indicate construction */ - JS_IS_CONSTRUCTING, - - /** value of static block object slot */ - JS_BLOCK_NEEDS_CLONE, - - /** see class js::HashableValue */ - JS_HASH_KEY_EMPTY, - - /** error while running Ion code */ - JS_ION_ERROR, - - /** missing recover instruction result */ - JS_ION_BAILOUT, - - /** optimized out slot */ - JS_OPTIMIZED_OUT, - - /** uninitialized lexical bindings that produce ReferenceError on touch. */ - JS_UNINITIALIZED_LEXICAL, - - /** for local use */ - JS_GENERIC_MAGIC, - - JS_WHY_MAGIC_COUNT -} JSWhyMagic; - -namespace JS { - -static inline constexpr JS::Value UndefinedValue(); -static inline JS::Value PoisonedObjectValue(JSObject* obj); - -namespace detail { - -constexpr int CanonicalizedNaNSignBit = 0; -constexpr uint64_t CanonicalizedNaNSignificand = 0x8000000000000ULL; - -constexpr uint64_t CanonicalizedNaNBits = - mozilla::SpecificNaNBits::value; - -} // namespace detail - -/** - * Returns a generic quiet NaN value, with all payload bits set to zero. - * - * Among other properties, this NaN's bit pattern conforms to JS::Value's - * bit pattern restrictions. - */ -static MOZ_ALWAYS_INLINE double -GenericNaN() -{ - return mozilla::SpecificNaN(detail::CanonicalizedNaNSignBit, - detail::CanonicalizedNaNSignificand); -} - -/* MSVC with PGO miscompiles this function. */ -#if defined(_MSC_VER) -# pragma optimize("g", off) -#endif -static inline double -CanonicalizeNaN(double d) -{ - if (MOZ_UNLIKELY(mozilla::IsNaN(d))) - return GenericNaN(); - return d; -} -#if defined(_MSC_VER) -# pragma optimize("", on) -#endif - -/** - * JS::Value is the interface for a single JavaScript Engine value. A few - * general notes on JS::Value: - * - * - JS::Value has setX() and isX() members for X in - * - * { Int32, Double, String, Symbol, Boolean, Undefined, Null, Object, Magic } - * - * JS::Value also contains toX() for each of the non-singleton types. - * - * - Magic is a singleton type whose payload contains either a JSWhyMagic "reason" for - * the magic value or a uint32_t value. By providing JSWhyMagic values when - * creating and checking for magic values, it is possible to assert, at - * runtime, that only magic values with the expected reason flow through a - * particular value. For example, if cx->exception has a magic value, the - * reason must be JS_GENERATOR_CLOSING. - * - * - The JS::Value operations are preferred. The JSVAL_* operations remain for - * compatibility; they may be removed at some point. These operations mostly - * provide similar functionality. But there are a few key differences. One - * is that JS::Value gives null a separate type. - * Also, to help prevent mistakenly boxing a nullable JSObject* as an object, - * Value::setObject takes a JSObject&. (Conversely, Value::toObject returns a - * JSObject&.) A convenience member Value::setObjectOrNull is provided. - * - * - JSVAL_VOID is the same as the singleton value of the Undefined type. - * - * - Note that JS::Value is 8 bytes on 32 and 64-bit architectures. Thus, on - * 32-bit user code should avoid copying jsval/JS::Value as much as possible, - * preferring to pass by const Value&. - */ -class MOZ_NON_PARAM alignas(8) Value -{ - public: -#if defined(JS_NUNBOX32) - using PayloadType = uint32_t; -#elif defined(JS_PUNBOX64) - using PayloadType = uint64_t; -#endif - - /* - * N.B. the default constructor leaves Value unitialized. Adding a default - * constructor prevents Value from being stored in a union. - */ - Value() = default; - Value(const Value& v) = default; - - /** - * Returns false if creating a NumberValue containing the given type would - * be lossy, true otherwise. - */ - template - static bool isNumberRepresentable(const T t) { - return T(double(t)) == t; - } - - /*** Mutators ***/ - - void setNull() { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_NULL, 0); - } - - void setUndefined() { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_UNDEFINED, 0); - } - - void setInt32(int32_t i) { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_INT32, uint32_t(i)); - } - - int32_t& getInt32Ref() { - MOZ_ASSERT(isInt32()); - return data.s.payload.i32; - } - - void setDouble(double d) { - // Don't assign to data.asDouble to fix a miscompilation with - // GCC 5.2.1 and 5.3.1. See bug 1312488. - data = layout(d); - MOZ_ASSERT(isDouble()); - } - - void setNaN() { - setDouble(GenericNaN()); - } - - double& getDoubleRef() { - MOZ_ASSERT(isDouble()); - return data.asDouble; - } - - void setString(JSString* str) { - MOZ_ASSERT(uintptr_t(str) > 0x1000); - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_STRING, PayloadType(str)); - } - - void setSymbol(JS::Symbol* sym) { - MOZ_ASSERT(uintptr_t(sym) > 0x1000); - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_SYMBOL, PayloadType(sym)); - } - - void setObject(JSObject& obj) { - MOZ_ASSERT(uintptr_t(&obj) > 0x1000 || uintptr_t(&obj) == 0x48); -#if defined(JS_PUNBOX64) - // VisualStudio cannot contain parenthesized C++ style cast and shift - // inside decltype in template parameter: - // AssertionConditionType> 1))> - // It throws syntax error. - MOZ_ASSERT((((uintptr_t)&obj) >> JSVAL_TAG_SHIFT) == 0); -#endif - setObjectNoCheck(&obj); - } - - private: - void setObjectNoCheck(JSObject* obj) { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_OBJECT, PayloadType(obj)); - } - - friend inline Value PoisonedObjectValue(JSObject* obj); - - public: - void setBoolean(bool b) { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_BOOLEAN, uint32_t(b)); - } - - void setMagic(JSWhyMagic why) { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_MAGIC, uint32_t(why)); - } - - void setMagicUint32(uint32_t payload) { - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_MAGIC, payload); - } - - bool setNumber(uint32_t ui) { - if (ui > JSVAL_INT_MAX) { - setDouble((double)ui); - return false; - } else { - setInt32((int32_t)ui); - return true; - } - } - - bool setNumber(double d) { - int32_t i; - if (mozilla::NumberIsInt32(d, &i)) { - setInt32(i); - return true; - } - - setDouble(d); - return false; - } - - void setObjectOrNull(JSObject* arg) { - if (arg) - setObject(*arg); - else - setNull(); - } - - void swap(Value& rhs) { - uint64_t tmp = rhs.data.asBits; - rhs.data.asBits = data.asBits; - data.asBits = tmp; - } - - private: - JSValueTag toTag() const { -#if defined(JS_NUNBOX32) - return data.s.tag; -#elif defined(JS_PUNBOX64) - return JSValueTag(data.asBits >> JSVAL_TAG_SHIFT); -#endif - } - - public: - /*** JIT-only interfaces to interact with and create raw Values ***/ -#if defined(JS_NUNBOX32) - PayloadType toNunboxPayload() const { - return data.s.payload.i32; - } - - JSValueTag toNunboxTag() const { - return data.s.tag; - } -#elif defined(JS_PUNBOX64) - const void* bitsAsPunboxPointer() const { - return reinterpret_cast(data.asBits); - } -#endif - - /*** Value type queries ***/ - - /* - * N.B. GCC, in some but not all cases, chooses to emit signed comparison - * of JSValueTag even though its underlying type has been forced to be - * uint32_t. Thus, all comparisons should explicitly cast operands to - * uint32_t. - */ - - bool isUndefined() const { -#if defined(JS_NUNBOX32) - return toTag() == JSVAL_TAG_UNDEFINED; -#elif defined(JS_PUNBOX64) - return data.asBits == JSVAL_SHIFTED_TAG_UNDEFINED; -#endif - } - - bool isNull() const { -#if defined(JS_NUNBOX32) - return toTag() == JSVAL_TAG_NULL; -#elif defined(JS_PUNBOX64) - return data.asBits == JSVAL_SHIFTED_TAG_NULL; -#endif - } - - bool isNullOrUndefined() const { - return isNull() || isUndefined(); - } - - bool isInt32() const { - return toTag() == JSVAL_TAG_INT32; - } - - bool isInt32(int32_t i32) const { - return data.asBits == bitsFromTagAndPayload(JSVAL_TAG_INT32, uint32_t(i32)); - } - - bool isDouble() const { -#if defined(JS_NUNBOX32) - return uint32_t(toTag()) <= uint32_t(JSVAL_TAG_CLEAR); -#elif defined(JS_PUNBOX64) - return (data.asBits | mozilla::DoubleTypeTraits::kSignBit) <= JSVAL_SHIFTED_TAG_MAX_DOUBLE; -#endif - } - - bool isNumber() const { -#if defined(JS_NUNBOX32) - MOZ_ASSERT(toTag() != JSVAL_TAG_CLEAR); - return uint32_t(toTag()) <= uint32_t(JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET); -#elif defined(JS_PUNBOX64) - return data.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET; -#endif - } - - bool isString() const { - return toTag() == JSVAL_TAG_STRING; - } - - bool isSymbol() const { - return toTag() == JSVAL_TAG_SYMBOL; - } - - bool isObject() const { -#if defined(JS_NUNBOX32) - return toTag() == JSVAL_TAG_OBJECT; -#elif defined(JS_PUNBOX64) - MOZ_ASSERT((data.asBits >> JSVAL_TAG_SHIFT) <= JSVAL_TAG_OBJECT); - return data.asBits >= JSVAL_SHIFTED_TAG_OBJECT; -#endif - } - - bool isPrimitive() const { -#if defined(JS_NUNBOX32) - return uint32_t(toTag()) < uint32_t(JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET); -#elif defined(JS_PUNBOX64) - return data.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET; -#endif - } - - bool isObjectOrNull() const { - MOZ_ASSERT(uint32_t(toTag()) <= uint32_t(JSVAL_TAG_OBJECT)); -#if defined(JS_NUNBOX32) - return uint32_t(toTag()) >= uint32_t(JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET); -#elif defined(JS_PUNBOX64) - return data.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET; -#endif - } - - bool isGCThing() const { -#if defined(JS_NUNBOX32) - /* gcc sometimes generates signed < without explicit casts. */ - return uint32_t(toTag()) >= uint32_t(JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET); -#elif defined(JS_PUNBOX64) - return data.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET; -#endif - } - - bool isBoolean() const { - return toTag() == JSVAL_TAG_BOOLEAN; - } - - bool isTrue() const { - return data.asBits == bitsFromTagAndPayload(JSVAL_TAG_BOOLEAN, uint32_t(true)); - } - - bool isFalse() const { - return data.asBits == bitsFromTagAndPayload(JSVAL_TAG_BOOLEAN, uint32_t(false)); - } - - bool isMagic() const { - return toTag() == JSVAL_TAG_MAGIC; - } - - bool isMagic(JSWhyMagic why) const { - MOZ_ASSERT_IF(isMagic(), data.s.payload.why == why); - return isMagic(); - } - - bool isMarkable() const { - return isGCThing() && !isNull(); - } - - JS::TraceKind traceKind() const { - MOZ_ASSERT(isMarkable()); - static_assert((JSVAL_TAG_STRING & 0x03) == size_t(JS::TraceKind::String), - "Value type tags must correspond with JS::TraceKinds."); - static_assert((JSVAL_TAG_SYMBOL & 0x03) == size_t(JS::TraceKind::Symbol), - "Value type tags must correspond with JS::TraceKinds."); - static_assert((JSVAL_TAG_OBJECT & 0x03) == size_t(JS::TraceKind::Object), - "Value type tags must correspond with JS::TraceKinds."); - if (MOZ_UNLIKELY(isPrivateGCThing())) - return JS::GCThingTraceKind(toGCThing()); - return JS::TraceKind(toTag() & 0x03); - } - - JSWhyMagic whyMagic() const { - MOZ_ASSERT(isMagic()); - return data.s.payload.why; - } - - uint32_t magicUint32() const { - MOZ_ASSERT(isMagic()); - return data.s.payload.u32; - } - - /*** Comparison ***/ - - bool operator==(const Value& rhs) const { - return data.asBits == rhs.data.asBits; - } - - bool operator!=(const Value& rhs) const { - return data.asBits != rhs.data.asBits; - } - - friend inline bool SameType(const Value& lhs, const Value& rhs); - - /*** Extract the value's typed payload ***/ - - int32_t toInt32() const { - MOZ_ASSERT(isInt32()); -#if defined(JS_NUNBOX32) - return data.s.payload.i32; -#elif defined(JS_PUNBOX64) - return int32_t(data.asBits); -#endif - } - - double toDouble() const { - MOZ_ASSERT(isDouble()); - return data.asDouble; - } - - double toNumber() const { - MOZ_ASSERT(isNumber()); - return isDouble() ? toDouble() : double(toInt32()); - } - - JSString* toString() const { - MOZ_ASSERT(isString()); -#if defined(JS_NUNBOX32) - return data.s.payload.str; -#elif defined(JS_PUNBOX64) - return reinterpret_cast(data.asBits & JSVAL_PAYLOAD_MASK); -#endif - } - - JS::Symbol* toSymbol() const { - MOZ_ASSERT(isSymbol()); -#if defined(JS_NUNBOX32) - return data.s.payload.sym; -#elif defined(JS_PUNBOX64) - return reinterpret_cast(data.asBits & JSVAL_PAYLOAD_MASK); -#endif - } - - JSObject& toObject() const { - MOZ_ASSERT(isObject()); -#if defined(JS_NUNBOX32) - return *data.s.payload.obj; -#elif defined(JS_PUNBOX64) - return *toObjectOrNull(); -#endif - } - - JSObject* toObjectOrNull() const { - MOZ_ASSERT(isObjectOrNull()); -#if defined(JS_NUNBOX32) - return data.s.payload.obj; -#elif defined(JS_PUNBOX64) - uint64_t ptrBits = data.asBits & JSVAL_PAYLOAD_MASK; - MOZ_ASSERT((ptrBits & 0x7) == 0); - return reinterpret_cast(ptrBits); -#endif - } - - js::gc::Cell* toGCThing() const { - MOZ_ASSERT(isGCThing()); -#if defined(JS_NUNBOX32) - return data.s.payload.cell; -#elif defined(JS_PUNBOX64) - uint64_t ptrBits = data.asBits & JSVAL_PAYLOAD_MASK; - MOZ_ASSERT((ptrBits & 0x7) == 0); - return reinterpret_cast(ptrBits); -#endif - } - - js::gc::Cell* toMarkablePointer() const { - MOZ_ASSERT(isMarkable()); - return toGCThing(); - } - - GCCellPtr toGCCellPtr() const { - return GCCellPtr(toGCThing(), traceKind()); - } - - bool toBoolean() const { - MOZ_ASSERT(isBoolean()); -#if defined(JS_NUNBOX32) - return bool(data.s.payload.boo); -#elif defined(JS_PUNBOX64) - return bool(data.asBits & JSVAL_PAYLOAD_MASK); -#endif - } - - uint32_t payloadAsRawUint32() const { - MOZ_ASSERT(!isDouble()); - return data.s.payload.u32; - } - - uint64_t asRawBits() const { - return data.asBits; - } - - JSValueType extractNonDoubleType() const { - uint32_t type = toTag() & 0xF; - MOZ_ASSERT(type > JSVAL_TYPE_DOUBLE); - return JSValueType(type); - } - - /* - * Private API - * - * Private setters/getters allow the caller to read/write arbitrary types - * that fit in the 64-bit payload. It is the caller's responsibility, after - * storing to a value with setPrivateX to read only using getPrivateX. - * Privates values are given a type which ensures they are not marked. - */ - - void setPrivate(void* ptr) { - MOZ_ASSERT((uintptr_t(ptr) & 1) == 0); -#if defined(JS_NUNBOX32) - data.s.tag = JSValueTag(0); - data.s.payload.ptr = ptr; -#elif defined(JS_PUNBOX64) - data.asBits = uintptr_t(ptr) >> 1; -#endif - MOZ_ASSERT(isDouble()); - } - - void* toPrivate() const { - MOZ_ASSERT(isDouble()); -#if defined(JS_NUNBOX32) - return data.s.payload.ptr; -#elif defined(JS_PUNBOX64) - MOZ_ASSERT((data.asBits & 0x8000000000000000ULL) == 0); - return reinterpret_cast(data.asBits << 1); -#endif - } - - void setPrivateUint32(uint32_t ui) { - MOZ_ASSERT(uint32_t(int32_t(ui)) == ui); - setInt32(int32_t(ui)); - } - - uint32_t toPrivateUint32() const { - return uint32_t(toInt32()); - } - - /* - * Private GC Thing API - * - * Non-JSObject, JSString, and JS::Symbol cells may be put into the 64-bit - * payload as private GC things. Such Values are considered isMarkable() - * and isGCThing(), and as such, automatically marked. Their traceKind() - * is gotten via their cells. - */ - - void setPrivateGCThing(js::gc::Cell* cell) { - MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::String, - "Private GC thing Values must not be strings. Make a StringValue instead."); - MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::Symbol, - "Private GC thing Values must not be symbols. Make a SymbolValue instead."); - MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::Object, - "Private GC thing Values must not be objects. Make an ObjectValue instead."); - - MOZ_ASSERT(uintptr_t(cell) > 0x1000); -#if defined(JS_PUNBOX64) - // VisualStudio cannot contain parenthesized C++ style cast and shift - // inside decltype in template parameter: - // AssertionConditionType> 1))> - // It throws syntax error. - MOZ_ASSERT((((uintptr_t)cell) >> JSVAL_TAG_SHIFT) == 0); -#endif - data.asBits = bitsFromTagAndPayload(JSVAL_TAG_PRIVATE_GCTHING, PayloadType(cell)); - } - - bool isPrivateGCThing() const { - return toTag() == JSVAL_TAG_PRIVATE_GCTHING; - } - - const size_t* payloadWord() const { -#if defined(JS_NUNBOX32) - return &data.s.payload.word; -#elif defined(JS_PUNBOX64) - return &data.asWord; -#endif - } - - const uintptr_t* payloadUIntPtr() const { -#if defined(JS_NUNBOX32) - return &data.s.payload.uintptr; -#elif defined(JS_PUNBOX64) - return &data.asUIntPtr; -#endif - } - -#if !defined(_MSC_VER) && !defined(__sparc) - // Value must be POD so that MSVC will pass it by value and not in memory - // (bug 689101); the same is true for SPARC as well (bug 737344). More - // precisely, we don't want Value return values compiled as out params. - private: -#endif - -#if MOZ_LITTLE_ENDIAN -# if defined(JS_NUNBOX32) - union layout { - uint64_t asBits; - struct { - union { - int32_t i32; - uint32_t u32; - uint32_t boo; // Don't use |bool| -- it must be four bytes. - JSString* str; - JS::Symbol* sym; - JSObject* obj; - js::gc::Cell* cell; - void* ptr; - JSWhyMagic why; - size_t word; - uintptr_t uintptr; - } payload; - JSValueTag tag; - } s; - double asDouble; - void* asPtr; - - layout() = default; - explicit constexpr layout(uint64_t bits) : asBits(bits) {} - explicit constexpr layout(double d) : asDouble(d) {} - } data; -# elif defined(JS_PUNBOX64) - union layout { - uint64_t asBits; -#if !defined(_WIN64) - /* MSVC does not pack these correctly :-( */ - struct { - uint64_t payload47 : 47; - JSValueTag tag : 17; - } debugView; -#endif - struct { - union { - int32_t i32; - uint32_t u32; - JSWhyMagic why; - } payload; - } s; - double asDouble; - void* asPtr; - size_t asWord; - uintptr_t asUIntPtr; - - layout() = default; - explicit constexpr layout(uint64_t bits) : asBits(bits) {} - explicit constexpr layout(double d) : asDouble(d) {} - } data; -# endif /* JS_PUNBOX64 */ -#else /* MOZ_LITTLE_ENDIAN */ -# if defined(JS_NUNBOX32) - union layout { - uint64_t asBits; - struct { - JSValueTag tag; - union { - int32_t i32; - uint32_t u32; - uint32_t boo; // Don't use |bool| -- it must be four bytes. - JSString* str; - JS::Symbol* sym; - JSObject* obj; - js::gc::Cell* cell; - void* ptr; - JSWhyMagic why; - size_t word; - uintptr_t uintptr; - } payload; - } s; - double asDouble; - void* asPtr; - - layout() = default; - explicit constexpr layout(uint64_t bits) : asBits(bits) {} - explicit constexpr layout(double d) : asDouble(d) {} - } data; -# elif defined(JS_PUNBOX64) - union layout { - uint64_t asBits; - struct { - JSValueTag tag : 17; - uint64_t payload47 : 47; - } debugView; - struct { - uint32_t padding; - union { - int32_t i32; - uint32_t u32; - JSWhyMagic why; - } payload; - } s; - double asDouble; - void* asPtr; - size_t asWord; - uintptr_t asUIntPtr; - - layout() = default; - explicit constexpr layout(uint64_t bits) : asBits(bits) {} - explicit constexpr layout(double d) : asDouble(d) {} - } data; -# endif /* JS_PUNBOX64 */ -#endif /* MOZ_LITTLE_ENDIAN */ - - private: - explicit constexpr Value(uint64_t asBits) : data(asBits) {} - explicit constexpr Value(double d) : data(d) {} - - void staticAssertions() { - JS_STATIC_ASSERT(sizeof(JSValueType) == 1); - JS_STATIC_ASSERT(sizeof(JSValueTag) == 4); - JS_STATIC_ASSERT(sizeof(JSWhyMagic) <= 4); - JS_STATIC_ASSERT(sizeof(Value) == 8); - } - - friend constexpr Value JS::UndefinedValue(); - - public: - static constexpr uint64_t - bitsFromTagAndPayload(JSValueTag tag, PayloadType payload) - { -#if defined(JS_NUNBOX32) - return (uint64_t(uint32_t(tag)) << 32) | payload; -#elif defined(JS_PUNBOX64) - return (uint64_t(uint32_t(tag)) << JSVAL_TAG_SHIFT) | payload; -#endif - } - - static constexpr Value - fromTagAndPayload(JSValueTag tag, PayloadType payload) - { - return fromRawBits(bitsFromTagAndPayload(tag, payload)); - } - - static constexpr Value - fromRawBits(uint64_t asBits) { - return Value(asBits); - } - - static constexpr Value - fromInt32(int32_t i) { - return fromTagAndPayload(JSVAL_TAG_INT32, uint32_t(i)); - } - - static constexpr Value - fromDouble(double d) { - return Value(d); - } -} JS_HAZ_GC_POINTER; - -static_assert(sizeof(Value) == 8, "Value size must leave three tag bits, be a binary power, and is ubiquitously depended upon everywhere"); - -inline bool -IsOptimizedPlaceholderMagicValue(const Value& v) -{ - if (v.isMagic()) { - MOZ_ASSERT(v.whyMagic() == JS_OPTIMIZED_ARGUMENTS || v.whyMagic() == JS_OPTIMIZED_OUT); - return true; - } - return false; -} - -static MOZ_ALWAYS_INLINE void -ExposeValueToActiveJS(const Value& v) -{ - if (v.isMarkable()) - js::gc::ExposeGCThingToActiveJS(GCCellPtr(v)); -} - -/************************************************************************/ - -static inline Value -NullValue() -{ - Value v; - v.setNull(); - return v; -} - -static inline constexpr Value -UndefinedValue() -{ - return Value::fromTagAndPayload(JSVAL_TAG_UNDEFINED, 0); -} - -static inline constexpr Value -Int32Value(int32_t i32) -{ - return Value::fromInt32(i32); -} - -static inline Value -DoubleValue(double dbl) -{ - Value v; - v.setDouble(dbl); - return v; -} - -static inline Value -CanonicalizedDoubleValue(double d) -{ - return MOZ_UNLIKELY(mozilla::IsNaN(d)) - ? Value::fromRawBits(detail::CanonicalizedNaNBits) - : Value::fromDouble(d); -} - -static inline bool -IsCanonicalized(double d) -{ - if (mozilla::IsInfinite(d) || mozilla::IsFinite(d)) - return true; - - uint64_t bits; - mozilla::BitwiseCast(d, &bits); - return (bits & ~mozilla::DoubleTypeTraits::kSignBit) == detail::CanonicalizedNaNBits; -} - -static inline Value -DoubleNaNValue() -{ - Value v; - v.setNaN(); - return v; -} - -static inline Value -Float32Value(float f) -{ - Value v; - v.setDouble(f); - return v; -} - -static inline Value -StringValue(JSString* str) -{ - Value v; - v.setString(str); - return v; -} - -static inline Value -SymbolValue(JS::Symbol* sym) -{ - Value v; - v.setSymbol(sym); - return v; -} - -static inline Value -BooleanValue(bool boo) -{ - Value v; - v.setBoolean(boo); - return v; -} - -static inline Value -TrueValue() -{ - Value v; - v.setBoolean(true); - return v; -} - -static inline Value -FalseValue() -{ - Value v; - v.setBoolean(false); - return v; -} - -static inline Value -ObjectValue(JSObject& obj) -{ - Value v; - v.setObject(obj); - return v; -} - -static inline Value -ObjectValueCrashOnTouch() -{ - Value v; - v.setObject(*reinterpret_cast(0x48)); - return v; -} - -static inline Value -MagicValue(JSWhyMagic why) -{ - Value v; - v.setMagic(why); - return v; -} - -static inline Value -MagicValueUint32(uint32_t payload) -{ - Value v; - v.setMagicUint32(payload); - return v; -} - -static inline Value -NumberValue(float f) -{ - Value v; - v.setNumber(f); - return v; -} - -static inline Value -NumberValue(double dbl) -{ - Value v; - v.setNumber(dbl); - return v; -} - -static inline Value -NumberValue(int8_t i) -{ - return Int32Value(i); -} - -static inline Value -NumberValue(uint8_t i) -{ - return Int32Value(i); -} - -static inline Value -NumberValue(int16_t i) -{ - return Int32Value(i); -} - -static inline Value -NumberValue(uint16_t i) -{ - return Int32Value(i); -} - -static inline Value -NumberValue(int32_t i) -{ - return Int32Value(i); -} - -static inline constexpr Value -NumberValue(uint32_t i) -{ - return i <= JSVAL_INT_MAX - ? Int32Value(int32_t(i)) - : Value::fromDouble(double(i)); -} - -namespace detail { - -template -class MakeNumberValue -{ - public: - template - static inline Value create(const T t) - { - Value v; - if (JSVAL_INT_MIN <= t && t <= JSVAL_INT_MAX) - v.setInt32(int32_t(t)); - else - v.setDouble(double(t)); - return v; - } -}; - -template <> -class MakeNumberValue -{ - public: - template - static inline Value create(const T t) - { - Value v; - if (t <= JSVAL_INT_MAX) - v.setInt32(int32_t(t)); - else - v.setDouble(double(t)); - return v; - } -}; - -} // namespace detail - -template -static inline Value -NumberValue(const T t) -{ - MOZ_ASSERT(Value::isNumberRepresentable(t), "value creation would be lossy"); - return detail::MakeNumberValue::is_signed>::create(t); -} - -static inline Value -ObjectOrNullValue(JSObject* obj) -{ - Value v; - v.setObjectOrNull(obj); - return v; -} - -static inline Value -PrivateValue(void* ptr) -{ - Value v; - v.setPrivate(ptr); - return v; -} - -static inline Value -PrivateUint32Value(uint32_t ui) -{ - Value v; - v.setPrivateUint32(ui); - return v; -} - -static inline Value -PrivateGCThingValue(js::gc::Cell* cell) -{ - Value v; - v.setPrivateGCThing(cell); - return v; -} - -static inline Value -PoisonedObjectValue(JSObject* obj) -{ - Value v; - v.setObjectNoCheck(obj); - return v; -} - -inline bool -SameType(const Value& lhs, const Value& rhs) -{ -#if defined(JS_NUNBOX32) - JSValueTag ltag = lhs.toTag(), rtag = rhs.toTag(); - return ltag == rtag || (ltag < JSVAL_TAG_CLEAR && rtag < JSVAL_TAG_CLEAR); -#elif defined(JS_PUNBOX64) - return (lhs.isDouble() && rhs.isDouble()) || - (((lhs.data.asBits ^ rhs.data.asBits) & 0xFFFF800000000000ULL) == 0); -#endif -} - -} // namespace JS - -/************************************************************************/ - -namespace JS { -JS_PUBLIC_API(void) HeapValuePostBarrier(Value* valuep, const Value& prev, const Value& next); - -template <> -struct GCPolicy -{ - static Value initial() { return UndefinedValue(); } - static void trace(JSTracer* trc, Value* v, const char* name) { - js::UnsafeTraceManuallyBarrieredEdge(trc, v, name); - } - static bool isTenured(const Value& thing) { - return !thing.isGCThing() || !IsInsideNursery(thing.toGCThing()); - } -}; - -} // namespace JS - -namespace js { - -template <> -struct BarrierMethods -{ - static gc::Cell* asGCThingOrNull(const JS::Value& v) { - return v.isMarkable() ? v.toGCThing() : nullptr; - } - static void postBarrier(JS::Value* v, const JS::Value& prev, const JS::Value& next) { - JS::HeapValuePostBarrier(v, prev, next); - } - static void exposeToJS(const JS::Value& v) { - JS::ExposeValueToActiveJS(v); - } -}; - -template class MutableValueOperations; - -/** - * A class designed for CRTP use in implementing the non-mutating parts of the - * Value interface in Value-like classes. Outer must be a class inheriting - * ValueOperations with a visible get() method returning a const - * reference to the Value abstracted by Outer. - */ -template -class ValueOperations -{ - friend class MutableValueOperations; - - const JS::Value& value() const { return static_cast(this)->get(); } - - public: - bool isUndefined() const { return value().isUndefined(); } - bool isNull() const { return value().isNull(); } - bool isBoolean() const { return value().isBoolean(); } - bool isTrue() const { return value().isTrue(); } - bool isFalse() const { return value().isFalse(); } - bool isNumber() const { return value().isNumber(); } - bool isInt32() const { return value().isInt32(); } - bool isInt32(int32_t i32) const { return value().isInt32(i32); } - bool isDouble() const { return value().isDouble(); } - bool isString() const { return value().isString(); } - bool isSymbol() const { return value().isSymbol(); } - bool isObject() const { return value().isObject(); } - bool isMagic() const { return value().isMagic(); } - bool isMagic(JSWhyMagic why) const { return value().isMagic(why); } - bool isMarkable() const { return value().isMarkable(); } - bool isPrimitive() const { return value().isPrimitive(); } - bool isGCThing() const { return value().isGCThing(); } - - bool isNullOrUndefined() const { return value().isNullOrUndefined(); } - bool isObjectOrNull() const { return value().isObjectOrNull(); } - - bool toBoolean() const { return value().toBoolean(); } - double toNumber() const { return value().toNumber(); } - int32_t toInt32() const { return value().toInt32(); } - double toDouble() const { return value().toDouble(); } - JSString* toString() const { return value().toString(); } - JS::Symbol* toSymbol() const { return value().toSymbol(); } - JSObject& toObject() const { return value().toObject(); } - JSObject* toObjectOrNull() const { return value().toObjectOrNull(); } - gc::Cell* toGCThing() const { return value().toGCThing(); } - JS::TraceKind traceKind() const { return value().traceKind(); } - void* toPrivate() const { return value().toPrivate(); } - uint32_t toPrivateUint32() const { return value().toPrivateUint32(); } - - uint64_t asRawBits() const { return value().asRawBits(); } - JSValueType extractNonDoubleType() const { return value().extractNonDoubleType(); } - - JSWhyMagic whyMagic() const { return value().whyMagic(); } - uint32_t magicUint32() const { return value().magicUint32(); } -}; - -/** - * A class designed for CRTP use in implementing all the mutating parts of the - * Value interface in Value-like classes. Outer must be a class inheriting - * MutableValueOperations with visible get() methods returning const and - * non-const references to the Value abstracted by Outer. - */ -template -class MutableValueOperations : public ValueOperations -{ - JS::Value& value() { return static_cast(this)->get(); } - - public: - void setNull() { value().setNull(); } - void setUndefined() { value().setUndefined(); } - void setInt32(int32_t i) { value().setInt32(i); } - void setDouble(double d) { value().setDouble(d); } - void setNaN() { setDouble(JS::GenericNaN()); } - void setBoolean(bool b) { value().setBoolean(b); } - void setMagic(JSWhyMagic why) { value().setMagic(why); } - bool setNumber(uint32_t ui) { return value().setNumber(ui); } - bool setNumber(double d) { return value().setNumber(d); } - void setString(JSString* str) { this->value().setString(str); } - void setSymbol(JS::Symbol* sym) { this->value().setSymbol(sym); } - void setObject(JSObject& obj) { this->value().setObject(obj); } - void setObjectOrNull(JSObject* arg) { this->value().setObjectOrNull(arg); } - void setPrivate(void* ptr) { this->value().setPrivate(ptr); } - void setPrivateUint32(uint32_t ui) { this->value().setPrivateUint32(ui); } - void setPrivateGCThing(js::gc::Cell* cell) { this->value().setPrivateGCThing(cell); } -}; - -/* - * Augment the generic Heap interface when T = Value with - * type-querying, value-extracting, and mutating operations. - */ -template <> -class HeapBase : public ValueOperations > -{ - typedef JS::Heap Outer; - - friend class ValueOperations; - - void setBarriered(const JS::Value& v) { - *static_cast*>(this) = v; - } - - public: - void setNull() { setBarriered(JS::NullValue()); } - void setUndefined() { setBarriered(JS::UndefinedValue()); } - void setInt32(int32_t i) { setBarriered(JS::Int32Value(i)); } - void setDouble(double d) { setBarriered(JS::DoubleValue(d)); } - void setNaN() { setDouble(JS::GenericNaN()); } - void setBoolean(bool b) { setBarriered(JS::BooleanValue(b)); } - void setMagic(JSWhyMagic why) { setBarriered(JS::MagicValue(why)); } - void setString(JSString* str) { setBarriered(JS::StringValue(str)); } - void setSymbol(JS::Symbol* sym) { setBarriered(JS::SymbolValue(sym)); } - void setObject(JSObject& obj) { setBarriered(JS::ObjectValue(obj)); } - void setPrivateGCThing(js::gc::Cell* cell) { setBarriered(JS::PrivateGCThingValue(cell)); } - - bool setNumber(uint32_t ui) { - if (ui > JSVAL_INT_MAX) { - setDouble((double)ui); - return false; - } else { - setInt32((int32_t)ui); - return true; - } - } - - bool setNumber(double d) { - int32_t i; - if (mozilla::NumberIsInt32(d, &i)) { - setInt32(i); - return true; - } - - setDouble(d); - return false; - } - - void setObjectOrNull(JSObject* arg) { - if (arg) - setObject(*arg); - else - setNull(); - } -}; - -template <> -class HandleBase : public ValueOperations > -{}; - -template <> -class MutableHandleBase : public MutableValueOperations > -{}; - -template <> -class RootedBase : public MutableValueOperations > -{}; - -template <> -class PersistentRootedBase : public MutableValueOperations> -{}; - -/* - * If the Value is a GC pointer type, convert to that type and call |f| with - * the pointer. If the Value is not a GC type, calls F::defaultValue. - */ -template -auto -DispatchTyped(F f, const JS::Value& val, Args&&... args) - -> decltype(f(static_cast(nullptr), mozilla::Forward(args)...)) -{ - if (val.isString()) - return f(val.toString(), mozilla::Forward(args)...); - if (val.isObject()) - return f(&val.toObject(), mozilla::Forward(args)...); - if (val.isSymbol()) - return f(val.toSymbol(), mozilla::Forward(args)...); - if (MOZ_UNLIKELY(val.isPrivateGCThing())) - return DispatchTyped(f, val.toGCCellPtr(), mozilla::Forward(args)...); - MOZ_ASSERT(!val.isMarkable()); - return F::defaultValue(val); -} - -template struct VoidDefaultAdaptor { static void defaultValue(const S&) {} }; -template struct IdentityDefaultAdaptor { static S defaultValue(const S& v) {return v;} }; -template struct BoolDefaultAdaptor { static bool defaultValue(const S&) { return v; } }; - -} // namespace js - -/************************************************************************/ - -namespace JS { - -extern JS_PUBLIC_DATA(const HandleValue) NullHandleValue; -extern JS_PUBLIC_DATA(const HandleValue) UndefinedHandleValue; -extern JS_PUBLIC_DATA(const HandleValue) TrueHandleValue; -extern JS_PUBLIC_DATA(const HandleValue) FalseHandleValue; - -} // namespace JS - -#endif /* js_Value_h */ diff --git a/android/x86/include/spidermonkey/js/Vector.h b/android/x86/include/spidermonkey/js/Vector.h deleted file mode 100644 index 6fa63e93..00000000 --- a/android/x86/include/spidermonkey/js/Vector.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_Vector_h -#define js_Vector_h - -#include "mozilla/Vector.h" - -/* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */ -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4345) -#endif - -namespace js { - -class TempAllocPolicy; - -namespace detail { - -template -struct TypeIsGCThing : mozilla::FalseType -{}; - -// Uncomment this once we actually can assert it: -//template <> -//struct TypeIsGCThing : mozilla::TrueType -//{}; - -} // namespace detail - -template ::value>::Type - > -using Vector = mozilla::Vector; - -} // namespace js - -#endif /* js_Vector_h */ diff --git a/android/x86/include/spidermonkey/js/WeakMapPtr.h b/android/x86/include/spidermonkey/js/WeakMapPtr.h deleted file mode 100644 index 41860551..00000000 --- a/android/x86/include/spidermonkey/js/WeakMapPtr.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 js_WeakMapPtr_h -#define js_WeakMapPtr_h - -#include "jspubtd.h" - -#include "js/TypeDecls.h" - -namespace JS { - -// A wrapper around the internal C++ representation of SpiderMonkey WeakMaps, -// usable outside the engine. -// -// The supported template specializations are enumerated in WeakMapPtr.cpp. If -// you want to use this class for a different key/value combination, add it to -// the list and the compiler will generate the relevant machinery. -template -class JS_PUBLIC_API(WeakMapPtr) -{ - public: - WeakMapPtr() : ptr(nullptr) {} - bool init(JSContext* cx); - bool initialized() { return ptr != nullptr; } - void destroy(); - virtual ~WeakMapPtr() { MOZ_ASSERT(!initialized()); } - void trace(JSTracer* tracer); - - V lookup(const K& key); - bool put(JSContext* cx, const K& key, const V& value); - - private: - void* ptr; - - // WeakMapPtr is neither copyable nor assignable. - WeakMapPtr(const WeakMapPtr& wmp) = delete; - WeakMapPtr& operator=(const WeakMapPtr& wmp) = delete; -}; - -} /* namespace JS */ - -#endif /* js_WeakMapPtr_h */ diff --git a/android/x86/include/spidermonkey/jsalloc.h b/android/x86/include/spidermonkey/jsalloc.h deleted file mode 100644 index b9ae5190..00000000 --- a/android/x86/include/spidermonkey/jsalloc.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* - * JS allocation policies. - * - * The allocators here are for system memory with lifetimes which are not - * managed by the GC. See the comment at the top of vm/MallocProvider.h. - */ - -#ifndef jsalloc_h -#define jsalloc_h - -#include "js/TypeDecls.h" -#include "js/Utility.h" - -namespace js { - -enum class AllocFunction { - Malloc, - Calloc, - Realloc -}; - -struct ContextFriendFields; - -/* Policy for using system memory functions and doing no error reporting. */ -class SystemAllocPolicy -{ - public: - template T* maybe_pod_malloc(size_t numElems) { return js_pod_malloc(numElems); } - template T* maybe_pod_calloc(size_t numElems) { return js_pod_calloc(numElems); } - template T* maybe_pod_realloc(T* p, size_t oldSize, size_t newSize) { - return js_pod_realloc(p, oldSize, newSize); - } - template T* pod_malloc(size_t numElems) { return maybe_pod_malloc(numElems); } - template T* pod_calloc(size_t numElems) { return maybe_pod_calloc(numElems); } - template T* pod_realloc(T* p, size_t oldSize, size_t newSize) { - return maybe_pod_realloc(p, oldSize, newSize); - } - void free_(void* p) { js_free(p); } - void reportAllocOverflow() const {} - bool checkSimulatedOOM() const { - return !js::oom::ShouldFailWithOOM(); - } -}; - -class ExclusiveContext; -void ReportOutOfMemory(ExclusiveContext* cxArg); - -/* - * Allocation policy that calls the system memory functions and reports errors - * to the context. Since the JSContext given on construction is stored for - * the lifetime of the container, this policy may only be used for containers - * whose lifetime is a shorter than the given JSContext. - * - * FIXME bug 647103 - rewrite this in terms of temporary allocation functions, - * not the system ones. - */ -class TempAllocPolicy -{ - ContextFriendFields* const cx_; - - /* - * Non-inline helper to call JSRuntime::onOutOfMemory with minimal - * code bloat. - */ - JS_FRIEND_API(void*) onOutOfMemory(AllocFunction allocFunc, size_t nbytes, - void* reallocPtr = nullptr); - - template - T* onOutOfMemoryTyped(AllocFunction allocFunc, size_t numElems, void* reallocPtr = nullptr) { - size_t bytes; - if (MOZ_UNLIKELY(!CalculateAllocSize(numElems, &bytes))) - return nullptr; - return static_cast(onOutOfMemory(allocFunc, bytes, reallocPtr)); - } - - public: - MOZ_IMPLICIT TempAllocPolicy(JSContext* cx) : cx_((ContextFriendFields*) cx) {} // :( - MOZ_IMPLICIT TempAllocPolicy(ContextFriendFields* cx) : cx_(cx) {} - - template - T* maybe_pod_malloc(size_t numElems) { - return js_pod_malloc(numElems); - } - - template - T* maybe_pod_calloc(size_t numElems) { - return js_pod_calloc(numElems); - } - - template - T* maybe_pod_realloc(T* prior, size_t oldSize, size_t newSize) { - return js_pod_realloc(prior, oldSize, newSize); - } - - template - T* pod_malloc(size_t numElems) { - T* p = maybe_pod_malloc(numElems); - if (MOZ_UNLIKELY(!p)) - p = onOutOfMemoryTyped(AllocFunction::Malloc, numElems); - return p; - } - - template - T* pod_calloc(size_t numElems) { - T* p = maybe_pod_calloc(numElems); - if (MOZ_UNLIKELY(!p)) - p = onOutOfMemoryTyped(AllocFunction::Calloc, numElems); - return p; - } - - template - T* pod_realloc(T* prior, size_t oldSize, size_t newSize) { - T* p2 = maybe_pod_realloc(prior, oldSize, newSize); - if (MOZ_UNLIKELY(!p2)) - p2 = onOutOfMemoryTyped(AllocFunction::Realloc, newSize, prior); - return p2; - } - - void free_(void* p) { - js_free(p); - } - - JS_FRIEND_API(void) reportAllocOverflow() const; - - bool checkSimulatedOOM() const { - if (js::oom::ShouldFailWithOOM()) { - js::ReportOutOfMemory(reinterpret_cast(cx_)); - return false; - } - - return true; - } -}; - -} /* namespace js */ - -#endif /* jsalloc_h */ diff --git a/android/x86/include/spidermonkey/jsapi.h b/android/x86/include/spidermonkey/jsapi.h deleted file mode 100644 index 84d639a0..00000000 --- a/android/x86/include/spidermonkey/jsapi.h +++ /dev/null @@ -1,6630 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* JavaScript API. */ - -#ifndef jsapi_h -#define jsapi_h - -#include "mozilla/AlreadyAddRefed.h" -#include "mozilla/FloatingPoint.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Range.h" -#include "mozilla/RangedPtr.h" -#include "mozilla/RefCounted.h" -#include "mozilla/RefPtr.h" -#include "mozilla/Variant.h" - -#include -#include -#include -#include - -#include "jsalloc.h" -#include "jspubtd.h" - -#include "js/CallArgs.h" -#include "js/CharacterEncoding.h" -#include "js/Class.h" -#include "js/GCVector.h" -#include "js/HashTable.h" -#include "js/Id.h" -#include "js/Principals.h" -#include "js/Realm.h" -#include "js/RootingAPI.h" -#include "js/TracingAPI.h" -#include "js/Utility.h" -#include "js/Value.h" -#include "js/Vector.h" - -/************************************************************************/ - -namespace JS { - -class TwoByteChars; - -#ifdef JS_DEBUG - -class JS_PUBLIC_API(AutoCheckRequestDepth) -{ - JSContext* cx; - public: - explicit AutoCheckRequestDepth(JSContext* cx); - explicit AutoCheckRequestDepth(js::ContextFriendFields* cx); - ~AutoCheckRequestDepth(); -}; - -# define CHECK_REQUEST(cx) \ - JS::AutoCheckRequestDepth _autoCheckRequestDepth(cx) - -#else - -# define CHECK_REQUEST(cx) \ - ((void) 0) - -#endif /* JS_DEBUG */ - -/** AutoValueArray roots an internal fixed-size array of Values. */ -template -class MOZ_RAII AutoValueArray : public AutoGCRooter -{ - const size_t length_; - Value elements_[N]; - - public: - explicit AutoValueArray(JSContext* cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, VALARRAY), length_(N) - { - /* Always initialize in case we GC before assignment. */ - mozilla::PodArrayZero(elements_); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - unsigned length() const { return length_; } - const Value* begin() const { return elements_; } - Value* begin() { return elements_; } - - HandleValue operator[](unsigned i) const { - MOZ_ASSERT(i < N); - return HandleValue::fromMarkedLocation(&elements_[i]); - } - MutableHandleValue operator[](unsigned i) { - MOZ_ASSERT(i < N); - return MutableHandleValue::fromMarkedLocation(&elements_[i]); - } - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -template -class MOZ_RAII AutoVectorRooterBase : protected AutoGCRooter -{ - typedef js::Vector VectorImpl; - VectorImpl vector; - - public: - explicit AutoVectorRooterBase(JSContext* cx, ptrdiff_t tag - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, tag), vector(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - explicit AutoVectorRooterBase(js::ContextFriendFields* cx, ptrdiff_t tag - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, tag), vector(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - typedef T ElementType; - typedef typename VectorImpl::Range Range; - - size_t length() const { return vector.length(); } - bool empty() const { return vector.empty(); } - - MOZ_MUST_USE bool append(const T& v) { return vector.append(v); } - MOZ_MUST_USE bool appendN(const T& v, size_t len) { return vector.appendN(v, len); } - MOZ_MUST_USE bool append(const T* ptr, size_t len) { return vector.append(ptr, len); } - MOZ_MUST_USE bool appendAll(const AutoVectorRooterBase& other) { - return vector.appendAll(other.vector); - } - - MOZ_MUST_USE bool insert(T* p, const T& val) { return vector.insert(p, val); } - - /* For use when space has already been reserved. */ - void infallibleAppend(const T& v) { vector.infallibleAppend(v); } - - void popBack() { vector.popBack(); } - T popCopy() { return vector.popCopy(); } - - MOZ_MUST_USE bool growBy(size_t inc) { - size_t oldLength = vector.length(); - if (!vector.growByUninitialized(inc)) - return false; - makeRangeGCSafe(oldLength); - return true; - } - - MOZ_MUST_USE bool resize(size_t newLength) { - size_t oldLength = vector.length(); - if (newLength <= oldLength) { - vector.shrinkBy(oldLength - newLength); - return true; - } - if (!vector.growByUninitialized(newLength - oldLength)) - return false; - makeRangeGCSafe(oldLength); - return true; - } - - void clear() { vector.clear(); } - - MOZ_MUST_USE bool reserve(size_t newLength) { - return vector.reserve(newLength); - } - - JS::MutableHandle operator[](size_t i) { - return JS::MutableHandle::fromMarkedLocation(&vector[i]); - } - JS::Handle operator[](size_t i) const { - return JS::Handle::fromMarkedLocation(&vector[i]); - } - - const T* begin() const { return vector.begin(); } - T* begin() { return vector.begin(); } - - const T* end() const { return vector.end(); } - T* end() { return vector.end(); } - - Range all() { return vector.all(); } - - const T& back() const { return vector.back(); } - - friend void AutoGCRooter::trace(JSTracer* trc); - - private: - void makeRangeGCSafe(size_t oldLength) { - T* t = vector.begin() + oldLength; - for (size_t i = oldLength; i < vector.length(); ++i, ++t) - memset(t, 0, sizeof(T)); - } - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -template -class MOZ_RAII AutoVectorRooter : public AutoVectorRooterBase -{ - public: - explicit AutoVectorRooter(JSContext* cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoVectorRooterBase(cx, this->GetTag(T())) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - explicit AutoVectorRooter(js::ContextFriendFields* cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoVectorRooterBase(cx, this->GetTag(T())) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class AutoValueVector : public Rooted> { - using Vec = GCVector; - using Base = Rooted; - public: - explicit AutoValueVector(JSContext* cx) : Base(cx, Vec(cx)) {} - explicit AutoValueVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {} -}; - -class AutoIdVector : public Rooted> { - using Vec = GCVector; - using Base = Rooted; - public: - explicit AutoIdVector(JSContext* cx) : Base(cx, Vec(cx)) {} - explicit AutoIdVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {} - - bool appendAll(const AutoIdVector& other) { return this->Base::appendAll(other.get()); } -}; - -class AutoObjectVector : public Rooted> { - using Vec = GCVector; - using Base = Rooted; - public: - explicit AutoObjectVector(JSContext* cx) : Base(cx, Vec(cx)) {} - explicit AutoObjectVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {} -}; - -using ValueVector = JS::GCVector; -using IdVector = JS::GCVector; -using ScriptVector = JS::GCVector; -using StringVector = JS::GCVector; - -template -class MOZ_RAII AutoHashMapRooter : protected AutoGCRooter -{ - private: - typedef js::HashMap HashMapImpl; - - public: - explicit AutoHashMapRooter(JSContext* cx, ptrdiff_t tag - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, tag), map(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - typedef Key KeyType; - typedef Value ValueType; - typedef typename HashMapImpl::Entry Entry; - typedef typename HashMapImpl::Lookup Lookup; - typedef typename HashMapImpl::Ptr Ptr; - typedef typename HashMapImpl::AddPtr AddPtr; - - bool init(uint32_t len = 16) { - return map.init(len); - } - bool initialized() const { - return map.initialized(); - } - Ptr lookup(const Lookup& l) const { - return map.lookup(l); - } - void remove(Ptr p) { - map.remove(p); - } - AddPtr lookupForAdd(const Lookup& l) const { - return map.lookupForAdd(l); - } - - template - bool add(AddPtr& p, const KeyInput& k, const ValueInput& v) { - return map.add(p, k, v); - } - - bool add(AddPtr& p, const Key& k) { - return map.add(p, k); - } - - template - bool relookupOrAdd(AddPtr& p, const KeyInput& k, const ValueInput& v) { - return map.relookupOrAdd(p, k, v); - } - - typedef typename HashMapImpl::Range Range; - Range all() const { - return map.all(); - } - - typedef typename HashMapImpl::Enum Enum; - - void clear() { - map.clear(); - } - - void finish() { - map.finish(); - } - - bool empty() const { - return map.empty(); - } - - uint32_t count() const { - return map.count(); - } - - size_t capacity() const { - return map.capacity(); - } - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return map.sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return map.sizeOfIncludingThis(mallocSizeOf); - } - - /************************************************** Shorthand operations */ - - bool has(const Lookup& l) const { - return map.has(l); - } - - template - bool put(const KeyInput& k, const ValueInput& v) { - return map.put(k, v); - } - - template - bool putNew(const KeyInput& k, const ValueInput& v) { - return map.putNew(k, v); - } - - Ptr lookupWithDefault(const Key& k, const Value& defaultValue) { - return map.lookupWithDefault(k, defaultValue); - } - - void remove(const Lookup& l) { - map.remove(l); - } - - friend void AutoGCRooter::trace(JSTracer* trc); - - private: - AutoHashMapRooter(const AutoHashMapRooter& hmr) = delete; - AutoHashMapRooter& operator=(const AutoHashMapRooter& hmr) = delete; - - HashMapImpl map; - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -template -class MOZ_RAII AutoHashSetRooter : protected AutoGCRooter -{ - private: - typedef js::HashSet HashSetImpl; - - public: - explicit AutoHashSetRooter(JSContext* cx, ptrdiff_t tag - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, tag), set(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - typedef typename HashSetImpl::Lookup Lookup; - typedef typename HashSetImpl::Ptr Ptr; - typedef typename HashSetImpl::AddPtr AddPtr; - - bool init(uint32_t len = 16) { - return set.init(len); - } - bool initialized() const { - return set.initialized(); - } - Ptr lookup(const Lookup& l) const { - return set.lookup(l); - } - void remove(Ptr p) { - set.remove(p); - } - AddPtr lookupForAdd(const Lookup& l) const { - return set.lookupForAdd(l); - } - - bool add(AddPtr& p, const T& t) { - return set.add(p, t); - } - - bool relookupOrAdd(AddPtr& p, const Lookup& l, const T& t) { - return set.relookupOrAdd(p, l, t); - } - - typedef typename HashSetImpl::Range Range; - Range all() const { - return set.all(); - } - - typedef typename HashSetImpl::Enum Enum; - - void clear() { - set.clear(); - } - - void finish() { - set.finish(); - } - - bool empty() const { - return set.empty(); - } - - uint32_t count() const { - return set.count(); - } - - size_t capacity() const { - return set.capacity(); - } - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return set.sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return set.sizeOfIncludingThis(mallocSizeOf); - } - - /************************************************** Shorthand operations */ - - bool has(const Lookup& l) const { - return set.has(l); - } - - bool put(const T& t) { - return set.put(t); - } - - bool putNew(const T& t) { - return set.putNew(t); - } - - void remove(const Lookup& l) { - set.remove(l); - } - - friend void AutoGCRooter::trace(JSTracer* trc); - - private: - AutoHashSetRooter(const AutoHashSetRooter& hmr) = delete; - AutoHashSetRooter& operator=(const AutoHashSetRooter& hmr) = delete; - - HashSetImpl set; - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -/** - * Custom rooting behavior for internal and external clients. - */ -class MOZ_RAII JS_PUBLIC_API(CustomAutoRooter) : private AutoGCRooter -{ - public: - template - explicit CustomAutoRooter(const CX& cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, CUSTOM) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - friend void AutoGCRooter::trace(JSTracer* trc); - - protected: - virtual ~CustomAutoRooter() {} - - /** Supplied by derived class to trace roots. */ - virtual void trace(JSTracer* trc) = 0; - - private: - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -/** A handle to an array of rooted values. */ -class HandleValueArray -{ - const size_t length_; - const Value * const elements_; - - HandleValueArray(size_t len, const Value* elements) : length_(len), elements_(elements) {} - - public: - explicit HandleValueArray(const RootedValue& value) : length_(1), elements_(value.address()) {} - - MOZ_IMPLICIT HandleValueArray(const AutoValueVector& values) - : length_(values.length()), elements_(values.begin()) {} - - template - MOZ_IMPLICIT HandleValueArray(const AutoValueArray& values) : length_(N), elements_(values.begin()) {} - - /** CallArgs must already be rooted somewhere up the stack. */ - MOZ_IMPLICIT HandleValueArray(const JS::CallArgs& args) : length_(args.length()), elements_(args.array()) {} - - /** Use with care! Only call this if the data is guaranteed to be marked. */ - static HandleValueArray fromMarkedLocation(size_t len, const Value* elements) { - return HandleValueArray(len, elements); - } - - static HandleValueArray subarray(const HandleValueArray& values, size_t startIndex, size_t len) { - MOZ_ASSERT(startIndex + len <= values.length()); - return HandleValueArray(len, values.begin() + startIndex); - } - - static HandleValueArray empty() { - return HandleValueArray(0, nullptr); - } - - size_t length() const { return length_; } - const Value* begin() const { return elements_; } - - HandleValue operator[](size_t i) const { - MOZ_ASSERT(i < length_); - return HandleValue::fromMarkedLocation(&elements_[i]); - } -}; - -} /* namespace JS */ - -/************************************************************************/ - -struct JSFreeOp { - protected: - JSRuntime* runtime_; - - explicit JSFreeOp(JSRuntime* rt) - : runtime_(rt) { } - - public: - JSRuntime* runtime() const { - MOZ_ASSERT(runtime_); - return runtime_; - } -}; - -/* Callbacks and their arguments. */ - -/************************************************************************/ - -typedef enum JSGCStatus { - JSGC_BEGIN, - JSGC_END -} JSGCStatus; - -typedef void -(* JSGCCallback)(JSContext* cx, JSGCStatus status, void* data); - -typedef void -(* JSObjectsTenuredCallback)(JSContext* cx, void* data); - -typedef enum JSFinalizeStatus { - /** - * Called when preparing to sweep a group of zones, before anything has been - * swept. The collector will not yield to the mutator before calling the - * callback with JSFINALIZE_GROUP_END status. - */ - JSFINALIZE_GROUP_START, - - /** - * Called when preparing to sweep a group of zones. Weak references to - * unmarked things have been removed and things that are not swept - * incrementally have been finalized at this point. The collector may yield - * to the mutator after this point. - */ - JSFINALIZE_GROUP_END, - - /** - * Called at the end of collection when everything has been swept. - */ - JSFINALIZE_COLLECTION_END -} JSFinalizeStatus; - -typedef void -(* JSFinalizeCallback)(JSFreeOp* fop, JSFinalizeStatus status, bool isZoneGC, void* data); - -typedef void -(* JSWeakPointerZoneGroupCallback)(JSContext* cx, void* data); - -typedef void -(* JSWeakPointerCompartmentCallback)(JSContext* cx, JSCompartment* comp, void* data); - -typedef bool -(* JSInterruptCallback)(JSContext* cx); - -typedef JSObject* -(* JSGetIncumbentGlobalCallback)(JSContext* cx); - -typedef bool -(* JSEnqueuePromiseJobCallback)(JSContext* cx, JS::HandleObject job, - JS::HandleObject allocationSite, JS::HandleObject incumbentGlobal, - void* data); - -enum class PromiseRejectionHandlingState { - Unhandled, - Handled -}; - -typedef void -(* JSPromiseRejectionTrackerCallback)(JSContext* cx, JS::HandleObject promise, - PromiseRejectionHandlingState state, void* data); - -typedef void -(* JSProcessPromiseCallback)(JSContext* cx, JS::HandleObject promise); - -/** - * Possible exception types. These types are part of a JSErrorFormatString - * structure. They define which error to throw in case of a runtime error. - * - * JSEXN_WARN is used for warnings in js.msg files (for instance because we - * don't want to prepend 'Error:' to warning messages). This value can go away - * if we ever decide to use an entirely separate mechanism for warnings. - */ -typedef enum JSExnType { - JSEXN_ERR, - JSEXN_FIRST = JSEXN_ERR, - JSEXN_INTERNALERR, - JSEXN_EVALERR, - JSEXN_RANGEERR, - JSEXN_REFERENCEERR, - JSEXN_SYNTAXERR, - JSEXN_TYPEERR, - JSEXN_URIERR, - JSEXN_DEBUGGEEWOULDRUN, - JSEXN_WASMCOMPILEERROR, - JSEXN_WASMRUNTIMEERROR, - JSEXN_WARN, - JSEXN_LIMIT -} JSExnType; - -typedef struct JSErrorFormatString { - /** The error message name in ASCII. */ - const char* name; - - /** The error format string in ASCII. */ - const char* format; - - /** The number of arguments to expand in the formatted error message. */ - uint16_t argCount; - - /** One of the JSExnType constants above. */ - int16_t exnType; -} JSErrorFormatString; - -typedef const JSErrorFormatString* -(* JSErrorCallback)(void* userRef, const unsigned errorNumber); - -typedef bool -(* JSLocaleToUpperCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval); - -typedef bool -(* JSLocaleToLowerCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval); - -typedef bool -(* JSLocaleCompare)(JSContext* cx, JS::HandleString src1, JS::HandleString src2, - JS::MutableHandleValue rval); - -typedef bool -(* JSLocaleToUnicode)(JSContext* cx, const char* src, JS::MutableHandleValue rval); - -/** - * Callback used to ask the embedding for the cross compartment wrapper handler - * that implements the desired prolicy for this kind of object in the - * destination compartment. |obj| is the object to be wrapped. If |existing| is - * non-nullptr, it will point to an existing wrapper object that should be - * re-used if possible. |existing| is guaranteed to be a cross-compartment - * wrapper with a lazily-defined prototype and the correct global. It is - * guaranteed not to wrap a function. - */ -typedef JSObject* -(* JSWrapObjectCallback)(JSContext* cx, JS::HandleObject existing, JS::HandleObject obj); - -/** - * Callback used by the wrap hook to ask the embedding to prepare an object - * for wrapping in a context. This might include unwrapping other wrappers - * or even finding a more suitable object for the new compartment. - */ -typedef void -(* JSPreWrapCallback)(JSContext* cx, JS::HandleObject scope, JS::HandleObject obj, - JS::HandleObject objectPassedToWrap, - JS::MutableHandleObject retObj); - -struct JSWrapObjectCallbacks -{ - JSWrapObjectCallback wrap; - JSPreWrapCallback preWrap; -}; - -typedef void -(* JSDestroyCompartmentCallback)(JSFreeOp* fop, JSCompartment* compartment); - -typedef size_t -(* JSSizeOfIncludingThisCompartmentCallback)(mozilla::MallocSizeOf mallocSizeOf, - JSCompartment* compartment); - -typedef void -(* JSZoneCallback)(JS::Zone* zone); - -typedef void -(* JSCompartmentNameCallback)(JSContext* cx, JSCompartment* compartment, - char* buf, size_t bufsize); - -/************************************************************************/ - -static MOZ_ALWAYS_INLINE JS::Value -JS_NumberValue(double d) -{ - int32_t i; - d = JS::CanonicalizeNaN(d); - if (mozilla::NumberIsInt32(d, &i)) - return JS::Int32Value(i); - return JS::DoubleValue(d); -} - -/************************************************************************/ - -JS_PUBLIC_API(bool) -JS_StringHasBeenPinned(JSContext* cx, JSString* str); - -namespace JS { - -/** - * Container class for passing in script source buffers to the JS engine. This - * not only groups the buffer and length values, it also provides a way to - * optionally pass ownership of the buffer to the JS engine without copying. - * Rules for use: - * - * 1) The data array must be allocated with js_malloc() or js_realloc() if - * ownership is being granted to the SourceBufferHolder. - * 2) If ownership is not given to the SourceBufferHolder, then the memory - * must be kept alive until the JS compilation is complete. - * 3) Any code calling SourceBufferHolder::take() must guarantee to keep the - * memory alive until JS compilation completes. Normally only the JS - * engine should be calling take(). - * - * Example use: - * - * size_t length = 512; - * char16_t* chars = static_cast(js_malloc(sizeof(char16_t) * length)); - * JS::SourceBufferHolder srcBuf(chars, length, JS::SourceBufferHolder::GiveOwnership); - * JS::Compile(cx, options, srcBuf); - */ -class MOZ_STACK_CLASS SourceBufferHolder final -{ - public: - enum Ownership { - NoOwnership, - GiveOwnership - }; - - SourceBufferHolder(const char16_t* data, size_t dataLength, Ownership ownership) - : data_(data), - length_(dataLength), - ownsChars_(ownership == GiveOwnership) - { - // Ensure that null buffers properly return an unowned, empty, - // null-terminated string. - static const char16_t NullChar_ = 0; - if (!get()) { - data_ = &NullChar_; - length_ = 0; - ownsChars_ = false; - } - } - - SourceBufferHolder(SourceBufferHolder&& other) - : data_(other.data_), - length_(other.length_), - ownsChars_(other.ownsChars_) - { - other.data_ = nullptr; - other.length_ = 0; - other.ownsChars_ = false; - } - - ~SourceBufferHolder() { - if (ownsChars_) - js_free(const_cast(data_)); - } - - // Access the underlying source buffer without affecting ownership. - const char16_t* get() const { return data_; } - - // Length of the source buffer in char16_t code units (not bytes) - size_t length() const { return length_; } - - // Returns true if the SourceBufferHolder owns the buffer and will free - // it upon destruction. If true, it is legal to call take(). - bool ownsChars() const { return ownsChars_; } - - // Retrieve and take ownership of the underlying data buffer. The caller - // is now responsible for calling js_free() on the returned value, *but only - // after JS script compilation has completed*. - // - // After the buffer has been taken the SourceBufferHolder functions as if - // it had been constructed on an unowned buffer; get() and length() still - // work. In order for this to be safe the taken buffer must be kept alive - // until after JS script compilation completes as noted above. - // - // Note, it's the caller's responsibility to check ownsChars() before taking - // the buffer. Taking and then free'ing an unowned buffer will have dire - // consequences. - char16_t* take() { - MOZ_ASSERT(ownsChars_); - ownsChars_ = false; - return const_cast(data_); - } - - private: - SourceBufferHolder(SourceBufferHolder&) = delete; - SourceBufferHolder& operator=(SourceBufferHolder&) = delete; - - const char16_t* data_; - size_t length_; - bool ownsChars_; -}; - -} /* namespace JS */ - -/************************************************************************/ - -/* Property attributes, set in JSPropertySpec and passed to API functions. - * - * NB: The data structure in which some of these values are stored only uses - * a uint8_t to store the relevant information. Proceed with caution if - * trying to reorder or change the the first byte worth of flags. - */ -#define JSPROP_ENUMERATE 0x01 /* property is visible to for/in loop */ -#define JSPROP_READONLY 0x02 /* not settable: assignment is no-op. - This flag is only valid when neither - JSPROP_GETTER nor JSPROP_SETTER is - set. */ -#define JSPROP_PERMANENT 0x04 /* property cannot be deleted */ -#define JSPROP_PROPOP_ACCESSORS 0x08 /* Passed to JS_Define(UC)Property* and - JS_DefineElement if getters/setters - are JSGetterOp/JSSetterOp */ -#define JSPROP_GETTER 0x10 /* property holds getter function */ -#define JSPROP_SETTER 0x20 /* property holds setter function */ -#define JSPROP_SHARED 0x40 /* don't allocate a value slot for this - property; don't copy the property on - set of the same-named property in an - object that delegates to a prototype - containing this property */ -#define JSPROP_INTERNAL_USE_BIT 0x80 /* internal JS engine use only */ -#define JSFUN_STUB_GSOPS 0x200 /* use JS_PropertyStub getter/setter - instead of defaulting to class gsops - for property holding function */ - -#define JSFUN_CONSTRUCTOR 0x400 /* native that can be called as a ctor */ - -// 0x800 /* Unused */ - -#define JSFUN_HAS_REST 0x1000 /* function has ...rest parameter. */ - -#define JSFUN_FLAGS_MASK 0x1e00 /* | of all the JSFUN_* flags */ - -/* - * If set, will allow redefining a non-configurable property, but only on a - * non-DOM global. This is a temporary hack that will need to go away in bug - * 1105518. - */ -#define JSPROP_REDEFINE_NONCONFIGURABLE 0x1000 - -/* - * Resolve hooks and enumerate hooks must pass this flag when calling - * JS_Define* APIs to reify lazily-defined properties. - * - * JSPROP_RESOLVING is used only with property-defining APIs. It tells the - * engine to skip the resolve hook when performing the lookup at the beginning - * of property definition. This keeps the resolve hook from accidentally - * triggering itself: unchecked recursion. - * - * For enumerate hooks, triggering the resolve hook would be merely silly, not - * fatal, except in some cases involving non-configurable properties. - */ -#define JSPROP_RESOLVING 0x2000 - -#define JSPROP_IGNORE_ENUMERATE 0x4000 /* ignore the value in JSPROP_ENUMERATE. - This flag only valid when defining over - an existing property. */ -#define JSPROP_IGNORE_READONLY 0x8000 /* ignore the value in JSPROP_READONLY. - This flag only valid when defining over - an existing property. */ -#define JSPROP_IGNORE_PERMANENT 0x10000 /* ignore the value in JSPROP_PERMANENT. - This flag only valid when defining over - an existing property. */ -#define JSPROP_IGNORE_VALUE 0x20000 /* ignore the Value in the descriptor. Nothing was - specified when passed to Object.defineProperty - from script. */ - -/** Microseconds since the epoch, midnight, January 1, 1970 UTC. */ -extern JS_PUBLIC_API(int64_t) -JS_Now(void); - -/** Don't want to export data, so provide accessors for non-inline Values. */ -extern JS_PUBLIC_API(JS::Value) -JS_GetNaNValue(JSContext* cx); - -extern JS_PUBLIC_API(JS::Value) -JS_GetNegativeInfinityValue(JSContext* cx); - -extern JS_PUBLIC_API(JS::Value) -JS_GetPositiveInfinityValue(JSContext* cx); - -extern JS_PUBLIC_API(JS::Value) -JS_GetEmptyStringValue(JSContext* cx); - -extern JS_PUBLIC_API(JSString*) -JS_GetEmptyString(JSContext* cx); - -extern JS_PUBLIC_API(bool) -JS_ValueToObject(JSContext* cx, JS::HandleValue v, JS::MutableHandleObject objp); - -extern JS_PUBLIC_API(JSFunction*) -JS_ValueToFunction(JSContext* cx, JS::HandleValue v); - -extern JS_PUBLIC_API(JSFunction*) -JS_ValueToConstructor(JSContext* cx, JS::HandleValue v); - -extern JS_PUBLIC_API(JSString*) -JS_ValueToSource(JSContext* cx, JS::Handle v); - -extern JS_PUBLIC_API(bool) -JS_DoubleIsInt32(double d, int32_t* ip); - -extern JS_PUBLIC_API(JSType) -JS_TypeOfValue(JSContext* cx, JS::Handle v); - -namespace JS { - -extern JS_PUBLIC_API(const char*) -InformalValueTypeName(const JS::Value& v); - -} /* namespace JS */ - -extern JS_PUBLIC_API(bool) -JS_StrictlyEqual(JSContext* cx, JS::Handle v1, JS::Handle v2, bool* equal); - -extern JS_PUBLIC_API(bool) -JS_LooselyEqual(JSContext* cx, JS::Handle v1, JS::Handle v2, bool* equal); - -extern JS_PUBLIC_API(bool) -JS_SameValue(JSContext* cx, JS::Handle v1, JS::Handle v2, bool* same); - -/** True iff fun is the global eval function. */ -extern JS_PUBLIC_API(bool) -JS_IsBuiltinEvalFunction(JSFunction* fun); - -/** True iff fun is the Function constructor. */ -extern JS_PUBLIC_API(bool) -JS_IsBuiltinFunctionConstructor(JSFunction* fun); - -/************************************************************************/ - -/* - * Locking, contexts, and memory allocation. - * - * It is important that SpiderMonkey be initialized, and the first context - * be created, in a single-threaded fashion. Otherwise the behavior of the - * library is undefined. - * See: http://developer.mozilla.org/en/docs/Category:JSAPI_Reference - */ - -extern JS_PUBLIC_API(JSContext*) -JS_NewContext(uint32_t maxbytes, - uint32_t maxNurseryBytes = JS::DefaultNurseryBytes, - JSContext* parentContext = nullptr); - -extern JS_PUBLIC_API(void) -JS_DestroyContext(JSContext* cx); - -typedef double (*JS_CurrentEmbedderTimeFunction)(); - -/** - * The embedding can specify a time function that will be used in some - * situations. The function can return the time however it likes; but - * the norm is to return times in units of milliseconds since an - * arbitrary, but consistent, epoch. If the time function is not set, - * a built-in default will be used. - */ -JS_PUBLIC_API(void) -JS_SetCurrentEmbedderTimeFunction(JS_CurrentEmbedderTimeFunction timeFn); - -/** - * Return the time as computed using the current time function, or a - * suitable default if one has not been set. - */ -JS_PUBLIC_API(double) -JS_GetCurrentEmbedderTime(); - -JS_PUBLIC_API(void*) -JS_GetContextPrivate(JSContext* cx); - -JS_PUBLIC_API(void) -JS_SetContextPrivate(JSContext* cx, void* data); - -extern JS_PUBLIC_API(JSContext*) -JS_GetParentContext(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_BeginRequest(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_EndRequest(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_SetFutexCanWait(JSContext* cx); - -namespace js { - -void -AssertHeapIsIdle(JSRuntime* rt); - -} /* namespace js */ - -class MOZ_RAII JSAutoRequest -{ - public: - explicit JSAutoRequest(JSContext* cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mContext(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - JS_BeginRequest(mContext); - } - ~JSAutoRequest() { - JS_EndRequest(mContext); - } - - protected: - JSContext* mContext; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - -#if 0 - private: - static void* operator new(size_t) CPP_THROW_NEW { return 0; } - static void operator delete(void*, size_t) { } -#endif -}; - -extern JS_PUBLIC_API(JSVersion) -JS_GetVersion(JSContext* cx); - -/** - * Mutate the version on the compartment. This is generally discouraged, but - * necessary to support the version mutation in the js and xpc shell command - * set. - * - * It would be nice to put this in jsfriendapi, but the linkage requirements - * of the shells make that impossible. - */ -JS_PUBLIC_API(void) -JS_SetVersionForCompartment(JSCompartment* compartment, JSVersion version); - -extern JS_PUBLIC_API(const char*) -JS_VersionToString(JSVersion version); - -extern JS_PUBLIC_API(JSVersion) -JS_StringToVersion(const char* string); - -namespace JS { - -class JS_PUBLIC_API(ContextOptions) { - public: - ContextOptions() - : baseline_(true), - ion_(true), - asmJS_(true), - wasm_(false), - wasmAlwaysBaseline_(false), - throwOnAsmJSValidationFailure_(false), - nativeRegExp_(true), - unboxedArrays_(false), - asyncStack_(true), - throwOnDebuggeeWouldRun_(true), - dumpStackOnDebuggeeWouldRun_(false), - werror_(false), - strictMode_(false), - extraWarnings_(false) - { - } - - bool baseline() const { return baseline_; } - ContextOptions& setBaseline(bool flag) { - baseline_ = flag; - return *this; - } - ContextOptions& toggleBaseline() { - baseline_ = !baseline_; - return *this; - } - - bool ion() const { return ion_; } - ContextOptions& setIon(bool flag) { - ion_ = flag; - return *this; - } - ContextOptions& toggleIon() { - ion_ = !ion_; - return *this; - } - - bool asmJS() const { return asmJS_; } - ContextOptions& setAsmJS(bool flag) { - asmJS_ = flag; - return *this; - } - ContextOptions& toggleAsmJS() { - asmJS_ = !asmJS_; - return *this; - } - - bool wasm() const { return wasm_; } - ContextOptions& setWasm(bool flag) { - wasm_ = flag; - return *this; - } - ContextOptions& toggleWasm() { - wasm_ = !wasm_; - return *this; - } - - bool wasmAlwaysBaseline() const { return wasmAlwaysBaseline_; } - ContextOptions& setWasmAlwaysBaseline(bool flag) { - wasmAlwaysBaseline_ = flag; - return *this; - } - ContextOptions& toggleWasmAlwaysBaseline() { - wasmAlwaysBaseline_ = !wasmAlwaysBaseline_; - return *this; - } - - bool throwOnAsmJSValidationFailure() const { return throwOnAsmJSValidationFailure_; } - ContextOptions& setThrowOnAsmJSValidationFailure(bool flag) { - throwOnAsmJSValidationFailure_ = flag; - return *this; - } - ContextOptions& toggleThrowOnAsmJSValidationFailure() { - throwOnAsmJSValidationFailure_ = !throwOnAsmJSValidationFailure_; - return *this; - } - - bool nativeRegExp() const { return nativeRegExp_; } - ContextOptions& setNativeRegExp(bool flag) { - nativeRegExp_ = flag; - return *this; - } - - bool unboxedArrays() const { return unboxedArrays_; } - ContextOptions& setUnboxedArrays(bool flag) { - unboxedArrays_ = flag; - return *this; - } - - bool asyncStack() const { return asyncStack_; } - ContextOptions& setAsyncStack(bool flag) { - asyncStack_ = flag; - return *this; - } - - bool throwOnDebuggeeWouldRun() const { return throwOnDebuggeeWouldRun_; } - ContextOptions& setThrowOnDebuggeeWouldRun(bool flag) { - throwOnDebuggeeWouldRun_ = flag; - return *this; - } - - bool dumpStackOnDebuggeeWouldRun() const { return dumpStackOnDebuggeeWouldRun_; } - ContextOptions& setDumpStackOnDebuggeeWouldRun(bool flag) { - dumpStackOnDebuggeeWouldRun_ = flag; - return *this; - } - - bool werror() const { return werror_; } - ContextOptions& setWerror(bool flag) { - werror_ = flag; - return *this; - } - ContextOptions& toggleWerror() { - werror_ = !werror_; - return *this; - } - - bool strictMode() const { return strictMode_; } - ContextOptions& setStrictMode(bool flag) { - strictMode_ = flag; - return *this; - } - ContextOptions& toggleStrictMode() { - strictMode_ = !strictMode_; - return *this; - } - - bool extraWarnings() const { return extraWarnings_; } - ContextOptions& setExtraWarnings(bool flag) { - extraWarnings_ = flag; - return *this; - } - ContextOptions& toggleExtraWarnings() { - extraWarnings_ = !extraWarnings_; - return *this; - } - - private: - bool baseline_ : 1; - bool ion_ : 1; - bool asmJS_ : 1; - bool wasm_ : 1; - bool wasmAlwaysBaseline_ : 1; - bool throwOnAsmJSValidationFailure_ : 1; - bool nativeRegExp_ : 1; - bool unboxedArrays_ : 1; - bool asyncStack_ : 1; - bool throwOnDebuggeeWouldRun_ : 1; - bool dumpStackOnDebuggeeWouldRun_ : 1; - bool werror_ : 1; - bool strictMode_ : 1; - bool extraWarnings_ : 1; -}; - -JS_PUBLIC_API(ContextOptions&) -ContextOptionsRef(JSContext* cx); - -/** - * Initialize the runtime's self-hosted code. Embeddings should call this - * exactly once per runtime/context, before the first JS_NewGlobalObject - * call. - */ -JS_PUBLIC_API(bool) -InitSelfHostedCode(JSContext* cx); - -/** - * Asserts (in debug and release builds) that `obj` belongs to the current - * thread's context. - */ -JS_PUBLIC_API(void) -AssertObjectBelongsToCurrentThread(JSObject* obj); - -} /* namespace JS */ - -extern JS_PUBLIC_API(const char*) -JS_GetImplementationVersion(void); - -extern JS_PUBLIC_API(void) -JS_SetDestroyCompartmentCallback(JSContext* cx, JSDestroyCompartmentCallback callback); - -extern JS_PUBLIC_API(void) -JS_SetSizeOfIncludingThisCompartmentCallback(JSContext* cx, - JSSizeOfIncludingThisCompartmentCallback callback); - -extern JS_PUBLIC_API(void) -JS_SetDestroyZoneCallback(JSContext* cx, JSZoneCallback callback); - -extern JS_PUBLIC_API(void) -JS_SetSweepZoneCallback(JSContext* cx, JSZoneCallback callback); - -extern JS_PUBLIC_API(void) -JS_SetCompartmentNameCallback(JSContext* cx, JSCompartmentNameCallback callback); - -extern JS_PUBLIC_API(void) -JS_SetWrapObjectCallbacks(JSContext* cx, const JSWrapObjectCallbacks* callbacks); - -extern JS_PUBLIC_API(void) -JS_SetCompartmentPrivate(JSCompartment* compartment, void* data); - -extern JS_PUBLIC_API(void*) -JS_GetCompartmentPrivate(JSCompartment* compartment); - -extern JS_PUBLIC_API(void) -JS_SetZoneUserData(JS::Zone* zone, void* data); - -extern JS_PUBLIC_API(void*) -JS_GetZoneUserData(JS::Zone* zone); - -extern JS_PUBLIC_API(bool) -JS_WrapObject(JSContext* cx, JS::MutableHandleObject objp); - -extern JS_PUBLIC_API(bool) -JS_WrapValue(JSContext* cx, JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(JSObject*) -JS_TransplantObject(JSContext* cx, JS::HandleObject origobj, JS::HandleObject target); - -extern JS_PUBLIC_API(bool) -JS_RefreshCrossCompartmentWrappers(JSContext* cx, JS::Handle obj); - -/* - * At any time, a JSContext has a current (possibly-nullptr) compartment. - * Compartments are described in: - * - * developer.mozilla.org/en-US/docs/SpiderMonkey/SpiderMonkey_compartments - * - * The current compartment of a context may be changed. The preferred way to do - * this is with JSAutoCompartment: - * - * void foo(JSContext* cx, JSObject* obj) { - * // in some compartment 'c' - * { - * JSAutoCompartment ac(cx, obj); // constructor enters - * // in the compartment of 'obj' - * } // destructor leaves - * // back in compartment 'c' - * } - * - * For more complicated uses that don't neatly fit in a C++ stack frame, the - * compartment can entered and left using separate function calls: - * - * void foo(JSContext* cx, JSObject* obj) { - * // in 'oldCompartment' - * JSCompartment* oldCompartment = JS_EnterCompartment(cx, obj); - * // in the compartment of 'obj' - * JS_LeaveCompartment(cx, oldCompartment); - * // back in 'oldCompartment' - * } - * - * Note: these calls must still execute in a LIFO manner w.r.t all other - * enter/leave calls on the context. Furthermore, only the return value of a - * JS_EnterCompartment call may be passed as the 'oldCompartment' argument of - * the corresponding JS_LeaveCompartment call. - */ - -class MOZ_RAII JS_PUBLIC_API(JSAutoCompartment) -{ - JSContext* cx_; - JSCompartment* oldCompartment_; - public: - JSAutoCompartment(JSContext* cx, JSObject* target - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - JSAutoCompartment(JSContext* cx, JSScript* target - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - ~JSAutoCompartment(); - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class MOZ_RAII JS_PUBLIC_API(JSAutoNullableCompartment) -{ - JSContext* cx_; - JSCompartment* oldCompartment_; - public: - explicit JSAutoNullableCompartment(JSContext* cx, JSObject* targetOrNull - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - ~JSAutoNullableCompartment(); - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -/** NB: This API is infallible; a nullptr return value does not indicate error. */ -extern JS_PUBLIC_API(JSCompartment*) -JS_EnterCompartment(JSContext* cx, JSObject* target); - -extern JS_PUBLIC_API(void) -JS_LeaveCompartment(JSContext* cx, JSCompartment* oldCompartment); - -typedef void (*JSIterateCompartmentCallback)(JSContext* cx, void* data, JSCompartment* compartment); - -/** - * This function calls |compartmentCallback| on every compartment. Beware that - * there is no guarantee that the compartment will survive after the callback - * returns. Also, barriers are disabled via the TraceSession. - */ -extern JS_PUBLIC_API(void) -JS_IterateCompartments(JSContext* cx, void* data, - JSIterateCompartmentCallback compartmentCallback); - -/** - * Initialize standard JS class constructors, prototypes, and any top-level - * functions and constants associated with the standard classes (e.g. isNaN - * for Number). - * - * NB: This sets cx's global object to obj if it was null. - */ -extern JS_PUBLIC_API(bool) -JS_InitStandardClasses(JSContext* cx, JS::Handle obj); - -/** - * Resolve id, which must contain either a string or an int, to a standard - * class name in obj if possible, defining the class's constructor and/or - * prototype and storing true in *resolved. If id does not name a standard - * class or a top-level property induced by initializing a standard class, - * store false in *resolved and just return true. Return false on error, - * as usual for bool result-typed API entry points. - * - * This API can be called directly from a global object class's resolve op, - * to define standard classes lazily. The class's enumerate op should call - * JS_EnumerateStandardClasses(cx, obj), to define eagerly during for..in - * loops any classes not yet resolved lazily. - */ -extern JS_PUBLIC_API(bool) -JS_ResolveStandardClass(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolved); - -extern JS_PUBLIC_API(bool) -JS_MayResolveStandardClass(const JSAtomState& names, jsid id, JSObject* maybeObj); - -extern JS_PUBLIC_API(bool) -JS_EnumerateStandardClasses(JSContext* cx, JS::HandleObject obj); - -extern JS_PUBLIC_API(bool) -JS_GetClassObject(JSContext* cx, JSProtoKey key, JS::MutableHandle objp); - -extern JS_PUBLIC_API(bool) -JS_GetClassPrototype(JSContext* cx, JSProtoKey key, JS::MutableHandle objp); - -namespace JS { - -/* - * Determine if the given object is an instance/prototype/constructor for a standard - * class. If so, return the associated JSProtoKey. If not, return JSProto_Null. - */ - -extern JS_PUBLIC_API(JSProtoKey) -IdentifyStandardInstance(JSObject* obj); - -extern JS_PUBLIC_API(JSProtoKey) -IdentifyStandardPrototype(JSObject* obj); - -extern JS_PUBLIC_API(JSProtoKey) -IdentifyStandardInstanceOrPrototype(JSObject* obj); - -extern JS_PUBLIC_API(JSProtoKey) -IdentifyStandardConstructor(JSObject* obj); - -extern JS_PUBLIC_API(void) -ProtoKeyToId(JSContext* cx, JSProtoKey key, JS::MutableHandleId idp); - -} /* namespace JS */ - -extern JS_PUBLIC_API(JSProtoKey) -JS_IdToProtoKey(JSContext* cx, JS::HandleId id); - -/** - * Returns the original value of |Function.prototype| from the global object in - * which |forObj| was created. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetFunctionPrototype(JSContext* cx, JS::HandleObject forObj); - -/** - * Returns the original value of |Object.prototype| from the global object in - * which |forObj| was created. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetObjectPrototype(JSContext* cx, JS::HandleObject forObj); - -/** - * Returns the original value of |Array.prototype| from the global object in - * which |forObj| was created. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetArrayPrototype(JSContext* cx, JS::HandleObject forObj); - -/** - * Returns the original value of |Error.prototype| from the global - * object of the current compartment of cx. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetErrorPrototype(JSContext* cx); - -/** - * Returns the %IteratorPrototype% object that all built-in iterator prototype - * chains go through for the global object of the current compartment of cx. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetIteratorPrototype(JSContext* cx); - -extern JS_PUBLIC_API(JSObject*) -JS_GetGlobalForObject(JSContext* cx, JSObject* obj); - -extern JS_PUBLIC_API(bool) -JS_IsGlobalObject(JSObject* obj); - -extern JS_PUBLIC_API(JSObject*) -JS_GlobalLexicalEnvironment(JSObject* obj); - -extern JS_PUBLIC_API(bool) -JS_HasExtensibleLexicalEnvironment(JSObject* obj); - -extern JS_PUBLIC_API(JSObject*) -JS_ExtensibleLexicalEnvironment(JSObject* obj); - -/** - * May return nullptr, if |c| never had a global (e.g. the atoms compartment), - * or if |c|'s global has been collected. - */ -extern JS_PUBLIC_API(JSObject*) -JS_GetGlobalForCompartmentOrNull(JSContext* cx, JSCompartment* c); - -namespace JS { - -extern JS_PUBLIC_API(JSObject*) -CurrentGlobalOrNull(JSContext* cx); - -} // namespace JS - -/** - * Add 'Reflect.parse', a SpiderMonkey extension, to the Reflect object on the - * given global. - */ -extern JS_PUBLIC_API(bool) -JS_InitReflectParse(JSContext* cx, JS::HandleObject global); - -/** - * Add various profiling-related functions as properties of the given object. - * Defined in builtin/Profilers.cpp. - */ -extern JS_PUBLIC_API(bool) -JS_DefineProfilingFunctions(JSContext* cx, JS::HandleObject obj); - -/* Defined in vm/Debugger.cpp. */ -extern JS_PUBLIC_API(bool) -JS_DefineDebuggerObject(JSContext* cx, JS::HandleObject obj); - -#ifdef JS_HAS_CTYPES -/** - * Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes' - * object will be sealed. - */ -extern JS_PUBLIC_API(bool) -JS_InitCTypesClass(JSContext* cx, JS::HandleObject global); - -/** - * Convert a unicode string 'source' of length 'slen' to the platform native - * charset, returning a null-terminated string allocated with JS_malloc. On - * failure, this function should report an error. - */ -typedef char* -(* JSCTypesUnicodeToNativeFun)(JSContext* cx, const char16_t* source, size_t slen); - -/** - * Set of function pointers that ctypes can use for various internal functions. - * See JS_SetCTypesCallbacks below. Providing nullptr for a function is safe, - * and will result in the applicable ctypes functionality not being available. - */ -struct JSCTypesCallbacks { - JSCTypesUnicodeToNativeFun unicodeToNative; -}; - -typedef struct JSCTypesCallbacks JSCTypesCallbacks; - -/** - * Set the callbacks on the provided 'ctypesObj' object. 'callbacks' should be a - * pointer to static data that exists for the lifetime of 'ctypesObj', but it - * may safely be altered after calling this function and without having - * to call this function again. - */ -extern JS_PUBLIC_API(void) -JS_SetCTypesCallbacks(JSObject* ctypesObj, const JSCTypesCallbacks* callbacks); -#endif - -extern JS_PUBLIC_API(void*) -JS_malloc(JSContext* cx, size_t nbytes); - -extern JS_PUBLIC_API(void*) -JS_realloc(JSContext* cx, void* p, size_t oldBytes, size_t newBytes); - -/** - * A wrapper for js_free(p) that may delay js_free(p) invocation as a - * performance optimization. - * cx may be nullptr. - */ -extern JS_PUBLIC_API(void) -JS_free(JSContext* cx, void* p); - -/** - * A wrapper for js_free(p) that may delay js_free(p) invocation as a - * performance optimization as specified by the given JSFreeOp instance. - */ -extern JS_PUBLIC_API(void) -JS_freeop(JSFreeOp* fop, void* p); - -extern JS_PUBLIC_API(void) -JS_updateMallocCounter(JSContext* cx, size_t nbytes); - -extern JS_PUBLIC_API(char*) -JS_strdup(JSContext* cx, const char* s); - -/** - * Register externally maintained GC roots. - * - * traceOp: the trace operation. For each root the implementation should call - * JS::TraceEdge whenever the root contains a traceable thing. - * data: the data argument to pass to each invocation of traceOp. - */ -extern JS_PUBLIC_API(bool) -JS_AddExtraGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data); - -/** Undo a call to JS_AddExtraGCRootsTracer. */ -extern JS_PUBLIC_API(void) -JS_RemoveExtraGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data); - -/* - * Garbage collector API. - */ -extern JS_PUBLIC_API(void) -JS_GC(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_MaybeGC(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_SetGCCallback(JSContext* cx, JSGCCallback cb, void* data); - -extern JS_PUBLIC_API(void) -JS_SetObjectsTenuredCallback(JSContext* cx, JSObjectsTenuredCallback cb, - void* data); - -extern JS_PUBLIC_API(bool) -JS_AddFinalizeCallback(JSContext* cx, JSFinalizeCallback cb, void* data); - -extern JS_PUBLIC_API(void) -JS_RemoveFinalizeCallback(JSContext* cx, JSFinalizeCallback cb); - -/* - * Weak pointers and garbage collection - * - * Weak pointers are by their nature not marked as part of garbage collection, - * but they may need to be updated in two cases after a GC: - * - * 1) Their referent was found not to be live and is about to be finalized - * 2) Their referent has been moved by a compacting GC - * - * To handle this, any part of the system that maintain weak pointers to - * JavaScript GC things must register a callback with - * JS_(Add,Remove)WeakPointer{ZoneGroup,Compartment}Callback(). This callback - * must then call JS_UpdateWeakPointerAfterGC() on all weak pointers it knows - * about. - * - * Since sweeping is incremental, we have several callbacks to avoid repeatedly - * having to visit all embedder structures. The WeakPointerZoneGroupCallback is - * called once for each strongly connected group of zones, whereas the - * WeakPointerCompartmentCallback is called once for each compartment that is - * visited while sweeping. Structures that cannot contain references in more - * than one compartment should sweep the relevant per-compartment structures - * using the latter callback to minimizer per-slice overhead. - * - * The argument to JS_UpdateWeakPointerAfterGC() is an in-out param. If the - * referent is about to be finalized the pointer will be set to null. If the - * referent has been moved then the pointer will be updated to point to the new - * location. - * - * Callers of this method are responsible for updating any state that is - * dependent on the object's address. For example, if the object's address is - * used as a key in a hashtable, then the object must be removed and - * re-inserted with the correct hash. - */ - -extern JS_PUBLIC_API(bool) -JS_AddWeakPointerZoneGroupCallback(JSContext* cx, JSWeakPointerZoneGroupCallback cb, void* data); - -extern JS_PUBLIC_API(void) -JS_RemoveWeakPointerZoneGroupCallback(JSContext* cx, JSWeakPointerZoneGroupCallback cb); - -extern JS_PUBLIC_API(bool) -JS_AddWeakPointerCompartmentCallback(JSContext* cx, JSWeakPointerCompartmentCallback cb, - void* data); - -extern JS_PUBLIC_API(void) -JS_RemoveWeakPointerCompartmentCallback(JSContext* cx, JSWeakPointerCompartmentCallback cb); - -extern JS_PUBLIC_API(void) -JS_UpdateWeakPointerAfterGC(JS::Heap* objp); - -extern JS_PUBLIC_API(void) -JS_UpdateWeakPointerAfterGCUnbarriered(JSObject** objp); - -typedef enum JSGCParamKey { - /** Maximum nominal heap before last ditch GC. */ - JSGC_MAX_BYTES = 0, - - /** Number of JS_malloc bytes before last ditch GC. */ - JSGC_MAX_MALLOC_BYTES = 1, - - /** Amount of bytes allocated by the GC. */ - JSGC_BYTES = 3, - - /** Number of times GC has been invoked. Includes both major and minor GC. */ - JSGC_NUMBER = 4, - - /** Select GC mode. */ - JSGC_MODE = 6, - - /** Number of cached empty GC chunks. */ - JSGC_UNUSED_CHUNKS = 7, - - /** Total number of allocated GC chunks. */ - JSGC_TOTAL_CHUNKS = 8, - - /** Max milliseconds to spend in an incremental GC slice. */ - JSGC_SLICE_TIME_BUDGET = 9, - - /** Maximum size the GC mark stack can grow to. */ - JSGC_MARK_STACK_LIMIT = 10, - - /** - * GCs less than this far apart in time will be considered 'high-frequency GCs'. - * See setGCLastBytes in jsgc.cpp. - */ - JSGC_HIGH_FREQUENCY_TIME_LIMIT = 11, - - /** Start of dynamic heap growth. */ - JSGC_HIGH_FREQUENCY_LOW_LIMIT = 12, - - /** End of dynamic heap growth. */ - JSGC_HIGH_FREQUENCY_HIGH_LIMIT = 13, - - /** Upper bound of heap growth. */ - JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX = 14, - - /** Lower bound of heap growth. */ - JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN = 15, - - /** Heap growth for low frequency GCs. */ - JSGC_LOW_FREQUENCY_HEAP_GROWTH = 16, - - /** - * If false, the heap growth factor is fixed at 3. If true, it is determined - * based on whether GCs are high- or low- frequency. - */ - JSGC_DYNAMIC_HEAP_GROWTH = 17, - - /** If true, high-frequency GCs will use a longer mark slice. */ - JSGC_DYNAMIC_MARK_SLICE = 18, - - /** Lower limit after which we limit the heap growth. */ - JSGC_ALLOCATION_THRESHOLD = 19, - - /** - * We try to keep at least this many unused chunks in the free chunk pool at - * all times, even after a shrinking GC. - */ - JSGC_MIN_EMPTY_CHUNK_COUNT = 21, - - /** We never keep more than this many unused chunks in the free chunk pool. */ - JSGC_MAX_EMPTY_CHUNK_COUNT = 22, - - /** Whether compacting GC is enabled. */ - JSGC_COMPACTING_ENABLED = 23, - - /** If true, painting can trigger IGC slices. */ - JSGC_REFRESH_FRAME_SLICES_ENABLED = 24, -} JSGCParamKey; - -extern JS_PUBLIC_API(void) -JS_SetGCParameter(JSContext* cx, JSGCParamKey key, uint32_t value); - -extern JS_PUBLIC_API(uint32_t) -JS_GetGCParameter(JSContext* cx, JSGCParamKey key); - -extern JS_PUBLIC_API(void) -JS_SetGCParametersBasedOnAvailableMemory(JSContext* cx, uint32_t availMem); - -/** - * Create a new JSString whose chars member refers to external memory, i.e., - * memory requiring application-specific finalization. - */ -extern JS_PUBLIC_API(JSString*) -JS_NewExternalString(JSContext* cx, const char16_t* chars, size_t length, - const JSStringFinalizer* fin); - -/** - * Return whether 'str' was created with JS_NewExternalString or - * JS_NewExternalStringWithClosure. - */ -extern JS_PUBLIC_API(bool) -JS_IsExternalString(JSString* str); - -/** - * Return the 'fin' arg passed to JS_NewExternalString. - */ -extern JS_PUBLIC_API(const JSStringFinalizer*) -JS_GetExternalStringFinalizer(JSString* str); - -/** - * Set the size of the native stack that should not be exceed. To disable - * stack size checking pass 0. - * - * SpiderMonkey allows for a distinction between system code (such as GCs, which - * may incidentally be triggered by script but are not strictly performed on - * behalf of such script), trusted script (as determined by JS_SetTrustedPrincipals), - * and untrusted script. Each kind of code may have a different stack quota, - * allowing embedders to keep higher-priority machinery running in the face of - * scripted stack exhaustion by something else. - * - * The stack quotas for each kind of code should be monotonically descending, - * and may be specified with this function. If 0 is passed for a given kind - * of code, it defaults to the value of the next-highest-priority kind. - * - * This function may only be called immediately after the runtime is initialized - * and before any code is executed and/or interrupts requested. - */ -extern JS_PUBLIC_API(void) -JS_SetNativeStackQuota(JSContext* cx, size_t systemCodeStackSize, - size_t trustedScriptStackSize = 0, - size_t untrustedScriptStackSize = 0); - -/************************************************************************/ - -extern JS_PUBLIC_API(bool) -JS_ValueToId(JSContext* cx, JS::HandleValue v, JS::MutableHandleId idp); - -extern JS_PUBLIC_API(bool) -JS_StringToId(JSContext* cx, JS::HandleString s, JS::MutableHandleId idp); - -extern JS_PUBLIC_API(bool) -JS_IdToValue(JSContext* cx, jsid id, JS::MutableHandle vp); - -namespace JS { - -/** - * Convert obj to a primitive value. On success, store the result in vp and - * return true. - * - * The hint argument must be JSTYPE_STRING, JSTYPE_NUMBER, or JSTYPE_VOID (no - * hint). - * - * Implements: ES6 7.1.1 ToPrimitive(input, [PreferredType]). - */ -extern JS_PUBLIC_API(bool) -ToPrimitive(JSContext* cx, JS::HandleObject obj, JSType hint, JS::MutableHandleValue vp); - -/** - * If args.get(0) is one of the strings "string", "number", or "default", set - * *result to JSTYPE_STRING, JSTYPE_NUMBER, or JSTYPE_VOID accordingly and - * return true. Otherwise, return false with a TypeError pending. - * - * This can be useful in implementing a @@toPrimitive method. - */ -extern JS_PUBLIC_API(bool) -GetFirstArgumentAsTypeHint(JSContext* cx, CallArgs args, JSType *result); - -} /* namespace JS */ - -extern JS_PUBLIC_API(bool) -JS_PropertyStub(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(bool) -JS_StrictPropertyStub(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp, JS::ObjectOpResult& result); - -template -struct JSConstScalarSpec { - const char* name; - T val; -}; - -typedef JSConstScalarSpec JSConstDoubleSpec; -typedef JSConstScalarSpec JSConstIntegerSpec; - -struct JSJitInfo; - -/** - * Wrapper to relace JSNative for JSPropertySpecs and JSFunctionSpecs. This will - * allow us to pass one JSJitInfo per function with the property/function spec, - * without additional field overhead. - */ -typedef struct JSNativeWrapper { - JSNative op; - const JSJitInfo* info; -} JSNativeWrapper; - -/* - * Macro static initializers which make it easy to pass no JSJitInfo as part of a - * JSPropertySpec or JSFunctionSpec. - */ -#define JSNATIVE_WRAPPER(native) { {native, nullptr} } - -/** - * Description of a property. JS_DefineProperties and JS_InitClass take arrays - * of these and define many properties at once. JS_PSG, JS_PSGS and JS_PS_END - * are helper macros for defining such arrays. - */ -struct JSPropertySpec { - struct SelfHostedWrapper { - void* unused; - const char* funname; - }; - - struct ValueWrapper { - uintptr_t type; - union { - const char* string; - int32_t int32; - }; - }; - - const char* name; - uint8_t flags; - union { - struct { - union { - JSNativeWrapper native; - SelfHostedWrapper selfHosted; - } getter; - union { - JSNativeWrapper native; - SelfHostedWrapper selfHosted; - } setter; - } accessors; - ValueWrapper value; - }; - - bool isAccessor() const { - return !(flags & JSPROP_INTERNAL_USE_BIT); - } - bool getValue(JSContext* cx, JS::MutableHandleValue value) const; - - bool isSelfHosted() const { - MOZ_ASSERT(isAccessor()); - -#ifdef DEBUG - // Verify that our accessors match our JSPROP_GETTER flag. - if (flags & JSPROP_GETTER) - checkAccessorsAreSelfHosted(); - else - checkAccessorsAreNative(); -#endif - return (flags & JSPROP_GETTER); - } - - static_assert(sizeof(SelfHostedWrapper) == sizeof(JSNativeWrapper), - "JSPropertySpec::getter/setter must be compact"); - static_assert(offsetof(SelfHostedWrapper, funname) == offsetof(JSNativeWrapper, info), - "JS_SELF_HOSTED* macros below require that " - "SelfHostedWrapper::funname overlay " - "JSNativeWrapper::info"); -private: - void checkAccessorsAreNative() const { - MOZ_ASSERT(accessors.getter.native.op); - // We may not have a setter at all. So all we can assert here, for the - // native case is that if we have a jitinfo for the setter then we have - // a setter op too. This is good enough to make sure we don't have a - // SelfHostedWrapper for the setter. - MOZ_ASSERT_IF(accessors.setter.native.info, accessors.setter.native.op); - } - - void checkAccessorsAreSelfHosted() const { - MOZ_ASSERT(!accessors.getter.selfHosted.unused); - MOZ_ASSERT(!accessors.setter.selfHosted.unused); - } -}; - -namespace JS { -namespace detail { - -/* NEVER DEFINED, DON'T USE. For use by JS_CAST_NATIVE_TO only. */ -inline int CheckIsNative(JSNative native); - -/* NEVER DEFINED, DON'T USE. For use by JS_CAST_STRING_TO only. */ -template -inline int -CheckIsCharacterLiteral(const char (&arr)[N]); - -/* NEVER DEFINED, DON'T USE. For use by JS_CAST_INT32_TO only. */ -inline int CheckIsInt32(int32_t value); - -/* NEVER DEFINED, DON'T USE. For use by JS_PROPERTYOP_GETTER only. */ -inline int CheckIsGetterOp(JSGetterOp op); - -/* NEVER DEFINED, DON'T USE. For use by JS_PROPERTYOP_SETTER only. */ -inline int CheckIsSetterOp(JSSetterOp op); - -} // namespace detail -} // namespace JS - -#define JS_CAST_NATIVE_TO(v, To) \ - (static_cast(sizeof(JS::detail::CheckIsNative(v))), \ - reinterpret_cast(v)) - -#define JS_CAST_STRING_TO(s, To) \ - (static_cast(sizeof(JS::detail::CheckIsCharacterLiteral(s))), \ - reinterpret_cast(s)) - -#define JS_CAST_INT32_TO(s, To) \ - (static_cast(sizeof(JS::detail::CheckIsInt32(s))), \ - reinterpret_cast(s)) - -#define JS_CHECK_ACCESSOR_FLAGS(flags) \ - (static_cast::Type>(0), \ - (flags)) - -#define JS_PROPERTYOP_GETTER(v) \ - (static_cast(sizeof(JS::detail::CheckIsGetterOp(v))), \ - reinterpret_cast(v)) - -#define JS_PROPERTYOP_SETTER(v) \ - (static_cast(sizeof(JS::detail::CheckIsSetterOp(v))), \ - reinterpret_cast(v)) - -#define JS_STUBGETTER JS_PROPERTYOP_GETTER(JS_PropertyStub) - -#define JS_STUBSETTER JS_PROPERTYOP_SETTER(JS_StrictPropertyStub) - -#define JS_PS_ACCESSOR_SPEC(name, getter, setter, flags, extraFlags) \ - { name, uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | extraFlags), \ - { { getter, setter } } } -#define JS_PS_VALUE_SPEC(name, value, flags) \ - { name, uint8_t(flags | JSPROP_INTERNAL_USE_BIT), \ - { { value, JSNATIVE_WRAPPER(nullptr) } } } - -#define SELFHOSTED_WRAPPER(name) \ - { { nullptr, JS_CAST_STRING_TO(name, const JSJitInfo*) } } -#define STRINGVALUE_WRAPPER(value) \ - { { reinterpret_cast(JSVAL_TYPE_STRING), JS_CAST_STRING_TO(value, const JSJitInfo*) } } -#define INT32VALUE_WRAPPER(value) \ - { { reinterpret_cast(JSVAL_TYPE_INT32), JS_CAST_INT32_TO(value, const JSJitInfo*) } } - -/* - * JSPropertySpec uses JSNativeWrapper. These macros encapsulate the definition - * of JSNative-backed JSPropertySpecs, by defining the JSNativeWrappers for - * them. - */ -#define JS_PSG(name, getter, flags) \ - JS_PS_ACCESSOR_SPEC(name, JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(nullptr), flags, \ - JSPROP_SHARED) -#define JS_PSGS(name, getter, setter, flags) \ - JS_PS_ACCESSOR_SPEC(name, JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(setter), flags, \ - JSPROP_SHARED) -#define JS_SELF_HOSTED_GET(name, getterName, flags) \ - JS_PS_ACCESSOR_SPEC(name, SELFHOSTED_WRAPPER(getterName), JSNATIVE_WRAPPER(nullptr), flags, \ - JSPROP_SHARED | JSPROP_GETTER) -#define JS_SELF_HOSTED_GETSET(name, getterName, setterName, flags) \ - JS_PS_ACCESSOR_SPEC(name, SELFHOSTED_WRAPPER(getterName), SELFHOSTED_WRAPPER(setterName), \ - flags, JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER) -#define JS_SELF_HOSTED_SYM_GET(symbol, getterName, flags) \ - JS_PS_ACCESSOR_SPEC(reinterpret_cast(uint32_t(::JS::SymbolCode::symbol) + 1), \ - SELFHOSTED_WRAPPER(getterName), JSNATIVE_WRAPPER(nullptr), flags, \ - JSPROP_SHARED | JSPROP_GETTER) -#define JS_STRING_PS(name, string, flags) \ - JS_PS_VALUE_SPEC(name, STRINGVALUE_WRAPPER(string), flags) -#define JS_STRING_SYM_PS(symbol, string, flags) \ - JS_PS_VALUE_SPEC(reinterpret_cast(uint32_t(::JS::SymbolCode::symbol) + 1), \ - STRINGVALUE_WRAPPER(string), flags) -#define JS_INT32_PS(name, value, flags) \ - JS_PS_VALUE_SPEC(name, INT32VALUE_WRAPPER(value), flags) -#define JS_PS_END \ - JS_PS_ACCESSOR_SPEC(nullptr, JSNATIVE_WRAPPER(nullptr), JSNATIVE_WRAPPER(nullptr), 0, 0) - -/** - * To define a native function, set call to a JSNativeWrapper. To define a - * self-hosted function, set selfHostedName to the name of a function - * compiled during JSRuntime::initSelfHosting. - */ -struct JSFunctionSpec { - const char* name; - JSNativeWrapper call; - uint16_t nargs; - uint16_t flags; - const char* selfHostedName; -}; - -/* - * Terminating sentinel initializer to put at the end of a JSFunctionSpec array - * that's passed to JS_DefineFunctions or JS_InitClass. - */ -#define JS_FS_END JS_FS(nullptr,nullptr,0,0) - -/* - * Initializer macros for a JSFunctionSpec array element. JS_FN (whose name pays - * homage to the old JSNative/JSFastNative split) simply adds the flag - * JSFUN_STUB_GSOPS. JS_FNINFO allows the simple adding of - * JSJitInfos. JS_SELF_HOSTED_FN declares a self-hosted function. - * JS_INLINABLE_FN allows specifying an InlinableNative enum value for natives - * inlined or specialized by the JIT. Finally JS_FNSPEC has slots for all the - * fields. - * - * The _SYM variants allow defining a function with a symbol key rather than a - * string key. For example, use JS_SYM_FN(iterator, ...) to define an - * @@iterator method. - */ -#define JS_FS(name,call,nargs,flags) \ - JS_FNSPEC(name, call, nullptr, nargs, flags, nullptr) -#define JS_FN(name,call,nargs,flags) \ - JS_FNSPEC(name, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr) -#define JS_INLINABLE_FN(name,call,nargs,flags,native) \ - JS_FNSPEC(name, call, &js::jit::JitInfo_##native, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr) -#define JS_SYM_FN(symbol,call,nargs,flags) \ - JS_SYM_FNSPEC(symbol, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr) -#define JS_FNINFO(name,call,info,nargs,flags) \ - JS_FNSPEC(name, call, info, nargs, flags, nullptr) -#define JS_SELF_HOSTED_FN(name,selfHostedName,nargs,flags) \ - JS_FNSPEC(name, nullptr, nullptr, nargs, flags, selfHostedName) -#define JS_SELF_HOSTED_SYM_FN(symbol, selfHostedName, nargs, flags) \ - JS_SYM_FNSPEC(symbol, nullptr, nullptr, nargs, flags, selfHostedName) -#define JS_SYM_FNSPEC(symbol, call, info, nargs, flags, selfHostedName) \ - JS_FNSPEC(reinterpret_cast( \ - uint32_t(::JS::SymbolCode::symbol) + 1), \ - call, info, nargs, flags, selfHostedName) -#define JS_FNSPEC(name,call,info,nargs,flags,selfHostedName) \ - {name, {call, info}, nargs, flags, selfHostedName} - -extern JS_PUBLIC_API(JSObject*) -JS_InitClass(JSContext* cx, JS::HandleObject obj, JS::HandleObject parent_proto, - const JSClass* clasp, JSNative constructor, unsigned nargs, - const JSPropertySpec* ps, const JSFunctionSpec* fs, - const JSPropertySpec* static_ps, const JSFunctionSpec* static_fs); - -/** - * Set up ctor.prototype = proto and proto.constructor = ctor with the - * right property flags. - */ -extern JS_PUBLIC_API(bool) -JS_LinkConstructorAndPrototype(JSContext* cx, JS::Handle ctor, - JS::Handle proto); - -extern JS_PUBLIC_API(const JSClass*) -JS_GetClass(JSObject* obj); - -extern JS_PUBLIC_API(bool) -JS_InstanceOf(JSContext* cx, JS::Handle obj, const JSClass* clasp, JS::CallArgs* args); - -extern JS_PUBLIC_API(bool) -JS_HasInstance(JSContext* cx, JS::Handle obj, JS::Handle v, bool* bp); - -namespace JS { - -// Implementation of -// http://www.ecma-international.org/ecma-262/6.0/#sec-ordinaryhasinstance. If -// you're looking for the equivalent of "instanceof", you want JS_HasInstance, -// not this function. -extern JS_PUBLIC_API(bool) -OrdinaryHasInstance(JSContext* cx, HandleObject objArg, HandleValue v, bool* bp); - -} // namespace JS - -extern JS_PUBLIC_API(void*) -JS_GetPrivate(JSObject* obj); - -extern JS_PUBLIC_API(void) -JS_SetPrivate(JSObject* obj, void* data); - -extern JS_PUBLIC_API(void*) -JS_GetInstancePrivate(JSContext* cx, JS::Handle obj, const JSClass* clasp, - JS::CallArgs* args); - -extern JS_PUBLIC_API(JSObject*) -JS_GetConstructor(JSContext* cx, JS::Handle proto); - -namespace JS { - -enum ZoneSpecifier { - FreshZone = 0, - SystemZone = 1 -}; - -/** - * CompartmentCreationOptions specifies options relevant to creating a new - * compartment, that are either immutable characteristics of that compartment - * or that are discarded after the compartment has been created. - * - * Access to these options on an existing compartment is read-only: if you - * need particular selections, make them before you create the compartment. - */ -class JS_PUBLIC_API(CompartmentCreationOptions) -{ - public: - CompartmentCreationOptions() - : addonId_(nullptr), - traceGlobal_(nullptr), - invisibleToDebugger_(false), - mergeable_(false), - preserveJitCode_(false), - cloneSingletons_(false), - sharedMemoryAndAtomics_(false), - secureContext_(false) - { - zone_.spec = JS::FreshZone; - } - - // A null add-on ID means that the compartment is not associated with an - // add-on. - JSAddonId* addonIdOrNull() const { return addonId_; } - CompartmentCreationOptions& setAddonId(JSAddonId* id) { - addonId_ = id; - return *this; - } - - JSTraceOp getTrace() const { - return traceGlobal_; - } - CompartmentCreationOptions& setTrace(JSTraceOp op) { - traceGlobal_ = op; - return *this; - } - - void* zonePointer() const { - MOZ_ASSERT(uintptr_t(zone_.pointer) > uintptr_t(JS::SystemZone)); - return zone_.pointer; - } - ZoneSpecifier zoneSpecifier() const { return zone_.spec; } - CompartmentCreationOptions& setZone(ZoneSpecifier spec); - CompartmentCreationOptions& setSameZoneAs(JSObject* obj); - - // Certain scopes (i.e. XBL compilation scopes) are implementation details - // of the embedding, and references to them should never leak out to script. - // This flag causes the this compartment to skip firing onNewGlobalObject - // and makes addDebuggee a no-op for this global. - bool invisibleToDebugger() const { return invisibleToDebugger_; } - CompartmentCreationOptions& setInvisibleToDebugger(bool flag) { - invisibleToDebugger_ = flag; - return *this; - } - - // Compartments used for off-thread compilation have their contents merged - // into a target compartment when the compilation is finished. This is only - // allowed if this flag is set. The invisibleToDebugger flag must also be - // set for such compartments. - bool mergeable() const { return mergeable_; } - CompartmentCreationOptions& setMergeable(bool flag) { - mergeable_ = flag; - return *this; - } - - // Determines whether this compartment should preserve JIT code on - // non-shrinking GCs. - bool preserveJitCode() const { return preserveJitCode_; } - CompartmentCreationOptions& setPreserveJitCode(bool flag) { - preserveJitCode_ = flag; - return *this; - } - - bool cloneSingletons() const { return cloneSingletons_; } - CompartmentCreationOptions& setCloneSingletons(bool flag) { - cloneSingletons_ = flag; - return *this; - } - - bool getSharedMemoryAndAtomicsEnabled() const; - CompartmentCreationOptions& setSharedMemoryAndAtomicsEnabled(bool flag); - - // This flag doesn't affect JS engine behavior. It is used by Gecko to - // mark whether content windows and workers are "Secure Context"s. See - // https://w3c.github.io/webappsec-secure-contexts/ - // https://bugzilla.mozilla.org/show_bug.cgi?id=1162772#c34 - bool secureContext() const { return secureContext_; } - CompartmentCreationOptions& setSecureContext(bool flag) { - secureContext_ = flag; - return *this; - } - - private: - JSAddonId* addonId_; - JSTraceOp traceGlobal_; - union { - ZoneSpecifier spec; - void* pointer; // js::Zone* is not exposed in the API. - } zone_; - bool invisibleToDebugger_; - bool mergeable_; - bool preserveJitCode_; - bool cloneSingletons_; - bool sharedMemoryAndAtomics_; - bool secureContext_; -}; - -/** - * CompartmentBehaviors specifies behaviors of a compartment that can be - * changed after the compartment's been created. - */ -class JS_PUBLIC_API(CompartmentBehaviors) -{ - public: - class Override { - public: - Override() : mode_(Default) {} - - bool get(bool defaultValue) const { - if (mode_ == Default) - return defaultValue; - return mode_ == ForceTrue; - } - - void set(bool overrideValue) { - mode_ = overrideValue ? ForceTrue : ForceFalse; - } - - void reset() { - mode_ = Default; - } - - private: - enum Mode { - Default, - ForceTrue, - ForceFalse - }; - - Mode mode_; - }; - - CompartmentBehaviors() - : version_(JSVERSION_UNKNOWN) - , discardSource_(false) - , disableLazyParsing_(false) - , singletonsAsTemplates_(true) - { - } - - JSVersion version() const { return version_; } - CompartmentBehaviors& setVersion(JSVersion aVersion) { - MOZ_ASSERT(aVersion != JSVERSION_UNKNOWN); - version_ = aVersion; - return *this; - } - - // For certain globals, we know enough about the code that will run in them - // that we can discard script source entirely. - bool discardSource() const { return discardSource_; } - CompartmentBehaviors& setDiscardSource(bool flag) { - discardSource_ = flag; - return *this; - } - - bool disableLazyParsing() const { return disableLazyParsing_; } - CompartmentBehaviors& setDisableLazyParsing(bool flag) { - disableLazyParsing_ = flag; - return *this; - } - - bool extraWarnings(JSContext* cx) const; - Override& extraWarningsOverride() { return extraWarningsOverride_; } - - bool getSingletonsAsTemplates() const { - return singletonsAsTemplates_; - } - CompartmentBehaviors& setSingletonsAsValues() { - singletonsAsTemplates_ = false; - return *this; - } - - private: - JSVersion version_; - bool discardSource_; - bool disableLazyParsing_; - Override extraWarningsOverride_; - - // To XDR singletons, we need to ensure that all singletons are all used as - // templates, by making JSOP_OBJECT return a clone of the JSScript - // singleton, instead of returning the value which is baked in the JSScript. - bool singletonsAsTemplates_; -}; - -/** - * CompartmentOptions specifies compartment characteristics: both those that - * can't be changed on a compartment once it's been created - * (CompartmentCreationOptions), and those that can be changed on an existing - * compartment (CompartmentBehaviors). - */ -class JS_PUBLIC_API(CompartmentOptions) -{ - public: - explicit CompartmentOptions() - : creationOptions_(), - behaviors_() - {} - - CompartmentOptions(const CompartmentCreationOptions& compartmentCreation, - const CompartmentBehaviors& compartmentBehaviors) - : creationOptions_(compartmentCreation), - behaviors_(compartmentBehaviors) - {} - - // CompartmentCreationOptions specify fundamental compartment - // characteristics that must be specified when the compartment is created, - // that can't be changed after the compartment is created. - CompartmentCreationOptions& creationOptions() { - return creationOptions_; - } - const CompartmentCreationOptions& creationOptions() const { - return creationOptions_; - } - - // CompartmentBehaviors specify compartment characteristics that can be - // changed after the compartment is created. - CompartmentBehaviors& behaviors() { - return behaviors_; - } - const CompartmentBehaviors& behaviors() const { - return behaviors_; - } - - private: - CompartmentCreationOptions creationOptions_; - CompartmentBehaviors behaviors_; -}; - -JS_PUBLIC_API(const CompartmentCreationOptions&) -CompartmentCreationOptionsRef(JSCompartment* compartment); - -JS_PUBLIC_API(const CompartmentCreationOptions&) -CompartmentCreationOptionsRef(JSObject* obj); - -JS_PUBLIC_API(const CompartmentCreationOptions&) -CompartmentCreationOptionsRef(JSContext* cx); - -JS_PUBLIC_API(CompartmentBehaviors&) -CompartmentBehaviorsRef(JSCompartment* compartment); - -JS_PUBLIC_API(CompartmentBehaviors&) -CompartmentBehaviorsRef(JSObject* obj); - -JS_PUBLIC_API(CompartmentBehaviors&) -CompartmentBehaviorsRef(JSContext* cx); - -/** - * During global creation, we fire notifications to callbacks registered - * via the Debugger API. These callbacks are arbitrary script, and can touch - * the global in arbitrary ways. When that happens, the global should not be - * in a half-baked state. But this creates a problem for consumers that need - * to set slots on the global to put it in a consistent state. - * - * This API provides a way for consumers to set slots atomically (immediately - * after the global is created), before any debugger hooks are fired. It's - * unfortunately on the clunky side, but that's the way the cookie crumbles. - * - * If callers have no additional state on the global to set up, they may pass - * |FireOnNewGlobalHook| to JS_NewGlobalObject, which causes that function to - * fire the hook as its final act before returning. Otherwise, callers should - * pass |DontFireOnNewGlobalHook|, which means that they are responsible for - * invoking JS_FireOnNewGlobalObject upon successfully creating the global. If - * an error occurs and the operation aborts, callers should skip firing the - * hook. But otherwise, callers must take care to fire the hook exactly once - * before compiling any script in the global's scope (we have assertions in - * place to enforce this). This lets us be sure that debugger clients never miss - * breakpoints. - */ -enum OnNewGlobalHookOption { - FireOnNewGlobalHook, - DontFireOnNewGlobalHook -}; - -} /* namespace JS */ - -extern JS_PUBLIC_API(JSObject*) -JS_NewGlobalObject(JSContext* cx, const JSClass* clasp, JSPrincipals* principals, - JS::OnNewGlobalHookOption hookOption, - const JS::CompartmentOptions& options); -/** - * Spidermonkey does not have a good way of keeping track of what compartments should be marked on - * their own. We can mark the roots unconditionally, but marking GC things only relevant in live - * compartments is hard. To mitigate this, we create a static trace hook, installed on each global - * object, from which we can be sure the compartment is relevant, and mark it. - * - * It is still possible to specify custom trace hooks for global object classes. They can be - * provided via the CompartmentOptions passed to JS_NewGlobalObject. - */ -extern JS_PUBLIC_API(void) -JS_GlobalObjectTraceHook(JSTracer* trc, JSObject* global); - -extern JS_PUBLIC_API(void) -JS_FireOnNewGlobalObject(JSContext* cx, JS::HandleObject global); - -extern JS_PUBLIC_API(JSObject*) -JS_NewObject(JSContext* cx, const JSClass* clasp); - -extern JS_PUBLIC_API(bool) -JS_IsNative(JSObject* obj); - -/** - * Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default - * proto. If proto is nullptr, the JS object will have `null` as [[Prototype]]. - */ -extern JS_PUBLIC_API(JSObject*) -JS_NewObjectWithGivenProto(JSContext* cx, const JSClass* clasp, JS::Handle proto); - -/** Creates a new plain object, like `new Object()`, with Object.prototype as [[Prototype]]. */ -extern JS_PUBLIC_API(JSObject*) -JS_NewPlainObject(JSContext* cx); - -/** - * Freeze obj, and all objects it refers to, recursively. This will not recurse - * through non-extensible objects, on the assumption that those are already - * deep-frozen. - */ -extern JS_PUBLIC_API(bool) -JS_DeepFreezeObject(JSContext* cx, JS::Handle obj); - -/** - * Freezes an object; see ES5's Object.freeze(obj) method. - */ -extern JS_PUBLIC_API(bool) -JS_FreezeObject(JSContext* cx, JS::Handle obj); - - -/*** Property descriptors ************************************************************************/ - -namespace JS { - -struct JS_PUBLIC_API(PropertyDescriptor) { - JSObject* obj; - unsigned attrs; - JSGetterOp getter; - JSSetterOp setter; - JS::Value value; - - PropertyDescriptor() - : obj(nullptr), attrs(0), getter(nullptr), setter(nullptr), value(JS::UndefinedValue()) - {} - - static void trace(PropertyDescriptor* self, JSTracer* trc) { self->trace(trc); } - void trace(JSTracer* trc); -}; - -template -class PropertyDescriptorOperations -{ - const PropertyDescriptor& desc() const { return static_cast(this)->get(); } - - bool has(unsigned bit) const { - MOZ_ASSERT(bit != 0); - MOZ_ASSERT((bit & (bit - 1)) == 0); // only a single bit - return (desc().attrs & bit) != 0; - } - - bool hasAny(unsigned bits) const { - return (desc().attrs & bits) != 0; - } - - bool hasAll(unsigned bits) const { - return (desc().attrs & bits) == bits; - } - - // Non-API attributes bit used internally for arguments objects. - enum { SHADOWABLE = JSPROP_INTERNAL_USE_BIT }; - - public: - // Descriptors with JSGetterOp/JSSetterOp are considered data - // descriptors. It's complicated. - bool isAccessorDescriptor() const { return hasAny(JSPROP_GETTER | JSPROP_SETTER); } - bool isGenericDescriptor() const { - return (desc().attrs& - (JSPROP_GETTER | JSPROP_SETTER | JSPROP_IGNORE_READONLY | JSPROP_IGNORE_VALUE)) == - (JSPROP_IGNORE_READONLY | JSPROP_IGNORE_VALUE); - } - bool isDataDescriptor() const { return !isAccessorDescriptor() && !isGenericDescriptor(); } - - bool hasConfigurable() const { return !has(JSPROP_IGNORE_PERMANENT); } - bool configurable() const { MOZ_ASSERT(hasConfigurable()); return !has(JSPROP_PERMANENT); } - - bool hasEnumerable() const { return !has(JSPROP_IGNORE_ENUMERATE); } - bool enumerable() const { MOZ_ASSERT(hasEnumerable()); return has(JSPROP_ENUMERATE); } - - bool hasValue() const { return !isAccessorDescriptor() && !has(JSPROP_IGNORE_VALUE); } - JS::HandleValue value() const { - return JS::HandleValue::fromMarkedLocation(&desc().value); - } - - bool hasWritable() const { return !isAccessorDescriptor() && !has(JSPROP_IGNORE_READONLY); } - bool writable() const { MOZ_ASSERT(hasWritable()); return !has(JSPROP_READONLY); } - - bool hasGetterObject() const { return has(JSPROP_GETTER); } - JS::HandleObject getterObject() const { - MOZ_ASSERT(hasGetterObject()); - return JS::HandleObject::fromMarkedLocation( - reinterpret_cast(&desc().getter)); - } - bool hasSetterObject() const { return has(JSPROP_SETTER); } - JS::HandleObject setterObject() const { - MOZ_ASSERT(hasSetterObject()); - return JS::HandleObject::fromMarkedLocation( - reinterpret_cast(&desc().setter)); - } - - bool hasGetterOrSetter() const { return desc().getter || desc().setter; } - bool isShared() const { return has(JSPROP_SHARED); } - - JS::HandleObject object() const { - return JS::HandleObject::fromMarkedLocation(&desc().obj); - } - unsigned attributes() const { return desc().attrs; } - JSGetterOp getter() const { return desc().getter; } - JSSetterOp setter() const { return desc().setter; } - - void assertValid() const { -#ifdef DEBUG - MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE | JSPROP_IGNORE_ENUMERATE | - JSPROP_PERMANENT | JSPROP_IGNORE_PERMANENT | - JSPROP_READONLY | JSPROP_IGNORE_READONLY | - JSPROP_IGNORE_VALUE | - JSPROP_GETTER | - JSPROP_SETTER | - JSPROP_SHARED | - JSPROP_REDEFINE_NONCONFIGURABLE | - JSPROP_RESOLVING | - SHADOWABLE)) == 0); - MOZ_ASSERT(!hasAll(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE)); - MOZ_ASSERT(!hasAll(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT)); - if (isAccessorDescriptor()) { - MOZ_ASSERT(has(JSPROP_SHARED)); - MOZ_ASSERT(!has(JSPROP_READONLY)); - MOZ_ASSERT(!has(JSPROP_IGNORE_READONLY)); - MOZ_ASSERT(!has(JSPROP_IGNORE_VALUE)); - MOZ_ASSERT(!has(SHADOWABLE)); - MOZ_ASSERT(value().isUndefined()); - MOZ_ASSERT_IF(!has(JSPROP_GETTER), !getter()); - MOZ_ASSERT_IF(!has(JSPROP_SETTER), !setter()); - } else { - MOZ_ASSERT(!hasAll(JSPROP_IGNORE_READONLY | JSPROP_READONLY)); - MOZ_ASSERT_IF(has(JSPROP_IGNORE_VALUE), value().isUndefined()); - } - MOZ_ASSERT(getter() != JS_PropertyStub); - MOZ_ASSERT(setter() != JS_StrictPropertyStub); - - MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_ENUMERATE)); - MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_PERMANENT)); - MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_READONLY)); - MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_VALUE)); - MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_REDEFINE_NONCONFIGURABLE)); -#endif - } - - void assertComplete() const { -#ifdef DEBUG - assertValid(); - MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE | - JSPROP_PERMANENT | - JSPROP_READONLY | - JSPROP_GETTER | - JSPROP_SETTER | - JSPROP_SHARED | - JSPROP_REDEFINE_NONCONFIGURABLE | - JSPROP_RESOLVING | - SHADOWABLE)) == 0); - MOZ_ASSERT_IF(isAccessorDescriptor(), has(JSPROP_GETTER) && has(JSPROP_SETTER)); -#endif - } - - void assertCompleteIfFound() const { -#ifdef DEBUG - if (object()) - assertComplete(); -#endif - } -}; - -template -class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations -{ - PropertyDescriptor& desc() { return static_cast(this)->get(); } - - public: - void clear() { - object().set(nullptr); - setAttributes(0); - setGetter(nullptr); - setSetter(nullptr); - value().setUndefined(); - } - - void initFields(HandleObject obj, HandleValue v, unsigned attrs, - JSGetterOp getterOp, JSSetterOp setterOp) { - MOZ_ASSERT(getterOp != JS_PropertyStub); - MOZ_ASSERT(setterOp != JS_StrictPropertyStub); - - object().set(obj); - value().set(v); - setAttributes(attrs); - setGetter(getterOp); - setSetter(setterOp); - } - - void assign(PropertyDescriptor& other) { - object().set(other.obj); - setAttributes(other.attrs); - setGetter(other.getter); - setSetter(other.setter); - value().set(other.value); - } - - void setDataDescriptor(HandleValue v, unsigned attrs) { - MOZ_ASSERT((attrs & ~(JSPROP_ENUMERATE | - JSPROP_PERMANENT | - JSPROP_READONLY | - JSPROP_IGNORE_ENUMERATE | - JSPROP_IGNORE_PERMANENT | - JSPROP_IGNORE_READONLY)) == 0); - object().set(nullptr); - setAttributes(attrs); - setGetter(nullptr); - setSetter(nullptr); - value().set(v); - } - - JS::MutableHandleObject object() { - return JS::MutableHandleObject::fromMarkedLocation(&desc().obj); - } - unsigned& attributesRef() { return desc().attrs; } - JSGetterOp& getter() { return desc().getter; } - JSSetterOp& setter() { return desc().setter; } - JS::MutableHandleValue value() { - return JS::MutableHandleValue::fromMarkedLocation(&desc().value); - } - void setValue(JS::HandleValue v) { - MOZ_ASSERT(!(desc().attrs & (JSPROP_GETTER | JSPROP_SETTER))); - attributesRef() &= ~JSPROP_IGNORE_VALUE; - value().set(v); - } - - void setConfigurable(bool configurable) { - setAttributes((desc().attrs & ~(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT)) | - (configurable ? 0 : JSPROP_PERMANENT)); - } - void setEnumerable(bool enumerable) { - setAttributes((desc().attrs & ~(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE)) | - (enumerable ? JSPROP_ENUMERATE : 0)); - } - void setWritable(bool writable) { - MOZ_ASSERT(!(desc().attrs & (JSPROP_GETTER | JSPROP_SETTER))); - setAttributes((desc().attrs & ~(JSPROP_IGNORE_READONLY | JSPROP_READONLY)) | - (writable ? 0 : JSPROP_READONLY)); - } - void setAttributes(unsigned attrs) { desc().attrs = attrs; } - - void setGetter(JSGetterOp op) { - MOZ_ASSERT(op != JS_PropertyStub); - desc().getter = op; - } - void setSetter(JSSetterOp op) { - MOZ_ASSERT(op != JS_StrictPropertyStub); - desc().setter = op; - } - void setGetterObject(JSObject* obj) { - desc().getter = reinterpret_cast(obj); - desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY); - desc().attrs |= JSPROP_GETTER | JSPROP_SHARED; - } - void setSetterObject(JSObject* obj) { - desc().setter = reinterpret_cast(obj); - desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY); - desc().attrs |= JSPROP_SETTER | JSPROP_SHARED; - } - - JS::MutableHandleObject getterObject() { - MOZ_ASSERT(this->hasGetterObject()); - return JS::MutableHandleObject::fromMarkedLocation( - reinterpret_cast(&desc().getter)); - } - JS::MutableHandleObject setterObject() { - MOZ_ASSERT(this->hasSetterObject()); - return JS::MutableHandleObject::fromMarkedLocation( - reinterpret_cast(&desc().setter)); - } -}; - -} /* namespace JS */ - -namespace js { - -template <> -class RootedBase - : public JS::MutablePropertyDescriptorOperations> -{}; - -template <> -class HandleBase - : public JS::PropertyDescriptorOperations> -{}; - -template <> -class MutableHandleBase - : public JS::MutablePropertyDescriptorOperations> -{}; - -} /* namespace js */ - -namespace JS { - -extern JS_PUBLIC_API(bool) -ObjectToCompletePropertyDescriptor(JSContext* cx, - JS::HandleObject obj, - JS::HandleValue descriptor, - JS::MutableHandle desc); - -/* - * ES6 draft rev 32 (2015 Feb 2) 6.2.4.4 FromPropertyDescriptor(Desc). - * - * If desc.object() is null, then vp is set to undefined. - */ -extern JS_PUBLIC_API(bool) -FromPropertyDescriptor(JSContext* cx, - JS::Handle desc, - JS::MutableHandleValue vp); - -} // namespace JS - - -/*** Standard internal methods ******************************************************************** - * - * The functions below are the fundamental operations on objects. - * - * ES6 specifies 14 internal methods that define how objects behave. The - * standard is actually quite good on this topic, though you may have to read - * it a few times. See ES6 sections 6.1.7.2 and 6.1.7.3. - * - * When 'obj' is an ordinary object, these functions have boring standard - * behavior as specified by ES6 section 9.1; see the section about internal - * methods in js/src/vm/NativeObject.h. - * - * Proxies override the behavior of internal methods. So when 'obj' is a proxy, - * any one of the functions below could do just about anything. See - * js/public/Proxy.h. - */ - -/** - * Get the prototype of obj, storing it in result. - * - * Implements: ES6 [[GetPrototypeOf]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_GetPrototype(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject result); - -/** - * If |obj| (underneath any functionally-transparent wrapper proxies) has as - * its [[GetPrototypeOf]] trap the ordinary [[GetPrototypeOf]] behavior defined - * for ordinary objects, set |*isOrdinary = true| and store |obj|'s prototype - * in |result|. Otherwise set |*isOrdinary = false|. In case of error, both - * outparams have unspecified value. - */ -extern JS_PUBLIC_API(bool) -JS_GetPrototypeIfOrdinary(JSContext* cx, JS::HandleObject obj, bool* isOrdinary, - JS::MutableHandleObject result); - -/** - * Change the prototype of obj. - * - * Implements: ES6 [[SetPrototypeOf]] internal method. - * - * In cases where ES6 [[SetPrototypeOf]] returns false without an exception, - * JS_SetPrototype throws a TypeError and returns false. - * - * Performance warning: JS_SetPrototype is very bad for performance. It may - * cause compiled jit-code to be invalidated. It also causes not only obj but - * all other objects in the same "group" as obj to be permanently deoptimized. - * It's better to create the object with the right prototype from the start. - */ -extern JS_PUBLIC_API(bool) -JS_SetPrototype(JSContext* cx, JS::HandleObject obj, JS::HandleObject proto); - -/** - * Determine whether obj is extensible. Extensible objects can have new - * properties defined on them. Inextensible objects can't, and their - * [[Prototype]] slot is fixed as well. - * - * Implements: ES6 [[IsExtensible]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_IsExtensible(JSContext* cx, JS::HandleObject obj, bool* extensible); - -/** - * Attempt to make |obj| non-extensible. - * - * Not all failures are treated as errors. See the comment on - * JS::ObjectOpResult in js/public/Class.h. - * - * Implements: ES6 [[PreventExtensions]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_PreventExtensions(JSContext* cx, JS::HandleObject obj, JS::ObjectOpResult& result); - -/** - * Attempt to make the [[Prototype]] of |obj| immutable, such that any attempt - * to modify it will fail. If an error occurs during the attempt, return false - * (with a pending exception set, depending upon the nature of the error). If - * no error occurs, return true with |*succeeded| set to indicate whether the - * attempt successfully made the [[Prototype]] immutable. - * - * This is a nonstandard internal method. - */ -extern JS_PUBLIC_API(bool) -JS_SetImmutablePrototype(JSContext* cx, JS::HandleObject obj, bool* succeeded); - -/** - * Get a description of one of obj's own properties. If no such property exists - * on obj, return true with desc.object() set to null. - * - * Implements: ES6 [[GetOwnProperty]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_GetOwnPropertyDescriptorById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandle desc); - -extern JS_PUBLIC_API(bool) -JS_GetOwnPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* name, - JS::MutableHandle desc); - -extern JS_PUBLIC_API(bool) -JS_GetOwnUCPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char16_t* name, - JS::MutableHandle desc); - -/** - * Like JS_GetOwnPropertyDescriptorById, but also searches the prototype chain - * if no own property is found directly on obj. The object on which the - * property is found is returned in desc.object(). If the property is not found - * on the prototype chain, this returns true with desc.object() set to null. - */ -extern JS_PUBLIC_API(bool) -JS_GetPropertyDescriptorById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandle desc); - -extern JS_PUBLIC_API(bool) -JS_GetPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* name, - JS::MutableHandle desc); - -/** - * Define a property on obj. - * - * This function uses JS::ObjectOpResult to indicate conditions that ES6 - * specifies as non-error failures. This is inconvenient at best, so use this - * function only if you are implementing a proxy handler's defineProperty() - * method. For all other purposes, use one of the many DefineProperty functions - * below that throw an exception in all failure cases. - * - * Implements: ES6 [[DefineOwnProperty]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::Handle desc, - JS::ObjectOpResult& result); - -/** - * Define a property on obj, throwing a TypeError if the attempt fails. - * This is the C++ equivalent of `Object.defineProperty(obj, id, desc)`. - */ -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::Handle desc); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleString value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, int32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, uint32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, double value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleValue value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleObject value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleString value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, int32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, uint32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, double value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::Handle desc, - JS::ObjectOpResult& result); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::Handle desc); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::HandleValue value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::HandleObject value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::HandleString value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - int32_t value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - uint32_t value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - double value, unsigned attrs, - JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleObject value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleString value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, int32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, uint32_t value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -extern JS_PUBLIC_API(bool) -JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, double value, - unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr); - -/** - * Compute the expression `id in obj`. - * - * If obj has an own or inherited property obj[id], set *foundp = true and - * return true. If not, set *foundp = false and return true. On error, return - * false with an exception pending. - * - * Implements: ES6 [[Has]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_HasPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_HasProperty(JSContext* cx, JS::HandleObject obj, const char* name, bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_HasUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - bool* vp); - -extern JS_PUBLIC_API(bool) -JS_HasElement(JSContext* cx, JS::HandleObject obj, uint32_t index, bool* foundp); - -/** - * Determine whether obj has an own property with the key `id`. - * - * Implements: ES6 7.3.11 HasOwnProperty(O, P). - */ -extern JS_PUBLIC_API(bool) -JS_HasOwnPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_HasOwnProperty(JSContext* cx, JS::HandleObject obj, const char* name, bool* foundp); - -/** - * Get the value of the property `obj[id]`, or undefined if no such property - * exists. This is the C++ equivalent of `vp = Reflect.get(obj, id, receiver)`. - * - * Most callers don't need the `receiver` argument. Consider using - * JS_GetProperty instead. (But if you're implementing a proxy handler's set() - * method, it's often correct to call this function and pass the receiver - * through.) - * - * Implements: ES6 [[Get]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_ForwardGetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::HandleValue receiver, JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(bool) -JS_ForwardGetElementTo(JSContext* cx, JS::HandleObject obj, uint32_t index, - JS::HandleObject receiver, JS::MutableHandleValue vp); - -/** - * Get the value of the property `obj[id]`, or undefined if no such property - * exists. The result is stored in vp. - * - * Implements: ES6 7.3.1 Get(O, P). - */ -extern JS_PUBLIC_API(bool) -JS_GetPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(bool) -JS_GetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(bool) -JS_GetUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(bool) -JS_GetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp); - -/** - * Perform the same property assignment as `Reflect.set(obj, id, v, receiver)`. - * - * This function has a `receiver` argument that most callers don't need. - * Consider using JS_SetProperty instead. - * - * Implements: ES6 [[Set]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_ForwardSetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v, - JS::HandleValue receiver, JS::ObjectOpResult& result); - -/** - * Perform the assignment `obj[id] = v`. - * - * This function performs non-strict assignment, so if the property is - * read-only, nothing happens and no error is thrown. - */ -extern JS_PUBLIC_API(bool) -JS_SetPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v); - -extern JS_PUBLIC_API(bool) -JS_SetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleValue v); - -extern JS_PUBLIC_API(bool) -JS_SetUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::HandleValue v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleValue v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleObject v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleString v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, int32_t v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, uint32_t v); - -extern JS_PUBLIC_API(bool) -JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, double v); - -/** - * Delete a property. This is the C++ equivalent of - * `result = Reflect.deleteProperty(obj, id)`. - * - * This function has a `result` out parameter that most callers don't need. - * Unless you can pass through an ObjectOpResult provided by your caller, it's - * probably best to use the JS_DeletePropertyById signature with just 3 - * arguments. - * - * Implements: ES6 [[Delete]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_DeletePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::ObjectOpResult& result); - -extern JS_PUBLIC_API(bool) -JS_DeleteProperty(JSContext* cx, JS::HandleObject obj, const char* name, - JS::ObjectOpResult& result); - -extern JS_PUBLIC_API(bool) -JS_DeleteUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen, - JS::ObjectOpResult& result); - -extern JS_PUBLIC_API(bool) -JS_DeleteElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::ObjectOpResult& result); - -/** - * Delete a property, ignoring strict failures. This is the C++ equivalent of - * the JS `delete obj[id]` in non-strict mode code. - */ -extern JS_PUBLIC_API(bool) -JS_DeletePropertyById(JSContext* cx, JS::HandleObject obj, jsid id); - -extern JS_PUBLIC_API(bool) -JS_DeleteProperty(JSContext* cx, JS::HandleObject obj, const char* name); - -extern JS_PUBLIC_API(bool) -JS_DeleteElement(JSContext* cx, JS::HandleObject obj, uint32_t index); - -/** - * Get an array of the non-symbol enumerable properties of obj. - * This function is roughly equivalent to: - * - * var result = []; - * for (key in obj) - * result.push(key); - * return result; - * - * This is the closest thing we currently have to the ES6 [[Enumerate]] - * internal method. - * - * The array of ids returned by JS_Enumerate must be rooted to protect its - * contents from garbage collection. Use JS::Rooted. - */ -extern JS_PUBLIC_API(bool) -JS_Enumerate(JSContext* cx, JS::HandleObject obj, JS::MutableHandle props); - -/* - * API for determining callability and constructability. [[Call]] and - * [[Construct]] are internal methods that aren't present on all objects, so it - * is useful to ask if they are there or not. The standard itself asks these - * questions routinely. - */ -namespace JS { - -/** - * Return true if the given object is callable. In ES6 terms, an object is - * callable if it has a [[Call]] internal method. - * - * Implements: ES6 7.2.3 IsCallable(argument). - * - * Functions are callable. A scripted proxy or wrapper is callable if its - * target is callable. Most other objects aren't callable. - */ -extern JS_PUBLIC_API(bool) -IsCallable(JSObject* obj); - -/** - * Return true if the given object is a constructor. In ES6 terms, an object is - * a constructor if it has a [[Construct]] internal method. The expression - * `new obj()` throws a TypeError if obj is not a constructor. - * - * Implements: ES6 7.2.4 IsConstructor(argument). - * - * JS functions and classes are constructors. Arrow functions and most builtin - * functions are not. A scripted proxy or wrapper is a constructor if its - * target is a constructor. - */ -extern JS_PUBLIC_API(bool) -IsConstructor(JSObject* obj); - -} /* namespace JS */ - -/** - * Call a function, passing a this-value and arguments. This is the C++ - * equivalent of `rval = Reflect.apply(fun, obj, args)`. - * - * Implements: ES6 7.3.12 Call(F, V, [argumentsList]). - * Use this function to invoke the [[Call]] internal method. - */ -extern JS_PUBLIC_API(bool) -JS_CallFunctionValue(JSContext* cx, JS::HandleObject obj, JS::HandleValue fval, - const JS::HandleValueArray& args, JS::MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -JS_CallFunction(JSContext* cx, JS::HandleObject obj, JS::HandleFunction fun, - const JS::HandleValueArray& args, JS::MutableHandleValue rval); - -/** - * Perform the method call `rval = obj[name](args)`. - */ -extern JS_PUBLIC_API(bool) -JS_CallFunctionName(JSContext* cx, JS::HandleObject obj, const char* name, - const JS::HandleValueArray& args, JS::MutableHandleValue rval); - -namespace JS { - -static inline bool -Call(JSContext* cx, JS::HandleObject thisObj, JS::HandleFunction fun, - const JS::HandleValueArray& args, MutableHandleValue rval) -{ - return !!JS_CallFunction(cx, thisObj, fun, args, rval); -} - -static inline bool -Call(JSContext* cx, JS::HandleObject thisObj, JS::HandleValue fun, const JS::HandleValueArray& args, - MutableHandleValue rval) -{ - return !!JS_CallFunctionValue(cx, thisObj, fun, args, rval); -} - -static inline bool -Call(JSContext* cx, JS::HandleObject thisObj, const char* name, const JS::HandleValueArray& args, - MutableHandleValue rval) -{ - return !!JS_CallFunctionName(cx, thisObj, name, args, rval); -} - -extern JS_PUBLIC_API(bool) -Call(JSContext* cx, JS::HandleValue thisv, JS::HandleValue fun, const JS::HandleValueArray& args, - MutableHandleValue rval); - -static inline bool -Call(JSContext* cx, JS::HandleValue thisv, JS::HandleObject funObj, const JS::HandleValueArray& args, - MutableHandleValue rval) -{ - MOZ_ASSERT(funObj); - JS::RootedValue fun(cx, JS::ObjectValue(*funObj)); - return Call(cx, thisv, fun, args, rval); -} - -/** - * Invoke a constructor. This is the C++ equivalent of - * `rval = Reflect.construct(fun, args, newTarget)`. - * - * JS::Construct() takes a `newTarget` argument that most callers don't need. - * Consider using the four-argument Construct signature instead. (But if you're - * implementing a subclass or a proxy handler's construct() method, this is the - * right function to call.) - * - * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]). - * Use this function to invoke the [[Construct]] internal method. - */ -extern JS_PUBLIC_API(bool) -Construct(JSContext* cx, JS::HandleValue fun, HandleObject newTarget, - const JS::HandleValueArray &args, MutableHandleObject objp); - -/** - * Invoke a constructor. This is the C++ equivalent of - * `rval = new fun(...args)`. - * - * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]), when - * newTarget is omitted. - */ -extern JS_PUBLIC_API(bool) -Construct(JSContext* cx, JS::HandleValue fun, const JS::HandleValueArray& args, - MutableHandleObject objp); - -} /* namespace JS */ - -/** - * Invoke a constructor, like the JS expression `new ctor(...args)`. Returns - * the new object, or null on error. - */ -extern JS_PUBLIC_API(JSObject*) -JS_New(JSContext* cx, JS::HandleObject ctor, const JS::HandleValueArray& args); - - -/*** Other property-defining functions ***********************************************************/ - -extern JS_PUBLIC_API(JSObject*) -JS_DefineObject(JSContext* cx, JS::HandleObject obj, const char* name, - const JSClass* clasp = nullptr, unsigned attrs = 0); - -extern JS_PUBLIC_API(bool) -JS_DefineConstDoubles(JSContext* cx, JS::HandleObject obj, const JSConstDoubleSpec* cds); - -extern JS_PUBLIC_API(bool) -JS_DefineConstIntegers(JSContext* cx, JS::HandleObject obj, const JSConstIntegerSpec* cis); - -extern JS_PUBLIC_API(bool) -JS_DefineProperties(JSContext* cx, JS::HandleObject obj, const JSPropertySpec* ps); - - -/* * */ - -extern JS_PUBLIC_API(bool) -JS_AlreadyHasOwnPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_AlreadyHasOwnProperty(JSContext* cx, JS::HandleObject obj, const char* name, - bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_AlreadyHasOwnUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, - size_t namelen, bool* foundp); - -extern JS_PUBLIC_API(bool) -JS_AlreadyHasOwnElement(JSContext* cx, JS::HandleObject obj, uint32_t index, bool* foundp); - -extern JS_PUBLIC_API(JSObject*) -JS_NewArrayObject(JSContext* cx, const JS::HandleValueArray& contents); - -extern JS_PUBLIC_API(JSObject*) -JS_NewArrayObject(JSContext* cx, size_t length); - -/** - * Returns true and sets |*isArray| indicating whether |value| is an Array - * object or a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isArray == false| when passed a proxy whose - * target is an Array, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -JS_IsArrayObject(JSContext* cx, JS::HandleValue value, bool* isArray); - -/** - * Returns true and sets |*isArray| indicating whether |obj| is an Array object - * or a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isArray == false| when passed a proxy whose - * target is an Array, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -JS_IsArrayObject(JSContext* cx, JS::HandleObject obj, bool* isArray); - -extern JS_PUBLIC_API(bool) -JS_GetArrayLength(JSContext* cx, JS::Handle obj, uint32_t* lengthp); - -extern JS_PUBLIC_API(bool) -JS_SetArrayLength(JSContext* cx, JS::Handle obj, uint32_t length); - -namespace JS { - -/** - * Returns true and sets |*isMap| indicating whether |obj| is an Map object - * or a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isMap == false| when passed a proxy whose - * target is an Map, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -IsMapObject(JSContext* cx, JS::HandleObject obj, bool* isMap); - -/** - * Returns true and sets |*isSet| indicating whether |obj| is an Set object - * or a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isSet == false| when passed a proxy whose - * target is an Set, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -IsSetObject(JSContext* cx, JS::HandleObject obj, bool* isSet); - -} /* namespace JS */ - -/** - * Assign 'undefined' to all of the object's non-reserved slots. Note: this is - * done for all slots, regardless of the associated property descriptor. - */ -JS_PUBLIC_API(void) -JS_SetAllNonReservedSlotsToUndefined(JSContext* cx, JSObject* objArg); - -/** - * Create a new array buffer with the given contents. It must be legal to pass - * these contents to free(). On success, the ownership is transferred to the - * new array buffer. - */ -extern JS_PUBLIC_API(JSObject*) -JS_NewArrayBufferWithContents(JSContext* cx, size_t nbytes, void* contents); - -/** - * Create a new array buffer with the given contents. The array buffer does not take ownership of - * contents, and JS_DetachArrayBuffer must be called before the contents are disposed of. - */ -extern JS_PUBLIC_API(JSObject*) -JS_NewArrayBufferWithExternalContents(JSContext* cx, size_t nbytes, void* contents); - -/** - * Steal the contents of the given array buffer. The array buffer has its - * length set to 0 and its contents array cleared. The caller takes ownership - * of the return value and must free it or transfer ownership via - * JS_NewArrayBufferWithContents when done using it. - */ -extern JS_PUBLIC_API(void*) -JS_StealArrayBufferContents(JSContext* cx, JS::HandleObject obj); - -/** - * Returns a pointer to the ArrayBuffer |obj|'s data. |obj| and its views will store and expose - * the data in the returned pointer: assigning into the returned pointer will affect values exposed - * by views of |obj| and vice versa. - * - * The caller must ultimately deallocate the returned pointer to avoid leaking. The memory is - * *not* garbage-collected with |obj|. These steps must be followed to deallocate: - * - * 1. The ArrayBuffer |obj| must be detached using JS_DetachArrayBuffer. - * 2. The returned pointer must be freed using JS_free. - * - * To perform step 1, callers *must* hold a reference to |obj| until they finish using the returned - * pointer. They *must not* attempt to let |obj| be GC'd, then JS_free the pointer. - * - * If |obj| isn't an ArrayBuffer, this function returns null and reports an error. - */ -extern JS_PUBLIC_API(void*) -JS_ExternalizeArrayBufferContents(JSContext* cx, JS::HandleObject obj); - -/** - * Create a new mapped array buffer with the given memory mapped contents. It - * must be legal to free the contents pointer by unmapping it. On success, - * ownership is transferred to the new mapped array buffer. - */ -extern JS_PUBLIC_API(JSObject*) -JS_NewMappedArrayBufferWithContents(JSContext* cx, size_t nbytes, void* contents); - -/** - * Create memory mapped array buffer contents. - * Caller must take care of closing fd after calling this function. - */ -extern JS_PUBLIC_API(void*) -JS_CreateMappedArrayBufferContents(int fd, size_t offset, size_t length); - -/** - * Release the allocated resource of mapped array buffer contents before the - * object is created. - * If a new object has been created by JS_NewMappedArrayBufferWithContents() - * with this content, then JS_DetachArrayBuffer() should be used instead to - * release the resource used by the object. - */ -extern JS_PUBLIC_API(void) -JS_ReleaseMappedArrayBufferContents(void* contents, size_t length); - -extern JS_PUBLIC_API(JS::Value) -JS_GetReservedSlot(JSObject* obj, uint32_t index); - -extern JS_PUBLIC_API(void) -JS_SetReservedSlot(JSObject* obj, uint32_t index, const JS::Value& v); - - -/************************************************************************/ - -/* - * Functions and scripts. - */ -extern JS_PUBLIC_API(JSFunction*) -JS_NewFunction(JSContext* cx, JSNative call, unsigned nargs, unsigned flags, - const char* name); - -namespace JS { - -extern JS_PUBLIC_API(JSFunction*) -GetSelfHostedFunction(JSContext* cx, const char* selfHostedName, HandleId id, - unsigned nargs); - -/** - * Create a new function based on the given JSFunctionSpec, *fs. - * id is the result of a successful call to - * `PropertySpecNameToPermanentId(cx, fs->name, &id)`. - * - * Unlike JS_DefineFunctions, this does not treat fs as an array. - * *fs must not be JS_FS_END. - */ -extern JS_PUBLIC_API(JSFunction*) -NewFunctionFromSpec(JSContext* cx, const JSFunctionSpec* fs, HandleId id); - -} /* namespace JS */ - -extern JS_PUBLIC_API(JSObject*) -JS_GetFunctionObject(JSFunction* fun); - -/** - * Return the function's identifier as a JSString, or null if fun is unnamed. - * The returned string lives as long as fun, so you don't need to root a saved - * reference to it if fun is well-connected or rooted, and provided you bound - * the use of the saved reference by fun's lifetime. - */ -extern JS_PUBLIC_API(JSString*) -JS_GetFunctionId(JSFunction* fun); - -/** - * Return a function's display name. This is the defined name if one was given - * where the function was defined, or it could be an inferred name by the JS - * engine in the case that the function was defined to be anonymous. This can - * still return nullptr if a useful display name could not be inferred. The - * same restrictions on rooting as those in JS_GetFunctionId apply. - */ -extern JS_PUBLIC_API(JSString*) -JS_GetFunctionDisplayId(JSFunction* fun); - -/* - * Return the arity (length) of fun. - */ -extern JS_PUBLIC_API(uint16_t) -JS_GetFunctionArity(JSFunction* fun); - -/** - * Infallible predicate to test whether obj is a function object (faster than - * comparing obj's class name to "Function", but equivalent unless someone has - * overwritten the "Function" identifier with a different constructor and then - * created instances using that constructor that might be passed in as obj). - */ -extern JS_PUBLIC_API(bool) -JS_ObjectIsFunction(JSContext* cx, JSObject* obj); - -extern JS_PUBLIC_API(bool) -JS_IsNativeFunction(JSObject* funobj, JSNative call); - -/** Return whether the given function is a valid constructor. */ -extern JS_PUBLIC_API(bool) -JS_IsConstructor(JSFunction* fun); - -extern JS_PUBLIC_API(bool) -JS_DefineFunctions(JSContext* cx, JS::Handle obj, const JSFunctionSpec* fs); - -extern JS_PUBLIC_API(JSFunction*) -JS_DefineFunction(JSContext* cx, JS::Handle obj, const char* name, JSNative call, - unsigned nargs, unsigned attrs); - -extern JS_PUBLIC_API(JSFunction*) -JS_DefineUCFunction(JSContext* cx, JS::Handle obj, - const char16_t* name, size_t namelen, JSNative call, - unsigned nargs, unsigned attrs); - -extern JS_PUBLIC_API(JSFunction*) -JS_DefineFunctionById(JSContext* cx, JS::Handle obj, JS::Handle id, JSNative call, - unsigned nargs, unsigned attrs); - -extern JS_PUBLIC_API(bool) -JS_IsFunctionBound(JSFunction* fun); - -extern JS_PUBLIC_API(JSObject*) -JS_GetBoundFunctionTarget(JSFunction* fun); - -namespace JS { - -/** - * Clone a top-level function into cx's global. This function will dynamically - * fail if funobj was lexically nested inside some other function. - */ -extern JS_PUBLIC_API(JSObject*) -CloneFunctionObject(JSContext* cx, HandleObject funobj); - -/** - * As above, but providing an explicit scope chain. scopeChain must not include - * the global object on it; that's implicit. It needs to contain the other - * objects that should end up on the clone's scope chain. - */ -extern JS_PUBLIC_API(JSObject*) -CloneFunctionObject(JSContext* cx, HandleObject funobj, AutoObjectVector& scopeChain); - -} // namespace JS - -/** - * Given a buffer, return false if the buffer might become a valid - * javascript statement with the addition of more lines. Otherwise return - * true. The intent is to support interactive compilation - accumulate - * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to - * the compiler. - */ -extern JS_PUBLIC_API(bool) -JS_BufferIsCompilableUnit(JSContext* cx, JS::Handle obj, const char* utf8, - size_t length); - -/** - * |script| will always be set. On failure, it will be set to nullptr. - */ -extern JS_PUBLIC_API(bool) -JS_CompileScript(JSContext* cx, const char* ascii, size_t length, - const JS::CompileOptions& options, - JS::MutableHandleScript script); - -/** - * |script| will always be set. On failure, it will be set to nullptr. - */ -extern JS_PUBLIC_API(bool) -JS_CompileUCScript(JSContext* cx, const char16_t* chars, size_t length, - const JS::CompileOptions& options, - JS::MutableHandleScript script); - -extern JS_PUBLIC_API(JSObject*) -JS_GetGlobalFromScript(JSScript* script); - -extern JS_PUBLIC_API(const char*) -JS_GetScriptFilename(JSScript* script); - -extern JS_PUBLIC_API(unsigned) -JS_GetScriptBaseLineNumber(JSContext* cx, JSScript* script); - -extern JS_PUBLIC_API(JSScript*) -JS_GetFunctionScript(JSContext* cx, JS::HandleFunction fun); - -namespace JS { - -/* Options for JavaScript compilation. */ - -/* - * In the most common use case, a CompileOptions instance is allocated on the - * stack, and holds non-owning references to non-POD option values: strings; - * principals; objects; and so on. The code declaring the instance guarantees - * that such option values will outlive the CompileOptions itself: objects are - * otherwise rooted; principals have had their reference counts bumped; strings - * will not be freed until the CompileOptions goes out of scope. In this - * situation, CompileOptions only refers to things others own, so it can be - * lightweight. - * - * In some cases, however, we need to hold compilation options with a - * non-stack-like lifetime. For example, JS::CompileOffThread needs to save - * compilation options where a worker thread can find them, and then return - * immediately. The worker thread will come along at some later point, and use - * the options. - * - * The compiler itself just needs to be able to access a collection of options; - * it doesn't care who owns them, or what's keeping them alive. It does its own - * addrefs/copies/tracing/etc. - * - * Furthermore, in some cases compile options are propagated from one entity to - * another (e.g. from a scriipt to a function defined in that script). This - * involves copying over some, but not all, of the options. - * - * So, we have a class hierarchy that reflects these four use cases: - * - * - TransitiveCompileOptions is the common base class, representing options - * that should get propagated from a script to functions defined in that - * script. This is never instantiated directly. - * - * - ReadOnlyCompileOptions is the only subclass of TransitiveCompileOptions, - * representing a full set of compile options. It can be used by code that - * simply needs to access options set elsewhere, like the compiler. This, - * again, is never instantiated directly. - * - * - The usual CompileOptions class must be stack-allocated, and holds - * non-owning references to the filename, element, and so on. It's derived - * from ReadOnlyCompileOptions, so the compiler can use it. - * - * - OwningCompileOptions roots / copies / reference counts of all its values, - * and unroots / frees / releases them when it is destructed. It too is - * derived from ReadOnlyCompileOptions, so the compiler accepts it. - */ - -enum class AsmJSOption : uint8_t { Enabled, Disabled, DisabledByDebugger }; - -/** - * The common base class for the CompileOptions hierarchy. - * - * Use this in code that needs to propagate compile options from one compilation - * unit to another. - */ -class JS_FRIEND_API(TransitiveCompileOptions) -{ - protected: - // The Web Platform allows scripts to be loaded from arbitrary cross-origin - // sources. This allows an attack by which a malicious website loads a - // sensitive file (say, a bank statement) cross-origin (using the user's - // cookies), and sniffs the generated syntax errors (via a window.onerror - // handler) for juicy morsels of its contents. - // - // To counter this attack, HTML5 specifies that script errors should be - // sanitized ("muted") when the script is not same-origin with the global - // for which it is loaded. Callers should set this flag for cross-origin - // scripts, and it will be propagated appropriately to child scripts and - // passed back in JSErrorReports. - bool mutedErrors_; - const char* filename_; - const char* introducerFilename_; - const char16_t* sourceMapURL_; - - // This constructor leaves 'version' set to JSVERSION_UNKNOWN. The structure - // is unusable until that's set to something more specific; the derived - // classes' constructors take care of that, in ways appropriate to their - // purpose. - TransitiveCompileOptions() - : mutedErrors_(false), - filename_(nullptr), - introducerFilename_(nullptr), - sourceMapURL_(nullptr), - version(JSVERSION_UNKNOWN), - versionSet(false), - utf8(false), - selfHostingMode(false), - canLazilyParse(true), - strictOption(false), - extraWarningsOption(false), - werrorOption(false), - asmJSOption(AsmJSOption::Disabled), - throwOnAsmJSValidationFailureOption(false), - forceAsync(false), - installedFile(false), - sourceIsLazy(false), - introductionType(nullptr), - introductionLineno(0), - introductionOffset(0), - hasIntroductionInfo(false) - { } - - // Set all POD options (those not requiring reference counts, copies, - // rooting, or other hand-holding) to their values in |rhs|. - void copyPODTransitiveOptions(const TransitiveCompileOptions& rhs); - - public: - // Read-only accessors for non-POD options. The proper way to set these - // depends on the derived type. - bool mutedErrors() const { return mutedErrors_; } - const char* filename() const { return filename_; } - const char* introducerFilename() const { return introducerFilename_; } - const char16_t* sourceMapURL() const { return sourceMapURL_; } - virtual JSObject* element() const = 0; - virtual JSString* elementAttributeName() const = 0; - virtual JSScript* introductionScript() const = 0; - - // POD options. - JSVersion version; - bool versionSet; - bool utf8; - bool selfHostingMode; - bool canLazilyParse; - bool strictOption; - bool extraWarningsOption; - bool werrorOption; - AsmJSOption asmJSOption; - bool throwOnAsmJSValidationFailureOption; - bool forceAsync; - bool installedFile; // 'true' iff pre-compiling js file in packaged app - bool sourceIsLazy; - - // |introductionType| is a statically allocated C string: - // one of "eval", "Function", or "GeneratorFunction". - const char* introductionType; - unsigned introductionLineno; - uint32_t introductionOffset; - bool hasIntroductionInfo; - - private: - void operator=(const TransitiveCompileOptions&) = delete; -}; - -/** - * The class representing a full set of compile options. - * - * Use this in code that only needs to access compilation options created - * elsewhere, like the compiler. Don't instantiate this class (the constructor - * is protected anyway); instead, create instances only of the derived classes: - * CompileOptions and OwningCompileOptions. - */ -class JS_FRIEND_API(ReadOnlyCompileOptions) : public TransitiveCompileOptions -{ - friend class CompileOptions; - - protected: - ReadOnlyCompileOptions() - : TransitiveCompileOptions(), - lineno(1), - column(0), - isRunOnce(false), - noScriptRval(false) - { } - - // Set all POD options (those not requiring reference counts, copies, - // rooting, or other hand-holding) to their values in |rhs|. - void copyPODOptions(const ReadOnlyCompileOptions& rhs); - - public: - // Read-only accessors for non-POD options. The proper way to set these - // depends on the derived type. - bool mutedErrors() const { return mutedErrors_; } - const char* filename() const { return filename_; } - const char* introducerFilename() const { return introducerFilename_; } - const char16_t* sourceMapURL() const { return sourceMapURL_; } - virtual JSObject* element() const = 0; - virtual JSString* elementAttributeName() const = 0; - virtual JSScript* introductionScript() const = 0; - - // POD options. - unsigned lineno; - unsigned column; - // isRunOnce only applies to non-function scripts. - bool isRunOnce; - bool noScriptRval; - - private: - void operator=(const ReadOnlyCompileOptions&) = delete; -}; - -/** - * Compilation options, with dynamic lifetime. An instance of this type - * makes a copy of / holds / roots all dynamically allocated resources - * (principals; elements; strings) that it refers to. Its destructor frees - * / drops / unroots them. This is heavier than CompileOptions, below, but - * unlike CompileOptions, it can outlive any given stack frame. - * - * Note that this *roots* any JS values it refers to - they're live - * unconditionally. Thus, instances of this type can't be owned, directly - * or indirectly, by a JavaScript object: if any value that this roots ever - * comes to refer to the object that owns this, then the whole cycle, and - * anything else it entrains, will never be freed. - */ -class JS_FRIEND_API(OwningCompileOptions) : public ReadOnlyCompileOptions -{ - PersistentRootedObject elementRoot; - PersistentRootedString elementAttributeNameRoot; - PersistentRootedScript introductionScriptRoot; - - public: - // A minimal constructor, for use with OwningCompileOptions::copy. This - // leaves |this.version| set to JSVERSION_UNKNOWN; the instance - // shouldn't be used until we've set that to something real (as |copy| - // will). - explicit OwningCompileOptions(JSContext* cx); - ~OwningCompileOptions(); - - JSObject* element() const override { return elementRoot; } - JSString* elementAttributeName() const override { return elementAttributeNameRoot; } - JSScript* introductionScript() const override { return introductionScriptRoot; } - - // Set this to a copy of |rhs|. Return false on OOM. - bool copy(JSContext* cx, const ReadOnlyCompileOptions& rhs); - - /* These setters make copies of their string arguments, and are fallible. */ - bool setFile(JSContext* cx, const char* f); - bool setFileAndLine(JSContext* cx, const char* f, unsigned l); - bool setSourceMapURL(JSContext* cx, const char16_t* s); - bool setIntroducerFilename(JSContext* cx, const char* s); - - /* These setters are infallible, and can be chained. */ - OwningCompileOptions& setLine(unsigned l) { lineno = l; return *this; } - OwningCompileOptions& setElement(JSObject* e) { - elementRoot = e; - return *this; - } - OwningCompileOptions& setElementAttributeName(JSString* p) { - elementAttributeNameRoot = p; - return *this; - } - OwningCompileOptions& setIntroductionScript(JSScript* s) { - introductionScriptRoot = s; - return *this; - } - OwningCompileOptions& setMutedErrors(bool mute) { - mutedErrors_ = mute; - return *this; - } - OwningCompileOptions& setVersion(JSVersion v) { - version = v; - versionSet = true; - return *this; - } - OwningCompileOptions& setUTF8(bool u) { utf8 = u; return *this; } - OwningCompileOptions& setColumn(unsigned c) { column = c; return *this; } - OwningCompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; } - OwningCompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; } - OwningCompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; } - OwningCompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; } - OwningCompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; } - OwningCompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; } - bool setIntroductionInfo(JSContext* cx, const char* introducerFn, const char* intro, - unsigned line, JSScript* script, uint32_t offset) - { - if (!setIntroducerFilename(cx, introducerFn)) - return false; - introductionType = intro; - introductionLineno = line; - introductionScriptRoot = script; - introductionOffset = offset; - hasIntroductionInfo = true; - return true; - } - - private: - void operator=(const CompileOptions& rhs) = delete; -}; - -/** - * Compilation options stored on the stack. An instance of this type - * simply holds references to dynamically allocated resources (element; - * filename; source map URL) that are owned by something else. If you - * create an instance of this type, it's up to you to guarantee that - * everything you store in it will outlive it. - */ -class MOZ_STACK_CLASS JS_FRIEND_API(CompileOptions) final : public ReadOnlyCompileOptions -{ - RootedObject elementRoot; - RootedString elementAttributeNameRoot; - RootedScript introductionScriptRoot; - - public: - explicit CompileOptions(JSContext* cx, JSVersion version = JSVERSION_UNKNOWN); - CompileOptions(js::ContextFriendFields* cx, const ReadOnlyCompileOptions& rhs) - : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx), - introductionScriptRoot(cx) - { - copyPODOptions(rhs); - - filename_ = rhs.filename(); - introducerFilename_ = rhs.introducerFilename(); - sourceMapURL_ = rhs.sourceMapURL(); - elementRoot = rhs.element(); - elementAttributeNameRoot = rhs.elementAttributeName(); - introductionScriptRoot = rhs.introductionScript(); - } - - CompileOptions(js::ContextFriendFields* cx, const TransitiveCompileOptions& rhs) - : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx), - introductionScriptRoot(cx) - { - copyPODTransitiveOptions(rhs); - - filename_ = rhs.filename(); - introducerFilename_ = rhs.introducerFilename(); - sourceMapURL_ = rhs.sourceMapURL(); - elementRoot = rhs.element(); - elementAttributeNameRoot = rhs.elementAttributeName(); - introductionScriptRoot = rhs.introductionScript(); - } - - JSObject* element() const override { return elementRoot; } - JSString* elementAttributeName() const override { return elementAttributeNameRoot; } - JSScript* introductionScript() const override { return introductionScriptRoot; } - - CompileOptions& setFile(const char* f) { filename_ = f; return *this; } - CompileOptions& setLine(unsigned l) { lineno = l; return *this; } - CompileOptions& setFileAndLine(const char* f, unsigned l) { - filename_ = f; lineno = l; return *this; - } - CompileOptions& setSourceMapURL(const char16_t* s) { sourceMapURL_ = s; return *this; } - CompileOptions& setElement(JSObject* e) { elementRoot = e; return *this; } - CompileOptions& setElementAttributeName(JSString* p) { - elementAttributeNameRoot = p; - return *this; - } - CompileOptions& setIntroductionScript(JSScript* s) { - introductionScriptRoot = s; - return *this; - } - CompileOptions& setMutedErrors(bool mute) { - mutedErrors_ = mute; - return *this; - } - CompileOptions& setVersion(JSVersion v) { - version = v; - versionSet = true; - return *this; - } - CompileOptions& setUTF8(bool u) { utf8 = u; return *this; } - CompileOptions& setColumn(unsigned c) { column = c; return *this; } - CompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; } - CompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; } - CompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; } - CompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; } - CompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; } - CompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; } - CompileOptions& setIntroductionInfo(const char* introducerFn, const char* intro, - unsigned line, JSScript* script, uint32_t offset) - { - introducerFilename_ = introducerFn; - introductionType = intro; - introductionLineno = line; - introductionScriptRoot = script; - introductionOffset = offset; - hasIntroductionInfo = true; - return *this; - } - CompileOptions& maybeMakeStrictMode(bool strict) { - strictOption = strictOption || strict; - return *this; - } - - private: - void operator=(const CompileOptions& rhs) = delete; -}; - -/** - * |script| will always be set. On failure, it will be set to nullptr. - */ -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* bytes, size_t length, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - FILE* file, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* filename, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* bytes, size_t length, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - FILE* file, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* filename, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CanCompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options, size_t length); - -/* - * Off thread compilation control flow. - * - * After successfully triggering an off thread compile of a script, the - * callback will eventually be invoked with the specified data and a token - * for the compilation. The callback will be invoked while off the main thread, - * so must ensure that its operations are thread safe. Afterwards, one of the - * following functions must be invoked on the main thread: - * - * - FinishOffThreadScript, to get the result script (or nullptr on failure). - * - CancelOffThreadScript, to free the resources without creating a script. - * - * The characters passed in to CompileOffThread must remain live until the - * callback is invoked, and the resulting script will be rooted until the call - * to FinishOffThreadScript. - */ - -extern JS_PUBLIC_API(bool) -CompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, - OffThreadCompileCallback callback, void* callbackData); - -extern JS_PUBLIC_API(JSScript*) -FinishOffThreadScript(JSContext* cx, void* token); - -extern JS_PUBLIC_API(void) -CancelOffThreadScript(JSContext* cx, void* token); - -extern JS_PUBLIC_API(bool) -CompileOffThreadModule(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, - OffThreadCompileCallback callback, void* callbackData); - -extern JS_PUBLIC_API(JSObject*) -FinishOffThreadModule(JSContext* cx, void* token); - -extern JS_PUBLIC_API(void) -CancelOffThreadModule(JSContext* cx, void* token); - -/** - * Compile a function with envChain plus the global as its scope chain. - * envChain must contain objects in the current compartment of cx. The actual - * scope chain used for the function will consist of With wrappers for those - * objects, followed by the current global of the compartment cx is in. This - * global must not be explicitly included in the scope chain. - */ -extern JS_PUBLIC_API(bool) -CompileFunction(JSContext* cx, AutoObjectVector& envChain, - const ReadOnlyCompileOptions& options, - const char* name, unsigned nargs, const char* const* argnames, - const char16_t* chars, size_t length, JS::MutableHandleFunction fun); - -/** - * Same as above, but taking a SourceBufferHolder for the function body. - */ -extern JS_PUBLIC_API(bool) -CompileFunction(JSContext* cx, AutoObjectVector& envChain, - const ReadOnlyCompileOptions& options, - const char* name, unsigned nargs, const char* const* argnames, - SourceBufferHolder& srcBuf, JS::MutableHandleFunction fun); - -/** - * Same as above, but taking a const char * for the function body. - */ -extern JS_PUBLIC_API(bool) -CompileFunction(JSContext* cx, AutoObjectVector& envChain, - const ReadOnlyCompileOptions& options, - const char* name, unsigned nargs, const char* const* argnames, - const char* bytes, size_t length, JS::MutableHandleFunction fun); - -} /* namespace JS */ - -extern JS_PUBLIC_API(JSString*) -JS_DecompileScript(JSContext* cx, JS::Handle script, const char* name, unsigned indent); - -/* - * API extension: OR this into indent to avoid pretty-printing the decompiled - * source resulting from JS_DecompileFunction. - */ -#define JS_DONT_PRETTY_PRINT ((unsigned)0x8000) - -extern JS_PUBLIC_API(JSString*) -JS_DecompileFunction(JSContext* cx, JS::Handle fun, unsigned indent); - - -/* - * NB: JS_ExecuteScript and the JS::Evaluate APIs come in two flavors: either - * they use the global as the scope, or they take an AutoObjectVector of objects - * to use as the scope chain. In the former case, the global is also used as - * the "this" keyword value and the variables object (ECMA parlance for where - * 'var' and 'function' bind names) of the execution context for script. In the - * latter case, the first object in the provided list is used, unless the list - * is empty, in which case the global is used. - * - * Why a runtime option? The alternative is to add APIs duplicating those - * for the other value of flags, and that doesn't seem worth the code bloat - * cost. Such new entry points would probably have less obvious names, too, so - * would not tend to be used. The ContextOptionsRef adjustment, OTOH, can be - * more easily hacked into existing code that does not depend on the bug; such - * code can continue to use the familiar JS::Evaluate, etc., entry points. - */ - -/** - * Evaluate a script in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -JS_ExecuteScript(JSContext* cx, JS::HandleScript script, JS::MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -JS_ExecuteScript(JSContext* cx, JS::HandleScript script); - -/** - * As above, but providing an explicit scope chain. envChain must not include - * the global object on it; that's implicit. It needs to contain the other - * objects that should end up on the script's scope chain. - */ -extern JS_PUBLIC_API(bool) -JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain, - JS::HandleScript script, JS::MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain, JS::HandleScript script); - -namespace JS { - -/** - * Like the above, but handles a cross-compartment script. If the script is - * cross-compartment, it is cloned into the current compartment before executing. - */ -extern JS_PUBLIC_API(bool) -CloneAndExecuteScript(JSContext* cx, JS::Handle script, - JS::MutableHandleValue rval); - -} /* namespace JS */ - -namespace JS { - -/** - * Evaluate the given source buffer in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleValue rval); - -/** - * As above, but providing an explicit scope chain. envChain must not include - * the global object on it; that's implicit. It needs to contain the other - * objects that should end up on the script's scope chain. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, AutoObjectVector& envChain, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleValue rval); - -/** - * Evaluate the given character buffer in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, JS::MutableHandleValue rval); - -/** - * As above, but providing an explicit scope chain. envChain must not include - * the global object on it; that's implicit. It needs to contain the other - * objects that should end up on the script's scope chain. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, AutoObjectVector& envChain, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, JS::MutableHandleValue rval); - -/** - * Evaluate the given byte buffer in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* bytes, size_t length, JS::MutableHandleValue rval); - -/** - * Evaluate the given file in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* filename, JS::MutableHandleValue rval); - -/** - * Get the HostResolveImportedModule hook for a global. - */ -extern JS_PUBLIC_API(JSFunction*) -GetModuleResolveHook(JSContext* cx); - -/** - * Set the HostResolveImportedModule hook for a global to the given function. - */ -extern JS_PUBLIC_API(void) -SetModuleResolveHook(JSContext* cx, JS::HandleFunction func); - -/** - * Parse the given source buffer as a module in the scope of the current global - * of cx and return a source text module record. - */ -extern JS_PUBLIC_API(bool) -CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleObject moduleRecord); - -/** - * Set the [[HostDefined]] field of a source text module record to the given - * value. - */ -extern JS_PUBLIC_API(void) -SetModuleHostDefinedField(JSObject* module, const JS::Value& value); - -/** - * Get the [[HostDefined]] field of a source text module record. - */ -extern JS_PUBLIC_API(JS::Value) -GetModuleHostDefinedField(JSObject* module); - -/* - * Perform the ModuleDeclarationInstantiation operation on on the give source - * text module record. - * - * This transitively resolves all module dependencies (calling the - * HostResolveImportedModule hook) and initializes the environment record for - * the module. - */ -extern JS_PUBLIC_API(bool) -ModuleDeclarationInstantiation(JSContext* cx, JS::HandleObject moduleRecord); - -/* - * Perform the ModuleEvaluation operation on on the give source text module - * record. - * - * This does nothing if this module has already been evaluated. Otherwise, it - * transitively evaluates all dependences of this module and then evaluates this - * module. - * - * ModuleDeclarationInstantiation must have completed prior to calling this. - */ -extern JS_PUBLIC_API(bool) -ModuleEvaluation(JSContext* cx, JS::HandleObject moduleRecord); - -/* - * Get a list of the module specifiers used by a source text module - * record to request importation of modules. - * - * The result is a JavaScript array of string values. To extract the individual - * values use only JS_GetArrayLength and JS_GetElement with indices 0 to - * length - 1. - */ -extern JS_PUBLIC_API(JSObject*) -GetRequestedModules(JSContext* cx, JS::HandleObject moduleRecord); - -/* - * Get the script associated with a module. - */ -extern JS_PUBLIC_API(JSScript*) -GetModuleScript(JSContext* cx, JS::HandleObject moduleRecord); - -} /* namespace JS */ - -extern JS_PUBLIC_API(bool) -JS_CheckForInterrupt(JSContext* cx); - -/* - * These functions allow setting an interrupt callback that will be called - * from the JS thread some time after any thread triggered the callback using - * JS_RequestInterruptCallback(cx). - * - * To schedule the GC and for other activities the engine internally triggers - * interrupt callbacks. The embedding should thus not rely on callbacks being - * triggered through the external API only. - * - * Important note: Additional callbacks can occur inside the callback handler - * if it re-enters the JS engine. The embedding must ensure that the callback - * is disconnected before attempting such re-entry. - */ -extern JS_PUBLIC_API(bool) -JS_AddInterruptCallback(JSContext* cx, JSInterruptCallback callback); - -extern JS_PUBLIC_API(bool) -JS_DisableInterruptCallback(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_ResetInterruptCallback(JSContext* cx, bool enable); - -extern JS_PUBLIC_API(void) -JS_RequestInterruptCallback(JSContext* cx); - -namespace JS { - -/** - * Sets the callback that's invoked whenever an incumbent global is required. - * - * SpiderMonkey doesn't itself have a notion of incumbent globals as defined - * by the html spec, so we need the embedding to provide this. - * See dom/base/ScriptSettings.h for details. - */ -extern JS_PUBLIC_API(void) -SetGetIncumbentGlobalCallback(JSContext* cx, JSGetIncumbentGlobalCallback callback); - -/** - * Sets the callback that's invoked whenever a Promise job should be enqeued. - * - * SpiderMonkey doesn't schedule Promise resolution jobs itself; instead, - * using this function the embedding can provide a callback to do that - * scheduling. The provided `callback` is invoked with the promise job, - * the corresponding Promise's allocation stack, and the `data` pointer - * passed here as arguments. - */ -extern JS_PUBLIC_API(void) -SetEnqueuePromiseJobCallback(JSContext* cx, JSEnqueuePromiseJobCallback callback, - void* data = nullptr); - -/** - * Sets the callback that's invoked whenever a Promise is rejected without - * a rejection handler, and when a Promise that was previously rejected - * without a handler gets a handler attached. - */ -extern JS_PUBLIC_API(void) -SetPromiseRejectionTrackerCallback(JSContext* cx, JSPromiseRejectionTrackerCallback callback, - void* data = nullptr); - -/** - * Returns a new instance of the Promise builtin class in the current - * compartment, with the right slot layout. If a `proto` is passed, that gets - * set as the instance's [[Prototype]] instead of the original value of - * `Promise.prototype`. - */ -extern JS_PUBLIC_API(JSObject*) -NewPromiseObject(JSContext* cx, JS::HandleObject executor, JS::HandleObject proto = nullptr); - -/** - * Returns true if the given object is an unwrapped PromiseObject, false - * otherwise. - */ -extern JS_PUBLIC_API(bool) -IsPromiseObject(JS::HandleObject obj); - -/** - * Returns the current compartment's original Promise constructor. - */ -extern JS_PUBLIC_API(JSObject*) -GetPromiseConstructor(JSContext* cx); - -/** - * Returns the current compartment's original Promise.prototype. - */ -extern JS_PUBLIC_API(JSObject*) -GetPromisePrototype(JSContext* cx); - -// Keep this in sync with the PROMISE_STATE defines in SelfHostingDefines.h. -enum class PromiseState { - Pending, - Fulfilled, - Rejected -}; - -/** - * Returns the given Promise's state as a JS::PromiseState enum value. - */ -extern JS_PUBLIC_API(PromiseState) -GetPromiseState(JS::HandleObject promise); - -/** - * Returns the given Promise's process-unique ID. - */ -JS_PUBLIC_API(uint64_t) -GetPromiseID(JS::HandleObject promise); - -/** - * Returns the given Promise's result: either the resolution value for - * fulfilled promises, or the rejection reason for rejected ones. - */ -extern JS_PUBLIC_API(JS::Value) -GetPromiseResult(JS::HandleObject promise); - -/** - * Returns a js::SavedFrame linked list of the stack that lead to the given - * Promise's allocation. - */ -extern JS_PUBLIC_API(JSObject*) -GetPromiseAllocationSite(JS::HandleObject promise); - -extern JS_PUBLIC_API(JSObject*) -GetPromiseResolutionSite(JS::HandleObject promise); - -#ifdef DEBUG -extern JS_PUBLIC_API(void) -DumpPromiseAllocationSite(JSContext* cx, JS::HandleObject promise); - -extern JS_PUBLIC_API(void) -DumpPromiseResolutionSite(JSContext* cx, JS::HandleObject promise); -#endif - -/** - * Calls the current compartment's original Promise.resolve on the original - * Promise constructor, with `resolutionValue` passed as an argument. - */ -extern JS_PUBLIC_API(JSObject*) -CallOriginalPromiseResolve(JSContext* cx, JS::HandleValue resolutionValue); - -/** - * Calls the current compartment's original Promise.reject on the original - * Promise constructor, with `resolutionValue` passed as an argument. - */ -extern JS_PUBLIC_API(JSObject*) -CallOriginalPromiseReject(JSContext* cx, JS::HandleValue rejectionValue); - -/** - * Resolves the given Promise with the given `resolutionValue`. - * - * Calls the `resolve` function that was passed to the executor function when - * the Promise was created. - */ -extern JS_PUBLIC_API(bool) -ResolvePromise(JSContext* cx, JS::HandleObject promise, JS::HandleValue resolutionValue); - -/** - * Rejects the given `promise` with the given `rejectionValue`. - * - * Calls the `reject` function that was passed to the executor function when - * the Promise was created. - */ -extern JS_PUBLIC_API(bool) -RejectPromise(JSContext* cx, JS::HandleObject promise, JS::HandleValue rejectionValue); - -/** - * Calls the current compartment's original Promise.prototype.then on the - * given `promise`, with `onResolve` and `onReject` passed as arguments. - * - * Asserts if the passed-in `promise` object isn't an unwrapped instance of - * `Promise` or a subclass or `onResolve` and `onReject` aren't both either - * `nullptr` or callable objects. - */ -extern JS_PUBLIC_API(JSObject*) -CallOriginalPromiseThen(JSContext* cx, JS::HandleObject promise, - JS::HandleObject onResolve, JS::HandleObject onReject); - -/** - * Unforgeable, optimized version of the JS builtin Promise.prototype.then. - * - * Takes a Promise instance and `onResolve`, `onReject` callables to enqueue - * as reactions for that promise. In difference to Promise.prototype.then, - * this doesn't create and return a new Promise instance. - * - * Asserts if the passed-in `promise` object isn't an unwrapped instance of - * `Promise` or a subclass or `onResolve` and `onReject` aren't both callable - * objects. - */ -extern JS_PUBLIC_API(bool) -AddPromiseReactions(JSContext* cx, JS::HandleObject promise, - JS::HandleObject onResolve, JS::HandleObject onReject); - -/** - * Unforgeable version of the JS builtin Promise.all. - * - * Takes an AutoObjectVector of Promise objects and returns a promise that's - * resolved with an array of resolution values when all those promises ahve - * been resolved, or rejected with the rejection value of the first rejected - * promise. - * - * Asserts if the array isn't dense or one of the entries isn't an unwrapped - * instance of Promise or a subclass. - */ -extern JS_PUBLIC_API(JSObject*) -GetWaitForAllPromise(JSContext* cx, const JS::AutoObjectVector& promises); - -/** - * An AsyncTask represents a SpiderMonkey-internal operation that starts on a - * JSContext's owner thread, possibly executes on other threads, completes, and - * then needs to be scheduled to run again on the JSContext's owner thread. The - * embedding provides for this final dispatch back to the JSContext's owner - * thread by calling methods on this interface when requested. - */ -struct JS_PUBLIC_API(AsyncTask) -{ - AsyncTask() : user(nullptr) {} - virtual ~AsyncTask() {} - - /** - * After the FinishAsyncTaskCallback is called and succeeds, one of these - * two functions will be called on the original JSContext's owner thread. - */ - virtual void finish(JSContext* cx) = 0; - virtual void cancel(JSContext* cx) = 0; - - /* The embedding may use this field to attach arbitrary data to a task. */ - void* user; -}; - -/** - * A new AsyncTask object, created inside SpiderMonkey on the JSContext's owner - * thread, will be passed to the StartAsyncTaskCallback before it is dispatched - * to another thread. The embedding may use the AsyncTask::user field to attach - * additional task state. - * - * If this function succeeds, SpiderMonkey will call the FinishAsyncTaskCallback - * at some point in the future. Otherwise, FinishAsyncTaskCallback will *not* - * be called. SpiderMonkey assumes that, if StartAsyncTaskCallback fails, it is - * because the JSContext is being shut down. - */ -typedef bool -(*StartAsyncTaskCallback)(JSContext* cx, AsyncTask* task); - -/** - * The FinishAsyncTaskCallback may be called from any thread and will only be - * passed AsyncTasks that have already been started via StartAsyncTaskCallback. - * If the embedding returns 'true', indicating success, the embedding must call - * either task->finish() or task->cancel() on the JSContext's owner thread at - * some point in the future. - */ -typedef bool -(*FinishAsyncTaskCallback)(AsyncTask* task); - -/** - * Set the above callbacks for the given context. - */ -extern JS_PUBLIC_API(void) -SetAsyncTaskCallbacks(JSContext* cx, StartAsyncTaskCallback start, FinishAsyncTaskCallback finish); - -} // namespace JS - -extern JS_PUBLIC_API(bool) -JS_IsRunning(JSContext* cx); - -namespace JS { - -/** - * This class can be used to store a pointer to the youngest frame of a saved - * stack in the specified JSContext. This reference will be picked up by any new - * calls performed until the class is destroyed, with the specified asyncCause, - * that must not be empty. - * - * Any stack capture initiated during these new calls will go through the async - * stack instead of the current stack. - * - * Capturing the stack before a new call is performed will not be affected. - * - * The provided chain of SavedFrame objects can live in any compartment, - * although it will be copied to the compartment where the stack is captured. - * - * See also `js/src/doc/SavedFrame/SavedFrame.md` for documentation on async - * stack frames. - */ -class MOZ_STACK_CLASS JS_PUBLIC_API(AutoSetAsyncStackForNewCalls) -{ - JSContext* cx; - RootedObject oldAsyncStack; - const char* oldAsyncCause; - bool oldAsyncCallIsExplicit; - - public: - enum class AsyncCallKind { - // The ordinary kind of call, where we may apply an async - // parent if there is no ordinary parent. - IMPLICIT, - // An explicit async parent, e.g., callFunctionWithAsyncStack, - // where we always want to override any ordinary parent. - EXPLICIT - }; - - // The stack parameter cannot be null by design, because it would be - // ambiguous whether that would clear any scheduled async stack and make the - // normal stack reappear in the new call, or just keep the async stack - // already scheduled for the new call, if any. - // - // asyncCause is owned by the caller and its lifetime must outlive the - // lifetime of the AutoSetAsyncStackForNewCalls object. It is strongly - // encouraged that asyncCause be a string constant or similar statically - // allocated string. - AutoSetAsyncStackForNewCalls(JSContext* cx, HandleObject stack, - const char* asyncCause, - AsyncCallKind kind = AsyncCallKind::IMPLICIT); - ~AutoSetAsyncStackForNewCalls(); -}; - -} // namespace JS - -/************************************************************************/ - -/* - * Strings. - * - * NB: JS_NewUCString takes ownership of bytes on success, avoiding a copy; - * but on error (signified by null return), it leaves chars owned by the - * caller. So the caller must free bytes in the error case, if it has no use - * for them. In contrast, all the JS_New*StringCopy* functions do not take - * ownership of the character memory passed to them -- they copy it. - */ -extern JS_PUBLIC_API(JSString*) -JS_NewStringCopyN(JSContext* cx, const char* s, size_t n); - -extern JS_PUBLIC_API(JSString*) -JS_NewStringCopyZ(JSContext* cx, const char* s); - -extern JS_PUBLIC_API(JSString*) -JS_NewStringCopyUTF8Z(JSContext* cx, const JS::ConstUTF8CharsZ s); - -extern JS_PUBLIC_API(JSString*) -JS_NewStringCopyUTF8N(JSContext* cx, const JS::UTF8Chars s); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeAndPinJSString(JSContext* cx, JS::HandleString str); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeStringN(JSContext* cx, const char* s, size_t length); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeString(JSContext* cx, const char* s); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeAndPinStringN(JSContext* cx, const char* s, size_t length); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeAndPinString(JSContext* cx, const char* s); - -extern JS_PUBLIC_API(JSString*) -JS_NewUCString(JSContext* cx, char16_t* chars, size_t length); - -extern JS_PUBLIC_API(JSString*) -JS_NewUCStringCopyN(JSContext* cx, const char16_t* s, size_t n); - -extern JS_PUBLIC_API(JSString*) -JS_NewUCStringCopyZ(JSContext* cx, const char16_t* s); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeUCStringN(JSContext* cx, const char16_t* s, size_t length); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeUCString(JSContext* cx, const char16_t* s); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeAndPinUCStringN(JSContext* cx, const char16_t* s, size_t length); - -extern JS_PUBLIC_API(JSString*) -JS_AtomizeAndPinUCString(JSContext* cx, const char16_t* s); - -extern JS_PUBLIC_API(bool) -JS_CompareStrings(JSContext* cx, JSString* str1, JSString* str2, int32_t* result); - -extern JS_PUBLIC_API(bool) -JS_StringEqualsAscii(JSContext* cx, JSString* str, const char* asciiBytes, bool* match); - -extern JS_PUBLIC_API(size_t) -JS_PutEscapedString(JSContext* cx, char* buffer, size_t size, JSString* str, char quote); - -extern JS_PUBLIC_API(bool) -JS_FileEscapedString(FILE* fp, JSString* str, char quote); - -/* - * Extracting string characters and length. - * - * While getting the length of a string is infallible, getting the chars can - * fail. As indicated by the lack of a JSContext parameter, there are two - * special cases where getting the chars is infallible: - * - * The first case is for strings that have been atomized, e.g. directly by - * JS_AtomizeAndPinString or implicitly because it is stored in a jsid. - * - * The second case is "flat" strings that have been explicitly prepared in a - * fallible context by JS_FlattenString. To catch errors, a separate opaque - * JSFlatString type is returned by JS_FlattenString and expected by - * JS_GetFlatStringChars. Note, though, that this is purely a syntactic - * distinction: the input and output of JS_FlattenString are the same actual - * GC-thing. If a JSString is known to be flat, JS_ASSERT_STRING_IS_FLAT can be - * used to make a debug-checked cast. Example: - * - * // in a fallible context - * JSFlatString* fstr = JS_FlattenString(cx, str); - * if (!fstr) - * return false; - * MOZ_ASSERT(fstr == JS_ASSERT_STRING_IS_FLAT(str)); - * - * // in an infallible context, for the same 'str' - * AutoCheckCannotGC nogc; - * const char16_t* chars = JS_GetTwoByteFlatStringChars(nogc, fstr) - * MOZ_ASSERT(chars); - * - * Flat strings and interned strings are always null-terminated, so - * JS_FlattenString can be used to get a null-terminated string. - * - * Additionally, string characters are stored as either Latin1Char (8-bit) - * or char16_t (16-bit). Clients can use JS_StringHasLatin1Chars and can then - * call either the Latin1* or TwoByte* functions. Some functions like - * JS_CopyStringChars and JS_GetStringCharAt accept both Latin1 and TwoByte - * strings. - */ - -extern JS_PUBLIC_API(size_t) -JS_GetStringLength(JSString* str); - -extern JS_PUBLIC_API(bool) -JS_StringIsFlat(JSString* str); - -/** Returns true iff the string's characters are stored as Latin1. */ -extern JS_PUBLIC_API(bool) -JS_StringHasLatin1Chars(JSString* str); - -extern JS_PUBLIC_API(const JS::Latin1Char*) -JS_GetLatin1StringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str, - size_t* length); - -extern JS_PUBLIC_API(const char16_t*) -JS_GetTwoByteStringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str, - size_t* length); - -extern JS_PUBLIC_API(bool) -JS_GetStringCharAt(JSContext* cx, JSString* str, size_t index, char16_t* res); - -extern JS_PUBLIC_API(char16_t) -JS_GetFlatStringCharAt(JSFlatString* str, size_t index); - -extern JS_PUBLIC_API(const char16_t*) -JS_GetTwoByteExternalStringChars(JSString* str); - -extern JS_PUBLIC_API(bool) -JS_CopyStringChars(JSContext* cx, mozilla::Range dest, JSString* str); - -extern JS_PUBLIC_API(JSFlatString*) -JS_FlattenString(JSContext* cx, JSString* str); - -extern JS_PUBLIC_API(const JS::Latin1Char*) -JS_GetLatin1FlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str); - -extern JS_PUBLIC_API(const char16_t*) -JS_GetTwoByteFlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str); - -static MOZ_ALWAYS_INLINE JSFlatString* -JSID_TO_FLAT_STRING(jsid id) -{ - MOZ_ASSERT(JSID_IS_STRING(id)); - return (JSFlatString*)(JSID_BITS(id)); -} - -static MOZ_ALWAYS_INLINE JSFlatString* -JS_ASSERT_STRING_IS_FLAT(JSString* str) -{ - MOZ_ASSERT(JS_StringIsFlat(str)); - return (JSFlatString*)str; -} - -static MOZ_ALWAYS_INLINE JSString* -JS_FORGET_STRING_FLATNESS(JSFlatString* fstr) -{ - return (JSString*)fstr; -} - -/* - * Additional APIs that avoid fallibility when given a flat string. - */ - -extern JS_PUBLIC_API(bool) -JS_FlatStringEqualsAscii(JSFlatString* str, const char* asciiBytes); - -extern JS_PUBLIC_API(size_t) -JS_PutEscapedFlatString(char* buffer, size_t size, JSFlatString* str, char quote); - -/** - * Create a dependent string, i.e., a string that owns no character storage, - * but that refers to a slice of another string's chars. Dependent strings - * are mutable by definition, so the thread safety comments above apply. - */ -extern JS_PUBLIC_API(JSString*) -JS_NewDependentString(JSContext* cx, JS::HandleString str, size_t start, - size_t length); - -/** - * Concatenate two strings, possibly resulting in a rope. - * See above for thread safety comments. - */ -extern JS_PUBLIC_API(JSString*) -JS_ConcatStrings(JSContext* cx, JS::HandleString left, JS::HandleString right); - -/** - * For JS_DecodeBytes, set *dstlenp to the size of the destination buffer before - * the call; on return, *dstlenp contains the number of characters actually - * stored. To determine the necessary destination buffer size, make a sizing - * call that passes nullptr for dst. - * - * On errors, the functions report the error. In that case, *dstlenp contains - * the number of characters or bytes transferred so far. If cx is nullptr, no - * error is reported on failure, and the functions simply return false. - * - * NB: This function does not store an additional zero byte or char16_t after the - * transcoded string. - */ -JS_PUBLIC_API(bool) -JS_DecodeBytes(JSContext* cx, const char* src, size_t srclen, char16_t* dst, - size_t* dstlenp); - -/** - * A variation on JS_EncodeCharacters where a null terminated string is - * returned that you are expected to call JS_free on when done. - */ -JS_PUBLIC_API(char*) -JS_EncodeString(JSContext* cx, JSString* str); - -/** - * Same behavior as JS_EncodeString(), but encode into UTF-8 string - */ -JS_PUBLIC_API(char*) -JS_EncodeStringToUTF8(JSContext* cx, JS::HandleString str); - -/** - * Get number of bytes in the string encoding (without accounting for a - * terminating zero bytes. The function returns (size_t) -1 if the string - * can not be encoded into bytes and reports an error using cx accordingly. - */ -JS_PUBLIC_API(size_t) -JS_GetStringEncodingLength(JSContext* cx, JSString* str); - -/** - * Encode string into a buffer. The function does not stores an additional - * zero byte. The function returns (size_t) -1 if the string can not be - * encoded into bytes with no error reported. Otherwise it returns the number - * of bytes that are necessary to encode the string. If that exceeds the - * length parameter, the string will be cut and only length bytes will be - * written into the buffer. - */ -JS_PUBLIC_API(size_t) -JS_EncodeStringToBuffer(JSContext* cx, JSString* str, char* buffer, size_t length); - -class MOZ_RAII JSAutoByteString -{ - public: - JSAutoByteString(JSContext* cx, JSString* str - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mBytes(JS_EncodeString(cx, str)) - { - MOZ_ASSERT(cx); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - explicit JSAutoByteString(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) - : mBytes(nullptr) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - ~JSAutoByteString() { - JS_free(nullptr, mBytes); - } - - /* Take ownership of the given byte array. */ - void initBytes(char* bytes) { - MOZ_ASSERT(!mBytes); - mBytes = bytes; - } - - char* encodeLatin1(JSContext* cx, JSString* str) { - MOZ_ASSERT(!mBytes); - MOZ_ASSERT(cx); - mBytes = JS_EncodeString(cx, str); - return mBytes; - } - - char* encodeLatin1(js::ExclusiveContext* cx, JSString* str); - - char* encodeUtf8(JSContext* cx, JS::HandleString str) { - MOZ_ASSERT(!mBytes); - MOZ_ASSERT(cx); - mBytes = JS_EncodeStringToUTF8(cx, str); - return mBytes; - } - - void clear() { - js_free(mBytes); - mBytes = nullptr; - } - - char* ptr() const { - return mBytes; - } - - bool operator!() const { - return !mBytes; - } - - size_t length() const { - if (!mBytes) - return 0; - return strlen(mBytes); - } - - private: - char* mBytes; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - - /* Copy and assignment are not supported. */ - JSAutoByteString(const JSAutoByteString& another); - JSAutoByteString& operator=(const JSAutoByteString& another); -}; - -namespace JS { - -extern JS_PUBLIC_API(JSAddonId*) -NewAddonId(JSContext* cx, JS::HandleString str); - -extern JS_PUBLIC_API(JSString*) -StringOfAddonId(JSAddonId* id); - -extern JS_PUBLIC_API(JSAddonId*) -AddonIdOfObject(JSObject* obj); - -} // namespace JS - -/************************************************************************/ -/* - * Symbols - */ - -namespace JS { - -/** - * Create a new Symbol with the given description. This function never returns - * a Symbol that is in the Runtime-wide symbol registry. - * - * If description is null, the new Symbol's [[Description]] attribute is - * undefined. - */ -JS_PUBLIC_API(Symbol*) -NewSymbol(JSContext* cx, HandleString description); - -/** - * Symbol.for as specified in ES6. - * - * Get a Symbol with the description 'key' from the Runtime-wide symbol registry. - * If there is not already a Symbol with that description in the registry, a new - * Symbol is created and registered. 'key' must not be null. - */ -JS_PUBLIC_API(Symbol*) -GetSymbolFor(JSContext* cx, HandleString key); - -/** - * Get the [[Description]] attribute of the given symbol. - * - * This function is infallible. If it returns null, that means the symbol's - * [[Description]] is undefined. - */ -JS_PUBLIC_API(JSString*) -GetSymbolDescription(HandleSymbol symbol); - -/* Well-known symbols. */ -#define JS_FOR_EACH_WELL_KNOWN_SYMBOL(macro) \ - macro(isConcatSpreadable) \ - macro(iterator) \ - macro(match) \ - macro(replace) \ - macro(search) \ - macro(species) \ - macro(hasInstance) \ - macro(split) \ - macro(toPrimitive) \ - macro(toStringTag) \ - macro(unscopables) - -enum class SymbolCode : uint32_t { - // There is one SymbolCode for each well-known symbol. -#define JS_DEFINE_SYMBOL_ENUM(name) name, - JS_FOR_EACH_WELL_KNOWN_SYMBOL(JS_DEFINE_SYMBOL_ENUM) // SymbolCode::iterator, etc. -#undef JS_DEFINE_SYMBOL_ENUM - Limit, - InSymbolRegistry = 0xfffffffe, // created by Symbol.for() or JS::GetSymbolFor() - UniqueSymbol = 0xffffffff // created by Symbol() or JS::NewSymbol() -}; - -/* For use in loops that iterate over the well-known symbols. */ -const size_t WellKnownSymbolLimit = size_t(SymbolCode::Limit); - -/** - * Return the SymbolCode telling what sort of symbol `symbol` is. - * - * A symbol's SymbolCode never changes once it is created. - */ -JS_PUBLIC_API(SymbolCode) -GetSymbolCode(Handle symbol); - -/** - * Get one of the well-known symbols defined by ES6. A single set of well-known - * symbols is shared by all compartments in a JSRuntime. - * - * `which` must be in the range [0, WellKnownSymbolLimit). - */ -JS_PUBLIC_API(Symbol*) -GetWellKnownSymbol(JSContext* cx, SymbolCode which); - -/** - * Return true if the given JSPropertySpec::name or JSFunctionSpec::name value - * is actually a symbol code and not a string. See JS_SYM_FN. - */ -inline bool -PropertySpecNameIsSymbol(const char* name) -{ - uintptr_t u = reinterpret_cast(name); - return u != 0 && u - 1 < WellKnownSymbolLimit; -} - -JS_PUBLIC_API(bool) -PropertySpecNameEqualsId(const char* name, HandleId id); - -/** - * Create a jsid that does not need to be marked for GC. - * - * 'name' is a JSPropertySpec::name or JSFunctionSpec::name value. The - * resulting jsid, on success, is either an interned string or a well-known - * symbol; either way it is immune to GC so there is no need to visit *idp - * during GC marking. - */ -JS_PUBLIC_API(bool) -PropertySpecNameToPermanentId(JSContext* cx, const char* name, jsid* idp); - -} /* namespace JS */ - -/************************************************************************/ -/* - * JSON functions - */ -typedef bool (* JSONWriteCallback)(const char16_t* buf, uint32_t len, void* data); - -/** - * JSON.stringify as specified by ES5. - */ -JS_PUBLIC_API(bool) -JS_Stringify(JSContext* cx, JS::MutableHandleValue value, JS::HandleObject replacer, - JS::HandleValue space, JSONWriteCallback callback, void* data); - -namespace JS { - -/** - * An API akin to JS_Stringify but with the goal of not having observable - * side-effects when the stringification is performed. This means it does not - * allow a replacer or a custom space, and has the following constraints on its - * input: - * - * 1) The input must be a plain object or array, not an abitrary value. - * 2) Every value in the graph reached by the algorithm starting with this - * object must be one of the following: null, undefined, a string (NOT a - * string object!), a boolean, a finite number (i.e. no NaN or Infinity or - * -Infinity), a plain object with no accessor properties, or an Array with - * no holes. - * - * The actual behavior differs from JS_Stringify only in asserting the above and - * NOT attempting to get the "toJSON" property from things, since that could - * clearly have side-effects. - */ -JS_PUBLIC_API(bool) -ToJSONMaybeSafely(JSContext* cx, JS::HandleObject input, - JSONWriteCallback callback, void* data); - -} /* namespace JS */ - -/** - * JSON.parse as specified by ES5. - */ -JS_PUBLIC_API(bool) -JS_ParseJSON(JSContext* cx, const char16_t* chars, uint32_t len, JS::MutableHandleValue vp); - -JS_PUBLIC_API(bool) -JS_ParseJSON(JSContext* cx, JS::HandleString str, JS::MutableHandleValue vp); - -JS_PUBLIC_API(bool) -JS_ParseJSONWithReviver(JSContext* cx, const char16_t* chars, uint32_t len, JS::HandleValue reviver, - JS::MutableHandleValue vp); - -JS_PUBLIC_API(bool) -JS_ParseJSONWithReviver(JSContext* cx, JS::HandleString str, JS::HandleValue reviver, - JS::MutableHandleValue vp); - -/************************************************************************/ - -/** - * The default locale for the ECMAScript Internationalization API - * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat). - * Note that the Internationalization API encourages clients to - * specify their own locales. - * The locale string remains owned by the caller. - */ -extern JS_PUBLIC_API(bool) -JS_SetDefaultLocale(JSContext* cx, const char* locale); - -/** - * Look up the default locale for the ECMAScript Internationalization API. - */ -extern JS_PUBLIC_API(JS::UniqueChars) -JS_GetDefaultLocale(JSContext* cx); - -/** - * Reset the default locale to OS defaults. - */ -extern JS_PUBLIC_API(void) -JS_ResetDefaultLocale(JSContext* cx); - -/** - * Locale specific string conversion and error message callbacks. - */ -struct JSLocaleCallbacks { - JSLocaleToUpperCase localeToUpperCase; - JSLocaleToLowerCase localeToLowerCase; - JSLocaleCompare localeCompare; // not used #if EXPOSE_INTL_API - JSLocaleToUnicode localeToUnicode; -}; - -/** - * Establish locale callbacks. The pointer must persist as long as the - * JSContext. Passing nullptr restores the default behaviour. - */ -extern JS_PUBLIC_API(void) -JS_SetLocaleCallbacks(JSContext* cx, const JSLocaleCallbacks* callbacks); - -/** - * Return the address of the current locale callbacks struct, which may - * be nullptr. - */ -extern JS_PUBLIC_API(const JSLocaleCallbacks*) -JS_GetLocaleCallbacks(JSContext* cx); - -/************************************************************************/ - -/* - * Error reporting. - */ - -namespace JS { -const uint16_t MaxNumErrorArguments = 10; -}; - -/** - * Report an exception represented by the sprintf-like conversion of format - * and its arguments. - */ -extern JS_PUBLIC_API(void) -JS_ReportErrorASCII(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -extern JS_PUBLIC_API(void) -JS_ReportErrorLatin1(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -extern JS_PUBLIC_API(void) -JS_ReportErrorUTF8(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -/* - * Use an errorNumber to retrieve the format string, args are char* - */ -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberASCII(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, ...); - -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberASCIIVA(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, va_list ap); - -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberLatin1(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, ...); - -#ifdef va_start -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberLatin1VA(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, va_list ap); -#endif - -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberUTF8(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, ...); - -#ifdef va_start -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberUTF8VA(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, va_list ap); -#endif - -/* - * Use an errorNumber to retrieve the format string, args are char16_t* - */ -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberUC(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, ...); - -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberUCArray(JSContext* cx, JSErrorCallback errorCallback, - void* userRef, const unsigned errorNumber, - const char16_t** args); - -/** - * As above, but report a warning instead (JSREPORT_IS_WARNING(report.flags)). - * Return true if there was no error trying to issue the warning, and if the - * warning was not converted into an error due to the JSOPTION_WERROR option - * being set, false otherwise. - */ -extern JS_PUBLIC_API(bool) -JS_ReportWarningASCII(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -extern JS_PUBLIC_API(bool) -JS_ReportWarningLatin1(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -extern JS_PUBLIC_API(bool) -JS_ReportWarningUTF8(JSContext* cx, const char* format, ...) - MOZ_FORMAT_PRINTF(2, 3); - -extern JS_PUBLIC_API(bool) -JS_ReportErrorFlagsAndNumberASCII(JSContext* cx, unsigned flags, - JSErrorCallback errorCallback, void* userRef, - const unsigned errorNumber, ...); - -extern JS_PUBLIC_API(bool) -JS_ReportErrorFlagsAndNumberLatin1(JSContext* cx, unsigned flags, - JSErrorCallback errorCallback, void* userRef, - const unsigned errorNumber, ...); - -extern JS_PUBLIC_API(bool) -JS_ReportErrorFlagsAndNumberUTF8(JSContext* cx, unsigned flags, - JSErrorCallback errorCallback, void* userRef, - const unsigned errorNumber, ...); - -extern JS_PUBLIC_API(bool) -JS_ReportErrorFlagsAndNumberUC(JSContext* cx, unsigned flags, - JSErrorCallback errorCallback, void* userRef, - const unsigned errorNumber, ...); - -/** - * Complain when out of memory. - */ -extern JS_PUBLIC_API(void) -JS_ReportOutOfMemory(JSContext* cx); - -/** - * Complain when an allocation size overflows the maximum supported limit. - */ -extern JS_PUBLIC_API(void) -JS_ReportAllocationOverflow(JSContext* cx); - -class JSErrorReport -{ - // The (default) error message. - // If ownsMessage_ is true, the it is freed in destructor. - JS::ConstUTF8CharsZ message_; - - // Offending source line without final '\n'. - // If ownsLinebuf__ is true, the buffer is freed in destructor. - const char16_t* linebuf_; - - // Number of chars in linebuf_. Does not include trailing '\0'. - size_t linebufLength_; - - // The 0-based offset of error token in linebuf_. - size_t tokenOffset_; - - public: - JSErrorReport() - : linebuf_(nullptr), linebufLength_(0), tokenOffset_(0), - filename(nullptr), lineno(0), column(0), - flags(0), errorNumber(0), - exnType(0), isMuted(false), - ownsLinebuf_(false), ownsMessage_(false) - {} - - ~JSErrorReport() { - freeLinebuf(); - freeMessage(); - } - - const char* filename; /* source file name, URL, etc., or null */ - unsigned lineno; /* source line number */ - unsigned column; /* zero-based column index in line */ - unsigned flags; /* error/warning, etc. */ - unsigned errorNumber; /* the error number, e.g. see js.msg */ - int16_t exnType; /* One of the JSExnType constants */ - bool isMuted : 1; /* See the comment in ReadOnlyCompileOptions. */ - - private: - bool ownsLinebuf_ : 1; - bool ownsMessage_ : 1; - - public: - const char16_t* linebuf() const { - return linebuf_; - } - size_t linebufLength() const { - return linebufLength_; - } - size_t tokenOffset() const { - return tokenOffset_; - } - void initOwnedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg, size_t tokenOffsetArg) { - initBorrowedLinebuf(linebufArg, linebufLengthArg, tokenOffsetArg); - ownsLinebuf_ = true; - } - void initBorrowedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg, size_t tokenOffsetArg); - void freeLinebuf(); - - const JS::ConstUTF8CharsZ message() const { - return message_; - } - - void initOwnedMessage(const char* messageArg) { - initBorrowedMessage(messageArg); - ownsMessage_ = true; - } - void initBorrowedMessage(const char* messageArg) { - MOZ_ASSERT(!message_); - message_ = JS::ConstUTF8CharsZ(messageArg, strlen(messageArg)); - } - - JSString* newMessageString(JSContext* cx); - - void freeMessage(); -}; - -/* - * JSErrorReport flag values. These may be freely composed. - */ -#define JSREPORT_ERROR 0x0 /* pseudo-flag for default case */ -#define JSREPORT_WARNING 0x1 /* reported via JS_ReportWarning */ -#define JSREPORT_EXCEPTION 0x2 /* exception was thrown */ -#define JSREPORT_STRICT 0x4 /* error or warning due to strict option */ - -#define JSREPORT_USER_1 0x8 /* user-defined flag */ - -/* - * If JSREPORT_EXCEPTION is set, then a JavaScript-catchable exception - * has been thrown for this runtime error, and the host should ignore it. - * Exception-aware hosts should also check for JS_IsExceptionPending if - * JS_ExecuteScript returns failure, and signal or propagate the exception, as - * appropriate. - */ -#define JSREPORT_IS_WARNING(flags) (((flags) & JSREPORT_WARNING) != 0) -#define JSREPORT_IS_EXCEPTION(flags) (((flags) & JSREPORT_EXCEPTION) != 0) -#define JSREPORT_IS_STRICT(flags) (((flags) & JSREPORT_STRICT) != 0) - -namespace JS { - -using WarningReporter = void (*)(JSContext* cx, JSErrorReport* report); - -extern JS_PUBLIC_API(WarningReporter) -SetWarningReporter(JSContext* cx, WarningReporter reporter); - -extern JS_PUBLIC_API(WarningReporter) -GetWarningReporter(JSContext* cx); - -extern JS_PUBLIC_API(bool) -CreateError(JSContext* cx, JSExnType type, HandleObject stack, - HandleString fileName, uint32_t lineNumber, uint32_t columnNumber, - JSErrorReport* report, HandleString message, MutableHandleValue rval); - -/************************************************************************/ - -/* - * Weak Maps. - */ - -extern JS_PUBLIC_API(JSObject*) -NewWeakMapObject(JSContext* cx); - -extern JS_PUBLIC_API(bool) -IsWeakMapObject(JSObject* obj); - -extern JS_PUBLIC_API(bool) -GetWeakMapEntry(JSContext* cx, JS::HandleObject mapObj, JS::HandleObject key, - JS::MutableHandleValue val); - -extern JS_PUBLIC_API(bool) -SetWeakMapEntry(JSContext* cx, JS::HandleObject mapObj, JS::HandleObject key, - JS::HandleValue val); - -/* - * Map - */ -extern JS_PUBLIC_API(JSObject*) -NewMapObject(JSContext* cx); - -extern JS_PUBLIC_API(uint32_t) -MapSize(JSContext* cx, HandleObject obj); - -extern JS_PUBLIC_API(bool) -MapGet(JSContext* cx, HandleObject obj, - HandleValue key, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -MapHas(JSContext* cx, HandleObject obj, HandleValue key, bool* rval); - -extern JS_PUBLIC_API(bool) -MapSet(JSContext* cx, HandleObject obj, HandleValue key, HandleValue val); - -extern JS_PUBLIC_API(bool) -MapDelete(JSContext *cx, HandleObject obj, HandleValue key, bool *rval); - -extern JS_PUBLIC_API(bool) -MapClear(JSContext* cx, HandleObject obj); - -extern JS_PUBLIC_API(bool) -MapKeys(JSContext* cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -MapValues(JSContext* cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -MapEntries(JSContext* cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -MapForEach(JSContext *cx, HandleObject obj, HandleValue callbackFn, HandleValue thisVal); - -/* - * Set - */ -extern JS_PUBLIC_API(JSObject *) -NewSetObject(JSContext *cx); - -extern JS_PUBLIC_API(uint32_t) -SetSize(JSContext *cx, HandleObject obj); - -extern JS_PUBLIC_API(bool) -SetHas(JSContext *cx, HandleObject obj, HandleValue key, bool *rval); - -extern JS_PUBLIC_API(bool) -SetDelete(JSContext *cx, HandleObject obj, HandleValue key, bool *rval); - -extern JS_PUBLIC_API(bool) -SetAdd(JSContext *cx, HandleObject obj, HandleValue key); - -extern JS_PUBLIC_API(bool) -SetClear(JSContext *cx, HandleObject obj); - -extern JS_PUBLIC_API(bool) -SetKeys(JSContext *cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -SetValues(JSContext *cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -SetEntries(JSContext *cx, HandleObject obj, MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -SetForEach(JSContext *cx, HandleObject obj, HandleValue callbackFn, HandleValue thisVal); - -} /* namespace JS */ - -/* - * Dates. - */ - -extern JS_PUBLIC_API(JSObject*) -JS_NewDateObject(JSContext* cx, int year, int mon, int mday, int hour, int min, int sec); - -/** - * Returns true and sets |*isDate| indicating whether |obj| is a Date object or - * a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isDate == false| when passed a proxy whose - * target is a Date, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -JS_ObjectIsDate(JSContext* cx, JS::HandleObject obj, bool* isDate); - -/************************************************************************/ - -/* - * Regular Expressions. - */ -#define JSREG_FOLD 0x01u /* fold uppercase to lowercase */ -#define JSREG_GLOB 0x02u /* global exec, creates array of matches */ -#define JSREG_MULTILINE 0x04u /* treat ^ and $ as begin and end of line */ -#define JSREG_STICKY 0x08u /* only match starting at lastIndex */ -#define JSREG_UNICODE 0x10u /* unicode */ - -extern JS_PUBLIC_API(JSObject*) -JS_NewRegExpObject(JSContext* cx, const char* bytes, size_t length, unsigned flags); - -extern JS_PUBLIC_API(JSObject*) -JS_NewUCRegExpObject(JSContext* cx, const char16_t* chars, size_t length, unsigned flags); - -extern JS_PUBLIC_API(bool) -JS_SetRegExpInput(JSContext* cx, JS::HandleObject obj, JS::HandleString input); - -extern JS_PUBLIC_API(bool) -JS_ClearRegExpStatics(JSContext* cx, JS::HandleObject obj); - -extern JS_PUBLIC_API(bool) -JS_ExecuteRegExp(JSContext* cx, JS::HandleObject obj, JS::HandleObject reobj, - char16_t* chars, size_t length, size_t* indexp, bool test, - JS::MutableHandleValue rval); - -/* RegExp interface for clients without a global object. */ - -extern JS_PUBLIC_API(bool) -JS_ExecuteRegExpNoStatics(JSContext* cx, JS::HandleObject reobj, char16_t* chars, size_t length, - size_t* indexp, bool test, JS::MutableHandleValue rval); - -/** - * Returns true and sets |*isRegExp| indicating whether |obj| is a RegExp - * object or a wrapper around one, otherwise returns false on failure. - * - * This method returns true with |*isRegExp == false| when passed a proxy whose - * target is a RegExp, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API(bool) -JS_ObjectIsRegExp(JSContext* cx, JS::HandleObject obj, bool* isRegExp); - -extern JS_PUBLIC_API(unsigned) -JS_GetRegExpFlags(JSContext* cx, JS::HandleObject obj); - -extern JS_PUBLIC_API(JSString*) -JS_GetRegExpSource(JSContext* cx, JS::HandleObject obj); - -/************************************************************************/ - -extern JS_PUBLIC_API(bool) -JS_IsExceptionPending(JSContext* cx); - -extern JS_PUBLIC_API(bool) -JS_GetPendingException(JSContext* cx, JS::MutableHandleValue vp); - -extern JS_PUBLIC_API(void) -JS_SetPendingException(JSContext* cx, JS::HandleValue v); - -extern JS_PUBLIC_API(void) -JS_ClearPendingException(JSContext* cx); - -namespace JS { - -/** - * Save and later restore the current exception state of a given JSContext. - * This is useful for implementing behavior in C++ that's like try/catch - * or try/finally in JS. - * - * Typical usage: - * - * bool ok = JS::Evaluate(cx, ...); - * AutoSaveExceptionState savedExc(cx); - * ... cleanup that might re-enter JS ... - * return ok; - */ -class JS_PUBLIC_API(AutoSaveExceptionState) -{ - private: - JSContext* context; - bool wasPropagatingForcedReturn; - bool wasOverRecursed; - bool wasThrowing; - RootedValue exceptionValue; - - public: - /* - * Take a snapshot of cx's current exception state. Then clear any current - * pending exception in cx. - */ - explicit AutoSaveExceptionState(JSContext* cx); - - /* - * If neither drop() nor restore() was called, restore the exception - * state only if no exception is currently pending on cx. - */ - ~AutoSaveExceptionState(); - - /* - * Discard any stored exception state. - * If this is called, the destructor is a no-op. - */ - void drop() { - wasPropagatingForcedReturn = false; - wasOverRecursed = false; - wasThrowing = false; - exceptionValue.setUndefined(); - } - - /* - * Replace cx's exception state with the stored exception state. Then - * discard the stored exception state. If this is called, the - * destructor is a no-op. - */ - void restore(); -}; - -} /* namespace JS */ - -/* Deprecated API. Use AutoSaveExceptionState instead. */ -extern JS_PUBLIC_API(JSExceptionState*) -JS_SaveExceptionState(JSContext* cx); - -extern JS_PUBLIC_API(void) -JS_RestoreExceptionState(JSContext* cx, JSExceptionState* state); - -extern JS_PUBLIC_API(void) -JS_DropExceptionState(JSContext* cx, JSExceptionState* state); - -/** - * If the given object is an exception object, the exception will have (or be - * able to lazily create) an error report struct, and this function will return - * the address of that struct. Otherwise, it returns nullptr. The lifetime - * of the error report struct that might be returned is the same as the - * lifetime of the exception object. - */ -extern JS_PUBLIC_API(JSErrorReport*) -JS_ErrorFromException(JSContext* cx, JS::HandleObject obj); - -/** - * If the given object is an exception object (or an unwrappable - * cross-compartment wrapper for one), return the stack for that exception, if - * any. Will return null if the given object is not an exception object - * (including if it's null or a security wrapper that can't be unwrapped) or if - * the exception has no stack. - */ -extern JS_PUBLIC_API(JSObject*) -ExceptionStackOrNull(JS::HandleObject obj); - -/* - * Throws a StopIteration exception on cx. - */ -extern JS_PUBLIC_API(bool) -JS_ThrowStopIteration(JSContext* cx); - -extern JS_PUBLIC_API(bool) -JS_IsStopIteration(const JS::Value& v); - -/** - * A JS context always has an "owner thread". The owner thread is set when the - * context is created (to the current thread) and practically all entry points - * into the JS engine check that a context (or anything contained in the - * context: runtime, compartment, object, etc) is only touched by its owner - * thread. Embeddings may check this invariant outside the JS engine by calling - * JS_AbortIfWrongThread (which will abort if not on the owner thread, even for - * non-debug builds). - */ - -extern JS_PUBLIC_API(void) -JS_AbortIfWrongThread(JSContext* cx); - -/************************************************************************/ - -/** - * A constructor can request that the JS engine create a default new 'this' - * object of the given class, using the callee to determine parentage and - * [[Prototype]]. - */ -extern JS_PUBLIC_API(JSObject*) -JS_NewObjectForConstructor(JSContext* cx, const JSClass* clasp, const JS::CallArgs& args); - -/************************************************************************/ - -#ifdef JS_GC_ZEAL -#define JS_DEFAULT_ZEAL_FREQ 100 - -extern JS_PUBLIC_API(void) -JS_GetGCZealBits(JSContext* cx, uint32_t* zealBits, uint32_t* frequency, uint32_t* nextScheduled); - -extern JS_PUBLIC_API(void) -JS_SetGCZeal(JSContext* cx, uint8_t zeal, uint32_t frequency); - -extern JS_PUBLIC_API(void) -JS_ScheduleGC(JSContext* cx, uint32_t count); -#endif - -extern JS_PUBLIC_API(void) -JS_SetParallelParsingEnabled(JSContext* cx, bool enabled); - -extern JS_PUBLIC_API(void) -JS_SetOffthreadIonCompilationEnabled(JSContext* cx, bool enabled); - -#define JIT_COMPILER_OPTIONS(Register) \ - Register(BASELINE_WARMUP_TRIGGER, "baseline.warmup.trigger") \ - Register(ION_WARMUP_TRIGGER, "ion.warmup.trigger") \ - Register(ION_GVN_ENABLE, "ion.gvn.enable") \ - Register(ION_FORCE_IC, "ion.forceinlineCaches") \ - Register(ION_ENABLE, "ion.enable") \ - Register(ION_INTERRUPT_WITHOUT_SIGNAL, "ion.interrupt-without-signals") \ - Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis") \ - Register(BASELINE_ENABLE, "baseline.enable") \ - Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \ - Register(JUMP_THRESHOLD, "jump-threshold") \ - Register(ASMJS_ATOMICS_ENABLE, "asmjs.atomics.enable") \ - Register(WASM_TEST_MODE, "wasm.test-mode") \ - Register(WASM_FOLD_OFFSETS, "wasm.fold-offsets") - -typedef enum JSJitCompilerOption { -#define JIT_COMPILER_DECLARE(key, str) \ - JSJITCOMPILER_ ## key, - - JIT_COMPILER_OPTIONS(JIT_COMPILER_DECLARE) -#undef JIT_COMPILER_DECLARE - - JSJITCOMPILER_NOT_AN_OPTION -} JSJitCompilerOption; - -extern JS_PUBLIC_API(void) -JS_SetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t value); -extern JS_PUBLIC_API(bool) -JS_GetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t* valueOut); - -/** - * Convert a uint32_t index into a jsid. - */ -extern JS_PUBLIC_API(bool) -JS_IndexToId(JSContext* cx, uint32_t index, JS::MutableHandleId); - -/** - * Convert chars into a jsid. - * - * |chars| may not be an index. - */ -extern JS_PUBLIC_API(bool) -JS_CharsToId(JSContext* cx, JS::TwoByteChars chars, JS::MutableHandleId); - -/** - * Test if the given string is a valid ECMAScript identifier - */ -extern JS_PUBLIC_API(bool) -JS_IsIdentifier(JSContext* cx, JS::HandleString str, bool* isIdentifier); - -/** - * Test whether the given chars + length are a valid ECMAScript identifier. - * This version is infallible, so just returns whether the chars are an - * identifier. - */ -extern JS_PUBLIC_API(bool) -JS_IsIdentifier(const char16_t* chars, size_t length); - -namespace js { -class ScriptSource; -} // namespace js - -namespace JS { - -class MOZ_RAII JS_PUBLIC_API(AutoFilename) -{ - private: - js::ScriptSource* ss_; - mozilla::Variant filename_; - - AutoFilename(const AutoFilename&) = delete; - AutoFilename& operator=(const AutoFilename&) = delete; - - public: - AutoFilename() - : ss_(nullptr), - filename_(mozilla::AsVariant(nullptr)) - {} - - ~AutoFilename() { - reset(); - } - - void reset(); - - void setOwned(UniqueChars&& filename); - void setUnowned(const char* filename); - void setScriptSource(js::ScriptSource* ss); - - const char* get() const; -}; - -/** - * Return the current filename, line number and column number of the most - * currently running frame. Returns true if a scripted frame was found, false - * otherwise. - * - * If a the embedding has hidden the scripted caller for the topmost activation - * record, this will also return false. - */ -extern JS_PUBLIC_API(bool) -DescribeScriptedCaller(JSContext* cx, AutoFilename* filename = nullptr, - unsigned* lineno = nullptr, unsigned* column = nullptr); - -extern JS_PUBLIC_API(JSObject*) -GetScriptedCallerGlobal(JSContext* cx); - -/** - * Informs the JS engine that the scripted caller should be hidden. This can be - * used by the embedding to maintain an override of the scripted caller in its - * calculations, by hiding the scripted caller in the JS engine and pushing data - * onto a separate stack, which it inspects when DescribeScriptedCaller returns - * null. - * - * We maintain a counter on each activation record. Add() increments the counter - * of the topmost activation, and Remove() decrements it. The count may never - * drop below zero, and must always be exactly zero when the activation is - * popped from the stack. - */ -extern JS_PUBLIC_API(void) -HideScriptedCaller(JSContext* cx); - -extern JS_PUBLIC_API(void) -UnhideScriptedCaller(JSContext* cx); - -class MOZ_RAII AutoHideScriptedCaller -{ - public: - explicit AutoHideScriptedCaller(JSContext* cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mContext(cx) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - HideScriptedCaller(mContext); - } - ~AutoHideScriptedCaller() { - UnhideScriptedCaller(mContext); - } - - protected: - JSContext* mContext; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -/* - * Encode/Decode interpreted scripts and functions to/from memory. - */ - -typedef mozilla::Vector TranscodeBuffer; - -enum TranscodeResult -{ - // Successful encoding / decoding. - TranscodeResult_Ok = 0, - - // A warning message, is set to the message out-param. - TranscodeResult_Failure = 0x100, - TranscodeResult_Failure_BadBuildId = TranscodeResult_Failure | 0x1, - TranscodeResult_Failure_RunOnceNotSupported = TranscodeResult_Failure | 0x2, - TranscodeResult_Failure_AsmJSNotSupported = TranscodeResult_Failure | 0x3, - TranscodeResult_Failure_UnknownClassKind = TranscodeResult_Failure | 0x4, - - // A error, the JSContext has a pending exception. - TranscodeResult_Throw = 0x200 -}; - -extern JS_PUBLIC_API(TranscodeResult) -EncodeScript(JSContext* cx, TranscodeBuffer& buffer, JS::HandleScript script); - -extern JS_PUBLIC_API(TranscodeResult) -EncodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::HandleObject funobj); - -extern JS_PUBLIC_API(TranscodeResult) -DecodeScript(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleScript scriptp, - size_t cursorIndex = 0); - -extern JS_PUBLIC_API(TranscodeResult) -DecodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleFunction funp, - size_t cursorIndex = 0); - -} /* namespace JS */ - -namespace js { - -enum class StackFormat { SpiderMonkey, V8, Default }; - -/* - * Sets the format used for stringifying Error stacks. - * - * The default format is StackFormat::SpiderMonkey. Use StackFormat::V8 - * in order to emulate V8's stack formatting. StackFormat::Default can't be - * used here. - */ -extern JS_PUBLIC_API(void) -SetStackFormat(JSContext* cx, StackFormat format); - -extern JS_PUBLIC_API(StackFormat) -GetStackFormat(JSContext* cx); - -} - -namespace JS { - -/* - * This callback represents a request by the JS engine to open for reading the - * existing cache entry for the given global and char range that may contain a - * module. If a cache entry exists, the callback shall return 'true' and return - * the size, base address and an opaque file handle as outparams. If the - * callback returns 'true', the JS engine guarantees a call to - * CloseAsmJSCacheEntryForReadOp, passing the same base address, size and - * handle. - */ -typedef bool -(* OpenAsmJSCacheEntryForReadOp)(HandleObject global, const char16_t* begin, const char16_t* limit, - size_t* size, const uint8_t** memory, intptr_t* handle); -typedef void -(* CloseAsmJSCacheEntryForReadOp)(size_t size, const uint8_t* memory, intptr_t handle); - -/** The list of reasons why an asm.js module may not be stored in the cache. */ -enum AsmJSCacheResult -{ - AsmJSCache_Success, - AsmJSCache_MIN = AsmJSCache_Success, - AsmJSCache_ModuleTooSmall, - AsmJSCache_SynchronousScript, - AsmJSCache_QuotaExceeded, - AsmJSCache_StorageInitFailure, - AsmJSCache_Disabled_Internal, - AsmJSCache_Disabled_ShellFlags, - AsmJSCache_Disabled_JitInspector, - AsmJSCache_InternalError, - AsmJSCache_Disabled_PrivateBrowsing, - AsmJSCache_LIMIT -}; - -/* - * This callback represents a request by the JS engine to open for writing a - * cache entry of the given size for the given global and char range containing - * the just-compiled module. If cache entry space is available, the callback - * shall return 'true' and return the base address and an opaque file handle as - * outparams. If the callback returns 'true', the JS engine guarantees a call - * to CloseAsmJSCacheEntryForWriteOp passing the same base address, size and - * handle. - * - * If 'installed' is true, then the cache entry is associated with a permanently - * installed JS file (e.g., in a packaged webapp). This information allows the - * embedding to store the cache entry in a installed location associated with - * the principal of 'global' where it will not be evicted until the associated - * installed JS file is removed. - */ -typedef AsmJSCacheResult -(* OpenAsmJSCacheEntryForWriteOp)(HandleObject global, bool installed, - const char16_t* begin, const char16_t* end, - size_t size, uint8_t** memory, intptr_t* handle); -typedef void -(* CloseAsmJSCacheEntryForWriteOp)(size_t size, uint8_t* memory, intptr_t handle); - -struct AsmJSCacheOps -{ - OpenAsmJSCacheEntryForReadOp openEntryForRead; - CloseAsmJSCacheEntryForReadOp closeEntryForRead; - OpenAsmJSCacheEntryForWriteOp openEntryForWrite; - CloseAsmJSCacheEntryForWriteOp closeEntryForWrite; -}; - -extern JS_PUBLIC_API(void) -SetAsmJSCacheOps(JSContext* cx, const AsmJSCacheOps* callbacks); - -/** - * Return the buildId (represented as a sequence of characters) associated with - * the currently-executing build. If the JS engine is embedded such that a - * single cache entry can be observed by different compiled versions of the JS - * engine, it is critical that the buildId shall change for each new build of - * the JS engine. - */ -typedef js::Vector BuildIdCharVector; - -typedef bool -(* BuildIdOp)(BuildIdCharVector* buildId); - -extern JS_PUBLIC_API(void) -SetBuildIdOp(JSContext* cx, BuildIdOp buildIdOp); - -/** - * The WasmModule interface allows the embedding to hold a reference to the - * underying C++ implementation of a JS WebAssembly.Module object for purposes - * of (de)serialization off the object's JSRuntime's thread. - * - * - Serialization starts when WebAssembly.Module is passed to the - * structured-clone algorithm. JS::GetWasmModule is called on the JSRuntime - * thread that initiated the structured clone to get the JS::WasmModule. - * This interface is then taken to a background thread where serializedSize() - * and serialize() are called to write the object to two files: a bytecode file - * that always allows successful deserialization and a compiled-code file keyed - * on cpu- and build-id that may become invalid if either of these change between - * serialization and deserialization. After serialization, the reference is - * dropped from the background thread. - * - * - Deserialization starts when the structured clone algorithm encounters a - * serialized WebAssembly.Module. On a background thread, the compiled-code file - * is opened and CompiledWasmModuleAssumptionsMatch is called to see if it is - * still valid (as described above). DeserializeWasmModule is then called to - * construct a JS::WasmModule (also on the background thread), passing the - * bytecode file descriptor and, if valid, the compiled-code file descriptor. - * The JS::WasmObject is then transported to the JSRuntime thread (which - * originated the request) and the wrapping WebAssembly.Module object is created - * by calling createObject(). - */ - -struct WasmModule : mozilla::external::AtomicRefCounted -{ - MOZ_DECLARE_REFCOUNTED_TYPENAME(WasmModule) - virtual ~WasmModule() {} - - virtual void serializedSize(size_t* maybeBytecodeSize, size_t* maybeCompiledSize) const = 0; - virtual void serialize(uint8_t* maybeBytecodeBegin, size_t maybeBytecodeSize, - uint8_t* maybeCompiledBegin, size_t maybeCompiledSize) const = 0; - - virtual JSObject* createObject(JSContext* cx) = 0; -}; - -extern JS_PUBLIC_API(bool) -IsWasmModuleObject(HandleObject obj); - -extern JS_PUBLIC_API(RefPtr) -GetWasmModule(HandleObject obj); - -extern JS_PUBLIC_API(bool) -CompiledWasmModuleAssumptionsMatch(PRFileDesc* compiled, BuildIdCharVector&& buildId); - -extern JS_PUBLIC_API(RefPtr) -DeserializeWasmModule(PRFileDesc* bytecode, PRFileDesc* maybeCompiled, BuildIdCharVector&& buildId, - JS::UniqueChars filename, unsigned line, unsigned column); - -/** - * Convenience class for imitating a JS level for-of loop. Typical usage: - * - * ForOfIterator it(cx); - * if (!it.init(iterable)) - * return false; - * RootedValue val(cx); - * while (true) { - * bool done; - * if (!it.next(&val, &done)) - * return false; - * if (done) - * break; - * if (!DoStuff(cx, val)) - * return false; - * } - */ -class MOZ_STACK_CLASS JS_PUBLIC_API(ForOfIterator) { - protected: - JSContext* cx_; - /* - * Use the ForOfPIC on the global object (see vm/GlobalObject.h) to try - * to optimize iteration across arrays. - * - * Case 1: Regular Iteration - * iterator - pointer to the iterator object. - * index - fixed to NOT_ARRAY (== UINT32_MAX) - * - * Case 2: Optimized Array Iteration - * iterator - pointer to the array object. - * index - current position in array. - * - * The cases are distinguished by whether or not |index| is equal to NOT_ARRAY. - */ - JS::RootedObject iterator; - uint32_t index; - - static const uint32_t NOT_ARRAY = UINT32_MAX; - - ForOfIterator(const ForOfIterator&) = delete; - ForOfIterator& operator=(const ForOfIterator&) = delete; - - public: - explicit ForOfIterator(JSContext* cx) : cx_(cx), iterator(cx_), index(NOT_ARRAY) { } - - enum NonIterableBehavior { - ThrowOnNonIterable, - AllowNonIterable - }; - - /** - * Initialize the iterator. If AllowNonIterable is passed then if getting - * the @@iterator property from iterable returns undefined init() will just - * return true instead of throwing. Callers must then check - * valueIsIterable() before continuing with the iteration. - */ - bool init(JS::HandleValue iterable, - NonIterableBehavior nonIterableBehavior = ThrowOnNonIterable); - - /** - * Get the next value from the iterator. If false *done is true - * after this call, do not examine val. - */ - bool next(JS::MutableHandleValue val, bool* done); - - /** - * If initialized with throwOnNonCallable = false, check whether - * the value is iterable. - */ - bool valueIsIterable() const { - return iterator; - } - - private: - inline bool nextFromOptimizedArray(MutableHandleValue val, bool* done); - bool materializeArrayIterator(); -}; - - -/** - * If a large allocation fails when calling pod_{calloc,realloc}CanGC, the JS - * engine may call the large-allocation- failure callback, if set, to allow the - * embedding to flush caches, possibly perform shrinking GCs, etc. to make some - * room. The allocation will then be retried (and may still fail.) - */ - -typedef void -(* LargeAllocationFailureCallback)(void* data); - -extern JS_PUBLIC_API(void) -SetLargeAllocationFailureCallback(JSContext* cx, LargeAllocationFailureCallback afc, void* data); - -/** - * Unlike the error reporter, which is only called if the exception for an OOM - * bubbles up and is not caught, the OutOfMemoryCallback is called immediately - * at the OOM site to allow the embedding to capture the current state of heap - * allocation before anything is freed. If the large-allocation-failure callback - * is called at all (not all allocation sites call the large-allocation-failure - * callback on failure), it is called before the out-of-memory callback; the - * out-of-memory callback is only called if the allocation still fails after the - * large-allocation-failure callback has returned. - */ - -typedef void -(* OutOfMemoryCallback)(JSContext* cx, void* data); - -extern JS_PUBLIC_API(void) -SetOutOfMemoryCallback(JSContext* cx, OutOfMemoryCallback cb, void* data); - -/** - * Capture all frames. - */ -struct AllFrames { }; - -/** - * Capture at most this many frames. - */ -struct MaxFrames -{ - uint32_t maxFrames; - - explicit MaxFrames(uint32_t max) - : maxFrames(max) - { - MOZ_ASSERT(max > 0); - } -}; - -/** - * Capture the first frame with the given principals. By default, do not - * consider self-hosted frames with the given principals as satisfying the stack - * capture. - */ -struct FirstSubsumedFrame -{ - JSContext* cx; - JSPrincipals* principals; - bool ignoreSelfHosted; - - /** - * Use the cx's current compartment's principals. - */ - explicit FirstSubsumedFrame(JSContext* cx, bool ignoreSelfHostedFrames = true); - - explicit FirstSubsumedFrame(JSContext* ctx, JSPrincipals* p, bool ignoreSelfHostedFrames = true) - : cx(ctx) - , principals(p) - , ignoreSelfHosted(ignoreSelfHostedFrames) - { - if (principals) - JS_HoldPrincipals(principals); - } - - // No copying because we want to avoid holding and dropping principals - // unnecessarily. - FirstSubsumedFrame(const FirstSubsumedFrame&) = delete; - FirstSubsumedFrame& operator=(const FirstSubsumedFrame&) = delete; - - FirstSubsumedFrame(FirstSubsumedFrame&& rhs) - : principals(rhs.principals) - , ignoreSelfHosted(rhs.ignoreSelfHosted) - { - MOZ_ASSERT(this != &rhs, "self move disallowed"); - rhs.principals = nullptr; - } - - FirstSubsumedFrame& operator=(FirstSubsumedFrame&& rhs) { - new (this) FirstSubsumedFrame(mozilla::Move(rhs)); - return *this; - } - - ~FirstSubsumedFrame() { - if (principals) - JS_DropPrincipals(cx, principals); - } -}; - -using StackCapture = mozilla::Variant; - -/** - * Capture the current call stack as a chain of SavedFrame JSObjects, and set - * |stackp| to the SavedFrame for the youngest stack frame, or nullptr if there - * are no JS frames on the stack. - * - * The |capture| parameter describes the portion of the JS stack to capture: - * - * * |JS::AllFrames|: Capture all frames on the stack. - * - * * |JS::MaxFrames|: Capture no more than |JS::MaxFrames::maxFrames| from the - * stack. - * - * * |JS::FirstSubsumedFrame|: Capture the first frame whose principals are - * subsumed by |JS::FirstSubsumedFrame::principals|. By default, do not - * consider self-hosted frames; this can be controlled via the - * |JS::FirstSubsumedFrame::ignoreSelfHosted| flag. Do not capture any async - * stack. - */ -extern JS_PUBLIC_API(bool) -CaptureCurrentStack(JSContext* cx, MutableHandleObject stackp, - StackCapture&& capture = StackCapture(AllFrames())); - -/* - * This is a utility function for preparing an async stack to be used - * by some other object. This may be used when you need to treat a - * given stack trace as an async parent. If you just need to capture - * the current stack, async parents and all, use CaptureCurrentStack - * instead. - * - * Here |asyncStack| is the async stack to prepare. It is copied into - * |cx|'s current compartment, and the newest frame is given - * |asyncCause| as its asynchronous cause. If |maxFrameCount| is - * non-zero, capture at most the youngest |maxFrameCount| frames. The - * new stack object is written to |stackp|. Returns true on success, - * or sets an exception and returns |false| on error. - */ -extern JS_PUBLIC_API(bool) -CopyAsyncStack(JSContext* cx, HandleObject asyncStack, - HandleString asyncCause, MutableHandleObject stackp, - unsigned maxFrameCount); - -/* - * Accessors for working with SavedFrame JSObjects - * - * Each of these functions assert that if their `HandleObject savedFrame` - * argument is non-null, its JSClass is the SavedFrame class (or it is a - * cross-compartment or Xray wrapper around an object with the SavedFrame class) - * and the object is not the SavedFrame.prototype object. - * - * Each of these functions will find the first SavedFrame object in the chain - * whose underlying stack frame principals are subsumed by the cx's current - * compartment's principals, and operate on that SavedFrame object. This - * prevents leaking information about privileged frames to un-privileged - * callers. As a result, the SavedFrame in parameters do _NOT_ need to be in the - * same compartment as the cx, and the various out parameters are _NOT_ - * guaranteed to be in the same compartment as cx. - * - * You may consider or skip over self-hosted frames by passing - * `SavedFrameSelfHosted::Include` or `SavedFrameSelfHosted::Exclude` - * respectively. - * - * Additionally, it may be the case that there is no such SavedFrame object - * whose captured frame's principals are subsumed by the caller's compartment's - * principals! If the `HandleObject savedFrame` argument is null, or the - * caller's principals do not subsume any of the chained SavedFrame object's - * principals, `SavedFrameResult::AccessDenied` is returned and a (hopefully) - * sane default value is chosen for the out param. - * - * See also `js/src/doc/SavedFrame/SavedFrame.md`. - */ - -enum class SavedFrameResult { - Ok, - AccessDenied -}; - -enum class SavedFrameSelfHosted { - Include, - Exclude -}; - -/** - * Given a SavedFrame JSObject, get its source property. Defaults to the empty - * string. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameSource(JSContext* cx, HandleObject savedFrame, MutableHandleString sourcep, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its line property. Defaults to 0. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameLine(JSContext* cx, HandleObject savedFrame, uint32_t* linep, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its column property. Defaults to 0. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameColumn(JSContext* cx, HandleObject savedFrame, uint32_t* columnp, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its functionDisplayName string, or nullptr - * if SpiderMonkey was unable to infer a name for the captured frame's - * function. Defaults to nullptr. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameFunctionDisplayName(JSContext* cx, HandleObject savedFrame, MutableHandleString namep, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its asyncCause string. Defaults to nullptr. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameAsyncCause(JSContext* cx, HandleObject savedFrame, MutableHandleString asyncCausep, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its asyncParent SavedFrame object or nullptr - * if there is no asyncParent. The `asyncParentp` out parameter is _NOT_ - * guaranteed to be in the cx's compartment. Defaults to nullptr. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameAsyncParent(JSContext* cx, HandleObject savedFrame, MutableHandleObject asyncParentp, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject, get its parent SavedFrame object or nullptr if - * it is the oldest frame in the stack. The `parentp` out parameter is _NOT_ - * guaranteed to be in the cx's compartment. Defaults to nullptr. - */ -extern JS_PUBLIC_API(SavedFrameResult) -GetSavedFrameParent(JSContext* cx, HandleObject savedFrame, MutableHandleObject parentp, - SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include); - -/** - * Given a SavedFrame JSObject stack, stringify it in the same format as - * Error.prototype.stack. The stringified stack out parameter is placed in the - * cx's compartment. Defaults to the empty string. - * - * The same notes above about SavedFrame accessors applies here as well: cx - * doesn't need to be in stack's compartment, and stack can be null, a - * SavedFrame object, or a wrapper (CCW or Xray) around a SavedFrame object. - * - * Optional indent parameter specifies the number of white spaces to indent - * each line. - */ -extern JS_PUBLIC_API(bool) -BuildStackString(JSContext* cx, HandleObject stack, MutableHandleString stringp, - size_t indent = 0, js::StackFormat stackFormat = js::StackFormat::Default); - -/** - * Return true iff the given object is either a SavedFrame object or wrapper - * around a SavedFrame object, and it is not the SavedFrame.prototype object. - */ -extern JS_PUBLIC_API(bool) -IsSavedFrame(JSObject* obj); - -} /* namespace JS */ - - -/* Stopwatch-based performance monitoring. */ - -namespace js { - -class AutoStopwatch; - -/** - * Abstract base class for a representation of the performance of a - * component. Embeddings interested in performance monitoring should - * provide a concrete implementation of this class, as well as the - * relevant callbacks (see below). - */ -struct PerformanceGroup { - PerformanceGroup(); - - // The current iteration of the event loop. - uint64_t iteration() const; - - // `true` if an instance of `AutoStopwatch` is already monitoring - // the performance of this performance group for this iteration - // of the event loop, `false` otherwise. - bool isAcquired(uint64_t it) const; - - // `true` if a specific instance of `AutoStopwatch` is already monitoring - // the performance of this performance group for this iteration - // of the event loop, `false` otherwise. - bool isAcquired(uint64_t it, const AutoStopwatch* owner) const; - - // Mark that an instance of `AutoStopwatch` is monitoring - // the performance of this group for a given iteration. - void acquire(uint64_t it, const AutoStopwatch* owner); - - // Mark that no `AutoStopwatch` is monitoring the - // performance of this group for the iteration. - void release(uint64_t it, const AutoStopwatch* owner); - - // The number of cycles spent in this group during this iteration - // of the event loop. Note that cycles are not a reliable measure, - // especially over short intervals. See Stopwatch.* for a more - // complete discussion on the imprecision of cycle measurement. - uint64_t recentCycles(uint64_t iteration) const; - void addRecentCycles(uint64_t iteration, uint64_t cycles); - - // The number of times this group has been activated during this - // iteration of the event loop. - uint64_t recentTicks(uint64_t iteration) const; - void addRecentTicks(uint64_t iteration, uint64_t ticks); - - // The number of microseconds spent doing CPOW during this - // iteration of the event loop. - uint64_t recentCPOW(uint64_t iteration) const; - void addRecentCPOW(uint64_t iteration, uint64_t CPOW); - - // Get rid of any data that pretends to be recent. - void resetRecentData(); - - // `true` if new measures should be added to this group, `false` - // otherwise. - bool isActive() const; - void setIsActive(bool); - - // `true` if this group has been used in the current iteration, - // `false` otherwise. - bool isUsedInThisIteration() const; - void setIsUsedInThisIteration(bool); - protected: - // An implementation of `delete` for this object. Must be provided - // by the embedding. - virtual void Delete() = 0; - - private: - // The number of cycles spent in this group during this iteration - // of the event loop. Note that cycles are not a reliable measure, - // especially over short intervals. See Runtime.cpp for a more - // complete discussion on the imprecision of cycle measurement. - uint64_t recentCycles_; - - // The number of times this group has been activated during this - // iteration of the event loop. - uint64_t recentTicks_; - - // The number of microseconds spent doing CPOW during this - // iteration of the event loop. - uint64_t recentCPOW_; - - // The current iteration of the event loop. If necessary, - // may safely overflow. - uint64_t iteration_; - - // `true` if new measures should be added to this group, `false` - // otherwise. - bool isActive_; - - // `true` if this group has been used in the current iteration, - // `false` otherwise. - bool isUsedInThisIteration_; - - // The stopwatch currently monitoring the group, - // or `nullptr` if none. Used ony for comparison. - const AutoStopwatch* owner_; - - public: - // Compatibility with RefPtr<> - void AddRef(); - void Release(); - uint64_t refCount_; -}; - -using PerformanceGroupVector = mozilla::Vector, 0, SystemAllocPolicy>; - -/** - * Commit any Performance Monitoring data. - * - * Until `FlushMonitoring` has been called, all PerformanceMonitoring data is invisible - * to the outside world and can cancelled with a call to `ResetMonitoring`. - */ -extern JS_PUBLIC_API(bool) -FlushPerformanceMonitoring(JSContext*); - -/** - * Cancel any measurement that hasn't been committed. - */ -extern JS_PUBLIC_API(void) -ResetPerformanceMonitoring(JSContext*); - -/** - * Cleanup any memory used by performance monitoring. - */ -extern JS_PUBLIC_API(void) -DisposePerformanceMonitoring(JSContext*); - -/** - * Turn on/off stopwatch-based CPU monitoring. - * - * `SetStopwatchIsMonitoringCPOW` or `SetStopwatchIsMonitoringJank` - * may return `false` if monitoring could not be activated, which may - * happen if we are out of memory. - */ -extern JS_PUBLIC_API(bool) -SetStopwatchIsMonitoringCPOW(JSContext*, bool); -extern JS_PUBLIC_API(bool) -GetStopwatchIsMonitoringCPOW(JSContext*); -extern JS_PUBLIC_API(bool) -SetStopwatchIsMonitoringJank(JSContext*, bool); -extern JS_PUBLIC_API(bool) -GetStopwatchIsMonitoringJank(JSContext*); - -// Extract the CPU rescheduling data. -extern JS_PUBLIC_API(void) -GetPerfMonitoringTestCpuRescheduling(JSContext*, uint64_t* stayed, uint64_t* moved); - - -/** - * Add a number of microseconds to the time spent waiting on CPOWs - * since process start. - */ -extern JS_PUBLIC_API(void) -AddCPOWPerformanceDelta(JSContext*, uint64_t delta); - -typedef bool -(*StopwatchStartCallback)(uint64_t, void*); -extern JS_PUBLIC_API(bool) -SetStopwatchStartCallback(JSContext*, StopwatchStartCallback, void*); - -typedef bool -(*StopwatchCommitCallback)(uint64_t, PerformanceGroupVector&, void*); -extern JS_PUBLIC_API(bool) -SetStopwatchCommitCallback(JSContext*, StopwatchCommitCallback, void*); - -typedef bool -(*GetGroupsCallback)(JSContext*, PerformanceGroupVector&, void*); -extern JS_PUBLIC_API(bool) -SetGetPerformanceGroupsCallback(JSContext*, GetGroupsCallback, void*); - -} /* namespace js */ - - -#endif /* jsapi_h */ diff --git a/android/x86/include/spidermonkey/jsbytecode.h b/android/x86/include/spidermonkey/jsbytecode.h deleted file mode 100644 index 8e4f4cf9..00000000 --- a/android/x86/include/spidermonkey/jsbytecode.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsbytecode_h -#define jsbytecode_h - -#include - -typedef uint8_t jsbytecode; - -#endif /* jsbytecode_h */ diff --git a/android/x86/include/spidermonkey/jsclist.h b/android/x86/include/spidermonkey/jsclist.h deleted file mode 100644 index b8455152..00000000 --- a/android/x86/include/spidermonkey/jsclist.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsclist_h -#define jsclist_h - -#include "jstypes.h" - -/* -** Circular linked list -*/ -typedef struct JSCListStr { - struct JSCListStr* next; - struct JSCListStr* prev; -} JSCList; - -/* -** Insert element "_e" into the list, before "_l". -*/ -#define JS_INSERT_BEFORE(_e,_l) \ - JS_BEGIN_MACRO \ - (_e)->next = (_l); \ - (_e)->prev = (_l)->prev; \ - (_l)->prev->next = (_e); \ - (_l)->prev = (_e); \ - JS_END_MACRO - -/* -** Insert element "_e" into the list, after "_l". -*/ -#define JS_INSERT_AFTER(_e,_l) \ - JS_BEGIN_MACRO \ - (_e)->next = (_l)->next; \ - (_e)->prev = (_l); \ - (_l)->next->prev = (_e); \ - (_l)->next = (_e); \ - JS_END_MACRO - -/* -** Return the element following element "_e" -*/ -#define JS_NEXT_LINK(_e) \ - ((_e)->next) -/* -** Return the element preceding element "_e" -*/ -#define JS_PREV_LINK(_e) \ - ((_e)->prev) - -/* -** Append an element "_e" to the end of the list "_l" -*/ -#define JS_APPEND_LINK(_e,_l) JS_INSERT_BEFORE(_e,_l) - -/* -** Insert an element "_e" at the head of the list "_l" -*/ -#define JS_INSERT_LINK(_e,_l) JS_INSERT_AFTER(_e,_l) - -/* Return the head/tail of the list */ -#define JS_LIST_HEAD(_l) (_l)->next -#define JS_LIST_TAIL(_l) (_l)->prev - -/* -** Remove the element "_e" from it's circular list. -*/ -#define JS_REMOVE_LINK(_e) \ - JS_BEGIN_MACRO \ - (_e)->prev->next = (_e)->next; \ - (_e)->next->prev = (_e)->prev; \ - JS_END_MACRO - -/* -** Remove the element "_e" from it's circular list. Also initializes the -** linkage. -*/ -#define JS_REMOVE_AND_INIT_LINK(_e) \ - JS_BEGIN_MACRO \ - (_e)->prev->next = (_e)->next; \ - (_e)->next->prev = (_e)->prev; \ - (_e)->next = (_e); \ - (_e)->prev = (_e); \ - JS_END_MACRO - -/* -** Return non-zero if the given circular list "_l" is empty, zero if the -** circular list is not empty -*/ -#define JS_CLIST_IS_EMPTY(_l) \ - bool((_l)->next == (_l)) - -/* -** Initialize a circular list -*/ -#define JS_INIT_CLIST(_l) \ - JS_BEGIN_MACRO \ - (_l)->next = (_l); \ - (_l)->prev = (_l); \ - JS_END_MACRO - -#define JS_INIT_STATIC_CLIST(_l) \ - {(_l), (_l)} - -#endif /* jsclist_h */ diff --git a/android/x86/include/spidermonkey/jscpucfg.h b/android/x86/include/spidermonkey/jscpucfg.h deleted file mode 100644 index 80fdf6bb..00000000 --- a/android/x86/include/spidermonkey/jscpucfg.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jscpucfg_h -#define jscpucfg_h - -#include "mozilla/EndianUtils.h" - -#ifndef JS_STACK_GROWTH_DIRECTION -# ifdef __hppa -# define JS_STACK_GROWTH_DIRECTION (1) -# else -# define JS_STACK_GROWTH_DIRECTION (-1) -# endif -#endif - -#endif /* jscpucfg_h */ diff --git a/android/x86/include/spidermonkey/jsfriendapi.h b/android/x86/include/spidermonkey/jsfriendapi.h deleted file mode 100644 index d6463d3d..00000000 --- a/android/x86/include/spidermonkey/jsfriendapi.h +++ /dev/null @@ -1,3067 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsfriendapi_h -#define jsfriendapi_h - -#include "mozilla/Atomics.h" -#include "mozilla/Casting.h" -#include "mozilla/Maybe.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/UniquePtr.h" - -#include "jsapi.h" // For JSAutoByteString. See bug 1033916. -#include "jsbytecode.h" -#include "jspubtd.h" - -#include "js/CallArgs.h" -#include "js/CallNonGenericMethod.h" -#include "js/Class.h" -#include "js/Utility.h" - -#if JS_STACK_GROWTH_DIRECTION > 0 -# define JS_CHECK_STACK_SIZE(limit, sp) (MOZ_LIKELY((uintptr_t)(sp) < (limit))) -#else -# define JS_CHECK_STACK_SIZE(limit, sp) (MOZ_LIKELY((uintptr_t)(sp) > (limit))) -#endif - -class JSAtom; -struct JSErrorFormatString; -class JSLinearString; -struct JSJitInfo; -class JSErrorReport; - -namespace JS { -template -class Heap; -} /* namespace JS */ - -namespace js { -class JS_FRIEND_API(BaseProxyHandler); -class InterpreterFrame; -} /* namespace js */ - -extern JS_FRIEND_API(void) -JS_SetGrayGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data); - -extern JS_FRIEND_API(JSObject*) -JS_FindCompilationScope(JSContext* cx, JS::HandleObject obj); - -extern JS_FRIEND_API(JSFunction*) -JS_GetObjectFunction(JSObject* obj); - -extern JS_FRIEND_API(bool) -JS_SplicePrototype(JSContext* cx, JS::HandleObject obj, JS::HandleObject proto); - -extern JS_FRIEND_API(JSObject*) -JS_NewObjectWithUniqueType(JSContext* cx, const JSClass* clasp, JS::HandleObject proto); - -/** - * Allocate an object in exactly the same way as JS_NewObjectWithGivenProto, but - * without invoking the metadata callback on it. This allows creation of - * internal bookkeeping objects that are guaranteed to not have metadata - * attached to them. - */ -extern JS_FRIEND_API(JSObject*) -JS_NewObjectWithoutMetadata(JSContext* cx, const JSClass* clasp, JS::Handle proto); - -extern JS_FRIEND_API(uint32_t) -JS_ObjectCountDynamicSlots(JS::HandleObject obj); - -extern JS_FRIEND_API(size_t) -JS_SetProtoCalled(JSContext* cx); - -extern JS_FRIEND_API(size_t) -JS_GetCustomIteratorCount(JSContext* cx); - -extern JS_FRIEND_API(bool) -JS_NondeterministicGetWeakMapKeys(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret); - -extern JS_FRIEND_API(bool) -JS_NondeterministicGetWeakSetKeys(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret); - -// Raw JSScript* because this needs to be callable from a signal handler. -extern JS_FRIEND_API(unsigned) -JS_PCToLineNumber(JSScript* script, jsbytecode* pc, unsigned* columnp = nullptr); - -/** - * Determine whether the given object is backed by a DeadObjectProxy. - * - * Such objects hold no other objects (they have no outgoing reference edges) - * and will throw if you touch them (e.g. by reading/writing a property). - */ -extern JS_FRIEND_API(bool) -JS_IsDeadWrapper(JSObject* obj); - -/* - * Used by the cycle collector to trace through a shape or object group and - * all cycle-participating data it reaches, using bounded stack space. - */ -extern JS_FRIEND_API(void) -JS_TraceShapeCycleCollectorChildren(JS::CallbackTracer* trc, JS::GCCellPtr shape); -extern JS_FRIEND_API(void) -JS_TraceObjectGroupCycleCollectorChildren(JS::CallbackTracer* trc, JS::GCCellPtr group); - -enum { - JS_TELEMETRY_GC_REASON, - JS_TELEMETRY_GC_IS_ZONE_GC, - JS_TELEMETRY_GC_MS, - JS_TELEMETRY_GC_BUDGET_MS, - JS_TELEMETRY_GC_ANIMATION_MS, - JS_TELEMETRY_GC_MAX_PAUSE_MS, - JS_TELEMETRY_GC_MARK_MS, - JS_TELEMETRY_GC_SWEEP_MS, - JS_TELEMETRY_GC_COMPACT_MS, - JS_TELEMETRY_GC_MARK_ROOTS_MS, - JS_TELEMETRY_GC_MARK_GRAY_MS, - JS_TELEMETRY_GC_SLICE_MS, - JS_TELEMETRY_GC_SLOW_PHASE, - JS_TELEMETRY_GC_MMU_50, - JS_TELEMETRY_GC_RESET, - JS_TELEMETRY_GC_RESET_REASON, - JS_TELEMETRY_GC_INCREMENTAL_DISABLED, - JS_TELEMETRY_GC_NON_INCREMENTAL, - JS_TELEMETRY_GC_NON_INCREMENTAL_REASON, - JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS, - JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS, - JS_TELEMETRY_GC_MINOR_REASON, - JS_TELEMETRY_GC_MINOR_REASON_LONG, - JS_TELEMETRY_GC_MINOR_US, - JS_TELEMETRY_GC_NURSERY_BYTES, - JS_TELEMETRY_GC_PRETENURE_COUNT, - JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, - JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_ADDONS, - JS_TELEMETRY_ADDON_EXCEPTIONS, - JS_TELEMETRY_AOT_USAGE, - JS_TELEMETRY_END -}; - -typedef void -(*JSAccumulateTelemetryDataCallback)(int id, uint32_t sample, const char* key); - -extern JS_FRIEND_API(void) -JS_SetAccumulateTelemetryCallback(JSContext* cx, JSAccumulateTelemetryDataCallback callback); - -extern JS_FRIEND_API(bool) -JS_GetIsSecureContext(JSCompartment* compartment); - -extern JS_FRIEND_API(JSPrincipals*) -JS_GetCompartmentPrincipals(JSCompartment* compartment); - -extern JS_FRIEND_API(void) -JS_SetCompartmentPrincipals(JSCompartment* compartment, JSPrincipals* principals); - -extern JS_FRIEND_API(JSPrincipals*) -JS_GetScriptPrincipals(JSScript* script); - -extern JS_FRIEND_API(bool) -JS_ScriptHasMutedErrors(JSScript* script); - -extern JS_FRIEND_API(JSObject*) -JS_CloneObject(JSContext* cx, JS::HandleObject obj, JS::HandleObject proto); - -/** - * Copy the own properties of src to dst in a fast way. src and dst must both - * be native and must be in the compartment of cx. They must have the same - * class, the same parent, and the same prototype. Class reserved slots will - * NOT be copied. - * - * dst must not have any properties on it before this function is called. - * - * src must have been allocated via JS_NewObjectWithoutMetadata so that we can - * be sure it has no metadata that needs copying to dst. This also means that - * dst needs to have the compartment global as its parent. This function will - * preserve the existing metadata on dst, if any. - */ -extern JS_FRIEND_API(bool) -JS_InitializePropertiesFromCompatibleNativeObject(JSContext* cx, - JS::HandleObject dst, - JS::HandleObject src); - -extern JS_FRIEND_API(JSString*) -JS_BasicObjectToString(JSContext* cx, JS::HandleObject obj); - -namespace js { - -JS_FRIEND_API(bool) -GetBuiltinClass(JSContext* cx, JS::HandleObject obj, ESClass* cls); - -JS_FRIEND_API(const char*) -ObjectClassName(JSContext* cx, JS::HandleObject obj); - -JS_FRIEND_API(void) -ReportOverRecursed(JSContext* maybecx); - -JS_FRIEND_API(bool) -AddRawValueRoot(JSContext* cx, JS::Value* vp, const char* name); - -JS_FRIEND_API(void) -RemoveRawValueRoot(JSContext* cx, JS::Value* vp); - -JS_FRIEND_API(JSAtom*) -GetPropertyNameFromPC(JSScript* script, jsbytecode* pc); - -#ifdef JS_DEBUG - -/* - * Routines to print out values during debugging. These are FRIEND_API to help - * the debugger find them and to support temporarily hacking js::Dump* calls - * into other code. Note that there are overloads that do not require the FILE* - * parameter, which will default to stderr. - */ - -extern JS_FRIEND_API(void) -DumpString(JSString* str, FILE* fp); - -extern JS_FRIEND_API(void) -DumpAtom(JSAtom* atom, FILE* fp); - -extern JS_FRIEND_API(void) -DumpObject(JSObject* obj, FILE* fp); - -extern JS_FRIEND_API(void) -DumpChars(const char16_t* s, size_t n, FILE* fp); - -extern JS_FRIEND_API(void) -DumpValue(const JS::Value& val, FILE* fp); - -extern JS_FRIEND_API(void) -DumpId(jsid id, FILE* fp); - -extern JS_FRIEND_API(void) -DumpInterpreterFrame(JSContext* cx, FILE* fp, InterpreterFrame* start = nullptr); - -extern JS_FRIEND_API(bool) -DumpPC(JSContext* cx, FILE* fp); - -extern JS_FRIEND_API(bool) -DumpScript(JSContext* cx, JSScript* scriptArg, FILE* fp); - -// Versions for use directly in a debugger (default parameters are not handled -// well in gdb; built-in handles like stderr are not handled well in lldb.) -extern JS_FRIEND_API(void) DumpString(JSString* str); -extern JS_FRIEND_API(void) DumpAtom(JSAtom* atom); -extern JS_FRIEND_API(void) DumpObject(JSObject* obj); -extern JS_FRIEND_API(void) DumpChars(const char16_t* s, size_t n); -extern JS_FRIEND_API(void) DumpValue(const JS::Value& val); -extern JS_FRIEND_API(void) DumpId(jsid id); -extern JS_FRIEND_API(void) DumpInterpreterFrame(JSContext* cx, InterpreterFrame* start = nullptr); -extern JS_FRIEND_API(bool) DumpPC(JSContext* cx); -extern JS_FRIEND_API(bool) DumpScript(JSContext* cx, JSScript* scriptArg); - -#endif - -extern JS_FRIEND_API(void) -DumpBacktrace(JSContext* cx, FILE* fp); - -extern JS_FRIEND_API(void) -DumpBacktrace(JSContext* cx); - -} // namespace js - -namespace JS { - -/** Exposed for DumpJSStack */ -extern JS_FRIEND_API(char*) -FormatStackDump(JSContext* cx, char* buf, bool showArgs, bool showLocals, bool showThisProps); - -/** - * Set all of the uninitialized lexicals on an object to undefined. Return - * true if any lexicals were initialized and false otherwise. - * */ -extern JS_FRIEND_API(bool) -ForceLexicalInitialization(JSContext *cx, HandleObject obj); - -} // namespace JS - -/** - * Copies all own properties from |obj| to |target|. |obj| must be a "native" - * object (that is to say, normal-ish - not an Array or a Proxy). - * - * This function immediately enters a compartment, and does not impose any - * restrictions on the compartment of |cx|. - */ -extern JS_FRIEND_API(bool) -JS_CopyPropertiesFrom(JSContext* cx, JS::HandleObject target, JS::HandleObject obj); - -/* - * Single-property version of the above. This function asserts that an |own| - * property of the given name exists on |obj|. - * - * On entry, |cx| must be same-compartment with |obj|. - * - * The copyBehavior argument controls what happens with - * non-configurable properties. - */ -typedef enum { - MakeNonConfigurableIntoConfigurable, - CopyNonConfigurableAsIs -} PropertyCopyBehavior; - -extern JS_FRIEND_API(bool) -JS_CopyPropertyFrom(JSContext* cx, JS::HandleId id, JS::HandleObject target, - JS::HandleObject obj, - PropertyCopyBehavior copyBehavior = CopyNonConfigurableAsIs); - -extern JS_FRIEND_API(bool) -JS_WrapPropertyDescriptor(JSContext* cx, JS::MutableHandle desc); - -struct JSFunctionSpecWithHelp { - const char* name; - JSNative call; - uint16_t nargs; - uint16_t flags; - const JSJitInfo* jitInfo; - const char* usage; - const char* help; -}; - -#define JS_FN_HELP(name,call,nargs,flags,usage,help) \ - {name, call, nargs, (flags) | JSPROP_ENUMERATE | JSFUN_STUB_GSOPS, nullptr, usage, help} -#define JS_INLINABLE_FN_HELP(name,call,nargs,flags,native,usage,help) \ - {name, call, nargs, (flags) | JSPROP_ENUMERATE | JSFUN_STUB_GSOPS, &js::jit::JitInfo_##native,\ - usage, help} -#define JS_FS_HELP_END \ - {nullptr, nullptr, 0, 0, nullptr, nullptr} - -extern JS_FRIEND_API(bool) -JS_DefineFunctionsWithHelp(JSContext* cx, JS::HandleObject obj, const JSFunctionSpecWithHelp* fs); - -namespace js { - -extern JS_FRIEND_DATA(const js::ClassOps) ProxyClassOps; -extern JS_FRIEND_DATA(const js::ClassExtension) ProxyClassExtension; -extern JS_FRIEND_DATA(const js::ObjectOps) ProxyObjectOps; - -/* - * Helper Macros for creating JSClasses that function as proxies. - * - * NB: The macro invocation must be surrounded by braces, so as to - * allow for potential JSClass extensions. - */ -#define PROXY_MAKE_EXT(objectMoved) \ - { \ - js::proxy_WeakmapKeyDelegate, \ - objectMoved \ - } - -#define PROXY_CLASS_WITH_EXT(name, flags, extPtr) \ - { \ - name, \ - js::Class::NON_NATIVE | \ - JSCLASS_IS_PROXY | \ - JSCLASS_DELAY_METADATA_BUILDER | \ - flags, \ - &js::ProxyClassOps, \ - JS_NULL_CLASS_SPEC, \ - extPtr, \ - &js::ProxyObjectOps \ - } - -#define PROXY_CLASS_DEF(name, flags) \ - PROXY_CLASS_WITH_EXT(name, flags, &js::ProxyClassExtension) - -/* - * Proxy stubs, similar to JS_*Stub, for embedder proxy class definitions. - * - * NB: Should not be called directly. - */ - -extern JS_FRIEND_API(bool) -proxy_LookupProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleObject objp, - JS::MutableHandle propp); -extern JS_FRIEND_API(bool) -proxy_DefineProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::Handle desc, - JS::ObjectOpResult& result); -extern JS_FRIEND_API(bool) -proxy_HasProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp); -extern JS_FRIEND_API(bool) -proxy_GetProperty(JSContext* cx, JS::HandleObject obj, JS::HandleValue receiver, JS::HandleId id, - JS::MutableHandleValue vp); -extern JS_FRIEND_API(bool) -proxy_SetProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue bp, - JS::HandleValue receiver, JS::ObjectOpResult& result); -extern JS_FRIEND_API(bool) -proxy_GetOwnPropertyDescriptor(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandle desc); -extern JS_FRIEND_API(bool) -proxy_DeleteProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::ObjectOpResult& result); - -extern JS_FRIEND_API(void) -proxy_Trace(JSTracer* trc, JSObject* obj); -extern JS_FRIEND_API(JSObject*) -proxy_WeakmapKeyDelegate(JSObject* obj); -extern JS_FRIEND_API(bool) -proxy_Convert(JSContext* cx, JS::HandleObject proxy, JSType hint, JS::MutableHandleValue vp); -extern JS_FRIEND_API(void) -proxy_Finalize(FreeOp* fop, JSObject* obj); -extern JS_FRIEND_API(void) -proxy_ObjectMoved(JSObject* obj, const JSObject* old); -extern JS_FRIEND_API(bool) -proxy_HasInstance(JSContext* cx, JS::HandleObject proxy, JS::MutableHandleValue v, bool* bp); -extern JS_FRIEND_API(bool) -proxy_Call(JSContext* cx, unsigned argc, JS::Value* vp); -extern JS_FRIEND_API(bool) -proxy_Construct(JSContext* cx, unsigned argc, JS::Value* vp); -extern JS_FRIEND_API(JSObject*) -proxy_innerObject(JSObject* obj); -extern JS_FRIEND_API(bool) -proxy_Watch(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable); -extern JS_FRIEND_API(bool) -proxy_Unwatch(JSContext* cx, JS::HandleObject obj, JS::HandleId id); -extern JS_FRIEND_API(bool) -proxy_GetElements(JSContext* cx, JS::HandleObject proxy, uint32_t begin, uint32_t end, - ElementAdder* adder); -extern JS_FRIEND_API(JSString*) -proxy_FunToString(JSContext* cx, JS::HandleObject proxy, unsigned indent); - -/** - * A class of objects that return source code on demand. - * - * When code is compiled with setSourceIsLazy(true), SpiderMonkey doesn't - * retain the source code (and doesn't do lazy bytecode generation). If we ever - * need the source code, say, in response to a call to Function.prototype. - * toSource or Debugger.Source.prototype.text, then we call the 'load' member - * function of the instance of this class that has hopefully been registered - * with the runtime, passing the code's URL, and hope that it will be able to - * find the source. - */ -class SourceHook { - public: - virtual ~SourceHook() { } - - /** - * Set |*src| and |*length| to refer to the source code for |filename|. - * On success, the caller owns the buffer to which |*src| points, and - * should use JS_free to free it. - */ - virtual bool load(JSContext* cx, const char* filename, char16_t** src, size_t* length) = 0; -}; - -/** - * Have |cx| use |hook| to retrieve lazily-retrieved source code. See the - * comments for SourceHook. The context takes ownership of the hook, and - * will delete it when the context itself is deleted, or when a new hook is - * set. - */ -extern JS_FRIEND_API(void) -SetSourceHook(JSContext* cx, mozilla::UniquePtr hook); - -/** Remove |cx|'s source hook, and return it. The caller now owns the hook. */ -extern JS_FRIEND_API(mozilla::UniquePtr) -ForgetSourceHook(JSContext* cx); - -extern JS_FRIEND_API(JS::Zone*) -GetCompartmentZone(JSCompartment* comp); - -typedef bool -(* PreserveWrapperCallback)(JSContext* cx, JSObject* obj); - -typedef enum { - CollectNurseryBeforeDump, - IgnoreNurseryObjects -} DumpHeapNurseryBehaviour; - - /** - * Dump the complete object graph of heap-allocated things. - * fp is the file for the dump output. - */ -extern JS_FRIEND_API(void) -DumpHeap(JSContext* cx, FILE* fp, DumpHeapNurseryBehaviour nurseryBehaviour); - -#ifdef JS_OLD_GETTER_SETTER_METHODS -JS_FRIEND_API(bool) obj_defineGetter(JSContext* cx, unsigned argc, JS::Value* vp); -JS_FRIEND_API(bool) obj_defineSetter(JSContext* cx, unsigned argc, JS::Value* vp); -#endif - -extern JS_FRIEND_API(bool) -IsSystemCompartment(JSCompartment* comp); - -extern JS_FRIEND_API(bool) -IsSystemZone(JS::Zone* zone); - -extern JS_FRIEND_API(bool) -IsAtomsCompartment(JSCompartment* comp); - -extern JS_FRIEND_API(bool) -IsAtomsZone(JS::Zone* zone); - -struct WeakMapTracer -{ - JSContext* context; - - explicit WeakMapTracer(JSContext* cx) : context(cx) {} - - // Weak map tracer callback, called once for every binding of every - // weak map that was live at the time of the last garbage collection. - // - // m will be nullptr if the weak map is not contained in a JS Object. - // - // The callback should not GC (and will assert in a debug build if it does so.) - virtual void trace(JSObject* m, JS::GCCellPtr key, JS::GCCellPtr value) = 0; -}; - -extern JS_FRIEND_API(void) -TraceWeakMaps(WeakMapTracer* trc); - -extern JS_FRIEND_API(bool) -AreGCGrayBitsValid(JSContext* cx); - -extern JS_FRIEND_API(bool) -ZoneGlobalsAreAllGray(JS::Zone* zone); - -typedef void -(*GCThingCallback)(void* closure, JS::GCCellPtr thing); - -extern JS_FRIEND_API(void) -VisitGrayWrapperTargets(JS::Zone* zone, GCThingCallback callback, void* closure); - -extern JS_FRIEND_API(JSObject*) -GetWeakmapKeyDelegate(JSObject* key); - -/** - * Invoke cellCallback on every gray JSObject in the given zone. - */ -extern JS_FRIEND_API(void) -IterateGrayObjects(JS::Zone* zone, GCThingCallback cellCallback, void* data); - -/** - * Invoke cellCallback on every gray JSObject in the given zone while cycle - * collection is in progress. - */ -extern JS_FRIEND_API(void) -IterateGrayObjectsUnderCC(JS::Zone* zone, GCThingCallback cellCallback, void* data); - -#ifdef JS_HAS_CTYPES -extern JS_FRIEND_API(size_t) -SizeOfDataIfCDataObject(mozilla::MallocSizeOf mallocSizeOf, JSObject* obj); -#endif - -extern JS_FRIEND_API(JSCompartment*) -GetAnyCompartmentInZone(JS::Zone* zone); - -/* - * Shadow declarations of JS internal structures, for access by inline access - * functions below. Do not use these structures in any other way. When adding - * new fields for access by inline methods, make sure to add static asserts to - * the original header file to ensure that offsets are consistent. - */ -namespace shadow { - -struct ObjectGroup { - const Class* clasp; - JSObject* proto; - JSCompartment* compartment; -}; - -struct BaseShape { - const js::Class* clasp_; - JSObject* parent; -}; - -class Shape { -public: - shadow::BaseShape* base; - jsid _1; - uint32_t slotInfo; - - static const uint32_t FIXED_SLOTS_SHIFT = 27; -}; - -/** - * This layout is shared by all native objects. For non-native objects, the - * group may always be accessed safely, and other members may be as well, - * depending on the object's specific layout. - */ -struct Object { - shadow::ObjectGroup* group; - shadow::Shape* shape; - JS::Value* slots; - void* _1; - - size_t numFixedSlots() const { return shape->slotInfo >> Shape::FIXED_SLOTS_SHIFT; } - JS::Value* fixedSlots() const { - return (JS::Value*)(uintptr_t(this) + sizeof(shadow::Object)); - } - - JS::Value& slotRef(size_t slot) const { - size_t nfixed = numFixedSlots(); - if (slot < nfixed) - return fixedSlots()[slot]; - return slots[slot - nfixed]; - } -}; - -struct Function { - Object base; - uint16_t nargs; - uint16_t flags; - /* Used only for natives */ - JSNative native; - const JSJitInfo* jitinfo; - void* _1; -}; - -struct String -{ - static const uint32_t INLINE_CHARS_BIT = JS_BIT(2); - static const uint32_t LATIN1_CHARS_BIT = JS_BIT(6); - static const uint32_t ROPE_FLAGS = 0; - static const uint32_t TYPE_FLAGS_MASK = JS_BIT(6) - 1; - uint32_t flags; - uint32_t length; - union { - const JS::Latin1Char* nonInlineCharsLatin1; - const char16_t* nonInlineCharsTwoByte; - JS::Latin1Char inlineStorageLatin1[1]; - char16_t inlineStorageTwoByte[1]; - }; -}; - -} /* namespace shadow */ - -// This is equal to |&JSObject::class_|. Use it in places where you don't want -// to #include jsobj.h. -extern JS_FRIEND_DATA(const js::Class* const) ObjectClassPtr; - -inline const js::Class* -GetObjectClass(const JSObject* obj) -{ - return reinterpret_cast(obj)->group->clasp; -} - -inline const JSClass* -GetObjectJSClass(JSObject* obj) -{ - return js::Jsvalify(GetObjectClass(obj)); -} - -JS_FRIEND_API(const Class*) -ProtoKeyToClass(JSProtoKey key); - -// Returns the key for the class inherited by a given standard class (that -// is to say, the prototype of this standard class's prototype). -// -// You must be sure that this corresponds to a standard class with a cached -// JSProtoKey before calling this function. In general |key| will match the -// cached proto key, except in cases where multiple JSProtoKeys share a -// JSClass. -inline JSProtoKey -InheritanceProtoKeyForStandardClass(JSProtoKey key) -{ - // [Object] has nothing to inherit from. - if (key == JSProto_Object) - return JSProto_Null; - - // If we're ClassSpec defined return the proto key from that - if (ProtoKeyToClass(key)->specDefined()) - return ProtoKeyToClass(key)->specInheritanceProtoKey(); - - // Otherwise, we inherit [Object]. - return JSProto_Object; -} - -JS_FRIEND_API(bool) -IsFunctionObject(JSObject* obj); - -static MOZ_ALWAYS_INLINE JSCompartment* -GetObjectCompartment(JSObject* obj) -{ - return reinterpret_cast(obj)->group->compartment; -} - -JS_FRIEND_API(JSObject*) -GetGlobalForObjectCrossCompartment(JSObject* obj); - -JS_FRIEND_API(JSObject*) -GetPrototypeNoProxy(JSObject* obj); - -JS_FRIEND_API(void) -AssertSameCompartment(JSContext* cx, JSObject* obj); - -#ifdef JS_DEBUG -JS_FRIEND_API(void) -AssertSameCompartment(JSObject* objA, JSObject* objB); -#else -inline void AssertSameCompartment(JSObject* objA, JSObject* objB) {} -#endif - -JS_FRIEND_API(void) -NotifyAnimationActivity(JSObject* obj); - -/** - * Return the outermost enclosing function (script) of the scripted caller. - * This function returns nullptr in several cases: - * - no script is running on the context - * - the caller is in global or eval code - * In particular, this function will "stop" its outermost search at eval() and - * thus it will really return the outermost enclosing function *since the - * innermost eval*. - */ -JS_FRIEND_API(JSFunction*) -GetOutermostEnclosingFunctionOfScriptedCaller(JSContext* cx); - -JS_FRIEND_API(JSFunction*) -DefineFunctionWithReserved(JSContext* cx, JSObject* obj, const char* name, JSNative call, - unsigned nargs, unsigned attrs); - -JS_FRIEND_API(JSFunction*) -NewFunctionWithReserved(JSContext* cx, JSNative call, unsigned nargs, unsigned flags, - const char* name); - -JS_FRIEND_API(JSFunction*) -NewFunctionByIdWithReserved(JSContext* cx, JSNative native, unsigned nargs, unsigned flags, - jsid id); - -JS_FRIEND_API(const JS::Value&) -GetFunctionNativeReserved(JSObject* fun, size_t which); - -JS_FRIEND_API(void) -SetFunctionNativeReserved(JSObject* fun, size_t which, const JS::Value& val); - -JS_FRIEND_API(bool) -FunctionHasNativeReserved(JSObject* fun); - -JS_FRIEND_API(bool) -GetObjectProto(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject proto); - -extern JS_FRIEND_API(JSObject*) -GetStaticPrototype(JSObject* obj); - -JS_FRIEND_API(bool) -GetOriginalEval(JSContext* cx, JS::HandleObject scope, - JS::MutableHandleObject eval); - -inline void* -GetObjectPrivate(JSObject* obj) -{ - MOZ_ASSERT(GetObjectClass(obj)->flags & JSCLASS_HAS_PRIVATE); - const shadow::Object* nobj = reinterpret_cast(obj); - void** addr = reinterpret_cast(&nobj->fixedSlots()[nobj->numFixedSlots()]); - return *addr; -} - -inline const JS::Value& -GetReservedSlot(JSObject* obj, size_t slot) -{ - MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj))); - return reinterpret_cast(obj)->slotRef(slot); -} - -JS_FRIEND_API(void) -SetReservedOrProxyPrivateSlotWithBarrier(JSObject* obj, size_t slot, const JS::Value& value); - -inline void -SetReservedSlot(JSObject* obj, size_t slot, const JS::Value& value) -{ - MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj))); - shadow::Object* sobj = reinterpret_cast(obj); - if (sobj->slotRef(slot).isMarkable() || value.isMarkable()) - SetReservedOrProxyPrivateSlotWithBarrier(obj, slot, value); - else - sobj->slotRef(slot) = value; -} - -JS_FRIEND_API(uint32_t) -GetObjectSlotSpan(JSObject* obj); - -inline const JS::Value& -GetObjectSlot(JSObject* obj, size_t slot) -{ - MOZ_ASSERT(slot < GetObjectSlotSpan(obj)); - return reinterpret_cast(obj)->slotRef(slot); -} - -MOZ_ALWAYS_INLINE size_t -GetAtomLength(JSAtom* atom) -{ - return reinterpret_cast(atom)->length; -} - -static const uint32_t MaxStringLength = (1 << 28) - 1; - -MOZ_ALWAYS_INLINE size_t -GetStringLength(JSString* s) -{ - return reinterpret_cast(s)->length; -} - -MOZ_ALWAYS_INLINE size_t -GetFlatStringLength(JSFlatString* s) -{ - return reinterpret_cast(s)->length; -} - -MOZ_ALWAYS_INLINE size_t -GetLinearStringLength(JSLinearString* s) -{ - return reinterpret_cast(s)->length; -} - -MOZ_ALWAYS_INLINE bool -LinearStringHasLatin1Chars(JSLinearString* s) -{ - return reinterpret_cast(s)->flags & shadow::String::LATIN1_CHARS_BIT; -} - -MOZ_ALWAYS_INLINE bool -AtomHasLatin1Chars(JSAtom* atom) -{ - return reinterpret_cast(atom)->flags & shadow::String::LATIN1_CHARS_BIT; -} - -MOZ_ALWAYS_INLINE bool -StringHasLatin1Chars(JSString* s) -{ - return reinterpret_cast(s)->flags & shadow::String::LATIN1_CHARS_BIT; -} - -MOZ_ALWAYS_INLINE const JS::Latin1Char* -GetLatin1LinearStringChars(const JS::AutoCheckCannotGC& nogc, JSLinearString* linear) -{ - MOZ_ASSERT(LinearStringHasLatin1Chars(linear)); - - using shadow::String; - String* s = reinterpret_cast(linear); - if (s->flags & String::INLINE_CHARS_BIT) - return s->inlineStorageLatin1; - return s->nonInlineCharsLatin1; -} - -MOZ_ALWAYS_INLINE const char16_t* -GetTwoByteLinearStringChars(const JS::AutoCheckCannotGC& nogc, JSLinearString* linear) -{ - MOZ_ASSERT(!LinearStringHasLatin1Chars(linear)); - - using shadow::String; - String* s = reinterpret_cast(linear); - if (s->flags & String::INLINE_CHARS_BIT) - return s->inlineStorageTwoByte; - return s->nonInlineCharsTwoByte; -} - -MOZ_ALWAYS_INLINE JSLinearString* -AtomToLinearString(JSAtom* atom) -{ - return reinterpret_cast(atom); -} - -MOZ_ALWAYS_INLINE JSFlatString* -AtomToFlatString(JSAtom* atom) -{ - return reinterpret_cast(atom); -} - -MOZ_ALWAYS_INLINE JSLinearString* -FlatStringToLinearString(JSFlatString* s) -{ - return reinterpret_cast(s); -} - -MOZ_ALWAYS_INLINE const JS::Latin1Char* -GetLatin1AtomChars(const JS::AutoCheckCannotGC& nogc, JSAtom* atom) -{ - return GetLatin1LinearStringChars(nogc, AtomToLinearString(atom)); -} - -MOZ_ALWAYS_INLINE const char16_t* -GetTwoByteAtomChars(const JS::AutoCheckCannotGC& nogc, JSAtom* atom) -{ - return GetTwoByteLinearStringChars(nogc, AtomToLinearString(atom)); -} - -JS_FRIEND_API(JSLinearString*) -StringToLinearStringSlow(JSContext* cx, JSString* str); - -MOZ_ALWAYS_INLINE JSLinearString* -StringToLinearString(JSContext* cx, JSString* str) -{ - using shadow::String; - String* s = reinterpret_cast(str); - if (MOZ_UNLIKELY((s->flags & String::TYPE_FLAGS_MASK) == String::ROPE_FLAGS)) - return StringToLinearStringSlow(cx, str); - return reinterpret_cast(str); -} - -template -MOZ_ALWAYS_INLINE void -CopyLinearStringChars(CharType* dest, JSLinearString* s, size_t len, size_t start = 0); - -MOZ_ALWAYS_INLINE void -CopyLinearStringChars(char16_t* dest, JSLinearString* s, size_t len, size_t start = 0) -{ - MOZ_ASSERT(start + len <= GetLinearStringLength(s)); - JS::AutoCheckCannotGC nogc; - if (LinearStringHasLatin1Chars(s)) { - const JS::Latin1Char* src = GetLatin1LinearStringChars(nogc, s); - for (size_t i = 0; i < len; i++) - dest[i] = src[start + i]; - } else { - const char16_t* src = GetTwoByteLinearStringChars(nogc, s); - mozilla::PodCopy(dest, src + start, len); - } -} - -MOZ_ALWAYS_INLINE void -CopyLinearStringChars(char* dest, JSLinearString* s, size_t len, size_t start = 0) -{ - MOZ_ASSERT(start + len <= GetLinearStringLength(s)); - JS::AutoCheckCannotGC nogc; - if (LinearStringHasLatin1Chars(s)) { - const JS::Latin1Char* src = GetLatin1LinearStringChars(nogc, s); - for (size_t i = 0; i < len; i++) - dest[i] = char(src[start + i]); - } else { - const char16_t* src = GetTwoByteLinearStringChars(nogc, s); - for (size_t i = 0; i < len; i++) - dest[i] = char(src[start + i]); - } -} - -template -inline bool -CopyStringChars(JSContext* cx, CharType* dest, JSString* s, size_t len, size_t start = 0) -{ - JSLinearString* linear = StringToLinearString(cx, s); - if (!linear) - return false; - - CopyLinearStringChars(dest, linear, len, start); - return true; -} - -inline void -CopyFlatStringChars(char16_t* dest, JSFlatString* s, size_t len) -{ - CopyLinearStringChars(dest, FlatStringToLinearString(s), len); -} - -/** - * Add some or all property keys of obj to the id vector *props. - * - * The flags parameter controls which property keys are added. Pass a - * combination of the following bits: - * - * JSITER_OWNONLY - Don't also search the prototype chain; only consider - * obj's own properties. - * - * JSITER_HIDDEN - Include nonenumerable properties. - * - * JSITER_SYMBOLS - Include property keys that are symbols. The default - * behavior is to filter out symbols. - * - * JSITER_SYMBOLSONLY - Exclude non-symbol property keys. - * - * This is the closest C++ API we have to `Reflect.ownKeys(obj)`, or - * equivalently, the ES6 [[OwnPropertyKeys]] internal method. Pass - * `JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS` as flags to get - * results that match the output of Reflect.ownKeys. - */ -JS_FRIEND_API(bool) -GetPropertyKeys(JSContext* cx, JS::HandleObject obj, unsigned flags, JS::AutoIdVector* props); - -JS_FRIEND_API(bool) -AppendUnique(JSContext* cx, JS::AutoIdVector& base, JS::AutoIdVector& others); - -JS_FRIEND_API(bool) -StringIsArrayIndex(JSLinearString* str, uint32_t* indexp); - -JS_FRIEND_API(void) -SetPreserveWrapperCallback(JSContext* cx, PreserveWrapperCallback callback); - -JS_FRIEND_API(bool) -IsObjectInContextCompartment(JSObject* obj, const JSContext* cx); - -/* - * NB: keep these in sync with the copy in builtin/SelfHostingDefines.h. - * The first three are omitted because they shouldn't be used in new code. - */ -#define JSITER_ENUMERATE 0x1 /* for-in compatible hidden default iterator */ -#define JSITER_FOREACH 0x2 /* get obj[key] for each property */ -#define JSITER_KEYVALUE 0x4 /* obsolete destructuring for-in wants [key, value] */ -#define JSITER_OWNONLY 0x8 /* iterate over obj's own properties only */ -#define JSITER_HIDDEN 0x10 /* also enumerate non-enumerable properties */ -#define JSITER_SYMBOLS 0x20 /* also include symbol property keys */ -#define JSITER_SYMBOLSONLY 0x40 /* exclude string property keys */ - -JS_FRIEND_API(bool) -RunningWithTrustedPrincipals(JSContext* cx); - -inline uintptr_t -GetNativeStackLimit(JSContext* cx, StackKind kind, int extraAllowance = 0) -{ - uintptr_t limit = ContextFriendFields::get(cx)->nativeStackLimit[kind]; -#if JS_STACK_GROWTH_DIRECTION > 0 - limit += extraAllowance; -#else - limit -= extraAllowance; -#endif - return limit; -} - -inline uintptr_t -GetNativeStackLimit(JSContext* cx, int extraAllowance = 0) -{ - StackKind kind = RunningWithTrustedPrincipals(cx) ? StackForTrustedScript - : StackForUntrustedScript; - return GetNativeStackLimit(cx, kind, extraAllowance); -} - -/* - * These macros report a stack overflow and run |onerror| if we are close to - * using up the C stack. The JS_CHECK_CHROME_RECURSION variant gives us a - * little extra space so that we can ensure that crucial code is able to run. - * JS_CHECK_RECURSION_CONSERVATIVE allows less space than any other check, - * including a safety buffer (as in, it uses the untrusted limit and subtracts - * a little more from it). - */ - -#define JS_CHECK_RECURSION_LIMIT(cx, limit, onerror) \ - JS_BEGIN_MACRO \ - int stackDummy_; \ - if (!JS_CHECK_STACK_SIZE(limit, &stackDummy_)) { \ - js::ReportOverRecursed(cx); \ - onerror; \ - } \ - JS_END_MACRO - -#define JS_CHECK_RECURSION(cx, onerror) \ - JS_CHECK_RECURSION_LIMIT(cx, js::GetNativeStackLimit(cx), onerror) - -#define JS_CHECK_RECURSION_LIMIT_DONT_REPORT(cx, limit, onerror) \ - JS_BEGIN_MACRO \ - int stackDummy_; \ - if (!JS_CHECK_STACK_SIZE(limit, &stackDummy_)) { \ - onerror; \ - } \ - JS_END_MACRO - -#define JS_CHECK_RECURSION_DONT_REPORT(cx, onerror) \ - JS_CHECK_RECURSION_LIMIT_DONT_REPORT(cx, js::GetNativeStackLimit(cx), onerror) - -#define JS_CHECK_RECURSION_WITH_SP_DONT_REPORT(cx, sp, onerror) \ - JS_BEGIN_MACRO \ - if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) { \ - onerror; \ - } \ - JS_END_MACRO - -#define JS_CHECK_RECURSION_WITH_SP(cx, sp, onerror) \ - JS_BEGIN_MACRO \ - if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) { \ - js::ReportOverRecursed(cx); \ - onerror; \ - } \ - JS_END_MACRO - -#define JS_CHECK_SYSTEM_RECURSION(cx, onerror) \ - JS_CHECK_RECURSION_LIMIT(cx, js::GetNativeStackLimit(cx, js::StackForSystemCode), onerror) - -#define JS_CHECK_RECURSION_CONSERVATIVE(cx, onerror) \ - JS_CHECK_RECURSION_LIMIT(cx, \ - js::GetNativeStackLimit(cx, js::StackForUntrustedScript, -1024 * int(sizeof(size_t))), \ - onerror) - -#define JS_CHECK_RECURSION_CONSERVATIVE_DONT_REPORT(cx, onerror) \ - JS_CHECK_RECURSION_LIMIT_DONT_REPORT(cx, \ - js::GetNativeStackLimit(cx, js::StackForUntrustedScript, -1024 * int(sizeof(size_t))), \ - onerror) - -JS_FRIEND_API(void) -StartPCCountProfiling(JSContext* cx); - -JS_FRIEND_API(void) -StopPCCountProfiling(JSContext* cx); - -JS_FRIEND_API(void) -PurgePCCounts(JSContext* cx); - -JS_FRIEND_API(size_t) -GetPCCountScriptCount(JSContext* cx); - -JS_FRIEND_API(JSString*) -GetPCCountScriptSummary(JSContext* cx, size_t script); - -JS_FRIEND_API(JSString*) -GetPCCountScriptContents(JSContext* cx, size_t script); - -/** - * Generate lcov trace file content for the current compartment, and allocate a - * new buffer and return the content in it, the size of the newly allocated - * content within the buffer would be set to the length out-param. - * - * In case of out-of-memory, this function returns nullptr and does not set any - * value to the length out-param. - */ -JS_FRIEND_API(char*) -GetCodeCoverageSummary(JSContext* cx, size_t* length); - -typedef void -(* ActivityCallback)(void* arg, bool active); - -/** - * Sets a callback that is run whenever the runtime goes idle - the - * last active request ceases - and begins activity - when it was - * idle and a request begins. - */ -JS_FRIEND_API(void) -SetActivityCallback(JSContext* cx, ActivityCallback cb, void* arg); - -typedef bool -(* DOMInstanceClassHasProtoAtDepth)(const Class* instanceClass, - uint32_t protoID, uint32_t depth); -struct JSDOMCallbacks { - DOMInstanceClassHasProtoAtDepth instanceClassMatchesProto; -}; -typedef struct JSDOMCallbacks DOMCallbacks; - -extern JS_FRIEND_API(void) -SetDOMCallbacks(JSContext* cx, const DOMCallbacks* callbacks); - -extern JS_FRIEND_API(const DOMCallbacks*) -GetDOMCallbacks(JSContext* cx); - -extern JS_FRIEND_API(JSObject*) -GetTestingFunctions(JSContext* cx); - -/** - * Helper to convert FreeOp to JSFreeOp when the definition of FreeOp is not - * available and the compiler does not know that FreeOp inherits from - * JSFreeOp. - */ -inline JSFreeOp* -CastToJSFreeOp(FreeOp* fop) -{ - return reinterpret_cast(fop); -} - -/* Implemented in jsexn.cpp. */ - -/** - * Get an error type name from a JSExnType constant. - * Returns nullptr for invalid arguments and JSEXN_INTERNALERR - */ -extern JS_FRIEND_API(JSFlatString*) -GetErrorTypeName(JSContext* cx, int16_t exnType); - -#ifdef JS_DEBUG -extern JS_FRIEND_API(unsigned) -GetEnterCompartmentDepth(JSContext* cx); -#endif - -class RegExpGuard; -extern JS_FRIEND_API(bool) -RegExpToSharedNonInline(JSContext* cx, JS::HandleObject regexp, RegExpGuard* shared); - -/* Implemented in jswrapper.cpp. */ -typedef enum NukeReferencesToWindow { - NukeWindowReferences, - DontNukeWindowReferences -} NukeReferencesToWindow; - -/* - * These filters are designed to be ephemeral stack classes, and thus don't - * do any rooting or holding of their members. - */ -struct CompartmentFilter { - virtual bool match(JSCompartment* c) const = 0; -}; - -struct AllCompartments : public CompartmentFilter { - virtual bool match(JSCompartment* c) const override { return true; } -}; - -struct ContentCompartmentsOnly : public CompartmentFilter { - virtual bool match(JSCompartment* c) const override { - return !IsSystemCompartment(c); - } -}; - -struct ChromeCompartmentsOnly : public CompartmentFilter { - virtual bool match(JSCompartment* c) const override { - return IsSystemCompartment(c); - } -}; - -struct SingleCompartment : public CompartmentFilter { - JSCompartment* ours; - explicit SingleCompartment(JSCompartment* c) : ours(c) {} - virtual bool match(JSCompartment* c) const override { return c == ours; } -}; - -struct CompartmentsWithPrincipals : public CompartmentFilter { - JSPrincipals* principals; - explicit CompartmentsWithPrincipals(JSPrincipals* p) : principals(p) {} - virtual bool match(JSCompartment* c) const override { - return JS_GetCompartmentPrincipals(c) == principals; - } -}; - -extern JS_FRIEND_API(bool) -NukeCrossCompartmentWrappers(JSContext* cx, - const CompartmentFilter& sourceFilter, - const CompartmentFilter& targetFilter, - NukeReferencesToWindow nukeReferencesToWindow); - -/* Specify information about DOMProxy proxies in the DOM, for use by ICs. */ - -/* - * The DOMProxyShadowsCheck function will be called to check if the property for - * id should be gotten from the prototype, or if there is an own property that - * shadows it. - * * If ShadowsViaDirectExpando is returned, then the slot at - * listBaseExpandoSlot contains an expando object which has the property in - * question. - * * If ShadowsViaIndirectExpando is returned, then the slot at - * listBaseExpandoSlot contains a private pointer to an ExpandoAndGeneration - * and the expando object in the ExpandoAndGeneration has the property in - * question. - * * If DoesntShadow is returned then the slot at listBaseExpandoSlot should - * either be undefined or point to an expando object that would contain the - * own property. - * * If DoesntShadowUnique is returned then the slot at listBaseExpandoSlot - * should contain a private pointer to a ExpandoAndGeneration, which contains - * a JS::Value that should either be undefined or point to an expando object, - * and a uint64 value. If that value changes then the IC for getting a - * property will be invalidated. - * * If Shadows is returned, that means the property is an own property of the - * proxy but doesn't live on the expando object. - */ - -struct ExpandoAndGeneration { - ExpandoAndGeneration() - : expando(JS::UndefinedValue()), - generation(0) - {} - - void OwnerUnlinked() - { - ++generation; - } - - static size_t offsetOfExpando() - { - return offsetof(ExpandoAndGeneration, expando); - } - - static size_t offsetOfGeneration() - { - return offsetof(ExpandoAndGeneration, generation); - } - - JS::Heap expando; - uint64_t generation; -}; - -typedef enum DOMProxyShadowsResult { - ShadowCheckFailed, - Shadows, - DoesntShadow, - DoesntShadowUnique, - ShadowsViaDirectExpando, - ShadowsViaIndirectExpando -} DOMProxyShadowsResult; -typedef DOMProxyShadowsResult -(* DOMProxyShadowsCheck)(JSContext* cx, JS::HandleObject object, JS::HandleId id); -JS_FRIEND_API(void) -SetDOMProxyInformation(const void* domProxyHandlerFamily, uint32_t domProxyExpandoSlot, - DOMProxyShadowsCheck domProxyShadowsCheck); - -const void* GetDOMProxyHandlerFamily(); -uint32_t GetDOMProxyExpandoSlot(); -DOMProxyShadowsCheck GetDOMProxyShadowsCheck(); -inline bool DOMProxyIsShadowing(DOMProxyShadowsResult result) { - return result == Shadows || - result == ShadowsViaDirectExpando || - result == ShadowsViaIndirectExpando; -} - -/* Implemented in jsdate.cpp. */ - -/** Detect whether the internal date value is NaN. */ -extern JS_FRIEND_API(bool) -DateIsValid(JSContext* cx, JS::HandleObject obj, bool* isValid); - -extern JS_FRIEND_API(bool) -DateGetMsecSinceEpoch(JSContext* cx, JS::HandleObject obj, double* msecSinceEpoch); - -} /* namespace js */ - -/* Implemented in jscntxt.cpp. */ - -/** - * Report an exception, which is currently realized as a printf-style format - * string and its arguments. - */ -typedef enum JSErrNum { -#define MSG_DEF(name, count, exception, format) \ - name, -#include "js.msg" -#undef MSG_DEF - JSErr_Limit -} JSErrNum; - -namespace js { - -extern JS_FRIEND_API(const JSErrorFormatString*) -GetErrorMessage(void* userRef, const unsigned errorNumber); - -// AutoStableStringChars is here so we can use it in ErrorReport. It -// should get moved out of here if we can manage it. See bug 1040316. - -/** - * This class provides safe access to a string's chars across a GC. Once - * we allocate strings and chars in the nursery (bug 903519), this class - * will have to make a copy of the string's chars if they are allocated - * in the nursery, so it's best to avoid using this class unless you really - * need it. It's usually more efficient to use the latin1Chars/twoByteChars - * JSString methods and often the code can be rewritten so that only indexes - * instead of char pointers are used in parts of the code that can GC. - */ -class MOZ_STACK_CLASS AutoStableStringChars -{ - /* - * When copying string char, use this many bytes of inline storage. This is - * chosen to allow the inline string types to be copied without allocating. - * This is asserted in AutoStableStringChars::allocOwnChars. - */ - static const size_t InlineCapacity = 24; - - /* Ensure the string is kept alive while we're using its chars. */ - JS::RootedString s_; - union { - const char16_t* twoByteChars_; - const JS::Latin1Char* latin1Chars_; - }; - mozilla::Maybe> ownChars_; - enum State { Uninitialized, Latin1, TwoByte }; - State state_; - - public: - explicit AutoStableStringChars(JSContext* cx) - : s_(cx), state_(Uninitialized) - {} - - MOZ_MUST_USE - bool init(JSContext* cx, JSString* s); - - /* Like init(), but Latin1 chars are inflated to TwoByte. */ - MOZ_MUST_USE - bool initTwoByte(JSContext* cx, JSString* s); - - bool isLatin1() const { return state_ == Latin1; } - bool isTwoByte() const { return state_ == TwoByte; } - - const char16_t* twoByteChars() const { - MOZ_ASSERT(state_ == TwoByte); - return twoByteChars_; - } - - mozilla::Range latin1Range() const { - MOZ_ASSERT(state_ == Latin1); - return mozilla::Range(latin1Chars_, - GetStringLength(s_)); - } - - mozilla::Range twoByteRange() const { - MOZ_ASSERT(state_ == TwoByte); - return mozilla::Range(twoByteChars_, - GetStringLength(s_)); - } - - /* If we own the chars, transfer ownership to the caller. */ - bool maybeGiveOwnershipToCaller() { - MOZ_ASSERT(state_ != Uninitialized); - if (!ownChars_.isSome() || !ownChars_->extractRawBuffer()) - return false; - state_ = Uninitialized; - ownChars_.reset(); - return true; - } - - private: - AutoStableStringChars(const AutoStableStringChars& other) = delete; - void operator=(const AutoStableStringChars& other) = delete; - - bool baseIsInline(JS::Handle linearString); - template T* allocOwnChars(JSContext* cx, size_t count); - bool copyLatin1Chars(JSContext* cx, JS::Handle linearString); - bool copyTwoByteChars(JSContext* cx, JS::Handle linearString); - bool copyAndInflateLatin1Chars(JSContext*, JS::Handle linearString); -}; - -struct MOZ_STACK_CLASS JS_FRIEND_API(ErrorReport) -{ - explicit ErrorReport(JSContext* cx); - ~ErrorReport(); - - enum SniffingBehavior { - WithSideEffects, - NoSideEffects - }; - - /** - * Generate a JSErrorReport from the provided thrown value. - * - * If the value is a (possibly wrapped) Error object, the JSErrorReport will - * be exactly initialized from the Error object's information, without - * observable side effects. (The Error object's JSErrorReport is reused, if - * it has one.) - * - * Otherwise various attempts are made to derive JSErrorReport information - * from |exn| and from the current execution state. This process is - * *definitely* inconsistent with any standard, and particulars of the - * behavior implemented here generally shouldn't be relied upon. - * - * If the value of |sniffingBehavior| is |WithSideEffects|, some of these - * attempts *may* invoke user-configurable behavior when |exn| is an object: - * converting |exn| to a string, detecting and getting properties on |exn|, - * accessing |exn|'s prototype chain, and others are possible. Users *must* - * tolerate |ErrorReport::init| potentially having arbitrary effects. Any - * exceptions thrown by these operations will be caught and silently - * ignored, and "default" values will be substituted into the JSErrorReport. - * - * But if the value of |sniffingBehavior| is |NoSideEffects|, these attempts - * *will not* invoke any observable side effects. The JSErrorReport will - * simply contain fewer, less precise details. - * - * Unlike some functions involved in error handling, this function adheres - * to the usual JSAPI return value error behavior. - */ - bool init(JSContext* cx, JS::HandleValue exn, - SniffingBehavior sniffingBehavior); - - JSErrorReport* report() - { - return reportp; - } - - const JS::ConstUTF8CharsZ toStringResult() - { - return toStringResult_; - } - - private: - // More or less an equivalent of JS_ReportErrorNumber/js::ReportErrorNumberVA - // but fills in an ErrorReport instead of reporting it. Uses varargs to - // make it simpler to call js::ExpandErrorArgumentsVA. - // - // Returns false if we fail to actually populate the ErrorReport - // for some reason (probably out of memory). - bool populateUncaughtExceptionReportUTF8(JSContext* cx, ...); - bool populateUncaughtExceptionReportUTF8VA(JSContext* cx, va_list ap); - - // Reports exceptions from add-on scopes to telementry. - void ReportAddonExceptionToTelementry(JSContext* cx); - - // We may have a provided JSErrorReport, so need a way to represent that. - JSErrorReport* reportp; - - // Or we may need to synthesize a JSErrorReport one of our own. - JSErrorReport ownedReport; - - // And we have a string to maybe keep alive that has pointers into - // it from ownedReport. - JS::RootedString str; - - // And keep its chars alive too. - AutoStableStringChars strChars; - - // And we need to root our exception value. - JS::RootedObject exnObject; - - // And for our filename. - JSAutoByteString filename; - - // We may have a result of error.toString(). - // FIXME: We should not call error.toString(), since it could have side - // effect (see bug 633623). - JS::ConstUTF8CharsZ toStringResult_; - JSAutoByteString toStringResultBytesStorage; -}; - -/* Implemented in vm/StructuredClone.cpp. */ -extern JS_FRIEND_API(uint64_t) -GetSCOffset(JSStructuredCloneWriter* writer); - -namespace Scalar { - -/** - * Scalar types that can appear in typed arrays and typed objects. The enum - * values must to be kept in sync with the JS_SCALARTYPEREPR_ constants, as - * well as the TypedArrayObject::classes and TypedArrayObject::protoClasses - * definitions. - */ -enum Type { - Int8 = 0, - Uint8, - Int16, - Uint16, - Int32, - Uint32, - Float32, - Float64, - - /** - * Special type that is a uint8_t, but assignments are clamped to [0, 256). - * Treat the raw data type as a uint8_t. - */ - Uint8Clamped, - - /** - * Types that don't have their own TypedArray equivalent, for now. - */ - MaxTypedArrayViewType, - - Int64, - Float32x4, - Int8x16, - Int16x8, - Int32x4 -}; - -static inline size_t -byteSize(Type atype) -{ - switch (atype) { - case Int8: - case Uint8: - case Uint8Clamped: - return 1; - case Int16: - case Uint16: - return 2; - case Int32: - case Uint32: - case Float32: - return 4; - case Int64: - case Float64: - return 8; - case Int8x16: - case Int16x8: - case Int32x4: - case Float32x4: - return 16; - default: - MOZ_CRASH("invalid scalar type"); - } -} - -static inline bool -isSignedIntType(Type atype) { - switch (atype) { - case Int8: - case Int16: - case Int32: - case Int64: - case Int8x16: - case Int16x8: - case Int32x4: - return true; - case Uint8: - case Uint8Clamped: - case Uint16: - case Uint32: - case Float32: - case Float64: - case Float32x4: - return false; - default: - MOZ_CRASH("invalid scalar type"); - } -} - -static inline bool -isSimdType(Type atype) { - switch (atype) { - case Int8: - case Uint8: - case Uint8Clamped: - case Int16: - case Uint16: - case Int32: - case Uint32: - case Int64: - case Float32: - case Float64: - return false; - case Int8x16: - case Int16x8: - case Int32x4: - case Float32x4: - return true; - case MaxTypedArrayViewType: - break; - } - MOZ_CRASH("invalid scalar type"); -} - -static inline size_t -scalarByteSize(Type atype) { - switch (atype) { - case Int8x16: - return 1; - case Int16x8: - return 2; - case Int32x4: - case Float32x4: - return 4; - case Int8: - case Uint8: - case Uint8Clamped: - case Int16: - case Uint16: - case Int32: - case Uint32: - case Int64: - case Float32: - case Float64: - case MaxTypedArrayViewType: - break; - } - MOZ_CRASH("invalid simd type"); -} - -} /* namespace Scalar */ -} /* namespace js */ - -/* - * Create a new typed array with nelements elements. - * - * These functions (except the WithBuffer variants) fill in the array with zeros. - */ - -extern JS_FRIEND_API(JSObject*) -JS_NewInt8Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8ClampedArray(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewInt16Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewUint16Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewInt32Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewUint32Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat32Array(JSContext* cx, uint32_t nelements); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat64Array(JSContext* cx, uint32_t nelements); - -/* - * Create a new typed array and copy in values from the given object. The - * object is used as if it were an array; that is, the new array (if - * successfully created) will have length given by array.length, and its - * elements will be those specified by array[0], array[1], and so on, after - * conversion to the typed array element type. - */ - -extern JS_FRIEND_API(JSObject*) -JS_NewInt8ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8ClampedArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewInt16ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewUint16ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewInt32ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewUint32ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat32ArrayFromArray(JSContext* cx, JS::HandleObject array); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat64ArrayFromArray(JSContext* cx, JS::HandleObject array); - -/* - * Create a new typed array using the given ArrayBuffer or - * SharedArrayBuffer for storage. The length value is optional; if -1 - * is passed, enough elements to use up the remainder of the byte - * array is used as the default value. - */ - -extern JS_FRIEND_API(JSObject*) -JS_NewInt8ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewUint8ClampedArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewInt16ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewUint16ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewInt32ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewUint32ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat32ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); -extern JS_FRIEND_API(JSObject*) -JS_NewFloat64ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer, - uint32_t byteOffset, int32_t length); - -/** - * Create a new SharedArrayBuffer with the given byte length. This - * may only be called if - * JS::CompartmentCreationOptionsRef(cx).getSharedMemoryAndAtomicsEnabled() is - * true. - */ -extern JS_FRIEND_API(JSObject*) -JS_NewSharedArrayBuffer(JSContext* cx, uint32_t nbytes); - -/** - * Create a new ArrayBuffer with the given byte length. - */ -extern JS_FRIEND_API(JSObject*) -JS_NewArrayBuffer(JSContext* cx, uint32_t nbytes); - -/** - * Check whether obj supports JS_GetTypedArray* APIs. Note that this may return - * false if a security wrapper is encountered that denies the unwrapping. If - * this test or one of the JS_Is*Array tests succeeds, then it is safe to call - * the various accessor JSAPI calls defined below. - */ -extern JS_FRIEND_API(bool) -JS_IsTypedArrayObject(JSObject* obj); - -/** - * Check whether obj supports JS_GetArrayBufferView* APIs. Note that this may - * return false if a security wrapper is encountered that denies the - * unwrapping. If this test or one of the more specific tests succeeds, then it - * is safe to call the various ArrayBufferView accessor JSAPI calls defined - * below. - */ -extern JS_FRIEND_API(bool) -JS_IsArrayBufferViewObject(JSObject* obj); - -/* - * Test for specific typed array types (ArrayBufferView subtypes) - */ - -extern JS_FRIEND_API(bool) -JS_IsInt8Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsUint8Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsUint8ClampedArray(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsInt16Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsUint16Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsInt32Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsUint32Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsFloat32Array(JSObject* obj); -extern JS_FRIEND_API(bool) -JS_IsFloat64Array(JSObject* obj); - -/** - * Return the isShared flag of a typed array, which denotes whether - * the underlying buffer is a SharedArrayBuffer. - * - * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow - * be known that it would pass such a test: it is a typed array or a wrapper of - * a typed array, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(bool) -JS_GetTypedArraySharedness(JSObject* obj); - -/* - * Test for specific typed array types (ArrayBufferView subtypes) and return - * the unwrapped object if so, else nullptr. Never throws. - */ - -namespace js { - -extern JS_FRIEND_API(JSObject*) -UnwrapInt8Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapUint8Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapUint8ClampedArray(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapInt16Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapUint16Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapInt32Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapUint32Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapFloat32Array(JSObject* obj); -extern JS_FRIEND_API(JSObject*) -UnwrapFloat64Array(JSObject* obj); - -extern JS_FRIEND_API(JSObject*) -UnwrapArrayBuffer(JSObject* obj); - -extern JS_FRIEND_API(JSObject*) -UnwrapArrayBufferView(JSObject* obj); - -extern JS_FRIEND_API(JSObject*) -UnwrapSharedArrayBuffer(JSObject* obj); - - -namespace detail { - -extern JS_FRIEND_DATA(const Class* const) Int8ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Uint8ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Uint8ClampedArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Int16ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Uint16ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Int32ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Uint32ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Float32ArrayClassPtr; -extern JS_FRIEND_DATA(const Class* const) Float64ArrayClassPtr; - -const size_t TypedArrayLengthSlot = 1; - -} // namespace detail - -#define JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Type, type) \ -inline void \ -Get ## Type ## ArrayLengthAndData(JSObject* obj, uint32_t* length, bool* isSharedMemory, type** data) \ -{ \ - MOZ_ASSERT(GetObjectClass(obj) == detail::Type ## ArrayClassPtr); \ - const JS::Value& lenSlot = GetReservedSlot(obj, detail::TypedArrayLengthSlot); \ - *length = mozilla::AssertedCast(lenSlot.toInt32()); \ - *isSharedMemory = JS_GetTypedArraySharedness(obj); \ - *data = static_cast(GetObjectPrivate(obj)); \ -} - -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int8, int8_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint8, uint8_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint8Clamped, uint8_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int16, int16_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint16, uint16_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int32, int32_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint32, uint32_t) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float32, float) -JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float64, double) - -#undef JS_DEFINE_DATA_AND_LENGTH_ACCESSOR - -// This one isn't inlined because it's rather tricky (by dint of having to deal -// with a dozen-plus classes and varying slot layouts. -extern JS_FRIEND_API(void) -GetArrayBufferViewLengthAndData(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); - -// This one isn't inlined because there are a bunch of different ArrayBuffer -// classes that would have to be individually handled here. -// -// There is an isShared out argument for API consistency (eases use from DOM). -// It will always be set to false. -extern JS_FRIEND_API(void) -GetArrayBufferLengthAndData(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); - -// Ditto for SharedArrayBuffer. -// -// There is an isShared out argument for API consistency (eases use from DOM). -// It will always be set to true. -extern JS_FRIEND_API(void) -GetSharedArrayBufferLengthAndData(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); - -} // namespace js - -JS_FRIEND_API(uint8_t*) -JS_GetSharedArrayBufferData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); - -/* - * Unwrap Typed arrays all at once. Return nullptr without throwing if the - * object cannot be viewed as the correct typed array, or the typed array - * object on success, filling both outparameters. - */ -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsInt8Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, int8_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsUint8Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsUint8ClampedArray(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsInt16Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, int16_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsUint16Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint16_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsInt32Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, int32_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsUint32Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint32_t** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsFloat32Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, float** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsFloat64Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, double** data); -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsArrayBufferView(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); - -/* - * Unwrap an ArrayBuffer, return nullptr if it's a different type. - */ -extern JS_FRIEND_API(JSObject*) -JS_GetObjectAsArrayBuffer(JSObject* obj, uint32_t* length, uint8_t** data); - -/* - * Get the type of elements in a typed array, or MaxTypedArrayViewType if a DataView. - * - * |obj| must have passed a JS_IsArrayBufferView/JS_Is*Array test, or somehow - * be known that it would pass such a test: it is an ArrayBufferView or a - * wrapper of an ArrayBufferView, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(js::Scalar::Type) -JS_GetArrayBufferViewType(JSObject* obj); - -extern JS_FRIEND_API(js::Scalar::Type) -JS_GetSharedArrayBufferViewType(JSObject* obj); - -/* - * Check whether obj supports the JS_GetArrayBuffer* APIs. Note that this may - * return false if a security wrapper is encountered that denies the - * unwrapping. If this test succeeds, then it is safe to call the various - * accessor JSAPI calls defined below. - */ -extern JS_FRIEND_API(bool) -JS_IsArrayBufferObject(JSObject* obj); - -extern JS_FRIEND_API(bool) -JS_IsSharedArrayBufferObject(JSObject* obj); - -/** - * Return the available byte length of an array buffer. - * - * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known - * that it would pass such a test: it is an ArrayBuffer or a wrapper of an - * ArrayBuffer, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(uint32_t) -JS_GetArrayBufferByteLength(JSObject* obj); - -extern JS_FRIEND_API(uint32_t) -JS_GetSharedArrayBufferByteLength(JSObject* obj); - -/** - * Return true if the arrayBuffer contains any data. This will return false for - * ArrayBuffer.prototype and detached ArrayBuffers. - * - * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known - * that it would pass such a test: it is an ArrayBuffer or a wrapper of an - * ArrayBuffer, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(bool) -JS_ArrayBufferHasData(JSObject* obj); - -/** - * Return a pointer to the start of the data referenced by a typed array. The - * data is still owned by the typed array, and should not be modified on - * another thread. Furthermore, the pointer can become invalid on GC (if the - * data is small and fits inside the array's GC header), so callers must take - * care not to hold on across anything that could GC. - * - * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known - * that it would pass such a test: it is an ArrayBuffer or a wrapper of an - * ArrayBuffer, and the unwrapping will succeed. - * - * *isSharedMemory will be set to false, the argument is present to simplify - * its use from code that also interacts with SharedArrayBuffer. - */ -extern JS_FRIEND_API(uint8_t*) -JS_GetArrayBufferData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); - -/** - * Check whether the obj is ArrayBufferObject and memory mapped. Note that this - * may return false if a security wrapper is encountered that denies the - * unwrapping. - */ -extern JS_FRIEND_API(bool) -JS_IsMappedArrayBufferObject(JSObject* obj); - -/** - * Return the number of elements in a typed array. - * - * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow - * be known that it would pass such a test: it is a typed array or a wrapper of - * a typed array, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(uint32_t) -JS_GetTypedArrayLength(JSObject* obj); - -/** - * Return the byte offset from the start of an array buffer to the start of a - * typed array view. - * - * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow - * be known that it would pass such a test: it is a typed array or a wrapper of - * a typed array, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(uint32_t) -JS_GetTypedArrayByteOffset(JSObject* obj); - -/** - * Return the byte length of a typed array. - * - * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow - * be known that it would pass such a test: it is a typed array or a wrapper of - * a typed array, and the unwrapping will succeed. - */ -extern JS_FRIEND_API(uint32_t) -JS_GetTypedArrayByteLength(JSObject* obj); - -/** - * Check whether obj supports JS_ArrayBufferView* APIs. Note that this may - * return false if a security wrapper is encountered that denies the - * unwrapping. - */ -extern JS_FRIEND_API(bool) -JS_IsArrayBufferViewObject(JSObject* obj); - -/** - * More generic name for JS_GetTypedArrayByteLength to cover DataViews as well - */ -extern JS_FRIEND_API(uint32_t) -JS_GetArrayBufferViewByteLength(JSObject* obj); - -/* - * Return a pointer to the start of the data referenced by a typed array. The - * data is still owned by the typed array, and should not be modified on - * another thread. Furthermore, the pointer can become invalid on GC (if the - * data is small and fits inside the array's GC header), so callers must take - * care not to hold on across anything that could GC. - * - * |obj| must have passed a JS_Is*Array test, or somehow be known that it would - * pass such a test: it is a typed array or a wrapper of a typed array, and the - * unwrapping will succeed. - * - * *isSharedMemory will be set to true if the typed array maps a - * SharedArrayBuffer, otherwise to false. - */ - -extern JS_FRIEND_API(int8_t*) -JS_GetInt8ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(uint8_t*) -JS_GetUint8ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(uint8_t*) -JS_GetUint8ClampedArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(int16_t*) -JS_GetInt16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(uint16_t*) -JS_GetUint16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(int32_t*) -JS_GetInt32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(uint32_t*) -JS_GetUint32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(float*) -JS_GetFloat32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); -extern JS_FRIEND_API(double*) -JS_GetFloat64ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); - -/** - * Same as above, but for any kind of ArrayBufferView. Prefer the type-specific - * versions when possible. - */ -extern JS_FRIEND_API(void*) -JS_GetArrayBufferViewData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&); - -/** - * Return the ArrayBuffer or SharedArrayBuffer underlying an ArrayBufferView. - * This may return a detached buffer. |obj| must be an object that would - * return true for JS_IsArrayBufferViewObject(). - */ -extern JS_FRIEND_API(JSObject*) -JS_GetArrayBufferViewBuffer(JSContext* cx, JS::HandleObject obj, bool* isSharedMemory); - -/** - * Detach an ArrayBuffer, causing all associated views to no longer refer to - * the ArrayBuffer's original attached memory. - * - * The |changeData| argument is obsolete and ignored. - */ -extern JS_FRIEND_API(bool) -JS_DetachArrayBuffer(JSContext* cx, JS::HandleObject obj); - -/** - * Check whether the obj is a detached ArrayBufferObject. Note that this may - * return false if a security wrapper is encountered that denies the - * unwrapping. - */ -extern JS_FRIEND_API(bool) -JS_IsDetachedArrayBufferObject(JSObject* obj); - -/** - * Check whether obj supports JS_GetDataView* APIs. - */ -JS_FRIEND_API(bool) -JS_IsDataViewObject(JSObject* obj); - -/** - * Create a new DataView using the given ArrayBuffer for storage. The given - * buffer must be an ArrayBuffer (or a cross-compartment wrapper of an - * ArrayBuffer), and the offset and length must fit within the bounds of the - * arrayBuffer. Currently, nullptr will be returned and an exception will be - * thrown if these conditions do not hold, but do not depend on that behavior. - */ -JS_FRIEND_API(JSObject*) -JS_NewDataView(JSContext* cx, JS::HandleObject arrayBuffer, uint32_t byteOffset, int32_t byteLength); - -/** - * Return the byte offset of a data view into its array buffer. |obj| must be a - * DataView. - * - * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that - * it would pass such a test: it is a data view or a wrapper of a data view, - * and the unwrapping will succeed. - */ -JS_FRIEND_API(uint32_t) -JS_GetDataViewByteOffset(JSObject* obj); - -/** - * Return the byte length of a data view. - * - * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that - * it would pass such a test: it is a data view or a wrapper of a data view, - * and the unwrapping will succeed. If cx is nullptr, then DEBUG builds may be - * unable to assert when unwrapping should be disallowed. - */ -JS_FRIEND_API(uint32_t) -JS_GetDataViewByteLength(JSObject* obj); - -/** - * Return a pointer to the beginning of the data referenced by a DataView. - * - * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that - * it would pass such a test: it is a data view or a wrapper of a data view, - * and the unwrapping will succeed. If cx is nullptr, then DEBUG builds may be - * unable to assert when unwrapping should be disallowed. - */ -JS_FRIEND_API(void*) -JS_GetDataViewData(JSObject* obj, const JS::AutoCheckCannotGC&); - -namespace js { - -/** - * Add a watchpoint -- in the Object.prototype.watch sense -- to |obj| for the - * property |id|, using the callable object |callable| as the function to be - * called for notifications. - * - * This is an internal function exposed -- temporarily -- only so that DOM - * proxies can be watchable. Don't use it! We'll soon kill off the - * Object.prototype.{,un}watch functions, at which point this will go too. - */ -extern JS_FRIEND_API(bool) -WatchGuts(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable); - -/** - * Remove a watchpoint -- in the Object.prototype.watch sense -- from |obj| for - * the property |id|. - * - * This is an internal function exposed -- temporarily -- only so that DOM - * proxies can be watchable. Don't use it! We'll soon kill off the - * Object.prototype.{,un}watch functions, at which point this will go too. - */ -extern JS_FRIEND_API(bool) -UnwatchGuts(JSContext* cx, JS::HandleObject obj, JS::HandleId id); - -namespace jit { - -enum class InlinableNative : uint16_t; - -} // namespace jit - -} // namespace js - -/** - * A class, expected to be passed by value, which represents the CallArgs for a - * JSJitGetterOp. - */ -class JSJitGetterCallArgs : protected JS::MutableHandleValue -{ - public: - explicit JSJitGetterCallArgs(const JS::CallArgs& args) - : JS::MutableHandleValue(args.rval()) - {} - - explicit JSJitGetterCallArgs(JS::RootedValue* rooted) - : JS::MutableHandleValue(rooted) - {} - - JS::MutableHandleValue rval() { - return *this; - } -}; - -/** - * A class, expected to be passed by value, which represents the CallArgs for a - * JSJitSetterOp. - */ -class JSJitSetterCallArgs : protected JS::MutableHandleValue -{ - public: - explicit JSJitSetterCallArgs(const JS::CallArgs& args) - : JS::MutableHandleValue(args[0]) - {} - - JS::MutableHandleValue operator[](unsigned i) { - MOZ_ASSERT(i == 0); - return *this; - } - - unsigned length() const { return 1; } - - // Add get() or maybe hasDefined() as needed -}; - -struct JSJitMethodCallArgsTraits; - -/** - * A class, expected to be passed by reference, which represents the CallArgs - * for a JSJitMethodOp. - */ -class JSJitMethodCallArgs : protected JS::detail::CallArgsBase -{ - private: - typedef JS::detail::CallArgsBase Base; - friend struct JSJitMethodCallArgsTraits; - - public: - explicit JSJitMethodCallArgs(const JS::CallArgs& args) { - argv_ = args.array(); - argc_ = args.length(); - } - - JS::MutableHandleValue rval() const { - return Base::rval(); - } - - unsigned length() const { return Base::length(); } - - JS::MutableHandleValue operator[](unsigned i) const { - return Base::operator[](i); - } - - bool hasDefined(unsigned i) const { - return Base::hasDefined(i); - } - - JSObject& callee() const { - // We can't use Base::callee() because that will try to poke at - // this->usedRval_, which we don't have. - return argv_[-2].toObject(); - } - - JS::HandleValue get(unsigned i) const { - return Base::get(i); - } -}; - -struct JSJitMethodCallArgsTraits -{ - static const size_t offsetOfArgv = offsetof(JSJitMethodCallArgs, argv_); - static const size_t offsetOfArgc = offsetof(JSJitMethodCallArgs, argc_); -}; - -typedef bool -(* JSJitGetterOp)(JSContext* cx, JS::HandleObject thisObj, - void* specializedThis, JSJitGetterCallArgs args); -typedef bool -(* JSJitSetterOp)(JSContext* cx, JS::HandleObject thisObj, - void* specializedThis, JSJitSetterCallArgs args); -typedef bool -(* JSJitMethodOp)(JSContext* cx, JS::HandleObject thisObj, - void* specializedThis, const JSJitMethodCallArgs& args); - -/** - * This struct contains metadata passed from the DOM to the JS Engine for JIT - * optimizations on DOM property accessors. Eventually, this should be made - * available to general JSAPI users, but we are not currently ready to do so. - */ -struct JSJitInfo { - enum OpType { - Getter, - Setter, - Method, - StaticMethod, - InlinableNative, - // Must be last - OpTypeCount - }; - - enum ArgType { - // Basic types - String = (1 << 0), - Integer = (1 << 1), // Only 32-bit or less - Double = (1 << 2), // Maybe we want to add Float sometime too - Boolean = (1 << 3), - Object = (1 << 4), - Null = (1 << 5), - - // And derived types - Numeric = Integer | Double, - // Should "Primitive" use the WebIDL definition, which - // excludes string and null, or the typical JS one that includes them? - Primitive = Numeric | Boolean | Null | String, - ObjectOrNull = Object | Null, - Any = ObjectOrNull | Primitive, - - // Our sentinel value. - ArgTypeListEnd = (1 << 31) - }; - - static_assert(Any & String, "Any must include String."); - static_assert(Any & Integer, "Any must include Integer."); - static_assert(Any & Double, "Any must include Double."); - static_assert(Any & Boolean, "Any must include Boolean."); - static_assert(Any & Object, "Any must include Object."); - static_assert(Any & Null, "Any must include Null."); - - /** - * An enum that describes what this getter/setter/method aliases. This - * determines what things can be hoisted past this call, and if this - * call is movable what it can be hoisted past. - */ - enum AliasSet { - /** - * Alias nothing: a constant value, getting it can't affect any other - * values, nothing can affect it. - */ - AliasNone, - - /** - * Alias things that can modify the DOM but nothing else. Doing the - * call can't affect the behavior of any other function. - */ - AliasDOMSets, - - /** - * Alias the world. Calling this can change arbitrary values anywhere - * in the system. Most things fall in this bucket. - */ - AliasEverything, - - /** Must be last. */ - AliasSetCount - }; - - bool needsOuterizedThisObject() const - { - return type() != Getter && type() != Setter; - } - - bool isTypedMethodJitInfo() const - { - return isTypedMethod; - } - - OpType type() const - { - return OpType(type_); - } - - AliasSet aliasSet() const - { - return AliasSet(aliasSet_); - } - - JSValueType returnType() const - { - return JSValueType(returnType_); - } - - union { - JSJitGetterOp getter; - JSJitSetterOp setter; - JSJitMethodOp method; - /** A DOM static method, used for Promise wrappers */ - JSNative staticMethod; - }; - - union { - uint16_t protoID; - js::jit::InlinableNative inlinableNative; - }; - - union { - uint16_t depth; - - // Additional opcode for some InlinableNative functions. - uint16_t nativeOp; - }; - - // These fields are carefully packed to take up 4 bytes. If you need more - // bits for whatever reason, please see if you can steal bits from existing - // fields before adding more members to this structure. - -#define JITINFO_OP_TYPE_BITS 4 -#define JITINFO_ALIAS_SET_BITS 4 -#define JITINFO_RETURN_TYPE_BITS 8 -#define JITINFO_SLOT_INDEX_BITS 10 - - /** The OpType that says what sort of function we are. */ - uint32_t type_ : JITINFO_OP_TYPE_BITS; - - /** - * The alias set for this op. This is a _minimal_ alias set; in - * particular for a method it does not include whatever argument - * conversions might do. That's covered by argTypes and runtime - * analysis of the actual argument types being passed in. - */ - uint32_t aliasSet_ : JITINFO_ALIAS_SET_BITS; - - /** The return type tag. Might be JSVAL_TYPE_UNKNOWN. */ - uint32_t returnType_ : JITINFO_RETURN_TYPE_BITS; - - static_assert(OpTypeCount <= (1 << JITINFO_OP_TYPE_BITS), - "Not enough space for OpType"); - static_assert(AliasSetCount <= (1 << JITINFO_ALIAS_SET_BITS), - "Not enough space for AliasSet"); - static_assert((sizeof(JSValueType) * 8) <= JITINFO_RETURN_TYPE_BITS, - "Not enough space for JSValueType"); - -#undef JITINFO_RETURN_TYPE_BITS -#undef JITINFO_ALIAS_SET_BITS -#undef JITINFO_OP_TYPE_BITS - - /** Is op fallible? False in setters. */ - uint32_t isInfallible : 1; - - /** - * Is op movable? To be movable the op must - * not AliasEverything, but even that might - * not be enough (e.g. in cases when it can - * throw or is explicitly not movable). - */ - uint32_t isMovable : 1; - - /** - * Can op be dead-code eliminated? Again, this - * depends on whether the op can throw, in - * addition to the alias set. - */ - uint32_t isEliminatable : 1; - - // XXXbz should we have a JSValueType for the type of the member? - /** - * True if this is a getter that can always - * get the value from a slot of the "this" object. - */ - uint32_t isAlwaysInSlot : 1; - - /** - * True if this is a getter that can sometimes (if the slot doesn't contain - * UndefinedValue()) get the value from a slot of the "this" object. - */ - uint32_t isLazilyCachedInSlot : 1; - - /** True if this is an instance of JSTypedMethodJitInfo. */ - uint32_t isTypedMethod : 1; - - /** - * If isAlwaysInSlot or isSometimesInSlot is true, - * the index of the slot to get the value from. - * Otherwise 0. - */ - uint32_t slotIndex : JITINFO_SLOT_INDEX_BITS; - - static const size_t maxSlotIndex = (1 << JITINFO_SLOT_INDEX_BITS) - 1; - -#undef JITINFO_SLOT_INDEX_BITS -}; - -static_assert(sizeof(JSJitInfo) == (sizeof(void*) + 2 * sizeof(uint32_t)), - "There are several thousand instances of JSJitInfo stored in " - "a binary. Please don't increase its space requirements without " - "verifying that there is no other way forward (better packing, " - "smaller datatypes for fields, subclassing, etc.)."); - -struct JSTypedMethodJitInfo -{ - // We use C-style inheritance here, rather than C++ style inheritance - // because not all compilers support brace-initialization for non-aggregate - // classes. Using C++ style inheritance and constructors instead of - // brace-initialization would also force the creation of static - // constructors (on some compilers) when JSJitInfo and JSTypedMethodJitInfo - // structures are declared. Since there can be several thousand of these - // structures present and we want to have roughly equivalent performance - // across a range of compilers, we do things manually. - JSJitInfo base; - - const JSJitInfo::ArgType* const argTypes; /* For a method, a list of sets of - types that the function - expects. This can be used, - for example, to figure out - when argument coercions can - have side-effects. */ -}; - -namespace js { - -static MOZ_ALWAYS_INLINE shadow::Function* -FunctionObjectToShadowFunction(JSObject* fun) -{ - MOZ_ASSERT(GetObjectClass(fun) == FunctionClassPtr); - return reinterpret_cast(fun); -} - -/* Statically asserted in jsfun.h. */ -static const unsigned JS_FUNCTION_INTERPRETED_BITS = 0x0201; - -// Return whether the given function object is native. -static MOZ_ALWAYS_INLINE bool -FunctionObjectIsNative(JSObject* fun) -{ - return !(FunctionObjectToShadowFunction(fun)->flags & JS_FUNCTION_INTERPRETED_BITS); -} - -static MOZ_ALWAYS_INLINE JSNative -GetFunctionObjectNative(JSObject* fun) -{ - MOZ_ASSERT(FunctionObjectIsNative(fun)); - return FunctionObjectToShadowFunction(fun)->native; -} - -} // namespace js - -static MOZ_ALWAYS_INLINE const JSJitInfo* -FUNCTION_VALUE_TO_JITINFO(const JS::Value& v) -{ - MOZ_ASSERT(js::FunctionObjectIsNative(&v.toObject())); - return js::FunctionObjectToShadowFunction(&v.toObject())->jitinfo; -} - -static MOZ_ALWAYS_INLINE void -SET_JITINFO(JSFunction * func, const JSJitInfo* info) -{ - js::shadow::Function* fun = reinterpret_cast(func); - MOZ_ASSERT(!(fun->flags & js::JS_FUNCTION_INTERPRETED_BITS)); - fun->jitinfo = info; -} - -/* - * Engine-internal extensions of jsid. This code is here only until we - * eliminate Gecko's dependencies on it! - */ - -static MOZ_ALWAYS_INLINE jsid -JSID_FROM_BITS(size_t bits) -{ - jsid id; - JSID_BITS(id) = bits; - return id; -} - -namespace js { -namespace detail { -bool IdMatchesAtom(jsid id, JSAtom* atom); -} // namespace detail -} // namespace js - -/** - * Must not be used on atoms that are representable as integer jsids. - * Prefer NameToId or AtomToId over this function: - * - * A PropertyName is an atom that does not contain an integer in the range - * [0, UINT32_MAX]. However, jsid can only hold an integer in the range - * [0, JSID_INT_MAX] (where JSID_INT_MAX == 2^31-1). Thus, for the range of - * integers (JSID_INT_MAX, UINT32_MAX], to represent as a jsid 'id', it must be - * the case JSID_IS_ATOM(id) and !JSID_TO_ATOM(id)->isPropertyName(). In most - * cases when creating a jsid, code does not have to care about this corner - * case because: - * - * - When given an arbitrary JSAtom*, AtomToId must be used, which checks for - * integer atoms representable as integer jsids, and does this conversion. - * - * - When given a PropertyName*, NameToId can be used which which does not need - * to do any dynamic checks. - * - * Thus, it is only the rare third case which needs this function, which - * handles any JSAtom* that is known not to be representable with an int jsid. - */ -static MOZ_ALWAYS_INLINE jsid -NON_INTEGER_ATOM_TO_JSID(JSAtom* atom) -{ - MOZ_ASSERT(((size_t)atom & 0x7) == 0); - jsid id = JSID_FROM_BITS((size_t)atom); - MOZ_ASSERT(js::detail::IdMatchesAtom(id, atom)); - return id; -} - -/* All strings stored in jsids are atomized, but are not necessarily property names. */ -static MOZ_ALWAYS_INLINE bool -JSID_IS_ATOM(jsid id) -{ - return JSID_IS_STRING(id); -} - -static MOZ_ALWAYS_INLINE bool -JSID_IS_ATOM(jsid id, JSAtom* atom) -{ - return id == JSID_FROM_BITS((size_t)atom); -} - -static MOZ_ALWAYS_INLINE JSAtom* -JSID_TO_ATOM(jsid id) -{ - return (JSAtom*)JSID_TO_STRING(id); -} - -JS_STATIC_ASSERT(sizeof(jsid) == sizeof(void*)); - -namespace js { - -static MOZ_ALWAYS_INLINE JS::Value -IdToValue(jsid id) -{ - if (JSID_IS_STRING(id)) - return JS::StringValue(JSID_TO_STRING(id)); - if (JSID_IS_INT(id)) - return JS::Int32Value(JSID_TO_INT(id)); - if (JSID_IS_SYMBOL(id)) - return JS::SymbolValue(JSID_TO_SYMBOL(id)); - MOZ_ASSERT(JSID_IS_VOID(id)); - return JS::UndefinedValue(); -} - -/** - * If the embedder has registered a ScriptEnvironmentPreparer, - * PrepareScriptEnvironmentAndInvoke will call the preparer's 'invoke' method - * with the given |closure|, with the assumption that the preparer will set up - * any state necessary to run script in |scope|, invoke |closure| with a valid - * JSContext*, report any exceptions thrown from the closure, and return. - * - * If no preparer is registered, PrepareScriptEnvironmentAndInvoke will assert - * that |rt| has exactly one JSContext associated with it, enter the compartment - * of |scope| on that context, and invoke |closure|. - * - * In both cases, PrepareScriptEnvironmentAndInvoke will report any exceptions - * that are thrown by the closure. Consumers who want to propagate back - * whether the closure succeeded should do so via members of the closure - * itself. - */ - -struct ScriptEnvironmentPreparer { - struct Closure { - virtual bool operator()(JSContext* cx) = 0; - }; - - virtual void invoke(JS::HandleObject scope, Closure& closure) = 0; -}; - -extern JS_FRIEND_API(void) -PrepareScriptEnvironmentAndInvoke(JSContext* cx, JS::HandleObject scope, - ScriptEnvironmentPreparer::Closure& closure); - -JS_FRIEND_API(void) -SetScriptEnvironmentPreparer(JSContext* cx, ScriptEnvironmentPreparer* preparer); - -enum CTypesActivityType { - CTYPES_CALL_BEGIN, - CTYPES_CALL_END, - CTYPES_CALLBACK_BEGIN, - CTYPES_CALLBACK_END -}; - -typedef void -(* CTypesActivityCallback)(JSContext* cx, CTypesActivityType type); - -/** - * Sets a callback that is run whenever js-ctypes is about to be used when - * calling into C. - */ -JS_FRIEND_API(void) -SetCTypesActivityCallback(JSContext* cx, CTypesActivityCallback cb); - -class MOZ_RAII JS_FRIEND_API(AutoCTypesActivityCallback) { - private: - JSContext* cx; - CTypesActivityCallback callback; - CTypesActivityType endType; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - - public: - AutoCTypesActivityCallback(JSContext* cx, CTypesActivityType beginType, - CTypesActivityType endType - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - ~AutoCTypesActivityCallback() { - DoEndCallback(); - } - void DoEndCallback() { - if (callback) { - callback(cx, endType); - callback = nullptr; - } - } -}; - -// Abstract base class for objects that build allocation metadata for JavaScript -// values. -struct AllocationMetadataBuilder { - AllocationMetadataBuilder() { } - - // Return a metadata object for the newly constructed object |obj|, or - // nullptr if there's no metadata to attach. - // - // Implementations should treat all errors as fatal; there is no way to - // report errors from this callback. In particular, the caller provides an - // oomUnsafe for overriding implementations to use. - virtual JSObject* build(JSContext* cx, JS::HandleObject obj, - AutoEnterOOMUnsafeRegion& oomUnsafe) const - { - return nullptr; - } -}; - -/** - * Specify a callback to invoke when creating each JS object in the current - * compartment, which may return a metadata object to associate with the - * object. - */ -JS_FRIEND_API(void) -SetAllocationMetadataBuilder(JSContext* cx, const AllocationMetadataBuilder *callback); - -/** Get the metadata associated with an object. */ -JS_FRIEND_API(JSObject*) -GetAllocationMetadata(JSObject* obj); - -JS_FRIEND_API(bool) -GetElementsWithAdder(JSContext* cx, JS::HandleObject obj, JS::HandleObject receiver, - uint32_t begin, uint32_t end, js::ElementAdder* adder); - -JS_FRIEND_API(bool) -ForwardToNative(JSContext* cx, JSNative native, const JS::CallArgs& args); - -/** - * Helper function for HTMLDocument and HTMLFormElement. - * - * These are the only two interfaces that have [OverrideBuiltins], a named - * getter, and no named setter. They're implemented as proxies with a custom - * getOwnPropertyDescriptor() method. Unfortunately, overriding - * getOwnPropertyDescriptor() automatically affects the behavior of set(), - * which normally is just common sense but is *not* desired for these two - * interfaces. - * - * The fix is for these two interfaces to override set() to ignore the - * getOwnPropertyDescriptor() override. - * - * SetPropertyIgnoringNamedGetter is exposed to make it easier to override - * set() in this way. It carries out all the steps of BaseProxyHandler::set() - * except the initial getOwnPropertyDescriptor() call. The caller must supply - * that descriptor as the 'ownDesc' parameter. - * - * Implemented in proxy/BaseProxyHandler.cpp. - */ -JS_FRIEND_API(bool) -SetPropertyIgnoringNamedGetter(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::HandleValue v, JS::HandleValue receiver, - JS::Handle ownDesc, - JS::ObjectOpResult& result); - -JS_FRIEND_API(void) -ReportASCIIErrorWithId(JSContext* cx, const char* msg, JS::HandleId id); - -// This function is for one specific use case, please don't use this for anything else! -extern JS_FRIEND_API(bool) -ExecuteInGlobalAndReturnScope(JSContext* cx, JS::HandleObject obj, JS::HandleScript script, - JS::MutableHandleObject scope); - -#if defined(XP_WIN) && defined(_WIN64) -// Parameters use void* types to avoid #including windows.h. The return value of -// this function is returned from the exception handler. -typedef long -(*JitExceptionHandler)(void* exceptionRecord, // PEXECTION_RECORD - void* context); // PCONTEXT - -/** - * Windows uses "structured exception handling" to handle faults. When a fault - * occurs, the stack is searched for a handler (similar to C++ exception - * handling). If the search does not find a handler, the "unhandled exception - * filter" is called. Breakpad uses the unhandled exception filter to do crash - * reporting. Unfortunately, on Win64, JIT code on the stack completely throws - * off this unwinding process and prevents the unhandled exception filter from - * being called. The reason is that Win64 requires unwind information be - * registered for all code regions and JIT code has none. While it is possible - * to register full unwind information for JIT code, this is a lot of work (one - * has to be able to recover the frame pointer at any PC) so instead we register - * a handler for all JIT code that simply calls breakpad's unhandled exception - * filter (which will perform crash reporting and then terminate the process). - * This would be wrong if there was an outer __try block that expected to handle - * the fault, but this is not generally allowed. - * - * Gecko must call SetJitExceptionFilter before any JIT code is compiled and - * only once per process. - */ -extern JS_FRIEND_API(void) -SetJitExceptionHandler(JitExceptionHandler handler); -#endif - -/** - * Get the nearest enclosing with environment object for a given function. If - * the function is not scripted or is not enclosed by a with scope, returns - * the global. - */ -extern JS_FRIEND_API(JSObject*) -GetNearestEnclosingWithEnvironmentObjectForFunction(JSFunction* fun); - -/** - * Get the first SavedFrame object in this SavedFrame stack whose principals are - * subsumed by the cx's principals. If there is no such frame, return nullptr. - * - * Do NOT pass a non-SavedFrame object here. - * - * The savedFrame and cx do not need to be in the same compartment. - */ -extern JS_FRIEND_API(JSObject*) -GetFirstSubsumedSavedFrame(JSContext* cx, JS::HandleObject savedFrame, JS::SavedFrameSelfHosted selfHosted); - -extern JS_FRIEND_API(bool) -ReportIsNotFunction(JSContext* cx, JS::HandleValue v); - -extern JS_FRIEND_API(JSObject*) -ConvertArgsToArray(JSContext* cx, const JS::CallArgs& args); - -/** - * Window and WindowProxy - * - * The functions below have to do with Windows and WindowProxies. There's an - * invariant that actual Window objects (the global objects of web pages) are - * never directly exposed to script. Instead we often substitute a WindowProxy. - * - * The environment chain, on the other hand, contains the Window and never its - * WindowProxy. - * - * As a result, we have calls to these "substitute-this-object-for-that-object" - * functions sprinkled at apparently arbitrary (but actually *very* carefully - * and nervously selected) places throughout the engine and indeed the - * universe. - */ - -/** - * Tell the JS engine which Class is used for WindowProxy objects. Used by the - * functions below. - */ -extern JS_FRIEND_API(void) -SetWindowProxyClass(JSContext* cx, const Class* clasp); - -/** - * Associates a WindowProxy with a Window (global object). `windowProxy` must - * have the Class set by SetWindowProxyClass. - */ -extern JS_FRIEND_API(void) -SetWindowProxy(JSContext* cx, JS::HandleObject global, JS::HandleObject windowProxy); - -namespace detail { - -JS_FRIEND_API(bool) -IsWindowSlow(JSObject* obj); - -} // namespace detail - -/** - * Returns true iff `obj` is a global object with an associated WindowProxy, - * see SetWindowProxy. - */ -inline bool -IsWindow(JSObject* obj) -{ - if (GetObjectClass(obj)->flags & JSCLASS_IS_GLOBAL) - return detail::IsWindowSlow(obj); - return false; -} - -/** - * Returns true iff `obj` has the WindowProxy Class (see SetWindowProxyClass). - */ -JS_FRIEND_API(bool) -IsWindowProxy(JSObject* obj); - -/** - * If `obj` is a Window, get its associated WindowProxy (or a CCW or dead - * wrapper if the page was navigated away from), else return `obj`. This - * function is infallible and never returns nullptr. - */ -extern JS_FRIEND_API(JSObject*) -ToWindowProxyIfWindow(JSObject* obj); - -/** - * If `obj` is a WindowProxy, get its associated Window (the compartment's - * global), else return `obj`. This function is infallible and never returns - * nullptr. - */ -extern JS_FRIEND_API(JSObject*) -ToWindowIfWindowProxy(JSObject* obj); - -} /* namespace js */ - -class NativeProfiler -{ - public: - virtual ~NativeProfiler() {}; - virtual void sampleNative(void* addr, uint32_t size) = 0; - virtual void removeNative(void* addr) = 0; - virtual void reset() = 0; -}; - -class GCHeapProfiler -{ - public: - virtual ~GCHeapProfiler() {}; - virtual void sampleTenured(void* addr, uint32_t size) = 0; - virtual void sampleNursery(void* addr, uint32_t size) = 0; - virtual void markTenuredStart() = 0; - virtual void markTenured(void* addr) = 0; - virtual void sweepTenured() = 0; - virtual void sweepNursery() = 0; - virtual void moveNurseryToTenured(void* addrOld, void* addrNew) = 0; - virtual void reset() = 0; -}; - -class MemProfiler -{ - static mozilla::Atomic sActiveProfilerCount; - static NativeProfiler* sNativeProfiler; - - static GCHeapProfiler* GetGCHeapProfiler(void* addr); - static GCHeapProfiler* GetGCHeapProfiler(JSRuntime* runtime); - - static NativeProfiler* GetNativeProfiler() { - return sNativeProfiler; - } - - GCHeapProfiler* mGCHeapProfiler; - JSRuntime* mRuntime; - - public: - explicit MemProfiler(JSRuntime* aRuntime) : mGCHeapProfiler(nullptr), mRuntime(aRuntime) {} - - void start(GCHeapProfiler* aGCHeapProfiler); - void stop(); - - GCHeapProfiler* getGCHeapProfiler() const { - return mGCHeapProfiler; - } - - static MOZ_ALWAYS_INLINE bool enabled() { - return sActiveProfilerCount > 0; - } - - static MemProfiler* GetMemProfiler(JSContext* context); - - static void SetNativeProfiler(NativeProfiler* aProfiler) { - sNativeProfiler = aProfiler; - } - - static MOZ_ALWAYS_INLINE void SampleNative(void* addr, uint32_t size) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - NativeProfiler* profiler = GetNativeProfiler(); - if (profiler) - profiler->sampleNative(addr, size); - } - - static MOZ_ALWAYS_INLINE void SampleTenured(void* addr, uint32_t size) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(addr); - if (profiler) - profiler->sampleTenured(addr, size); - } - - static MOZ_ALWAYS_INLINE void SampleNursery(void* addr, uint32_t size) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(addr); - if (profiler) - profiler->sampleNursery(addr, size); - } - - static MOZ_ALWAYS_INLINE void RemoveNative(void* addr) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - NativeProfiler* profiler = GetNativeProfiler(); - if (profiler) - profiler->removeNative(addr); - } - - static MOZ_ALWAYS_INLINE void MarkTenuredStart(JSRuntime* runtime) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(runtime); - if (profiler) - profiler->markTenuredStart(); - } - - static MOZ_ALWAYS_INLINE void MarkTenured(void* addr) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(addr); - if (profiler) - profiler->markTenured(addr); - } - - static MOZ_ALWAYS_INLINE void SweepTenured(JSRuntime* runtime) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(runtime); - if (profiler) - profiler->sweepTenured(); - } - - static MOZ_ALWAYS_INLINE void SweepNursery(JSRuntime* runtime) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(runtime); - if (profiler) - profiler->sweepNursery(); - } - - static MOZ_ALWAYS_INLINE void MoveNurseryToTenured(void* addrOld, void* addrNew) { - JS::AutoSuppressGCAnalysis nogc; - - if (MOZ_LIKELY(!enabled())) - return; - - GCHeapProfiler* profiler = GetGCHeapProfiler(addrOld); - if (profiler) - profiler->moveNurseryToTenured(addrOld, addrNew); - } -}; - -#endif /* jsfriendapi_h */ diff --git a/android/x86/include/spidermonkey/jsperf.h b/android/x86/include/spidermonkey/jsperf.h deleted file mode 100644 index b8f2909a..00000000 --- a/android/x86/include/spidermonkey/jsperf.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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 perf_jsperf_h -#define perf_jsperf_h - -#include "jstypes.h" - -#include "js/TypeDecls.h" -#include "js/Utility.h" - -namespace JS { - -/* - * JS::PerfMeasurement is a generic way to access detailed performance - * measurement APIs provided by your operating system. The details of - * exactly how this works and what can be measured are highly - * system-specific, but this interface is (one hopes) implementable - * on top of all of them. - * - * To use this API, create a PerfMeasurement object, passing its - * constructor a bitmask indicating which events you are interested - * in. Thereafter, Start() zeroes all counters and starts timing; - * Stop() stops timing again; and the counters for the events you - * requested are available as data values after calling Stop(). The - * object may be reused for many measurements. - */ -class JS_FRIEND_API(PerfMeasurement) -{ - protected: - // Implementation-specific data, if any. - void* impl; - - public: - /* - * Events that may be measured. Taken directly from the list of - * "generalized hardware performance event types" in the Linux - * perf_event API, plus some of the "software events". - */ - enum EventMask { - CPU_CYCLES = 0x00000001, - INSTRUCTIONS = 0x00000002, - CACHE_REFERENCES = 0x00000004, - CACHE_MISSES = 0x00000008, - BRANCH_INSTRUCTIONS = 0x00000010, - BRANCH_MISSES = 0x00000020, - BUS_CYCLES = 0x00000040, - PAGE_FAULTS = 0x00000080, - MAJOR_PAGE_FAULTS = 0x00000100, - CONTEXT_SWITCHES = 0x00000200, - CPU_MIGRATIONS = 0x00000400, - - ALL = 0x000007ff, - NUM_MEASURABLE_EVENTS = 11 - }; - - /* - * Bitmask of events that will be measured when this object is - * active (between Start() and Stop()). This may differ from the - * bitmask passed to the constructor if the platform does not - * support measuring all of the requested events. - */ - const EventMask eventsMeasured; - - /* - * Counters for each measurable event. - * Immediately after one of these objects is created, all of the - * counters for enabled events will be zero, and all of the - * counters for disabled events will be uint64_t(-1). - */ - uint64_t cpu_cycles; - uint64_t instructions; - uint64_t cache_references; - uint64_t cache_misses; - uint64_t branch_instructions; - uint64_t branch_misses; - uint64_t bus_cycles; - uint64_t page_faults; - uint64_t major_page_faults; - uint64_t context_switches; - uint64_t cpu_migrations; - - /* - * Prepare to measure the indicated set of events. If not all of - * the requested events can be measured on the current platform, - * then the eventsMeasured bitmask will only include the subset of - * |toMeasure| corresponding to the events that can be measured. - */ - explicit PerfMeasurement(EventMask toMeasure); - - /* Done with this set of measurements, tear down OS-level state. */ - ~PerfMeasurement(); - - /* Start a measurement cycle. */ - void start(); - - /* - * End a measurement cycle, and for each enabled counter, add the - * number of measured events of that type to the appropriate - * visible variable. - */ - void stop(); - - /* Reset all enabled counters to zero. */ - void reset(); - - /* - * True if this platform supports measuring _something_, i.e. it's - * not using the stub implementation. - */ - static bool canMeasureSomething(); -}; - -/* Inject a Javascript wrapper around the above C++ class into the - * Javascript object passed as an argument (this will normally be a - * global object). The JS-visible API is identical to the C++ API. - */ -extern JS_FRIEND_API(JSObject*) - RegisterPerfMeasurement(JSContext* cx, JS::HandleObject global); - -/* - * Given a Value which contains an instance of the aforementioned - * wrapper class, extract the C++ object. Returns nullptr if the - * Value is not an instance of the wrapper. - */ -extern JS_FRIEND_API(PerfMeasurement*) - ExtractPerfMeasurement(const Value& wrapper); - -} // namespace JS - -#endif /* perf_jsperf_h */ diff --git a/android/x86/include/spidermonkey/jsprf.h b/android/x86/include/spidermonkey/jsprf.h deleted file mode 100644 index b84b5a5c..00000000 --- a/android/x86/include/spidermonkey/jsprf.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsprf_h -#define jsprf_h - -/* -** API for PR printf like routines. Supports the following formats -** %d - decimal -** %u - unsigned decimal -** %x - unsigned hex -** %X - unsigned uppercase hex -** %o - unsigned octal -** %hd, %hu, %hx, %hX, %ho - "short" versions of above -** %ld, %lu, %lx, %lX, %lo - "long" versions of above -** %lld, %llu, %llx, %llX, %llo - "long long" versions of above -** %zd, %zo, %zu, %zx, %zX - size_t versions of above -** %Id, %Io, %Iu, %Ix, %IX - size_t versions of above (for Windows compat) -** You should use PRI*SIZE macros instead -** %s - string -** %c - character -** %p - pointer (deals with machine dependent pointer size) -** %f - float -** %g - float -*/ - -#include "mozilla/IntegerPrintfMacros.h" -#include "mozilla/SizePrintfMacros.h" - -#include - -#include "jstypes.h" - -/* -** sprintf into a malloc'd buffer. Return a pointer to the malloc'd -** buffer on success, nullptr on failure. Call "JS_smprintf_free" to release -** the memory returned. -*/ -extern JS_PUBLIC_API(char*) JS_smprintf(const char* fmt, ...) - MOZ_FORMAT_PRINTF(1, 2); - -/* -** Free the memory allocated, for the caller, by JS_smprintf -*/ -extern JS_PUBLIC_API(void) JS_smprintf_free(char* mem); - -/* -** "append" sprintf into a malloc'd buffer. "last" is the last value of -** the malloc'd buffer. sprintf will append data to the end of last, -** growing it as necessary using realloc. If last is nullptr, JS_sprintf_append -** will allocate the initial string. The return value is the new value of -** last for subsequent calls, or nullptr if there is a malloc failure. -*/ -extern JS_PUBLIC_API(char*) JS_sprintf_append(char* last, const char* fmt, ...) - MOZ_FORMAT_PRINTF(2, 3); - -/* -** va_list forms of the above. -*/ -extern JS_PUBLIC_API(char*) JS_vsmprintf(const char* fmt, va_list ap); -extern JS_PUBLIC_API(char*) JS_vsprintf_append(char* last, const char* fmt, va_list ap); - -#endif /* jsprf_h */ diff --git a/android/x86/include/spidermonkey/jsprototypes.h b/android/x86/include/spidermonkey/jsprototypes.h deleted file mode 100644 index f409dce9..00000000 --- a/android/x86/include/spidermonkey/jsprototypes.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsprototypes_h -#define jsprototypes_h - -/* A higher-order macro for enumerating all JSProtoKey values. */ -/* - * Consumers define macros as follows: - * macro(name, code, init, clasp) - * name: The canonical name of the class. - * code: The enumerator code. There are part of the XDR API, and must not change. - * init: Initialization function. These are |extern "C";|, and clients should use - * |extern "C" {}| as appropriate when using this macro. - * clasp: The JSClass for this object, or "dummy" if it doesn't exist. - * - * - * Consumers wishing to iterate over all the JSProtoKey values, can use - * JS_FOR_EACH_PROTOTYPE. However, there are certain values that don't correspond - * to real constructors, like Null or constructors that are disabled via - * preprocessor directives. We still need to include these in the JSProtoKey list - * in order to maintain binary XDR compatibility, but we need to provide a tool - * to handle them differently. JS_FOR_PROTOTYPES fills this niche. - * - * Consumers pass two macros to JS_FOR_PROTOTYPES - |real| and |imaginary|. The - * former is invoked for entries that have real client-exposed constructors, and - * the latter is called for the rest. Consumers that don't care about this - * distinction can simply pass the same macro to both, which is exactly what - * JS_FOR_EACH_PROTOTYPE does. - */ - -#define CLASP(name) (&name##Class) -#define OCLASP(name) (&name##Object::class_) -#define TYPED_ARRAY_CLASP(type) (&TypedArrayObject::classes[Scalar::type]) -#define ERROR_CLASP(type) (&ErrorObject::classes[type]) - -#ifdef EXPOSE_INTL_API -#define IF_INTL(real,imaginary) real -#else -#define IF_INTL(real,imaginary) imaginary -#endif - -#ifdef ENABLE_BINARYDATA -#define IF_BDATA(real,imaginary) real -#else -#define IF_BDATA(real,imaginary) imaginary -#endif - -#ifdef ENABLE_SIMD -# define IF_SIMD(real,imaginary) real -#else -# define IF_SIMD(real,imaginary) imaginary -#endif - -#ifdef ENABLE_SHARED_ARRAY_BUFFER -#define IF_SAB(real,imaginary) real -#else -#define IF_SAB(real,imaginary) imaginary -#endif - -#ifdef SPIDERMONKEY_PROMISE -#define IF_PROMISE(real,imaginary) real -#else -#define IF_PROMISE(real,imaginary) imaginary -#endif - -#define JS_FOR_PROTOTYPES(real,imaginary) \ - imaginary(Null, 0, InitNullClass, dummy) \ - real(Object, 1, InitViaClassSpec, OCLASP(Plain)) \ - real(Function, 2, InitViaClassSpec, &JSFunction::class_) \ - real(Array, 3, InitViaClassSpec, OCLASP(Array)) \ - real(Boolean, 4, InitBooleanClass, OCLASP(Boolean)) \ - real(JSON, 5, InitJSONClass, CLASP(JSON)) \ - real(Date, 6, InitViaClassSpec, OCLASP(Date)) \ - real(Math, 7, InitMathClass, CLASP(Math)) \ - real(Number, 8, InitNumberClass, OCLASP(Number)) \ - real(String, 9, InitStringClass, OCLASP(String)) \ - real(RegExp, 10, InitViaClassSpec, OCLASP(RegExp)) \ - real(Error, 11, InitViaClassSpec, ERROR_CLASP(JSEXN_ERR)) \ - real(InternalError, 12, InitViaClassSpec, ERROR_CLASP(JSEXN_INTERNALERR)) \ - real(EvalError, 13, InitViaClassSpec, ERROR_CLASP(JSEXN_EVALERR)) \ - real(RangeError, 14, InitViaClassSpec, ERROR_CLASP(JSEXN_RANGEERR)) \ - real(ReferenceError, 15, InitViaClassSpec, ERROR_CLASP(JSEXN_REFERENCEERR)) \ - real(SyntaxError, 16, InitViaClassSpec, ERROR_CLASP(JSEXN_SYNTAXERR)) \ - real(TypeError, 17, InitViaClassSpec, ERROR_CLASP(JSEXN_TYPEERR)) \ - real(URIError, 18, InitViaClassSpec, ERROR_CLASP(JSEXN_URIERR)) \ - real(DebuggeeWouldRun, 19, InitViaClassSpec, ERROR_CLASP(JSEXN_DEBUGGEEWOULDRUN)) \ - real(CompileError, 20, InitViaClassSpec, ERROR_CLASP(JSEXN_WASMCOMPILEERROR)) \ - real(RuntimeError, 21, InitViaClassSpec, ERROR_CLASP(JSEXN_WASMRUNTIMEERROR)) \ - real(Iterator, 22, InitLegacyIteratorClass,OCLASP(PropertyIterator)) \ - real(StopIteration, 23, InitStopIterationClass, OCLASP(StopIteration)) \ - real(ArrayBuffer, 24, InitViaClassSpec, OCLASP(ArrayBuffer)) \ - real(Int8Array, 25, InitViaClassSpec, TYPED_ARRAY_CLASP(Int8)) \ - real(Uint8Array, 26, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint8)) \ - real(Int16Array, 27, InitViaClassSpec, TYPED_ARRAY_CLASP(Int16)) \ - real(Uint16Array, 28, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint16)) \ - real(Int32Array, 29, InitViaClassSpec, TYPED_ARRAY_CLASP(Int32)) \ - real(Uint32Array, 30, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint32)) \ - real(Float32Array, 31, InitViaClassSpec, TYPED_ARRAY_CLASP(Float32)) \ - real(Float64Array, 32, InitViaClassSpec, TYPED_ARRAY_CLASP(Float64)) \ - real(Uint8ClampedArray, 33, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint8Clamped)) \ - real(Proxy, 34, InitProxyClass, js::ProxyClassPtr) \ - real(WeakMap, 35, InitWeakMapClass, OCLASP(WeakMap)) \ - real(Map, 36, InitMapClass, OCLASP(Map)) \ - real(Set, 37, InitSetClass, OCLASP(Set)) \ - real(DataView, 38, InitDataViewClass, OCLASP(DataView)) \ - real(Symbol, 39, InitSymbolClass, OCLASP(Symbol)) \ -IF_SAB(real,imaginary)(SharedArrayBuffer, 40, InitViaClassSpec, OCLASP(SharedArrayBuffer)) \ -IF_INTL(real,imaginary) (Intl, 41, InitIntlClass, CLASP(Intl)) \ -IF_BDATA(real,imaginary)(TypedObject, 42, InitTypedObjectModuleObject, OCLASP(TypedObjectModule)) \ - real(Reflect, 43, InitReflect, nullptr) \ -IF_SIMD(real,imaginary)(SIMD, 44, InitSimdClass, OCLASP(Simd)) \ - real(WeakSet, 45, InitWeakSetClass, OCLASP(WeakSet)) \ - real(TypedArray, 46, InitViaClassSpec, &js::TypedArrayObject::sharedTypedArrayPrototypeClass) \ -IF_SAB(real,imaginary)(Atomics, 47, InitAtomicsClass, OCLASP(Atomics)) \ - real(SavedFrame, 48, InitViaClassSpec, &js::SavedFrame::class_) \ - real(WebAssembly, 49, InitWebAssemblyClass, CLASP(WebAssembly)) \ - imaginary(WasmModule, 50, dummy, dummy) \ - imaginary(WasmInstance, 51, dummy, dummy) \ - imaginary(WasmMemory, 52, dummy, dummy) \ - imaginary(WasmTable, 53, dummy, dummy) \ -IF_PROMISE(real,imaginary)(Promise, 54, InitViaClassSpec, OCLASP(Promise)) \ - -#define JS_FOR_EACH_PROTOTYPE(macro) JS_FOR_PROTOTYPES(macro,macro) - -#endif /* jsprototypes_h */ diff --git a/android/x86/include/spidermonkey/jspubtd.h b/android/x86/include/spidermonkey/jspubtd.h deleted file mode 100644 index 309b9d74..00000000 --- a/android/x86/include/spidermonkey/jspubtd.h +++ /dev/null @@ -1,476 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jspubtd_h -#define jspubtd_h - -/* - * JS public API typedefs. - */ - -#include "mozilla/Assertions.h" -#include "mozilla/EnumeratedArray.h" -#include "mozilla/LinkedList.h" -#include "mozilla/PodOperations.h" - -#include "jsprototypes.h" -#include "jstypes.h" - -#include "js/TraceKind.h" -#include "js/TypeDecls.h" - -#if defined(JS_GC_ZEAL) || defined(DEBUG) -# define JSGC_HASH_TABLE_CHECKS -#endif - -namespace JS { - -class AutoIdVector; -class CallArgs; - -template -class Rooted; - -class JS_FRIEND_API(CompileOptions); -class JS_FRIEND_API(ReadOnlyCompileOptions); -class JS_FRIEND_API(OwningCompileOptions); -class JS_FRIEND_API(TransitiveCompileOptions); -class JS_PUBLIC_API(CompartmentOptions); - -struct RootingContext; -class Value; -struct Zone; - -namespace shadow { -struct Runtime; -} // namespace shadow - -} // namespace JS - -namespace js { -class RootLists; -} // namespace js - -/* - * Run-time version enumeration. For compile-time version checking, please use - * the JS_HAS_* macros in jsversion.h, or use MOZJS_MAJOR_VERSION, - * MOZJS_MINOR_VERSION, MOZJS_PATCH_VERSION, and MOZJS_ALPHA definitions. - */ -enum JSVersion { - JSVERSION_ECMA_3 = 148, - JSVERSION_1_6 = 160, - JSVERSION_1_7 = 170, - JSVERSION_1_8 = 180, - JSVERSION_ECMA_5 = 185, - JSVERSION_DEFAULT = 0, - JSVERSION_UNKNOWN = -1, - JSVERSION_LATEST = JSVERSION_ECMA_5 -}; - -/* Result of typeof operator enumeration. */ -enum JSType { - JSTYPE_VOID, /* undefined */ - JSTYPE_OBJECT, /* object */ - JSTYPE_FUNCTION, /* function */ - JSTYPE_STRING, /* string */ - JSTYPE_NUMBER, /* number */ - JSTYPE_BOOLEAN, /* boolean */ - JSTYPE_NULL, /* null */ - JSTYPE_SYMBOL, /* symbol */ - JSTYPE_LIMIT -}; - -/* Dense index into cached prototypes and class atoms for standard objects. */ -enum JSProtoKey { -#define PROTOKEY_AND_INITIALIZER(name,code,init,clasp) JSProto_##name = code, - JS_FOR_EACH_PROTOTYPE(PROTOKEY_AND_INITIALIZER) -#undef PROTOKEY_AND_INITIALIZER - JSProto_LIMIT -}; - -/* Struct forward declarations. */ -struct JSClass; -struct JSCompartment; -struct JSCrossCompartmentCall; -class JSErrorReport; -struct JSExceptionState; -struct JSFunctionSpec; -struct JSLocaleCallbacks; -struct JSObjectMap; -struct JSPrincipals; -struct JSPropertyName; -struct JSPropertySpec; -struct JSRuntime; -struct JSSecurityCallbacks; -struct JSStructuredCloneCallbacks; -struct JSStructuredCloneReader; -struct JSStructuredCloneWriter; -class JS_PUBLIC_API(JSTracer); - -class JSFlatString; - -typedef bool (*JSInitCallback)(void); - -template struct JSConstScalarSpec; -typedef JSConstScalarSpec JSConstDoubleSpec; -typedef JSConstScalarSpec JSConstIntegerSpec; - -/* - * Generic trace operation that calls JS::TraceEdge on each traceable thing's - * location reachable from data. - */ -typedef void -(* JSTraceDataOp)(JSTracer* trc, void* data); - -namespace js { -namespace gc { -class AutoTraceSession; -class StoreBuffer; -} // namespace gc - -// Whether the current thread is permitted access to any part of the specified -// runtime or zone. -JS_FRIEND_API(bool) -CurrentThreadCanAccessRuntime(const JSRuntime* rt); - -#ifdef DEBUG -JS_FRIEND_API(bool) -CurrentThreadIsPerformingGC(); -#endif - -} // namespace js - -namespace JS { - -class JS_PUBLIC_API(AutoEnterCycleCollection); -class JS_PUBLIC_API(AutoAssertOnBarrier); -struct JS_PUBLIC_API(PropertyDescriptor); - -typedef void (*OffThreadCompileCallback)(void* token, void* callbackData); - -enum class HeapState { - Idle, // doing nothing with the GC heap - Tracing, // tracing the GC heap without collecting, e.g. IterateCompartments() - MajorCollecting, // doing a GC of the major heap - MinorCollecting, // doing a GC of the minor heap (nursery) - CycleCollecting // in the "Unlink" phase of cycle collection -}; - -namespace shadow { - -struct Runtime -{ - private: - JS::HeapState heapState_; - - protected: - void setHeapState(JS::HeapState newState) { - MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(asRuntime())); - MOZ_ASSERT(heapState_ != newState); - heapState_ = newState; - } - - JS::HeapState heapState() const { - MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(asRuntime()) || - js::CurrentThreadIsPerformingGC()); - return heapState_; - } - - // In some cases, invoking GC barriers (incremental or otherwise) will break - // things. These barriers assert if this flag is set. - bool allowGCBarriers_; - friend class JS::AutoAssertOnBarrier; - - js::gc::StoreBuffer* gcStoreBufferPtr_; - - // The gray bits can become invalid if UnmarkGray overflows the stack. A - // full GC will reset this bit, since it fills in all the gray bits. - bool gcGrayBitsValid_; - - public: - Runtime() - : heapState_(JS::HeapState::Idle) - , allowGCBarriers_(true) - , gcStoreBufferPtr_(nullptr) - , gcGrayBitsValid_(false) - {} - - bool isHeapBusy() const { return heapState() != JS::HeapState::Idle; } - bool isHeapTracing() const { return heapState() == JS::HeapState::Tracing; } - bool isHeapMajorCollecting() const { return heapState() == JS::HeapState::MajorCollecting; } - bool isHeapMinorCollecting() const { return heapState() == JS::HeapState::MinorCollecting; } - bool isHeapCollecting() const { return isHeapMinorCollecting() || isHeapMajorCollecting(); } - bool isCycleCollecting() const { - return heapState() == JS::HeapState::CycleCollecting; - } - - bool allowGCBarriers() const { return allowGCBarriers_; } - - js::gc::StoreBuffer* gcStoreBufferPtr() { return gcStoreBufferPtr_; } - - bool areGCGrayBitsValid() const { return gcGrayBitsValid_; } - void setGCGrayBitsValid(bool valid) { gcGrayBitsValid_ = valid; } - - const JSRuntime* asRuntime() const { - return reinterpret_cast(this); - } - - static JS::shadow::Runtime* asShadowRuntime(JSRuntime* rt) { - return reinterpret_cast(rt); - } - - protected: - void setGCStoreBufferPtr(js::gc::StoreBuffer* storeBuffer) { - gcStoreBufferPtr_ = storeBuffer; - } -}; - -} /* namespace shadow */ - -// Decorates the Unlinking phase of CycleCollection so that accidental use -// of barriered accessors results in assertions instead of leaks. -class MOZ_STACK_CLASS JS_PUBLIC_API(AutoEnterCycleCollection) -{ -#ifdef DEBUG - JSRuntime* runtime; - - public: - explicit AutoEnterCycleCollection(JSContext* cx); - ~AutoEnterCycleCollection(); -#else - public: - explicit AutoEnterCycleCollection(JSContext* cx) {} - ~AutoEnterCycleCollection() {} -#endif -}; - -class JS_PUBLIC_API(AutoGCRooter) -{ - public: - AutoGCRooter(JSContext* cx, ptrdiff_t tag); - AutoGCRooter(JS::RootingContext* cx, ptrdiff_t tag); - - ~AutoGCRooter() { - MOZ_ASSERT(this == *stackTop); - *stackTop = down; - } - - /* Implemented in gc/RootMarking.cpp. */ - inline void trace(JSTracer* trc); - static void traceAll(JSTracer* trc); - static void traceAllWrappers(JSTracer* trc); - - protected: - AutoGCRooter * const down; - - /* - * Discriminates actual subclass of this being used. If non-negative, the - * subclass roots an array of values of the length stored in this field. - * If negative, meaning is indicated by the corresponding value in the enum - * below. Any other negative value indicates some deeper problem such as - * memory corruption. - */ - ptrdiff_t tag_; - - enum { - VALARRAY = -2, /* js::AutoValueArray */ - PARSER = -3, /* js::frontend::Parser */ - VALVECTOR = -10, /* js::AutoValueVector */ - IDVECTOR = -11, /* js::AutoIdVector */ - OBJVECTOR = -14, /* js::AutoObjectVector */ - IONMASM = -19, /* js::jit::MacroAssembler */ - WRAPVECTOR = -20, /* js::AutoWrapperVector */ - WRAPPER = -21, /* js::AutoWrapperRooter */ - CUSTOM = -26 /* js::CustomAutoRooter */ - }; - - static ptrdiff_t GetTag(const Value& value) { return VALVECTOR; } - static ptrdiff_t GetTag(const jsid& id) { return IDVECTOR; } - static ptrdiff_t GetTag(JSObject* obj) { return OBJVECTOR; } - - private: - AutoGCRooter ** const stackTop; - - /* No copy or assignment semantics. */ - AutoGCRooter(AutoGCRooter& ida) = delete; - void operator=(AutoGCRooter& ida) = delete; -}; - -// Our instantiations of Rooted and PersistentRooted require an -// instantiation of MapTypeToRootKind. -template <> -struct MapTypeToRootKind { - static const RootKind kind = RootKind::Traceable; -}; - -} /* namespace JS */ - -namespace js { - -class ExclusiveContext; - -/* - * This list enumerates the different types of conceptual stacks we have in - * SpiderMonkey. In reality, they all share the C stack, but we allow different - * stack limits depending on the type of code running. - */ -enum StackKind -{ - StackForSystemCode, // C++, such as the GC, running on behalf of the VM. - StackForTrustedScript, // Script running with trusted principals. - StackForUntrustedScript, // Script running with untrusted principals. - StackKindCount -}; - -using RootedListHeads = mozilla::EnumeratedArray*>; - -// Abstracts JS rooting mechanisms so they can be shared between the JSContext -// and JSRuntime. -class RootLists -{ - // Stack GC roots for Rooted GC heap pointers. - RootedListHeads stackRoots_; - template friend class JS::Rooted; - - // Stack GC roots for AutoFooRooter classes. - JS::AutoGCRooter* autoGCRooters_; - friend class JS::AutoGCRooter; - - // Heap GC roots for PersistentRooted pointers. - mozilla::EnumeratedArray>> heapRoots_; - template friend class JS::PersistentRooted; - - public: - RootLists() : autoGCRooters_(nullptr) { - for (auto& stackRootPtr : stackRoots_) - stackRootPtr = nullptr; - } - - ~RootLists() { - // The semantics of PersistentRooted containing pointers and tagged - // pointers are somewhat different from those of PersistentRooted - // containing a structure with a trace method. PersistentRooted - // containing pointers are allowed to outlive the owning RootLists, - // whereas those containing a traceable structure are not. - // - // The purpose of this feature is to support lazy initialization of - // global references for the several places in Gecko that do not have - // access to a tighter context, but that still need to refer to GC - // pointers. For such pointers, FinishPersistentRootedChains ensures - // that the contained references are nulled out when the owning - // RootLists dies to prevent UAF errors. - // - // However, for RootKind::Traceable, we do not know the concrete type - // of the held thing, so we simply cannot do this without accruing - // extra overhead and complexity for all users for a case that is - // unlikely to ever be used in practice. For this reason, the following - // assertion disallows usage of PersistentRooted that - // outlives the RootLists. - MOZ_ASSERT(heapRoots_[JS::RootKind::Traceable].isEmpty()); - } - - void traceStackRoots(JSTracer* trc); - void checkNoGCRooters(); - - void tracePersistentRoots(JSTracer* trc); - void finishPersistentRoots(); -}; - -} // namespace js - -namespace JS { - -/* - * JS::RootingContext is a base class of ContextFriendFields and JSContext. - * This class can be used to let code construct a Rooted<> or PersistentRooted<> - * instance, without giving it full access to the JSContext. - */ -struct RootingContext -{ - js::RootLists roots; - -#ifdef DEBUG - // Whether the derived class is a JSContext or an ExclusiveContext. - bool isJSContext; -#endif - - explicit RootingContext(bool isJSContextArg) -#ifdef DEBUG - : isJSContext(isJSContextArg) -#endif - {} - - static RootingContext* get(JSContext* cx) { - return reinterpret_cast(cx); - } -}; - -} // namespace JS - -namespace js { - -struct ContextFriendFields : public JS::RootingContext -{ - protected: - /* The current compartment. */ - JSCompartment* compartment_; - - /* The current zone. */ - JS::Zone* zone_; - - public: - /* Limit pointer for checking native stack consumption. */ - uintptr_t nativeStackLimit[js::StackKindCount]; - - explicit ContextFriendFields(bool isJSContext); - - static const ContextFriendFields* get(const JSContext* cx) { - return reinterpret_cast(cx); - } - - static ContextFriendFields* get(JSContext* cx) { - return reinterpret_cast(cx); - } - - friend JSCompartment* GetContextCompartment(const JSContext* cx); - friend JS::Zone* GetContextZone(const JSContext* cx); - template friend class JS::Rooted; -}; - -/* - * Inlinable accessors for JSContext. - * - * - These must not be available on the more restricted superclasses of - * JSContext, so we can't simply define them on ContextFriendFields. - * - * - They're perfectly ordinary JSContext functionality, so ought to be - * usable without resorting to jsfriendapi.h, and when JSContext is an - * incomplete type. - */ -inline JSCompartment* -GetContextCompartment(const JSContext* cx) -{ - return ContextFriendFields::get(cx)->compartment_; -} - -inline JS::Zone* -GetContextZone(const JSContext* cx) -{ - return ContextFriendFields::get(cx)->zone_; -} - -} /* namespace js */ - -MOZ_BEGIN_EXTERN_C - -// Defined in NSPR prio.h. -typedef struct PRFileDesc PRFileDesc; - -MOZ_END_EXTERN_C - -#endif /* jspubtd_h */ diff --git a/android/x86/include/spidermonkey/jstypes.h b/android/x86/include/spidermonkey/jstypes.h deleted file mode 100644 index 914674ab..00000000 --- a/android/x86/include/spidermonkey/jstypes.h +++ /dev/null @@ -1,219 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -/* -** File: jstypes.h -** Description: Definitions of NSPR's basic types -** -** Prototypes and macros used to make up for deficiencies in ANSI environments -** that we have found. -** -** Since we do not wrap and all the other standard headers, authors -** of portable code will not know in general that they need these definitions. -** Instead of requiring these authors to find the dependent uses in their code -** and take the following steps only in those C files, we take steps once here -** for all C files. -**/ - -#ifndef jstypes_h -#define jstypes_h - -#include "mozilla/Attributes.h" -#include "mozilla/Casting.h" -#include "mozilla/Types.h" - -// jstypes.h is (or should be!) included by every file in SpiderMonkey. -// js-config.h and jsversion.h also should be included by every file. -// So include them here. -// XXX: including them in js/RequiredDefines.h should be a better option, since -// that is by definition the header file that should be included in all -// SpiderMonkey code. However, Gecko doesn't do this! See bug 909576. -#include "js-config.h" -#include "jsversion.h" - -/*********************************************************************** -** MACROS: JS_EXTERN_API -** JS_EXPORT_API -** DESCRIPTION: -** These are only for externally visible routines and globals. For -** internal routines, just use "extern" for type checking and that -** will not export internal cross-file or forward-declared symbols. -** Define a macro for declaring procedures return types. We use this to -** deal with windoze specific type hackery for DLL definitions. Use -** JS_EXTERN_API when the prototype for the method is declared. Use -** JS_EXPORT_API for the implementation of the method. -** -** Example: -** in dowhim.h -** JS_EXTERN_API( void ) DoWhatIMean( void ); -** in dowhim.c -** JS_EXPORT_API( void ) DoWhatIMean( void ) { return; } -** -** -***********************************************************************/ - -#define JS_EXTERN_API(type) extern MOZ_EXPORT type -#define JS_EXPORT_API(type) MOZ_EXPORT type -#define JS_EXPORT_DATA(type) MOZ_EXPORT type -#define JS_IMPORT_API(type) MOZ_IMPORT_API type -#define JS_IMPORT_DATA(type) MOZ_IMPORT_DATA type - -/* - * The linkage of JS API functions differs depending on whether the file is - * used within the JS library or not. Any source file within the JS - * interpreter should define EXPORT_JS_API whereas any client of the library - * should not. STATIC_JS_API is used to build JS as a static library. - */ -#if defined(STATIC_JS_API) -# define JS_PUBLIC_API(t) t -# define JS_PUBLIC_DATA(t) t -# define JS_FRIEND_API(t) t -# define JS_FRIEND_DATA(t) t -#elif defined(EXPORT_JS_API) || defined(STATIC_EXPORTABLE_JS_API) -# define JS_PUBLIC_API(t) MOZ_EXPORT t -# define JS_PUBLIC_DATA(t) MOZ_EXPORT t -# define JS_FRIEND_API(t) MOZ_EXPORT t -# define JS_FRIEND_DATA(t) MOZ_EXPORT t -#else -# define JS_PUBLIC_API(t) MOZ_IMPORT_API t -# define JS_PUBLIC_DATA(t) MOZ_IMPORT_DATA t -# define JS_FRIEND_API(t) MOZ_IMPORT_API t -# define JS_FRIEND_DATA(t) MOZ_IMPORT_DATA t -#endif - -#if defined(_MSC_VER) && defined(_M_IX86) -#define JS_FASTCALL __fastcall -#elif defined(__GNUC__) && defined(__i386__) -#define JS_FASTCALL __attribute__((fastcall)) -#else -#define JS_FASTCALL -#define JS_NO_FASTCALL -#endif - -/*********************************************************************** -** MACROS: JS_BEGIN_MACRO -** JS_END_MACRO -** DESCRIPTION: -** Macro body brackets so that macros with compound statement definitions -** behave syntactically more like functions when called. -***********************************************************************/ -#define JS_BEGIN_MACRO do { - -#if defined(_MSC_VER) -# define JS_END_MACRO \ - } __pragma(warning(push)) __pragma(warning(disable:4127)) \ - while (0) __pragma(warning(pop)) -#else -# define JS_END_MACRO } while (0) -#endif - -/*********************************************************************** -** MACROS: JS_BIT -** JS_BITMASK -** DESCRIPTION: -** Bit masking macros. XXX n must be <= 31 to be portable -***********************************************************************/ -#define JS_BIT(n) ((uint32_t)1 << (n)) -#define JS_BITMASK(n) (JS_BIT(n) - 1) - -/*********************************************************************** -** MACROS: JS_HOWMANY -** JS_ROUNDUP -** DESCRIPTION: -** Commonly used macros for operations on compatible types. -***********************************************************************/ -#define JS_HOWMANY(x,y) (((x)+(y)-1)/(y)) -#define JS_ROUNDUP(x,y) (JS_HOWMANY(x,y)*(y)) - -#include "jscpucfg.h" - -/* - * Define JS_64BIT iff we are building in an environment with 64-bit - * addresses. - */ -#ifdef _MSC_VER -# if defined(_M_X64) || defined(_M_AMD64) -# define JS_64BIT -# endif -#elif defined(__GNUC__) -/* Additional GCC defines are when running on Solaris, AIX, and HPUX */ -# if defined(__x86_64__) || defined(__sparcv9) || \ - defined(__64BIT__) || defined(__LP64__) -# define JS_64BIT -# endif -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Sun Studio C/C++ */ -# if defined(__x86_64) || defined(__sparcv9) -# define JS_64BIT -# endif -#elif defined(__xlc__) || defined(__xlC__) /* IBM XL C/C++ */ -# if defined(__64BIT__) -# define JS_64BIT -# endif -#elif defined(__HP_cc) || defined(__HP_aCC) /* HP-UX cc/aCC */ -# if defined(__LP64__) -# define JS_64BIT -# endif -#else -# error "Implement me" -#endif - -/*********************************************************************** -** MACROS: JS_ARRAY_LENGTH -** JS_ARRAY_END -** DESCRIPTION: -** Macros to get the number of elements and the pointer to one past the -** last element of a C array. Use them like this: -** -** char16_t buf[10]; -** JSString* str; -** ... -** for (char16_t* s = buf; s != JS_ARRAY_END(buf); ++s) *s = ...; -** ... -** str = JS_NewStringCopyN(cx, buf, JS_ARRAY_LENGTH(buf)); -** ... -** -***********************************************************************/ - -#define JS_ARRAY_LENGTH(array) (sizeof (array) / sizeof (array)[0]) -#define JS_ARRAY_END(array) ((array) + JS_ARRAY_LENGTH(array)) - -#define JS_BITS_PER_BYTE 8 -#define JS_BITS_PER_BYTE_LOG2 3 - -#if defined(JS_64BIT) -# define JS_BITS_PER_WORD 64 -#else -# define JS_BITS_PER_WORD 32 -#endif - -/*********************************************************************** -** MACROS: JS_FUNC_TO_DATA_PTR -** JS_DATA_TO_FUNC_PTR -** DESCRIPTION: -** Macros to convert between function and data pointers of the same -** size. Use them like this: -** -** JSGetterOp nativeGetter; -** JSObject* scriptedGetter; -** ... -** scriptedGetter = JS_FUNC_TO_DATA_PTR(JSObject*, nativeGetter); -** ... -** nativeGetter = JS_DATA_TO_FUNC_PTR(JSGetterOp, scriptedGetter); -** -***********************************************************************/ - -#define JS_FUNC_TO_DATA_PTR(type, fun) (mozilla::BitwiseCast(fun)) -#define JS_DATA_TO_FUNC_PTR(type, ptr) (mozilla::BitwiseCast(ptr)) - -#ifdef __GNUC__ -# define JS_EXTENSION __extension__ -# define JS_EXTENSION_(s) __extension__ ({ s; }) -#else -# define JS_EXTENSION -# define JS_EXTENSION_(s) s -#endif - -#endif /* jstypes_h */ diff --git a/android/x86/include/spidermonkey/jsversion.h b/android/x86/include/spidermonkey/jsversion.h deleted file mode 100644 index 8bdfe47b..00000000 --- a/android/x86/include/spidermonkey/jsversion.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jsversion_h -#define jsversion_h - -/* - * JS Capability Macros. - */ -#define JS_HAS_STR_HTML_HELPERS 1 /* (no longer used) */ -#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ -#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */ -#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */ -#define JS_HAS_CATCH_GUARD 1 /* has exception handling catch guard */ -#define JS_HAS_UNEVAL 1 /* has uneval() top-level function */ -#define JS_HAS_CONST 1 /* (no longer used) */ -#define JS_HAS_FUN_EXPR_STMT 1 /* (no longer used) */ -#define JS_HAS_FOR_EACH_IN 1 /* has for each (lhs in iterable) */ -#define JS_HAS_GENERATORS 1 /* (no longer used) */ -#define JS_HAS_BLOCK_SCOPE 1 /* (no longer used) */ -#define JS_HAS_DESTRUCTURING 2 /* (no longer used) */ -#define JS_HAS_GENERATOR_EXPRS 1 /* (no longer used) */ -#define JS_HAS_EXPR_CLOSURES 1 /* has function (formals) listexpr */ - -/* (no longer used) */ -#define JS_HAS_NEW_GLOBAL_OBJECT 1 - -/* (no longer used) */ -#define JS_HAS_DESTRUCTURING_SHORTHAND (JS_HAS_DESTRUCTURING == 2) - -/* - * Feature for Object.prototype.__{define,lookup}{G,S}etter__ legacy support; - * support likely to be made opt-in at some future time. - */ -#define JS_OLD_GETTER_SETTER_METHODS 1 - -#endif /* jsversion_h */ diff --git a/android/x86/include/spidermonkey/jswrapper.h b/android/x86/include/spidermonkey/jswrapper.h deleted file mode 100644 index 9b14c59e..00000000 --- a/android/x86/include/spidermonkey/jswrapper.h +++ /dev/null @@ -1,382 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jswrapper_h -#define jswrapper_h - -#include "mozilla/Attributes.h" - -#include "js/Proxy.h" - -namespace js { - -/* - * Helper for Wrapper::New default options. - * - * Callers of Wrapper::New() who wish to specify a prototype for the created - * Wrapper, *MUST* construct a WrapperOptions with a JSContext. - */ -class MOZ_STACK_CLASS WrapperOptions : public ProxyOptions { - public: - WrapperOptions() : ProxyOptions(false), - proto_() - {} - - explicit WrapperOptions(JSContext* cx) : ProxyOptions(false), - proto_() - { - proto_.emplace(cx); - } - - inline JSObject* proto() const; - WrapperOptions& setProto(JSObject* protoArg) { - MOZ_ASSERT(proto_); - *proto_ = protoArg; - return *this; - } - - private: - mozilla::Maybe proto_; -}; - -/* - * A wrapper is a proxy with a target object to which it generally forwards - * operations, but may restrict access to certain operations or augment those - * operations in various ways. - * - * A wrapper can be "unwrapped" in C++, exposing the underlying object. - * Callers should be careful to avoid unwrapping security wrappers in the wrong - * context. - * - * Important: If you add a method implementation here, you probably also need - * to add an override in CrossCompartmentWrapper. If you don't, you risk - * compartment mismatches. See bug 945826 comment 0. - */ -class JS_FRIEND_API(Wrapper) : public BaseProxyHandler -{ - unsigned mFlags; - - public: - explicit constexpr Wrapper(unsigned aFlags, bool aHasPrototype = false, - bool aHasSecurityPolicy = false) - : BaseProxyHandler(&family, aHasPrototype, aHasSecurityPolicy), - mFlags(aFlags) - { } - - virtual bool finalizeInBackground(const Value& priv) const override; - - /* Standard internal methods. */ - virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id, - MutableHandle desc) const override; - virtual bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id, - Handle desc, - ObjectOpResult& result) const override; - virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy, - AutoIdVector& props) const override; - virtual bool delete_(JSContext* cx, HandleObject proxy, HandleId id, - ObjectOpResult& result) const override; - virtual bool enumerate(JSContext* cx, HandleObject proxy, - MutableHandleObject objp) const override; - virtual bool getPrototype(JSContext* cx, HandleObject proxy, - MutableHandleObject protop) const override; - virtual bool setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto, - ObjectOpResult& result) const override; - virtual bool getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy, bool* isOrdinary, - MutableHandleObject protop) const override; - virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy, - bool* succeeded) const override; - virtual bool preventExtensions(JSContext* cx, HandleObject proxy, - ObjectOpResult& result) const override; - virtual bool isExtensible(JSContext* cx, HandleObject proxy, bool* extensible) const override; - virtual bool has(JSContext* cx, HandleObject proxy, HandleId id, - bool* bp) const override; - virtual bool get(JSContext* cx, HandleObject proxy, HandleValue receiver, - HandleId id, MutableHandleValue vp) const override; - virtual bool set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v, - HandleValue receiver, ObjectOpResult& result) const override; - virtual bool call(JSContext* cx, HandleObject proxy, const CallArgs& args) const override; - virtual bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const override; - - /* SpiderMonkey extensions. */ - virtual bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id, - MutableHandle desc) const override; - virtual bool hasOwn(JSContext* cx, HandleObject proxy, HandleId id, - bool* bp) const override; - virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject proxy, - AutoIdVector& props) const override; - virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl, - const CallArgs& args) const override; - virtual bool hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v, - bool* bp) const override; - virtual bool getBuiltinClass(JSContext* cx, HandleObject proxy, ESClass* cls) const override; - virtual bool isArray(JSContext* cx, HandleObject proxy, - JS::IsArrayAnswer* answer) const override; - virtual const char* className(JSContext* cx, HandleObject proxy) const override; - virtual JSString* fun_toString(JSContext* cx, HandleObject proxy, - unsigned indent) const override; - virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, - RegExpGuard* g) const override; - virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, - MutableHandleValue vp) const override; - virtual bool isCallable(JSObject* obj) const override; - virtual bool isConstructor(JSObject* obj) const override; - virtual JSObject* weakmapKeyDelegate(JSObject* proxy) const override; - - public: - using BaseProxyHandler::Action; - - enum Flags { - CROSS_COMPARTMENT = 1 << 0, - LAST_USED_FLAG = CROSS_COMPARTMENT - }; - - static JSObject* New(JSContext* cx, JSObject* obj, const Wrapper* handler, - const WrapperOptions& options = WrapperOptions()); - - static JSObject* Renew(JSContext* cx, JSObject* existing, JSObject* obj, const Wrapper* handler); - - static const Wrapper* wrapperHandler(JSObject* wrapper); - - static JSObject* wrappedObject(JSObject* wrapper); - - unsigned flags() const { - return mFlags; - } - - static const char family; - static const Wrapper singleton; - static const Wrapper singletonWithPrototype; - - static JSObject* defaultProto; -}; - -inline JSObject* -WrapperOptions::proto() const -{ - return proto_ ? *proto_ : Wrapper::defaultProto; -} - -/* Base class for all cross compartment wrapper handlers. */ -class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper -{ - public: - explicit constexpr CrossCompartmentWrapper(unsigned aFlags, bool aHasPrototype = false, - bool aHasSecurityPolicy = false) - : Wrapper(CROSS_COMPARTMENT | aFlags, aHasPrototype, aHasSecurityPolicy) - { } - - /* Standard internal methods. */ - virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id, - MutableHandle desc) const override; - virtual bool defineProperty(JSContext* cx, HandleObject wrapper, HandleId id, - Handle desc, - ObjectOpResult& result) const override; - virtual bool ownPropertyKeys(JSContext* cx, HandleObject wrapper, - AutoIdVector& props) const override; - virtual bool delete_(JSContext* cx, HandleObject wrapper, HandleId id, - ObjectOpResult& result) const override; - virtual bool enumerate(JSContext* cx, HandleObject wrapper, MutableHandleObject objp) const override; - virtual bool getPrototype(JSContext* cx, HandleObject proxy, - MutableHandleObject protop) const override; - virtual bool setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto, - ObjectOpResult& result) const override; - - virtual bool getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy, bool* isOrdinary, - MutableHandleObject protop) const override; - virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy, - bool* succeeded) const override; - virtual bool preventExtensions(JSContext* cx, HandleObject wrapper, - ObjectOpResult& result) const override; - virtual bool isExtensible(JSContext* cx, HandleObject wrapper, bool* extensible) const override; - virtual bool has(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp) const override; - virtual bool get(JSContext* cx, HandleObject wrapper, HandleValue receiver, - HandleId id, MutableHandleValue vp) const override; - virtual bool set(JSContext* cx, HandleObject wrapper, HandleId id, HandleValue v, - HandleValue receiver, ObjectOpResult& result) const override; - virtual bool call(JSContext* cx, HandleObject wrapper, const CallArgs& args) const override; - virtual bool construct(JSContext* cx, HandleObject wrapper, const CallArgs& args) const override; - - /* SpiderMonkey extensions. */ - virtual bool getPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id, - MutableHandle desc) const override; - virtual bool hasOwn(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp) const override; - virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject wrapper, - AutoIdVector& props) const override; - virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl, - const CallArgs& args) const override; - virtual bool hasInstance(JSContext* cx, HandleObject wrapper, MutableHandleValue v, - bool* bp) const override; - virtual const char* className(JSContext* cx, HandleObject proxy) const override; - virtual JSString* fun_toString(JSContext* cx, HandleObject wrapper, - unsigned indent) const override; - virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const override; - virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const override; - - // Allocate CrossCompartmentWrappers in the nursery. - virtual bool canNurseryAllocate() const override { return true; } - - static const CrossCompartmentWrapper singleton; - static const CrossCompartmentWrapper singletonWithPrototype; -}; - -class JS_FRIEND_API(OpaqueCrossCompartmentWrapper) : public CrossCompartmentWrapper -{ - public: - explicit constexpr OpaqueCrossCompartmentWrapper() : CrossCompartmentWrapper(0) - { } - - /* Standard internal methods. */ - virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id, - MutableHandle desc) const override; - virtual bool defineProperty(JSContext* cx, HandleObject wrapper, HandleId id, - Handle desc, - ObjectOpResult& result) const override; - virtual bool ownPropertyKeys(JSContext* cx, HandleObject wrapper, - AutoIdVector& props) const override; - virtual bool delete_(JSContext* cx, HandleObject wrapper, HandleId id, - ObjectOpResult& result) const override; - virtual bool enumerate(JSContext* cx, HandleObject wrapper, - MutableHandleObject objp) const override; - virtual bool getPrototype(JSContext* cx, HandleObject wrapper, - MutableHandleObject protop) const override; - virtual bool setPrototype(JSContext* cx, HandleObject wrapper, HandleObject proto, - ObjectOpResult& result) const override; - virtual bool getPrototypeIfOrdinary(JSContext* cx, HandleObject wrapper, bool* isOrdinary, - MutableHandleObject protop) const override; - virtual bool setImmutablePrototype(JSContext* cx, HandleObject wrapper, - bool* succeeded) const override; - virtual bool preventExtensions(JSContext* cx, HandleObject wrapper, - ObjectOpResult& result) const override; - virtual bool isExtensible(JSContext* cx, HandleObject wrapper, bool* extensible) const override; - virtual bool has(JSContext* cx, HandleObject wrapper, HandleId id, - bool* bp) const override; - virtual bool get(JSContext* cx, HandleObject wrapper, HandleValue receiver, - HandleId id, MutableHandleValue vp) const override; - virtual bool set(JSContext* cx, HandleObject wrapper, HandleId id, HandleValue v, - HandleValue receiver, ObjectOpResult& result) const override; - virtual bool call(JSContext* cx, HandleObject wrapper, const CallArgs& args) const override; - virtual bool construct(JSContext* cx, HandleObject wrapper, const CallArgs& args) const override; - - /* SpiderMonkey extensions. */ - virtual bool getPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id, - MutableHandle desc) const override; - virtual bool hasOwn(JSContext* cx, HandleObject wrapper, HandleId id, - bool* bp) const override; - virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject wrapper, - AutoIdVector& props) const override; - virtual bool getBuiltinClass(JSContext* cx, HandleObject wrapper, ESClass* cls) const override; - virtual bool isArray(JSContext* cx, HandleObject obj, - JS::IsArrayAnswer* answer) const override; - virtual const char* className(JSContext* cx, HandleObject wrapper) const override; - virtual JSString* fun_toString(JSContext* cx, HandleObject proxy, unsigned indent) const override; - - static const OpaqueCrossCompartmentWrapper singleton; -}; - -/* - * Base class for security wrappers. A security wrapper is potentially hiding - * all or part of some wrapped object thus SecurityWrapper defaults to denying - * access to the wrappee. This is the opposite of Wrapper which tries to be - * completely transparent. - * - * NB: Currently, only a few ProxyHandler operations are overridden to deny - * access, relying on derived SecurityWrapper to block access when necessary. - */ -template -class JS_FRIEND_API(SecurityWrapper) : public Base -{ - public: - explicit constexpr SecurityWrapper(unsigned flags, bool hasPrototype = false) - : Base(flags, hasPrototype, /* hasSecurityPolicy = */ true) - { } - - virtual bool enter(JSContext* cx, HandleObject wrapper, HandleId id, Wrapper::Action act, - bool* bp) const override; - - virtual bool defineProperty(JSContext* cx, HandleObject wrapper, HandleId id, - Handle desc, - ObjectOpResult& result) const override; - virtual bool isExtensible(JSContext* cx, HandleObject wrapper, bool* extensible) const override; - virtual bool preventExtensions(JSContext* cx, HandleObject wrapper, - ObjectOpResult& result) const override; - virtual bool setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto, - ObjectOpResult& result) const override; - virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy, bool* succeeded) const override; - - virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl, - const CallArgs& args) const override; - virtual bool getBuiltinClass(JSContext* cx, HandleObject wrapper, ESClass* cls) const override; - virtual bool isArray(JSContext* cx, HandleObject wrapper, JS::IsArrayAnswer* answer) const override; - virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const override; - virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const override; - - // Allow isCallable and isConstructor. They used to be class-level, and so could not be guarded - // against. - - virtual bool watch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, - JS::HandleObject callable) const override; - virtual bool unwatch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id) const override; - - /* - * Allow our subclasses to select the superclass behavior they want without - * needing to specify an exact superclass. - */ - typedef Base Permissive; - typedef SecurityWrapper Restrictive; -}; - -typedef SecurityWrapper CrossCompartmentSecurityWrapper; - -extern JSObject* -TransparentObjectWrapper(JSContext* cx, HandleObject existing, HandleObject obj); - -inline bool -IsWrapper(JSObject* obj) -{ - return IsProxy(obj) && GetProxyHandler(obj)->family() == &Wrapper::family; -} - -// Given a JSObject, returns that object stripped of wrappers. If -// stopAtWindowProxy is true, then this returns the WindowProxy if it was -// previously wrapped. Otherwise, this returns the first object for -// which JSObject::isWrapper returns false. -JS_FRIEND_API(JSObject*) -UncheckedUnwrap(JSObject* obj, bool stopAtWindowProxy = true, unsigned* flagsp = nullptr); - -// Given a JSObject, returns that object stripped of wrappers. At each stage, -// the security wrapper has the opportunity to veto the unwrap. If -// stopAtWindowProxy is true, then this returns the WindowProxy if it was -// previously wrapped. -JS_FRIEND_API(JSObject*) -CheckedUnwrap(JSObject* obj, bool stopAtWindowProxy = true); - -// Unwrap only the outermost security wrapper, with the same semantics as -// above. This is the checked version of Wrapper::wrappedObject. -JS_FRIEND_API(JSObject*) -UnwrapOneChecked(JSObject* obj, bool stopAtWindowProxy = true); - -JS_FRIEND_API(bool) -IsCrossCompartmentWrapper(JSObject* obj); - -void -NukeCrossCompartmentWrapper(JSContext* cx, JSObject* wrapper); - -void -RemapWrapper(JSContext* cx, JSObject* wobj, JSObject* newTarget); - -JS_FRIEND_API(bool) -RemapAllWrappersForObject(JSContext* cx, JSObject* oldTarget, - JSObject* newTarget); - -// API to recompute all cross-compartment wrappers whose source and target -// match the given filters. -JS_FRIEND_API(bool) -RecomputeWrappers(JSContext* cx, const CompartmentFilter& sourceFilter, - const CompartmentFilter& targetFilter); - -} /* namespace js */ - -#endif /* jswrapper_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Alignment.h b/android/x86/include/spidermonkey/mozilla/Alignment.h deleted file mode 100644 index 4fcda4f3..00000000 --- a/android/x86/include/spidermonkey/mozilla/Alignment.h +++ /dev/null @@ -1,154 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Functionality related to memory alignment. */ - -#ifndef mozilla_Alignment_h -#define mozilla_Alignment_h - -#include "mozilla/Attributes.h" -#include -#include - -namespace mozilla { - -/* - * This class, and the corresponding macro MOZ_ALIGNOF, figures out how many - * bytes of alignment a given type needs. - */ -template -class AlignmentFinder -{ - struct Aligner - { - char mChar; - T mT; - }; - -public: - static const size_t alignment = sizeof(Aligner) - sizeof(T); -}; - -#define MOZ_ALIGNOF(T) mozilla::AlignmentFinder::alignment - -/* - * Declare the MOZ_ALIGNED_DECL macro for declaring aligned types. - * - * For instance, - * - * MOZ_ALIGNED_DECL(char arr[2], 8); - * - * will declare a two-character array |arr| aligned to 8 bytes. - */ - -#if defined(__GNUC__) -# define MOZ_ALIGNED_DECL(_type, _align) \ - _type __attribute__((aligned(_align))) -#elif defined(_MSC_VER) -# define MOZ_ALIGNED_DECL(_type, _align) \ - __declspec(align(_align)) _type -#else -# warning "We don't know how to align variables on this compiler." -# define MOZ_ALIGNED_DECL(_type, _align) _type -#endif - -/* - * AlignedElem is a structure whose alignment is guaranteed to be at least N - * bytes. - * - * We support 1, 2, 4, 8, and 16-bit alignment. - */ -template -struct AlignedElem; - -/* - * We have to specialize this template because GCC doesn't like - * __attribute__((aligned(foo))) where foo is a template parameter. - */ - -template<> -struct AlignedElem<1> -{ - MOZ_ALIGNED_DECL(uint8_t elem, 1); -}; - -template<> -struct AlignedElem<2> -{ - MOZ_ALIGNED_DECL(uint8_t elem, 2); -}; - -template<> -struct AlignedElem<4> -{ - MOZ_ALIGNED_DECL(uint8_t elem, 4); -}; - -template<> -struct AlignedElem<8> -{ - MOZ_ALIGNED_DECL(uint8_t elem, 8); -}; - -template<> -struct AlignedElem<16> -{ - MOZ_ALIGNED_DECL(uint8_t elem, 16); -}; - -/* - * This utility pales in comparison to Boost's aligned_storage. The utility - * simply assumes that uint64_t is enough alignment for anyone. This may need - * to be extended one day... - * - * As an important side effect, pulling the storage into this template is - * enough obfuscation to confuse gcc's strict-aliasing analysis into not giving - * false negatives when we cast from the char buffer to whatever type we've - * constructed using the bytes. - */ -template -struct AlignedStorage -{ - union U - { - char mBytes[Nbytes]; - uint64_t mDummy; - } u; - - const void* addr() const { return u.mBytes; } - void* addr() { return u.mBytes; } - - AlignedStorage() = default; - - // AlignedStorage is non-copyable: the default copy constructor violates - // strict aliasing rules, per bug 1269319. - AlignedStorage(const AlignedStorage&) = delete; - void operator=(const AlignedStorage&) = delete; -}; - -template -struct MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS AlignedStorage2 -{ - union U - { - char mBytes[sizeof(T)]; - uint64_t mDummy; - } u; - - const T* addr() const { return reinterpret_cast(u.mBytes); } - T* addr() { return static_cast(static_cast(u.mBytes)); } - - AlignedStorage2() = default; - - // AlignedStorage2 is non-copyable: the default copy constructor violates - // strict aliasing rules, per bug 1269319. - AlignedStorage2(const AlignedStorage2&) = delete; - void operator=(const AlignedStorage2&) = delete; -}; - -} /* namespace mozilla */ - -#endif /* mozilla_Alignment_h */ diff --git a/android/x86/include/spidermonkey/mozilla/AllocPolicy.h b/android/x86/include/spidermonkey/mozilla/AllocPolicy.h deleted file mode 100644 index 81f62b03..00000000 --- a/android/x86/include/spidermonkey/mozilla/AllocPolicy.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * An allocation policy concept, usable for structures and algorithms to - * control how memory is allocated and how failures are handled. - */ - -#ifndef mozilla_AllocPolicy_h -#define mozilla_AllocPolicy_h - -#include "mozilla/Attributes.h" -#include "mozilla/TemplateLib.h" - -#include -#include - -namespace mozilla { - -/* - * Allocation policies are used to implement the standard allocation behaviors - * in a customizable way. Additionally, custom behaviors may be added to these - * behaviors, such as additionally reporting an error through an out-of-band - * mechanism when OOM occurs. The concept modeled here is as follows: - * - * - public copy constructor, assignment, destructor - * - template T* maybe_pod_malloc(size_t) - * Fallible, but doesn't report an error on OOM. - * - template T* maybe_pod_calloc(size_t) - * Fallible, but doesn't report an error on OOM. - * - template T* maybe_pod_realloc(T*, size_t, size_t) - * Fallible, but doesn't report an error on OOM. The old allocation - * size is passed in, in addition to the new allocation size requested. - * - template T* pod_malloc(size_t) - * Responsible for OOM reporting when null is returned. - * - template T* pod_calloc(size_t) - * Responsible for OOM reporting when null is returned. - * - template T* pod_realloc(T*, size_t, size_t) - * Responsible for OOM reporting when null is returned. The old allocation - * size is passed in, in addition to the new allocation size requested. - * - void free_(void*) - * - void reportAllocOverflow() const - * Called on allocation overflow (that is, an allocation implicitly tried - * to allocate more than the available memory space -- think allocating an - * array of large-size objects, where N * size overflows) before null is - * returned. - * - bool checkSimulatedOOM() const - * Some clients generally allocate memory yet in some circumstances won't - * need to do so. For example, appending to a vector with a small amount of - * inline storage generally allocates memory, but no allocation occurs - * unless appending exceeds inline storage. But for testing purposes, it - * can be useful to treat *every* operation as allocating. - * Clients (such as this hypothetical append method implementation) should - * call this method in situations that don't allocate, but could generally, - * to support this. The default behavior should return true; more - * complicated behavior might be to return false only after a certain - * number of allocations-or-check-simulated-OOMs (coordinating with the - * other AllocPolicy methods) have occurred. - * - * mfbt provides (and typically uses by default) only MallocAllocPolicy, which - * does nothing more than delegate to the malloc/alloc/free functions. - */ - -/* - * A policy that straightforwardly uses malloc/calloc/realloc/free and adds no - * extra behaviors. - */ -class MallocAllocPolicy -{ -public: - template - T* maybe_pod_malloc(size_t aNumElems) - { - if (aNumElems & mozilla::tl::MulOverflowMask::value) { - return nullptr; - } - return static_cast(malloc(aNumElems * sizeof(T))); - } - - template - T* maybe_pod_calloc(size_t aNumElems) - { - return static_cast(calloc(aNumElems, sizeof(T))); - } - - template - T* maybe_pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) - { - if (aNewSize & mozilla::tl::MulOverflowMask::value) { - return nullptr; - } - return static_cast(realloc(aPtr, aNewSize * sizeof(T))); - } - - template - T* pod_malloc(size_t aNumElems) - { - return maybe_pod_malloc(aNumElems); - } - - template - T* pod_calloc(size_t aNumElems) - { - return maybe_pod_calloc(aNumElems); - } - - template - T* pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) - { - return maybe_pod_realloc(aPtr, aOldSize, aNewSize); - } - - void free_(void* aPtr) - { - free(aPtr); - } - - void reportAllocOverflow() const - { - } - - MOZ_MUST_USE bool checkSimulatedOOM() const - { - return true; - } -}; - -} // namespace mozilla - -#endif /* mozilla_AllocPolicy_h */ diff --git a/android/x86/include/spidermonkey/mozilla/AlreadyAddRefed.h b/android/x86/include/spidermonkey/mozilla/AlreadyAddRefed.h deleted file mode 100644 index 0d7b0cae..00000000 --- a/android/x86/include/spidermonkey/mozilla/AlreadyAddRefed.h +++ /dev/null @@ -1,147 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Typed temporary pointers for reference-counted smart pointers. */ - -#ifndef AlreadyAddRefed_h -#define AlreadyAddRefed_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" - -namespace mozilla { - -struct unused_t; - -} // namespace mozilla - -/** - * already_AddRefed cooperates with reference counting smart pointers to enable - * you to assign in a pointer _without_ |AddRef|ing it. You might want to use - * this as a return type from a function that returns an already |AddRef|ed - * pointer. - * - * TODO Move already_AddRefed to namespace mozilla. This has not yet been done - * because of the sheer number of usages of already_AddRefed. - */ -template -struct MOZ_MUST_USE_TYPE MOZ_NON_AUTOABLE already_AddRefed -{ - /* - * We want to allow returning nullptr from functions returning - * already_AddRefed, for simplicity. But we also don't want to allow - * returning raw T*, instead preferring creation of already_AddRefed from - * a reference counting smart pointer. - * - * We address the latter requirement by making the (T*) constructor explicit. - * But |return nullptr| won't consider an explicit constructor, so we need - * another constructor to handle it. Plain old (decltype(nullptr)) doesn't - * cut it, because if nullptr is emulated as __null (with type int or long), - * passing nullptr to an int/long parameter triggers compiler warnings. We - * need a type that no one can pass accidentally; a pointer-to-member-function - * (where no such function exists) does the trick nicely. - * - * That handles the return-value case. What about for locals, argument types, - * and so on? |already_AddRefed(nullptr)| considers both overloads (and - * the (already_AddRefed&&) overload as well!), so there's an ambiguity. - * We can target true nullptr using decltype(nullptr), but we can't target - * emulated nullptr the same way, because passing __null to an int/long - * parameter triggers compiler warnings. So just give up on this, and provide - * this behavior through the default constructor. - * - * We can revert to simply explicit (T*) and implicit (decltype(nullptr)) when - * nullptr no longer needs to be emulated to support the ancient b2g compiler. - * (The () overload could also be removed, if desired, if we changed callers.) - */ - already_AddRefed() : mRawPtr(nullptr) {} - - // The return and argument types here are arbitrarily selected so no - // corresponding member function exists. - typedef void (already_AddRefed::* MatchNullptr)(double, float); - MOZ_IMPLICIT already_AddRefed(MatchNullptr aRawPtr) : mRawPtr(nullptr) {} - - explicit already_AddRefed(T* aRawPtr) : mRawPtr(aRawPtr) {} - - // Disallow copy constructor and copy assignment operator: move semantics used instead. - already_AddRefed(const already_AddRefed& aOther) = delete; - already_AddRefed& operator=(const already_AddRefed& aOther) = delete; - - already_AddRefed(already_AddRefed&& aOther) : mRawPtr(aOther.take()) {} - - already_AddRefed& operator=(already_AddRefed&& aOther) - { - mRawPtr = aOther.take(); - return *this; - } - - /** - * This helper is useful in cases like - * - * already_AddRefed - * Foo() - * { - * RefPtr x = ...; - * return x.forget(); - * } - * - * The autoconversion allows one to omit the idiom - * - * RefPtr y = x.forget(); - * return y.forget(); - * - * Note that nsRefPtr is the XPCOM reference counting smart pointer class. - */ - template - MOZ_IMPLICIT already_AddRefed(already_AddRefed&& aOther) : mRawPtr(aOther.take()) {} - - ~already_AddRefed() { MOZ_ASSERT(!mRawPtr); } - - // Specialize the unused operator<< for already_AddRefed, to allow - // nsCOMPtr foo; - // Unused << foo.forget(); - // Note that nsCOMPtr is the XPCOM reference counting smart pointer class. - friend void operator<<(const mozilla::unused_t& aUnused, - const already_AddRefed& aRhs) - { - auto mutableAlreadyAddRefed = const_cast*>(&aRhs); - aUnused << mutableAlreadyAddRefed->take(); - } - - MOZ_MUST_USE T* take() - { - T* rawPtr = mRawPtr; - mRawPtr = nullptr; - return rawPtr; - } - - /** - * This helper provides a static_cast replacement for already_AddRefed, so - * if you have - * - * already_AddRefed F(); - * - * you can write - * - * already_AddRefed - * G() - * { - * return F().downcast(); - * } - */ - template - already_AddRefed downcast() - { - U* tmp = static_cast(mRawPtr); - mRawPtr = nullptr; - return already_AddRefed(tmp); - } - -private: - T* MOZ_OWNING_REF mRawPtr; -}; - -#endif // AlreadyAddRefed_h diff --git a/android/x86/include/spidermonkey/mozilla/Array.h b/android/x86/include/spidermonkey/mozilla/Array.h deleted file mode 100644 index 72b89ede..00000000 --- a/android/x86/include/spidermonkey/mozilla/Array.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A compile-time constant-length array with bounds-checking assertions. */ - -#ifndef mozilla_Array_h -#define mozilla_Array_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" -#include "mozilla/ReverseIterator.h" - -#include - -namespace mozilla { - -template -class Array -{ - T mArr[Length]; - -public: - Array() {} - - template - MOZ_IMPLICIT Array(Args&&... aArgs) - : mArr{mozilla::Forward(aArgs)...} - { - static_assert(sizeof...(aArgs) == Length, - "The number of arguments should be equal to the template parameter Length"); - } - - T& operator[](size_t aIndex) - { - MOZ_ASSERT(aIndex < Length); - return mArr[aIndex]; - } - - const T& operator[](size_t aIndex) const - { - MOZ_ASSERT(aIndex < Length); - return mArr[aIndex]; - } - - typedef T* iterator; - typedef const T* const_iterator; - typedef ReverseIterator reverse_iterator; - typedef ReverseIterator const_reverse_iterator; - - // Methods for range-based for loops. - iterator begin() { return mArr; } - const_iterator begin() const { return mArr; } - const_iterator cbegin() const { return begin(); } - iterator end() { return mArr + Length; } - const_iterator end() const { return mArr + Length; } - const_iterator cend() const { return end(); } - - // Methods for reverse iterating. - reverse_iterator rbegin() { return reverse_iterator(end()); } - const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } - const_reverse_iterator crbegin() const { return rbegin(); } - reverse_iterator rend() { return reverse_iterator(begin()); } - const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } - const_reverse_iterator crend() const { return rend(); } -}; - -template -class Array -{ -public: - T& operator[](size_t aIndex) - { - MOZ_CRASH("indexing into zero-length array"); - } - - const T& operator[](size_t aIndex) const - { - MOZ_CRASH("indexing into zero-length array"); - } -}; - -} /* namespace mozilla */ - -#endif /* mozilla_Array_h */ diff --git a/android/x86/include/spidermonkey/mozilla/ArrayUtils.h b/android/x86/include/spidermonkey/mozilla/ArrayUtils.h deleted file mode 100644 index 50236ccb..00000000 --- a/android/x86/include/spidermonkey/mozilla/ArrayUtils.h +++ /dev/null @@ -1,194 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Implements various helper functions related to arrays. - */ - -#ifndef mozilla_ArrayUtils_h -#define mozilla_ArrayUtils_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -#include - -#ifdef __cplusplus - -#include "mozilla/Alignment.h" -#include "mozilla/Array.h" -#include "mozilla/EnumeratedArray.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -/* - * Safely subtract two pointers when it is known that aEnd >= aBegin, yielding a - * size_t result. - * - * Ordinary pointer subtraction yields a ptrdiff_t result, which, being signed, - * has insufficient range to express the distance between pointers at opposite - * ends of the address space. Furthermore, most compilers use ptrdiff_t to - * represent the intermediate byte address distance, before dividing by - * sizeof(T); if that intermediate result overflows, they'll produce results - * with the wrong sign even when the correct scaled distance would fit in a - * ptrdiff_t. - */ -template -MOZ_ALWAYS_INLINE size_t -PointerRangeSize(T* aBegin, T* aEnd) -{ - MOZ_ASSERT(aEnd >= aBegin); - return (size_t(aEnd) - size_t(aBegin)) / sizeof(T); -} - -/* - * Compute the length of an array with constant length. (Use of this method - * with a non-array pointer will not compile.) - * - * Beware of the implicit trailing '\0' when using this with string constants. - */ -template -constexpr size_t -ArrayLength(T (&aArr)[N]) -{ - return N; -} - -template -constexpr size_t -ArrayLength(const Array& aArr) -{ - return N; -} - -template -constexpr size_t -ArrayLength(const EnumeratedArray& aArr) -{ - return size_t(N); -} - -/* - * Compute the address one past the last element of a constant-length array. - * - * Beware of the implicit trailing '\0' when using this with string constants. - */ -template -constexpr T* -ArrayEnd(T (&aArr)[N]) -{ - return aArr + ArrayLength(aArr); -} - -template -constexpr T* -ArrayEnd(Array& aArr) -{ - return &aArr[0] + ArrayLength(aArr); -} - -template -constexpr const T* -ArrayEnd(const Array& aArr) -{ - return &aArr[0] + ArrayLength(aArr); -} - -namespace detail { - -template::value>> -struct AlignedChecker -{ - static void - test(const Pointee* aPtr) - { - MOZ_ASSERT((uintptr_t(aPtr) % MOZ_ALIGNOF(AlignType)) == 0, - "performing a range-check with a misaligned pointer"); - } -}; - -template -struct AlignedChecker -{ - static void - test(const Pointee* aPtr) - { - } -}; - -} // namespace detail - -/** - * Determines whether |aPtr| points at an object in the range [aBegin, aEnd). - * - * |aPtr| must have the same alignment as |aBegin| and |aEnd|. This usually - * should be achieved by ensuring |aPtr| points at a |U|, not just that it - * points at a |T|. - * - * It is a usage error for any argument to be misaligned. - * - * It's okay for T* to be void*, and if so U* may also be void*. In the latter - * case no argument is required to be aligned (obviously, as void* implies no - * particular alignment). - */ -template -inline typename EnableIf::value || - IsBaseOf::value || - IsVoid::value, - bool>::Type -IsInRange(const T* aPtr, const U* aBegin, const U* aEnd) -{ - MOZ_ASSERT(aBegin <= aEnd); - detail::AlignedChecker::test(aPtr); - detail::AlignedChecker::test(aBegin); - detail::AlignedChecker::test(aEnd); - return aBegin <= reinterpret_cast(aPtr) && - reinterpret_cast(aPtr) < aEnd; -} - -/** - * Convenience version of the above method when the valid range is specified as - * uintptr_t values. As above, |aPtr| must be aligned, and |aBegin| and |aEnd| - * must be aligned with respect to |T|. - */ -template -inline bool -IsInRange(const T* aPtr, uintptr_t aBegin, uintptr_t aEnd) -{ - return IsInRange(aPtr, - reinterpret_cast(aBegin), - reinterpret_cast(aEnd)); -} - -namespace detail { - -/* - * Helper for the MOZ_ARRAY_LENGTH() macro to make the length a typesafe - * compile-time constant even on compilers lacking constexpr support. - */ -template -char (&ArrayLengthHelper(T (&array)[N]))[N]; - -} /* namespace detail */ - -} /* namespace mozilla */ - -#endif /* __cplusplus */ - -/* - * MOZ_ARRAY_LENGTH() is an alternative to mozilla::ArrayLength() for C files - * that can't use C++ template functions and for static_assert() calls that - * can't call ArrayLength() when it is not a C++11 constexpr function. - */ -#ifdef __cplusplus -# define MOZ_ARRAY_LENGTH(array) sizeof(mozilla::detail::ArrayLengthHelper(array)) -#else -# define MOZ_ARRAY_LENGTH(array) (sizeof(array)/sizeof((array)[0])) -#endif - -#endif /* mozilla_ArrayUtils_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Assertions.h b/android/x86/include/spidermonkey/mozilla/Assertions.h deleted file mode 100644 index e978af3d..00000000 --- a/android/x86/include/spidermonkey/mozilla/Assertions.h +++ /dev/null @@ -1,585 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implementations of runtime and static assertion macros for C and C++. */ - -#ifndef mozilla_Assertions_h -#define mozilla_Assertions_h - -#if defined(MOZILLA_INTERNAL_API) && defined(__cplusplus) -#define MOZ_DUMP_ASSERTION_STACK -#endif - -#include "mozilla/Attributes.h" -#include "mozilla/Compiler.h" -#include "mozilla/Likely.h" -#include "mozilla/MacroArgs.h" -#include "mozilla/StaticAnalysisFunctions.h" -#include "mozilla/Types.h" -#ifdef MOZ_DUMP_ASSERTION_STACK -#include "nsTraceRefcnt.h" -#endif - -#if defined(MOZ_HAS_MOZGLUE) || defined(MOZILLA_INTERNAL_API) -/* - * The crash reason set by MOZ_CRASH_ANNOTATE is consumed by the crash reporter - * if present. It is declared here (and defined in Assertions.cpp) to make it - * available to all code, even libraries that don't link with the crash reporter - * directly. - */ -MOZ_BEGIN_EXTERN_C -extern MFBT_DATA const char* gMozCrashReason; -MOZ_END_EXTERN_C - -static inline void -AnnotateMozCrashReason(const char* reason) -{ - gMozCrashReason = reason; -} -# define MOZ_CRASH_ANNOTATE(...) AnnotateMozCrashReason(__VA_ARGS__) -#else -# define MOZ_CRASH_ANNOTATE(...) do { /* nothing */ } while (0) -#endif - -#include -#include -#include -#ifdef WIN32 - /* - * TerminateProcess and GetCurrentProcess are defined in , which - * further depends on . We hardcode these few definitions manually - * because those headers clutter the global namespace with a significant - * number of undesired macros and symbols. - */ -# ifdef __cplusplus -extern "C" { -# endif -__declspec(dllimport) int __stdcall -TerminateProcess(void* hProcess, unsigned int uExitCode); -__declspec(dllimport) void* __stdcall GetCurrentProcess(void); -# ifdef __cplusplus -} -# endif -#else -# include -#endif -#ifdef ANDROID -# include -#endif - -/* - * MOZ_STATIC_ASSERT may be used to assert a condition *at compile time* in C. - * In C++11, static_assert is provided by the compiler to the same effect. - * This can be useful when you make certain assumptions about what must hold for - * optimal, or even correct, behavior. For example, you might assert that the - * size of a struct is a multiple of the target architecture's word size: - * - * struct S { ... }; - * // C - * MOZ_STATIC_ASSERT(sizeof(S) % sizeof(size_t) == 0, - * "S should be a multiple of word size for efficiency"); - * // C++11 - * static_assert(sizeof(S) % sizeof(size_t) == 0, - * "S should be a multiple of word size for efficiency"); - * - * This macro can be used in any location where both an extern declaration and a - * typedef could be used. - */ -#ifndef __cplusplus - /* - * Some of the definitions below create an otherwise-unused typedef. This - * triggers compiler warnings with some versions of gcc, so mark the typedefs - * as permissibly-unused to disable the warnings. - */ -# if defined(__GNUC__) -# define MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) -# else -# define MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE /* nothing */ -# endif -# define MOZ_STATIC_ASSERT_GLUE1(x, y) x##y -# define MOZ_STATIC_ASSERT_GLUE(x, y) MOZ_STATIC_ASSERT_GLUE1(x, y) -# if defined(__SUNPRO_CC) - /* - * The Sun Studio C++ compiler is buggy when declaring, inside a function, - * another extern'd function with an array argument whose length contains a - * sizeof, triggering the error message "sizeof expression not accepted as - * size of array parameter". This bug (6688515, not public yet) would hit - * defining moz_static_assert as a function, so we always define an extern - * array for Sun Studio. - * - * We include the line number in the symbol name in a best-effort attempt - * to avoid conflicts (see below). - */ -# define MOZ_STATIC_ASSERT(cond, reason) \ - extern char MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __LINE__)[(cond) ? 1 : -1] -# elif defined(__COUNTER__) - /* - * If there was no preferred alternative, use a compiler-agnostic version. - * - * Note that the non-__COUNTER__ version has a bug in C++: it can't be used - * in both |extern "C"| and normal C++ in the same translation unit. (Alas - * |extern "C"| isn't allowed in a function.) The only affected compiler - * we really care about is gcc 4.2. For that compiler and others like it, - * we include the line number in the function name to do the best we can to - * avoid conflicts. These should be rare: a conflict would require use of - * MOZ_STATIC_ASSERT on the same line in separate files in the same - * translation unit, *and* the uses would have to be in code with - * different linkage, *and* the first observed use must be in C++-linkage - * code. - */ -# define MOZ_STATIC_ASSERT(cond, reason) \ - typedef int MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __COUNTER__)[(cond) ? 1 : -1] MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE -# else -# define MOZ_STATIC_ASSERT(cond, reason) \ - extern void MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __LINE__)(int arg[(cond) ? 1 : -1]) MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE -# endif - -#define MOZ_STATIC_ASSERT_IF(cond, expr, reason) MOZ_STATIC_ASSERT(!(cond) || (expr), reason) -#else -#define MOZ_STATIC_ASSERT_IF(cond, expr, reason) static_assert(!(cond) || (expr), reason) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Prints |aStr| as an assertion failure (using aFilename and aLine as the - * location of the assertion) to the standard debug-output channel. - * - * Usually you should use MOZ_ASSERT or MOZ_CRASH instead of this method. This - * method is primarily for internal use in this header, and only secondarily - * for use in implementing release-build assertions. - */ -static MOZ_COLD MOZ_ALWAYS_INLINE void -MOZ_ReportAssertionFailure(const char* aStr, const char* aFilename, int aLine) - MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS -{ -#ifdef ANDROID - __android_log_print(ANDROID_LOG_FATAL, "MOZ_Assert", - "Assertion failure: %s, at %s:%d\n", - aStr, aFilename, aLine); -#else - fprintf(stderr, "Assertion failure: %s, at %s:%d\n", aStr, aFilename, aLine); -#if defined (MOZ_DUMP_ASSERTION_STACK) - nsTraceRefcnt::WalkTheStack(stderr); -#endif - fflush(stderr); -#endif -} - -static MOZ_COLD MOZ_ALWAYS_INLINE void -MOZ_ReportCrash(const char* aStr, const char* aFilename, int aLine) - MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS -{ -#ifdef ANDROID - __android_log_print(ANDROID_LOG_FATAL, "MOZ_CRASH", - "Hit MOZ_CRASH(%s) at %s:%d\n", aStr, aFilename, aLine); -#else - fprintf(stderr, "Hit MOZ_CRASH(%s) at %s:%d\n", aStr, aFilename, aLine); -#if defined(MOZ_DUMP_ASSERTION_STACK) - nsTraceRefcnt::WalkTheStack(stderr); -#endif - fflush(stderr); -#endif -} - -/** - * MOZ_REALLY_CRASH is used in the implementation of MOZ_CRASH(). You should - * call MOZ_CRASH instead. - */ -#if defined(_MSC_VER) - /* - * On MSVC use the __debugbreak compiler intrinsic, which produces an inline - * (not nested in a system function) breakpoint. This distinctively invokes - * Breakpad without requiring system library symbols on all stack-processing - * machines, as a nested breakpoint would require. - * - * We use TerminateProcess with the exit code aborting would generate - * because we don't want to invoke atexit handlers, destructors, library - * unload handlers, and so on when our process might be in a compromised - * state. - * - * We don't use abort() because it'd cause Windows to annoyingly pop up the - * process error dialog multiple times. See bug 345118 and bug 426163. - * - * We follow TerminateProcess() with a call to MOZ_NoReturn() so that the - * compiler doesn't hassle us to provide a return statement after a - * MOZ_REALLY_CRASH() call. - * - * (Technically these are Windows requirements, not MSVC requirements. But - * practically you need MSVC for debugging, and we only ship builds created - * by MSVC, so doing it this way reduces complexity.) - */ - -__declspec(noreturn) __inline void MOZ_NoReturn() {} - -# ifdef __cplusplus -# define MOZ_REALLY_CRASH() \ - do { \ - ::__debugbreak(); \ - *((volatile int*) NULL) = __LINE__; \ - ::TerminateProcess(::GetCurrentProcess(), 3); \ - ::MOZ_NoReturn(); \ - } while (0) -# else -# define MOZ_REALLY_CRASH() \ - do { \ - __debugbreak(); \ - *((volatile int*) NULL) = __LINE__; \ - TerminateProcess(GetCurrentProcess(), 3); \ - MOZ_NoReturn(); \ - } while (0) -# endif -#else -# ifdef __cplusplus -# define MOZ_REALLY_CRASH() \ - do { \ - *((volatile int*) NULL) = __LINE__; \ - ::abort(); \ - } while (0) -# else -# define MOZ_REALLY_CRASH() \ - do { \ - *((volatile int*) NULL) = __LINE__; \ - abort(); \ - } while (0) -# endif -#endif - -/* - * MOZ_CRASH([explanation-string]) crashes the program, plain and simple, in a - * Breakpad-compatible way, in both debug and release builds. - * - * MOZ_CRASH is a good solution for "handling" failure cases when you're - * unwilling or unable to handle them more cleanly -- for OOM, for likely memory - * corruption, and so on. It's also a good solution if you need safe behavior - * in release builds as well as debug builds. But if the failure is one that - * should be debugged and fixed, MOZ_ASSERT is generally preferable. - * - * The optional explanation-string, if provided, must be a string literal - * explaining why we're crashing. This argument is intended for use with - * MOZ_CRASH() calls whose rationale is non-obvious; don't use it if it's - * obvious why we're crashing. - * - * If we're a DEBUG build and we crash at a MOZ_CRASH which provides an - * explanation-string, we print the string to stderr. Otherwise, we don't - * print anything; this is because we want MOZ_CRASH to be 100% safe in release - * builds, and it's hard to print to stderr safely when memory might have been - * corrupted. - */ -#ifndef DEBUG -# define MOZ_CRASH(...) \ - do { \ - MOZ_CRASH_ANNOTATE("MOZ_CRASH(" __VA_ARGS__ ")"); \ - MOZ_REALLY_CRASH(); \ - } while (0) -#else -# define MOZ_CRASH(...) \ - do { \ - MOZ_ReportCrash("" __VA_ARGS__, __FILE__, __LINE__); \ - MOZ_CRASH_ANNOTATE("MOZ_CRASH(" __VA_ARGS__ ")"); \ - MOZ_REALLY_CRASH(); \ - } while (0) -#endif - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -/* - * MOZ_ASSERT(expr [, explanation-string]) asserts that |expr| must be truthy in - * debug builds. If it is, execution continues. Otherwise, an error message - * including the expression and the explanation-string (if provided) is printed, - * an attempt is made to invoke any existing debugger, and execution halts. - * MOZ_ASSERT is fatal: no recovery is possible. Do not assert a condition - * which can correctly be falsy. - * - * The optional explanation-string, if provided, must be a string literal - * explaining the assertion. It is intended for use with assertions whose - * correctness or rationale is non-obvious, and for assertions where the "real" - * condition being tested is best described prosaically. Don't provide an - * explanation if it's not actually helpful. - * - * // No explanation needed: pointer arguments often must not be NULL. - * MOZ_ASSERT(arg); - * - * // An explanation can be helpful to explain exactly how we know an - * // assertion is valid. - * MOZ_ASSERT(state == WAITING_FOR_RESPONSE, - * "given that and , we must have..."); - * - * // Or it might disambiguate multiple identical (save for their location) - * // assertions of the same expression. - * MOZ_ASSERT(getSlot(PRIMITIVE_THIS_SLOT).isUndefined(), - * "we already set [[PrimitiveThis]] for this Boolean object"); - * MOZ_ASSERT(getSlot(PRIMITIVE_THIS_SLOT).isUndefined(), - * "we already set [[PrimitiveThis]] for this String object"); - * - * MOZ_ASSERT has no effect in non-debug builds. It is designed to catch bugs - * *only* during debugging, not "in the field". If you want the latter, use - * MOZ_RELEASE_ASSERT, which applies to non-debug builds as well. - * - * MOZ_DIAGNOSTIC_ASSERT works like MOZ_RELEASE_ASSERT in Nightly/Aurora and - * MOZ_ASSERT in Beta/Release - use this when a condition is potentially rare - * enough to require real user testing to hit, but is not security-sensitive. - * This can cause user pain, so use it sparingly. If a MOZ_DIAGNOSTIC_ASSERT - * is firing, it should promptly be converted to a MOZ_ASSERT while the failure - * is being investigated, rather than letting users suffer. - */ - -/* - * Implement MOZ_VALIDATE_ASSERT_CONDITION_TYPE, which is used to guard against - * accidentally passing something unintended in lieu of an assertion condition. - */ - -#ifdef __cplusplus -# include "mozilla/TypeTraits.h" -namespace mozilla { -namespace detail { - -template -struct AssertionConditionType -{ - typedef typename RemoveReference::Type ValueT; - static_assert(!IsArray::value, - "Expected boolean assertion condition, got an array or a " - "string!"); - static_assert(!IsFunction::value, - "Expected boolean assertion condition, got a function! Did " - "you intend to call that function?"); - static_assert(!IsFloatingPoint::value, - "It's often a bad idea to assert that a floating-point number " - "is nonzero, because such assertions tend to intermittently " - "fail. Shouldn't your code gracefully handle this case instead " - "of asserting? Anyway, if you really want to do that, write an " - "explicit boolean condition, like !!x or x!=0."); - - static const bool isValid = true; -}; - -} // namespace detail -} // namespace mozilla -# define MOZ_VALIDATE_ASSERT_CONDITION_TYPE(x) \ - static_assert(mozilla::detail::AssertionConditionType::isValid, \ - "invalid assertion condition") -#else -# define MOZ_VALIDATE_ASSERT_CONDITION_TYPE(x) -#endif - -/* First the single-argument form. */ -#define MOZ_ASSERT_HELPER1(expr) \ - do { \ - MOZ_VALIDATE_ASSERT_CONDITION_TYPE(expr); \ - if (MOZ_UNLIKELY(!MOZ_CHECK_ASSERT_ASSIGNMENT(expr))) { \ - MOZ_ReportAssertionFailure(#expr, __FILE__, __LINE__); \ - MOZ_CRASH_ANNOTATE("MOZ_RELEASE_ASSERT(" #expr ")"); \ - MOZ_REALLY_CRASH(); \ - } \ - } while (0) -/* Now the two-argument form. */ -#define MOZ_ASSERT_HELPER2(expr, explain) \ - do { \ - MOZ_VALIDATE_ASSERT_CONDITION_TYPE(expr); \ - if (MOZ_UNLIKELY(!MOZ_CHECK_ASSERT_ASSIGNMENT(expr))) { \ - MOZ_ReportAssertionFailure(#expr " (" explain ")", __FILE__, __LINE__); \ - MOZ_CRASH_ANNOTATE("MOZ_RELEASE_ASSERT(" #expr ") (" explain ")"); \ - MOZ_REALLY_CRASH(); \ - } \ - } while (0) - -#define MOZ_RELEASE_ASSERT_GLUE(a, b) a b -#define MOZ_RELEASE_ASSERT(...) \ - MOZ_RELEASE_ASSERT_GLUE( \ - MOZ_PASTE_PREFIX_AND_ARG_COUNT(MOZ_ASSERT_HELPER, __VA_ARGS__), \ - (__VA_ARGS__)) - -#ifdef DEBUG -# define MOZ_ASSERT(...) MOZ_RELEASE_ASSERT(__VA_ARGS__) -#else -# define MOZ_ASSERT(...) do { } while (0) -#endif /* DEBUG */ - -#ifdef RELEASE_OR_BETA -# define MOZ_DIAGNOSTIC_ASSERT MOZ_ASSERT -#else -# define MOZ_DIAGNOSTIC_ASSERT MOZ_RELEASE_ASSERT -#endif - -/* - * MOZ_ASSERT_IF(cond1, cond2) is equivalent to MOZ_ASSERT(cond2) if cond1 is - * true. - * - * MOZ_ASSERT_IF(isPrime(num), num == 2 || isOdd(num)); - * - * As with MOZ_ASSERT, MOZ_ASSERT_IF has effect only in debug builds. It is - * designed to catch bugs during debugging, not "in the field". - */ -#ifdef DEBUG -# define MOZ_ASSERT_IF(cond, expr) \ - do { \ - if (cond) { \ - MOZ_ASSERT(expr); \ - } \ - } while (0) -#else -# define MOZ_ASSERT_IF(cond, expr) do { } while (0) -#endif - -/* - * MOZ_ASSUME_UNREACHABLE_MARKER() expands to an expression which states that - * it is undefined behavior for execution to reach this point. No guarantees - * are made about what will happen if this is reached at runtime. Most code - * should use MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE because it has extra - * asserts. - */ -#if defined(__clang__) || defined(__GNUC__) -# define MOZ_ASSUME_UNREACHABLE_MARKER() __builtin_unreachable() -#elif defined(_MSC_VER) -# define MOZ_ASSUME_UNREACHABLE_MARKER() __assume(0) -#else -# ifdef __cplusplus -# define MOZ_ASSUME_UNREACHABLE_MARKER() ::abort() -# else -# define MOZ_ASSUME_UNREACHABLE_MARKER() abort() -# endif -#endif - -/* - * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE([reason]) tells the compiler that it - * can assume that the macro call cannot be reached during execution. This lets - * the compiler generate better-optimized code under some circumstances, at the - * expense of the program's behavior being undefined if control reaches the - * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE. - * - * In Gecko, you probably should not use this macro outside of performance- or - * size-critical code, because it's unsafe. If you don't care about code size - * or performance, you should probably use MOZ_ASSERT or MOZ_CRASH. - * - * SpiderMonkey is a different beast, and there it's acceptable to use - * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE more widely. - * - * Note that MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE is noreturn, so it's valid - * not to return a value following a MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE - * call. - * - * Example usage: - * - * enum ValueType { - * VALUE_STRING, - * VALUE_INT, - * VALUE_FLOAT - * }; - * - * int ptrToInt(ValueType type, void* value) { - * { - * // We know for sure that type is either INT or FLOAT, and we want this - * // code to run as quickly as possible. - * switch (type) { - * case VALUE_INT: - * return *(int*) value; - * case VALUE_FLOAT: - * return (int) *(float*) value; - * default: - * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unexpected ValueType"); - * } - * } - */ - -/* - * Unconditional assert in debug builds for (assumed) unreachable code paths - * that have a safe return without crashing in release builds. - */ -#define MOZ_ASSERT_UNREACHABLE(reason) \ - MOZ_ASSERT(false, "MOZ_ASSERT_UNREACHABLE: " reason) - -#define MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE(reason) \ - do { \ - MOZ_ASSERT_UNREACHABLE(reason); \ - MOZ_ASSUME_UNREACHABLE_MARKER(); \ - } while (0) - -/** - * MOZ_FALLTHROUGH_ASSERT is an annotation to suppress compiler warnings about - * switch cases that MOZ_ASSERT(false) (or its alias MOZ_ASSERT_UNREACHABLE) in - * debug builds, but intentionally fall through in release builds to handle - * unexpected values. - * - * Why do we need MOZ_FALLTHROUGH_ASSERT in addition to MOZ_FALLTHROUGH? In - * release builds, the MOZ_ASSERT(false) will expand to `do { } while (0)`, - * requiring a MOZ_FALLTHROUGH annotation to suppress a -Wimplicit-fallthrough - * warning. In debug builds, the MOZ_ASSERT(false) will expand to something like - * `if (true) { MOZ_CRASH(); }` and the MOZ_FALLTHROUGH annotation will cause - * a -Wunreachable-code warning. The MOZ_FALLTHROUGH_ASSERT macro breaks this - * warning stalemate. - * - * // Example before MOZ_FALLTHROUGH_ASSERT: - * switch (foo) { - * default: - * // This case wants to assert in debug builds, fall through in release. - * MOZ_ASSERT(false); // -Wimplicit-fallthrough warning in release builds! - * MOZ_FALLTHROUGH; // but -Wunreachable-code warning in debug builds! - * case 5: - * return 5; - * } - * - * // Example with MOZ_FALLTHROUGH_ASSERT: - * switch (foo) { - * default: - * // This case asserts in debug builds, falls through in release. - * MOZ_FALLTHROUGH_ASSERT("Unexpected foo value?!"); - * case 5: - * return 5; - * } - */ -#ifdef DEBUG -# define MOZ_FALLTHROUGH_ASSERT(reason) MOZ_CRASH("MOZ_FALLTHROUGH_ASSERT: " reason) -#else -# define MOZ_FALLTHROUGH_ASSERT(...) MOZ_FALLTHROUGH -#endif - -/* - * MOZ_ALWAYS_TRUE(expr) and MOZ_ALWAYS_FALSE(expr) always evaluate the provided - * expression, in debug builds and in release builds both. Then, in debug - * builds only, the value of the expression is asserted either true or false - * using MOZ_ASSERT. - */ -#ifdef DEBUG -# define MOZ_ALWAYS_TRUE(expr) \ - do { \ - if ((expr)) { \ - /* Do nothing. */ \ - } else { \ - MOZ_ASSERT(false, #expr); \ - } \ - } while (0) -# define MOZ_ALWAYS_FALSE(expr) \ - do { \ - if ((expr)) { \ - MOZ_ASSERT(false, #expr); \ - } else { \ - /* Do nothing. */ \ - } \ - } while (0) -#else -# define MOZ_ALWAYS_TRUE(expr) \ - do { \ - if ((expr)) { \ - /* Silence MOZ_MUST_USE. */ \ - } \ - } while (0) -# define MOZ_ALWAYS_FALSE(expr) \ - do { \ - if ((expr)) { \ - /* Silence MOZ_MUST_USE. */ \ - } \ - } while (0) -#endif - -#undef MOZ_DUMP_ASSERTION_STACK -#undef MOZ_CRASH_CRASHREPORT - -#endif /* mozilla_Assertions_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Atomics.h b/android/x86/include/spidermonkey/mozilla/Atomics.h deleted file mode 100644 index 213d1b9f..00000000 --- a/android/x86/include/spidermonkey/mozilla/Atomics.h +++ /dev/null @@ -1,800 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Implements (almost always) lock-free atomic operations. The operations here - * are a subset of that which can be found in C++11's header, with a - * different API to enforce consistent memory ordering constraints. - * - * Anyone caught using |volatile| for inter-thread memory safety needs to be - * sent a copy of this header and the C++11 standard. - */ - -#ifndef mozilla_Atomics_h -#define mozilla_Atomics_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Compiler.h" -#include "mozilla/TypeTraits.h" - -#include - -/* - * Our minimum deployment target on clang/OS X is OS X 10.6, whose SDK - * does not have . So be sure to check for support - * along with C++0x support. - */ -#if defined(_MSC_VER) -# define MOZ_HAVE_CXX11_ATOMICS -#elif defined(__clang__) || defined(__GNUC__) - /* - * Clang doesn't like from libstdc++ before 4.7 due to the - * loose typing of the atomic builtins. GCC 4.5 and 4.6 lacks inline - * definitions for unspecialized std::atomic and causes linking errors. - * Therefore, we require at least 4.7.0 for using libstdc++. - * - * libc++ is only functional with clang. - */ -# if MOZ_USING_LIBSTDCXX && MOZ_LIBSTDCXX_VERSION_AT_LEAST(4, 7, 0) -# define MOZ_HAVE_CXX11_ATOMICS -# elif MOZ_USING_LIBCXX && defined(__clang__) -# define MOZ_HAVE_CXX11_ATOMICS -# endif -#endif - -namespace mozilla { - -/** - * An enum of memory ordering possibilities for atomics. - * - * Memory ordering is the observable state of distinct values in memory. - * (It's a separate concept from atomicity, which concerns whether an - * operation can ever be observed in an intermediate state. Don't - * conflate the two!) Given a sequence of operations in source code on - * memory, it is *not* always the case that, at all times and on all - * cores, those operations will appear to have occurred in that exact - * sequence. First, the compiler might reorder that sequence, if it - * thinks another ordering will be more efficient. Second, the CPU may - * not expose so consistent a view of memory. CPUs will often perform - * their own instruction reordering, above and beyond that performed by - * the compiler. And each core has its own memory caches, and accesses - * (reads and writes both) to "memory" may only resolve to out-of-date - * cache entries -- not to the "most recently" performed operation in - * some global sense. Any access to a value that may be used by - * multiple threads, potentially across multiple cores, must therefore - * have a memory ordering imposed on it, for all code on all - * threads/cores to have a sufficiently coherent worldview. - * - * http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync and - * http://en.cppreference.com/w/cpp/atomic/memory_order go into more - * detail on all this, including examples of how each mode works. - * - * Note that for simplicity and practicality, not all of the modes in - * C++11 are supported. The missing C++11 modes are either subsumed by - * the modes we provide below, or not relevant for the CPUs we support - * in Gecko. These three modes are confusing enough as it is! - */ -enum MemoryOrdering { - /* - * Relaxed ordering is the simplest memory ordering: none at all. - * When the result of a write is observed, nothing may be inferred - * about other memory. Writes ostensibly performed "before" on the - * writing thread may not yet be visible. Writes performed "after" on - * the writing thread may already be visible, if the compiler or CPU - * reordered them. (The latter can happen if reads and/or writes get - * held up in per-processor caches.) Relaxed ordering means - * operations can always use cached values (as long as the actual - * updates to atomic values actually occur, correctly, eventually), so - * it's usually the fastest sort of atomic access. For this reason, - * *it's also the most dangerous kind of access*. - * - * Relaxed ordering is good for things like process-wide statistics - * counters that don't need to be consistent with anything else, so - * long as updates themselves are atomic. (And so long as any - * observations of that value can tolerate being out-of-date -- if you - * need some sort of up-to-date value, you need some sort of other - * synchronizing operation.) It's *not* good for locks, mutexes, - * reference counts, etc. that mediate access to other memory, or must - * be observably consistent with other memory. - * - * x86 architectures don't take advantage of the optimization - * opportunities that relaxed ordering permits. Thus it's possible - * that using relaxed ordering will "work" on x86 but fail elsewhere - * (ARM, say, which *does* implement non-sequentially-consistent - * relaxed ordering semantics). Be extra-careful using relaxed - * ordering if you can't easily test non-x86 architectures! - */ - Relaxed, - - /* - * When an atomic value is updated with ReleaseAcquire ordering, and - * that new value is observed with ReleaseAcquire ordering, prior - * writes (atomic or not) are also observable. What ReleaseAcquire - * *doesn't* give you is any observable ordering guarantees for - * ReleaseAcquire-ordered operations on different objects. For - * example, if there are two cores that each perform ReleaseAcquire - * operations on separate objects, each core may or may not observe - * the operations made by the other core. The only way the cores can - * be synchronized with ReleaseAcquire is if they both - * ReleaseAcquire-access the same object. This implies that you can't - * necessarily describe some global total ordering of ReleaseAcquire - * operations. - * - * ReleaseAcquire ordering is good for (as the name implies) atomic - * operations on values controlling ownership of things: reference - * counts, mutexes, and the like. However, if you are thinking about - * using these to implement your own locks or mutexes, you should take - * a good, hard look at actual lock or mutex primitives first. - */ - ReleaseAcquire, - - /* - * When an atomic value is updated with SequentiallyConsistent - * ordering, all writes observable when the update is observed, just - * as with ReleaseAcquire ordering. But, furthermore, a global total - * ordering of SequentiallyConsistent operations *can* be described. - * For example, if two cores perform SequentiallyConsistent operations - * on separate objects, one core will observably perform its update - * (and all previous operations will have completed), then the other - * core will observably perform its update (and all previous - * operations will have completed). (Although those previous - * operations aren't themselves ordered -- they could be intermixed, - * or ordered if they occur on atomic values with ordering - * requirements.) SequentiallyConsistent is the *simplest and safest* - * ordering of atomic operations -- it's always as if one operation - * happens, then another, then another, in some order -- and every - * core observes updates to happen in that single order. Because it - * has the most synchronization requirements, operations ordered this - * way also tend to be slowest. - * - * SequentiallyConsistent ordering can be desirable when multiple - * threads observe objects, and they all have to agree on the - * observable order of changes to them. People expect - * SequentiallyConsistent ordering, even if they shouldn't, when - * writing code, atomic or otherwise. SequentiallyConsistent is also - * the ordering of choice when designing lockless data structures. If - * you don't know what order to use, use this one. - */ - SequentiallyConsistent, -}; - -} // namespace mozilla - -// Build up the underlying intrinsics. -#ifdef MOZ_HAVE_CXX11_ATOMICS - -# include - -namespace mozilla { -namespace detail { - -/* - * We provide CompareExchangeFailureOrder to work around a bug in some - * versions of GCC's header. See bug 898491. - */ -template struct AtomicOrderConstraints; - -template<> -struct AtomicOrderConstraints -{ - static const std::memory_order AtomicRMWOrder = std::memory_order_relaxed; - static const std::memory_order LoadOrder = std::memory_order_relaxed; - static const std::memory_order StoreOrder = std::memory_order_relaxed; - static const std::memory_order CompareExchangeFailureOrder = - std::memory_order_relaxed; -}; - -template<> -struct AtomicOrderConstraints -{ - static const std::memory_order AtomicRMWOrder = std::memory_order_acq_rel; - static const std::memory_order LoadOrder = std::memory_order_acquire; - static const std::memory_order StoreOrder = std::memory_order_release; - static const std::memory_order CompareExchangeFailureOrder = - std::memory_order_acquire; -}; - -template<> -struct AtomicOrderConstraints -{ - static const std::memory_order AtomicRMWOrder = std::memory_order_seq_cst; - static const std::memory_order LoadOrder = std::memory_order_seq_cst; - static const std::memory_order StoreOrder = std::memory_order_seq_cst; - static const std::memory_order CompareExchangeFailureOrder = - std::memory_order_seq_cst; -}; - -template -struct IntrinsicBase -{ - typedef std::atomic ValueType; - typedef AtomicOrderConstraints OrderedOp; -}; - -template -struct IntrinsicMemoryOps : public IntrinsicBase -{ - typedef IntrinsicBase Base; - - static T load(const typename Base::ValueType& aPtr) - { - return aPtr.load(Base::OrderedOp::LoadOrder); - } - - static void store(typename Base::ValueType& aPtr, T aVal) - { - aPtr.store(aVal, Base::OrderedOp::StoreOrder); - } - - static T exchange(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.exchange(aVal, Base::OrderedOp::AtomicRMWOrder); - } - - static bool compareExchange(typename Base::ValueType& aPtr, - T aOldVal, T aNewVal) - { - return aPtr.compare_exchange_strong(aOldVal, aNewVal, - Base::OrderedOp::AtomicRMWOrder, - Base::OrderedOp::CompareExchangeFailureOrder); - } -}; - -template -struct IntrinsicAddSub : public IntrinsicBase -{ - typedef IntrinsicBase Base; - - static T add(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.fetch_add(aVal, Base::OrderedOp::AtomicRMWOrder); - } - - static T sub(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.fetch_sub(aVal, Base::OrderedOp::AtomicRMWOrder); - } -}; - -template -struct IntrinsicAddSub : public IntrinsicBase -{ - typedef IntrinsicBase Base; - - static T* add(typename Base::ValueType& aPtr, ptrdiff_t aVal) - { - return aPtr.fetch_add(aVal, Base::OrderedOp::AtomicRMWOrder); - } - - static T* sub(typename Base::ValueType& aPtr, ptrdiff_t aVal) - { - return aPtr.fetch_sub(aVal, Base::OrderedOp::AtomicRMWOrder); - } -}; - -template -struct IntrinsicIncDec : public IntrinsicAddSub -{ - typedef IntrinsicBase Base; - - static T inc(typename Base::ValueType& aPtr) - { - return IntrinsicAddSub::add(aPtr, 1); - } - - static T dec(typename Base::ValueType& aPtr) - { - return IntrinsicAddSub::sub(aPtr, 1); - } -}; - -template -struct AtomicIntrinsics : public IntrinsicMemoryOps, - public IntrinsicIncDec -{ - typedef IntrinsicBase Base; - - static T or_(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.fetch_or(aVal, Base::OrderedOp::AtomicRMWOrder); - } - - static T xor_(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.fetch_xor(aVal, Base::OrderedOp::AtomicRMWOrder); - } - - static T and_(typename Base::ValueType& aPtr, T aVal) - { - return aPtr.fetch_and(aVal, Base::OrderedOp::AtomicRMWOrder); - } -}; - -template -struct AtomicIntrinsics - : public IntrinsicMemoryOps, public IntrinsicIncDec -{ -}; - -template -struct ToStorageTypeArgument -{ - static constexpr T convert (T aT) { return aT; } -}; - -} // namespace detail -} // namespace mozilla - -#elif defined(__GNUC__) - -namespace mozilla { -namespace detail { - -/* - * The __sync_* family of intrinsics is documented here: - * - * http://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Atomic-Builtins.html - * - * While these intrinsics are deprecated in favor of the newer __atomic_* - * family of intrincs: - * - * http://gcc.gnu.org/onlinedocs/gcc-4.7.3/gcc/_005f_005fatomic-Builtins.html - * - * any GCC version that supports the __atomic_* intrinsics will also support - * the header and so will be handled above. We provide a version of - * atomics using the __sync_* intrinsics to support older versions of GCC. - * - * All __sync_* intrinsics that we use below act as full memory barriers, for - * both compiler and hardware reordering, except for __sync_lock_test_and_set, - * which is a only an acquire barrier. When we call __sync_lock_test_and_set, - * we add a barrier above it as appropriate. - */ - -template struct Barrier; - -/* - * Some processors (in particular, x86) don't require quite so many calls to - * __sync_sychronize as our specializations of Barrier produce. If - * performance turns out to be an issue, defining these specializations - * on a per-processor basis would be a good first tuning step. - */ - -template<> -struct Barrier -{ - static void beforeLoad() {} - static void afterLoad() {} - static void beforeStore() {} - static void afterStore() {} -}; - -template<> -struct Barrier -{ - static void beforeLoad() {} - static void afterLoad() { __sync_synchronize(); } - static void beforeStore() { __sync_synchronize(); } - static void afterStore() {} -}; - -template<> -struct Barrier -{ - static void beforeLoad() { __sync_synchronize(); } - static void afterLoad() { __sync_synchronize(); } - static void beforeStore() { __sync_synchronize(); } - static void afterStore() { __sync_synchronize(); } -}; - -template::value> -struct AtomicStorageType -{ - // For non-enums, just use the type directly. - typedef T Type; -}; - -template -struct AtomicStorageType - : Conditional -{ - static_assert(sizeof(T) == 4 || sizeof(T) == 8, - "wrong type computed in conditional above"); -}; - -template -struct IntrinsicMemoryOps -{ - typedef typename AtomicStorageType::Type ValueType; - - static T load(const ValueType& aPtr) - { - Barrier::beforeLoad(); - T val = T(aPtr); - Barrier::afterLoad(); - return val; - } - - static void store(ValueType& aPtr, T aVal) - { - Barrier::beforeStore(); - aPtr = ValueType(aVal); - Barrier::afterStore(); - } - - static T exchange(ValueType& aPtr, T aVal) - { - // __sync_lock_test_and_set is only an acquire barrier; loads and stores - // can't be moved up from after to before it, but they can be moved down - // from before to after it. We may want a stricter ordering, so we need - // an explicit barrier. - Barrier::beforeStore(); - return T(__sync_lock_test_and_set(&aPtr, ValueType(aVal))); - } - - static bool compareExchange(ValueType& aPtr, T aOldVal, T aNewVal) - { - return __sync_bool_compare_and_swap(&aPtr, ValueType(aOldVal), ValueType(aNewVal)); - } -}; - -template -struct IntrinsicAddSub - : public IntrinsicMemoryOps -{ - typedef IntrinsicMemoryOps Base; - typedef typename Base::ValueType ValueType; - - static T add(ValueType& aPtr, T aVal) - { - return T(__sync_fetch_and_add(&aPtr, ValueType(aVal))); - } - - static T sub(ValueType& aPtr, T aVal) - { - return T(__sync_fetch_and_sub(&aPtr, ValueType(aVal))); - } -}; - -template -struct IntrinsicAddSub - : public IntrinsicMemoryOps -{ - typedef IntrinsicMemoryOps Base; - typedef typename Base::ValueType ValueType; - - /* - * The reinterpret_casts are needed so that - * __sync_fetch_and_{add,sub} will properly type-check. - * - * Also, these functions do not provide standard semantics for - * pointer types, so we need to adjust the addend. - */ - static ValueType add(ValueType& aPtr, ptrdiff_t aVal) - { - ValueType amount = reinterpret_cast(aVal * sizeof(T)); - return __sync_fetch_and_add(&aPtr, amount); - } - - static ValueType sub(ValueType& aPtr, ptrdiff_t aVal) - { - ValueType amount = reinterpret_cast(aVal * sizeof(T)); - return __sync_fetch_and_sub(&aPtr, amount); - } -}; - -template -struct IntrinsicIncDec : public IntrinsicAddSub -{ - typedef IntrinsicAddSub Base; - typedef typename Base::ValueType ValueType; - - static T inc(ValueType& aPtr) { return Base::add(aPtr, 1); } - static T dec(ValueType& aPtr) { return Base::sub(aPtr, 1); } -}; - -template -struct AtomicIntrinsics : public IntrinsicIncDec -{ - static T or_( T& aPtr, T aVal) { return __sync_fetch_and_or(&aPtr, aVal); } - static T xor_(T& aPtr, T aVal) { return __sync_fetch_and_xor(&aPtr, aVal); } - static T and_(T& aPtr, T aVal) { return __sync_fetch_and_and(&aPtr, aVal); } -}; - -template -struct AtomicIntrinsics : public IntrinsicIncDec -{ -}; - -template::value> -struct ToStorageTypeArgument -{ - typedef typename AtomicStorageType::Type ResultType; - - static constexpr ResultType convert (T aT) { return ResultType(aT); } -}; - -template -struct ToStorageTypeArgument -{ - static constexpr T convert (T aT) { return aT; } -}; - -} // namespace detail -} // namespace mozilla - -#else -# error "Atomic compiler intrinsics are not supported on your platform" -#endif - -namespace mozilla { - -namespace detail { - -template -class AtomicBase -{ - static_assert(sizeof(T) == 4 || sizeof(T) == 8, - "mozilla/Atomics.h only supports 32-bit and 64-bit types"); - -protected: - typedef typename detail::AtomicIntrinsics Intrinsics; - typedef typename Intrinsics::ValueType ValueType; - ValueType mValue; - -public: - constexpr AtomicBase() : mValue() {} - explicit constexpr AtomicBase(T aInit) - : mValue(ToStorageTypeArgument::convert(aInit)) - {} - - // Note: we can't provide operator T() here because Atomic inherits - // from AtomcBase with T=uint32_t and not T=bool. If we implemented - // operator T() here, it would cause errors when comparing Atomic with - // a regular bool. - - T operator=(T aVal) - { - Intrinsics::store(mValue, aVal); - return aVal; - } - - /** - * Performs an atomic swap operation. aVal is stored and the previous - * value of this variable is returned. - */ - T exchange(T aVal) - { - return Intrinsics::exchange(mValue, aVal); - } - - /** - * Performs an atomic compare-and-swap operation and returns true if it - * succeeded. This is equivalent to atomically doing - * - * if (mValue == aOldValue) { - * mValue = aNewValue; - * return true; - * } else { - * return false; - * } - */ - bool compareExchange(T aOldValue, T aNewValue) - { - return Intrinsics::compareExchange(mValue, aOldValue, aNewValue); - } - -private: - template - AtomicBase(const AtomicBase& aCopy) = delete; -}; - -template -class AtomicBaseIncDec : public AtomicBase -{ - typedef typename detail::AtomicBase Base; - -public: - constexpr AtomicBaseIncDec() : Base() {} - explicit constexpr AtomicBaseIncDec(T aInit) : Base(aInit) {} - - using Base::operator=; - - operator T() const { return Base::Intrinsics::load(Base::mValue); } - T operator++(int) { return Base::Intrinsics::inc(Base::mValue); } - T operator--(int) { return Base::Intrinsics::dec(Base::mValue); } - T operator++() { return Base::Intrinsics::inc(Base::mValue) + 1; } - T operator--() { return Base::Intrinsics::dec(Base::mValue) - 1; } - -private: - template - AtomicBaseIncDec(const AtomicBaseIncDec& aCopy) = delete; -}; - -} // namespace detail - -/** - * A wrapper for a type that enforces that all memory accesses are atomic. - * - * In general, where a variable |T foo| exists, |Atomic foo| can be used in - * its place. Implementations for integral and pointer types are provided - * below. - * - * Atomic accesses are sequentially consistent by default. You should - * use the default unless you are tall enough to ride the - * memory-ordering roller coaster (if you're not sure, you aren't) and - * you have a compelling reason to do otherwise. - * - * There is one exception to the case of atomic memory accesses: providing an - * initial value of the atomic value is not guaranteed to be atomic. This is a - * deliberate design choice that enables static atomic variables to be declared - * without introducing extra static constructors. - */ -template -class Atomic; - -/** - * Atomic implementation for integral types. - * - * In addition to atomic store and load operations, compound assignment and - * increment/decrement operators are implemented which perform the - * corresponding read-modify-write operation atomically. Finally, an atomic - * swap method is provided. - */ -template -class Atomic::value && - !IsSame::value>::Type> - : public detail::AtomicBaseIncDec -{ - typedef typename detail::AtomicBaseIncDec Base; - -public: - constexpr Atomic() : Base() {} - explicit constexpr Atomic(T aInit) : Base(aInit) {} - - using Base::operator=; - - T operator+=(T aDelta) - { - return Base::Intrinsics::add(Base::mValue, aDelta) + aDelta; - } - - T operator-=(T aDelta) - { - return Base::Intrinsics::sub(Base::mValue, aDelta) - aDelta; - } - - T operator|=(T aVal) - { - return Base::Intrinsics::or_(Base::mValue, aVal) | aVal; - } - - T operator^=(T aVal) - { - return Base::Intrinsics::xor_(Base::mValue, aVal) ^ aVal; - } - - T operator&=(T aVal) - { - return Base::Intrinsics::and_(Base::mValue, aVal) & aVal; - } - -private: - Atomic(Atomic& aOther) = delete; -}; - -/** - * Atomic implementation for pointer types. - * - * An atomic compare-and-swap primitive for pointer variables is provided, as - * are atomic increment and decement operators. Also provided are the compound - * assignment operators for addition and subtraction. Atomic swap (via - * exchange()) is included as well. - */ -template -class Atomic : public detail::AtomicBaseIncDec -{ - typedef typename detail::AtomicBaseIncDec Base; - -public: - constexpr Atomic() : Base() {} - explicit constexpr Atomic(T* aInit) : Base(aInit) {} - - using Base::operator=; - - T* operator+=(ptrdiff_t aDelta) - { - return Base::Intrinsics::add(Base::mValue, aDelta) + aDelta; - } - - T* operator-=(ptrdiff_t aDelta) - { - return Base::Intrinsics::sub(Base::mValue, aDelta) - aDelta; - } - -private: - Atomic(Atomic& aOther) = delete; -}; - -/** - * Atomic implementation for enum types. - * - * The atomic store and load operations and the atomic swap method is provided. - */ -template -class Atomic::value>::Type> - : public detail::AtomicBase -{ - typedef typename detail::AtomicBase Base; - -public: - constexpr Atomic() : Base() {} - explicit constexpr Atomic(T aInit) : Base(aInit) {} - - operator T() const { return T(Base::Intrinsics::load(Base::mValue)); } - - using Base::operator=; - -private: - Atomic(Atomic& aOther) = delete; -}; - -/** - * Atomic implementation for boolean types. - * - * The atomic store and load operations and the atomic swap method is provided. - * - * Note: - * - * - sizeof(Atomic) != sizeof(bool) for some implementations of - * bool and/or some implementations of std::atomic. This is allowed in - * [atomic.types.generic]p9. - * - * - It's not obvious whether the 8-bit atomic functions on Windows are always - * inlined or not. If they are not inlined, the corresponding functions in the - * runtime library are not available on Windows XP. This is why we implement - * Atomic with an underlying type of uint32_t. - */ -template -class Atomic - : protected detail::AtomicBase -{ - typedef typename detail::AtomicBase Base; - -public: - constexpr Atomic() : Base() {} - explicit constexpr Atomic(bool aInit) : Base(aInit) {} - - // We provide boolean wrappers for the underlying AtomicBase methods. - MOZ_IMPLICIT operator bool() const - { - return Base::Intrinsics::load(Base::mValue); - } - - bool operator=(bool aVal) - { - return Base::operator=(aVal); - } - - bool exchange(bool aVal) - { - return Base::exchange(aVal); - } - - bool compareExchange(bool aOldValue, bool aNewValue) - { - return Base::compareExchange(aOldValue, aNewValue); - } - -private: - Atomic(Atomic& aOther) = delete; -}; - -} // namespace mozilla - -#endif /* mozilla_Atomics_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Attributes.h b/android/x86/include/spidermonkey/mozilla/Attributes.h deleted file mode 100644 index df6172f3..00000000 --- a/android/x86/include/spidermonkey/mozilla/Attributes.h +++ /dev/null @@ -1,604 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implementations of various class and method modifier attributes. */ - -#ifndef mozilla_Attributes_h -#define mozilla_Attributes_h - -#include "mozilla/Compiler.h" - -/* - * MOZ_ALWAYS_INLINE is a macro which expands to tell the compiler that the - * method decorated with it must be inlined, even if the compiler thinks - * otherwise. This is only a (much) stronger version of the inline hint: - * compilers are not guaranteed to respect it (although they're much more likely - * to do so). - * - * The MOZ_ALWAYS_INLINE_EVEN_DEBUG macro is yet stronger. It tells the - * compiler to inline even in DEBUG builds. It should be used very rarely. - */ -#if defined(_MSC_VER) -# define MOZ_ALWAYS_INLINE_EVEN_DEBUG __forceinline -#elif defined(__GNUC__) -# define MOZ_ALWAYS_INLINE_EVEN_DEBUG __attribute__((always_inline)) inline -#else -# define MOZ_ALWAYS_INLINE_EVEN_DEBUG inline -#endif - -#if !defined(DEBUG) -# define MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE_EVEN_DEBUG -#elif defined(_MSC_VER) && !defined(__cplusplus) -# define MOZ_ALWAYS_INLINE __inline -#else -# define MOZ_ALWAYS_INLINE inline -#endif - -#if defined(_MSC_VER) -/* - * g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality - * without warnings (functionality used by the macros below). These modes are - * detectable by checking whether __GXX_EXPERIMENTAL_CXX0X__ is defined or, more - * standardly, by checking whether __cplusplus has a C++11 or greater value. - * Current versions of g++ do not correctly set __cplusplus, so we check both - * for forward compatibility. - */ -# define MOZ_HAVE_NEVER_INLINE __declspec(noinline) -# define MOZ_HAVE_NORETURN __declspec(noreturn) -#elif defined(__clang__) - /* - * Per Clang documentation, "Note that marketing version numbers should not - * be used to check for language features, as different vendors use different - * numbering schemes. Instead, use the feature checking macros." - */ -# ifndef __has_extension -# define __has_extension __has_feature /* compatibility, for older versions of clang */ -# endif -# if __has_attribute(noinline) -# define MOZ_HAVE_NEVER_INLINE __attribute__((noinline)) -# endif -# if __has_attribute(noreturn) -# define MOZ_HAVE_NORETURN __attribute__((noreturn)) -# endif -#elif defined(__GNUC__) -# define MOZ_HAVE_NEVER_INLINE __attribute__((noinline)) -# define MOZ_HAVE_NORETURN __attribute__((noreturn)) -#endif - -/* - * When built with clang analyzer (a.k.a scan-build), define MOZ_HAVE_NORETURN - * to mark some false positives - */ -#ifdef __clang_analyzer__ -# if __has_extension(attribute_analyzer_noreturn) -# define MOZ_HAVE_ANALYZER_NORETURN __attribute__((analyzer_noreturn)) -# endif -#endif - -/* - * MOZ_NEVER_INLINE is a macro which expands to tell the compiler that the - * method decorated with it must never be inlined, even if the compiler would - * otherwise choose to inline the method. Compilers aren't absolutely - * guaranteed to support this, but most do. - */ -#if defined(MOZ_HAVE_NEVER_INLINE) -# define MOZ_NEVER_INLINE MOZ_HAVE_NEVER_INLINE -#else -# define MOZ_NEVER_INLINE /* no support */ -#endif - -/* - * MOZ_NORETURN, specified at the start of a function declaration, indicates - * that the given function does not return. (The function definition does not - * need to be annotated.) - * - * MOZ_NORETURN void abort(const char* msg); - * - * This modifier permits the compiler to optimize code assuming a call to such a - * function will never return. It also enables the compiler to avoid spurious - * warnings about not initializing variables, or about any other seemingly-dodgy - * operations performed after the function returns. - * - * This modifier does not affect the corresponding function's linking behavior. - */ -#if defined(MOZ_HAVE_NORETURN) -# define MOZ_NORETURN MOZ_HAVE_NORETURN -#else -# define MOZ_NORETURN /* no support */ -#endif - -/** - * MOZ_COLD tells the compiler that a function is "cold", meaning infrequently - * executed. This may lead it to optimize for size more aggressively than speed, - * or to allocate the body of the function in a distant part of the text segment - * to help keep it from taking up unnecessary icache when it isn't in use. - * - * Place this attribute at the very beginning of a function definition. For - * example, write - * - * MOZ_COLD int foo(); - * - * or - * - * MOZ_COLD int foo() { return 42; } - */ -#if defined(__GNUC__) || defined(__clang__) -# define MOZ_COLD __attribute__ ((cold)) -#else -# define MOZ_COLD -#endif - -/** - * MOZ_NONNULL tells the compiler that some of the arguments to a function are - * known to be non-null. The arguments are a list of 1-based argument indexes - * identifying arguments which are known to be non-null. - * - * Place this attribute at the very beginning of a function definition. For - * example, write - * - * MOZ_NONNULL(1, 2) int foo(char *p, char *q); - */ -#if defined(__GNUC__) || defined(__clang__) -# define MOZ_NONNULL(...) __attribute__ ((nonnull(__VA_ARGS__))) -#else -# define MOZ_NONNULL(...) -#endif - -/* - * MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS, specified at the end of a function - * declaration, indicates that for the purposes of static analysis, this - * function does not return. (The function definition does not need to be - * annotated.) - * - * MOZ_ReportCrash(const char* s, const char* file, int ln) - * MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS - * - * Some static analyzers, like scan-build from clang, can use this information - * to eliminate false positives. From the upstream documentation of scan-build: - * "This attribute is useful for annotating assertion handlers that actually - * can return, but for the purpose of using the analyzer we want to pretend - * that such functions do not return." - * - */ -#if defined(MOZ_HAVE_ANALYZER_NORETURN) -# define MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS MOZ_HAVE_ANALYZER_NORETURN -#else -# define MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS /* no support */ -#endif - -/* - * MOZ_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time - * instrumentation shipped with Clang and GCC) to not instrument the annotated - * function. Furthermore, it will prevent the compiler from inlining the - * function because inlining currently breaks the blacklisting mechanism of - * AddressSanitizer. - */ -#if defined(__has_feature) -# if __has_feature(address_sanitizer) -# define MOZ_HAVE_ASAN_BLACKLIST -# endif -#elif defined(__GNUC__) -# if defined(__SANITIZE_ADDRESS__) -# define MOZ_HAVE_ASAN_BLACKLIST -# endif -#endif - -#if defined(MOZ_HAVE_ASAN_BLACKLIST) -# define MOZ_ASAN_BLACKLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_address)) -#else -# define MOZ_ASAN_BLACKLIST /* nothing */ -#endif - -/* - * MOZ_TSAN_BLACKLIST is a macro to tell ThreadSanitizer (a compile-time - * instrumentation shipped with Clang) to not instrument the annotated function. - * Furthermore, it will prevent the compiler from inlining the function because - * inlining currently breaks the blacklisting mechanism of ThreadSanitizer. - */ -#if defined(__has_feature) -# if __has_feature(thread_sanitizer) -# define MOZ_TSAN_BLACKLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_thread)) -# else -# define MOZ_TSAN_BLACKLIST /* nothing */ -# endif -#else -# define MOZ_TSAN_BLACKLIST /* nothing */ -#endif - -/** - * MOZ_ALLOCATOR tells the compiler that the function it marks returns either a - * "fresh", "pointer-free" block of memory, or nullptr. "Fresh" means that the - * block is not pointed to by any other reachable pointer in the program. - * "Pointer-free" means that the block contains no pointers to any valid object - * in the program. It may be initialized with other (non-pointer) values. - * - * Placing this attribute on appropriate functions helps GCC analyze pointer - * aliasing more accurately in their callers. - * - * GCC warns if a caller ignores the value returned by a function marked with - * MOZ_ALLOCATOR: it is hard to imagine cases where dropping the value returned - * by a function that meets the criteria above would be intentional. - * - * Place this attribute after the argument list and 'this' qualifiers of a - * function definition. For example, write - * - * void *my_allocator(size_t) MOZ_ALLOCATOR; - * - * or - * - * void *my_allocator(size_t bytes) MOZ_ALLOCATOR { ... } - */ -#if defined(__GNUC__) || defined(__clang__) -# define MOZ_ALLOCATOR __attribute__ ((malloc, warn_unused_result)) -#else -# define MOZ_ALLOCATOR -#endif - -/** - * MOZ_MUST_USE tells the compiler to emit a warning if a function's - * return value is not used by the caller. - * - * Place this attribute at the very beginning of a function declaration. For - * example, write - * - * MOZ_MUST_USE int foo(); - * - * or - * - * MOZ_MUST_USE int foo() { return 42; } - */ -#if defined(__GNUC__) || defined(__clang__) -# define MOZ_MUST_USE __attribute__ ((warn_unused_result)) -#else -# define MOZ_MUST_USE -#endif - -/** - * MOZ_FALLTHROUGH is an annotation to suppress compiler warnings about switch - * cases that fall through without a break or return statement. MOZ_FALLTHROUGH - * is only needed on cases that have code. - * - * MOZ_FALLTHROUGH_ASSERT is an annotation to suppress compiler warnings about - * switch cases that MOZ_ASSERT(false) (or its alias MOZ_ASSERT_UNREACHABLE) in - * debug builds, but intentionally fall through in release builds. See comment - * in Assertions.h for more details. - * - * switch (foo) { - * case 1: // These cases have no code. No fallthrough annotations are needed. - * case 2: - * case 3: // This case has code, so a fallthrough annotation is needed! - * foo++; - * MOZ_FALLTHROUGH; - * case 4: - * return foo; - * - * default: - * // This case asserts in debug builds, falls through in release. - * MOZ_FALLTHROUGH_ASSERT("Unexpected foo value?!"); - * case 5: - * return 5; - * } - */ -#if defined(__clang__) && __cplusplus >= 201103L - /* clang's fallthrough annotations are only available starting in C++11. */ -# define MOZ_FALLTHROUGH [[clang::fallthrough]] -#elif defined(_MSC_VER) - /* - * MSVC's __fallthrough annotations are checked by /analyze (Code Analysis): - * https://msdn.microsoft.com/en-us/library/ms235402%28VS.80%29.aspx - */ -# include -# define MOZ_FALLTHROUGH __fallthrough -#else -# define MOZ_FALLTHROUGH /* FALLTHROUGH */ -#endif - -#ifdef __cplusplus - -/* - * The following macros are attributes that support the static analysis plugin - * included with Mozilla, and will be implemented (when such support is enabled) - * as C++11 attributes. Since such attributes are legal pretty much everywhere - * and have subtly different semantics depending on their placement, the - * following is a guide on where to place the attributes. - * - * Attributes that apply to a struct or class precede the name of the class: - * (Note that this is different from the placement of final for classes!) - * - * class MOZ_CLASS_ATTRIBUTE SomeClass {}; - * - * Attributes that apply to functions follow the parentheses and const - * qualifiers but precede final, override and the function body: - * - * void DeclaredFunction() MOZ_FUNCTION_ATTRIBUTE; - * void SomeFunction() MOZ_FUNCTION_ATTRIBUTE {} - * void PureFunction() const MOZ_FUNCTION_ATTRIBUTE = 0; - * void OverriddenFunction() MOZ_FUNCTION_ATTIRBUTE override; - * - * Attributes that apply to variables or parameters follow the variable's name: - * - * int variable MOZ_VARIABLE_ATTRIBUTE; - * - * Attributes that apply to types follow the type name: - * - * typedef int MOZ_TYPE_ATTRIBUTE MagicInt; - * int MOZ_TYPE_ATTRIBUTE someVariable; - * int* MOZ_TYPE_ATTRIBUTE magicPtrInt; - * int MOZ_TYPE_ATTRIBUTE* ptrToMagicInt; - * - * Attributes that apply to statements precede the statement: - * - * MOZ_IF_ATTRIBUTE if (x == 0) - * MOZ_DO_ATTRIBUTE do { } while (0); - * - * Attributes that apply to labels precede the label: - * - * MOZ_LABEL_ATTRIBUTE target: - * goto target; - * MOZ_CASE_ATTRIBUTE case 5: - * MOZ_DEFAULT_ATTRIBUTE default: - * - * The static analyses that are performed by the plugin are as follows: - * - * MOZ_MUST_OVERRIDE: Applies to all C++ member functions. All immediate - * subclasses must provide an exact override of this method; if a subclass - * does not override this method, the compiler will emit an error. This - * attribute is not limited to virtual methods, so if it is applied to a - * nonvirtual method and the subclass does not provide an equivalent - * definition, the compiler will emit an error. - * MOZ_STACK_CLASS: Applies to all classes. Any class with this annotation is - * expected to live on the stack, so it is a compile-time error to use it, or - * an array of such objects, as a global or static variable, or as the type of - * a new expression (unless placement new is being used). If a member of - * another class uses this class, or if another class inherits from this - * class, then it is considered to be a stack class as well, although this - * attribute need not be provided in such cases. - * MOZ_NONHEAP_CLASS: Applies to all classes. Any class with this annotation is - * expected to live on the stack or in static storage, so it is a compile-time - * error to use it, or an array of such objects, as the type of a new - * expression. If a member of another class uses this class, or if another - * class inherits from this class, then it is considered to be a non-heap class - * as well, although this attribute need not be provided in such cases. - * MOZ_HEAP_CLASS: Applies to all classes. Any class with this annotation is - * expected to live on the heap, so it is a compile-time error to use it, or - * an array of such objects, as the type of a variable declaration, or as a - * temporary object. If a member of another class uses this class, or if - * another class inherits from this class, then it is considered to be a heap - * class as well, although this attribute need not be provided in such cases. - * MOZ_NON_TEMPORARY_CLASS: Applies to all classes. Any class with this - * annotation is expected not to live in a temporary. If a member of another - * class uses this class or if another class inherits from this class, then it - * is considered to be a non-temporary class as well, although this attribute - * need not be provided in such cases. - * MOZ_RAII: Applies to all classes. Any class with this annotation is assumed - * to be a RAII guard, which is expected to live on the stack in an automatic - * allocation. It is prohibited from being allocated in a temporary, static - * storage, or on the heap. This is a combination of MOZ_STACK_CLASS and - * MOZ_NON_TEMPORARY_CLASS. - * MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS: Applies to all classes that are - * intended to prevent introducing static initializers. This attribute - * currently makes it a compile-time error to instantiate these classes - * anywhere other than at the global scope, or as a static member of a class. - * In non-debug mode, it also prohibits non-trivial constructors and - * destructors. - * MOZ_TRIVIAL_CTOR_DTOR: Applies to all classes that must have both a trivial - * or constexpr constructor and a trivial destructor. Setting this attribute - * on a class makes it a compile-time error for that class to get a - * non-trivial constructor or destructor for any reason. - * MOZ_HEAP_ALLOCATOR: Applies to any function. This indicates that the return - * value is allocated on the heap, and will as a result check such allocations - * during MOZ_STACK_CLASS and MOZ_NONHEAP_CLASS annotation checking. - * MOZ_IMPLICIT: Applies to constructors. Implicit conversion constructors - * are disallowed by default unless they are marked as MOZ_IMPLICIT. This - * attribute must be used for constructors which intend to provide implicit - * conversions. - * MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT: Applies to functions. Makes it a compile - * time error to pass arithmetic expressions on variables to the function. - * MOZ_OWNING_REF: Applies to declarations of pointers to reference counted - * types. This attribute tells the compiler that the raw pointer is a strong - * reference, where ownership through methods such as AddRef and Release is - * managed manually. This can make the compiler ignore these pointers when - * validating the usage of pointers otherwise. - * - * Example uses include owned pointers inside of unions, and pointers stored - * in POD types where a using a smart pointer class would make the object - * non-POD. - * MOZ_NON_OWNING_REF: Applies to declarations of pointers to reference counted - * types. This attribute tells the compiler that the raw pointer is a weak - * reference, which is ensured to be valid by a guarantee that the reference - * will be nulled before the pointer becomes invalid. This can make the compiler - * ignore these pointers when validating the usage of pointers otherwise. - * - * Examples include an mOwner pointer, which is nulled by the owning class's - * destructor, and is null-checked before dereferencing. - * MOZ_UNSAFE_REF: Applies to declarations of pointers to reference counted types. - * Occasionally there are non-owning references which are valid, but do not take - * the form of a MOZ_NON_OWNING_REF. Their safety may be dependent on the behaviour - * of API consumers. The string argument passed to this macro documents the safety - * conditions. This can make the compiler ignore these pointers when validating - * the usage of pointers elsewhere. - * - * Examples include an nsIAtom* member which is known at compile time to point to a - * static atom which is valid throughout the lifetime of the program, or an API which - * stores a pointer, but doesn't take ownership over it, instead requiring the API - * consumer to correctly null the value before it becomes invalid. - * - * Use of this annotation is discouraged when a strong reference or one of the above - * two annotations can be used instead. - * MOZ_NO_ADDREF_RELEASE_ON_RETURN: Applies to function declarations. Makes it - * a compile time error to call AddRef or Release on the return value of a - * function. This is intended to be used with operator->() of our smart - * pointer classes to ensure that the refcount of an object wrapped in a - * smart pointer is not manipulated directly. - * MOZ_MUST_USE_TYPE: Applies to type declarations. Makes it a compile time - * error to not use the return value of a function which has this type. This - * is intended to be used with types which it is an error to not use. - * MOZ_NEEDS_NO_VTABLE_TYPE: Applies to template class declarations. Makes it - * a compile time error to instantiate this template with a type parameter which - * has a VTable. - * MOZ_NON_MEMMOVABLE: Applies to class declarations for types that are not safe - * to be moved in memory using memmove(). - * MOZ_NEEDS_MEMMOVABLE_TYPE: Applies to template class declarations where the - * template arguments are required to be safe to move in memory using - * memmove(). Passing MOZ_NON_MEMMOVABLE types to these templates is a - * compile time error. - * MOZ_NEEDS_MEMMOVABLE_MEMBERS: Applies to class declarations where each member - * must be safe to move in memory using memmove(). MOZ_NON_MEMMOVABLE types - * used in members of these classes are compile time errors. - * MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS: Applies to template class - * declarations where an instance of the template should be considered, for - * static analysis purposes, to inherit any type annotations (such as - * MOZ_MUST_USE_TYPE and MOZ_STACK_CLASS) from its template arguments. - * MOZ_INIT_OUTSIDE_CTOR: Applies to class member declarations. Occasionally - * there are class members that are not initialized in the constructor, - * but logic elsewhere in the class ensures they are initialized prior to use. - * Using this attribute on a member disables the check that this member must be - * initialized in constructors via list-initialization, in the constructor body, - * or via functions called from the constructor body. - * MOZ_IS_CLASS_INIT: Applies to class method declarations. Occasionally the - * constructor doesn't initialize all of the member variables and another function - * is used to initialize the rest. This marker is used to make the static analysis - * tool aware that the marked function is part of the initialization process - * and to include the marked function in the scan mechanism that determines witch - * member variables still remain uninitialized. - * MOZ_NON_PARAM: Applies to types. Makes it compile time error to use the type - * in parameter without pointer or reference. - * MOZ_NON_AUTOABLE: Applies to class declarations. Makes it a compile time error to - * use `auto` in place of this type in variable declarations. This is intended to - * be used with types which are intended to be implicitly constructed into other - * other types before being assigned to variables. - * MOZ_REQUIRED_BASE_METHOD: Applies to virtual class method declarations. - * Sometimes derived classes override methods that need to be called by their - * overridden counterparts. This marker indicates that the marked method must - * be called by the method that it overrides. - */ -#ifdef MOZ_CLANG_PLUGIN -# define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override"))) -# define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class"))) -# define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class"))) -# define MOZ_HEAP_CLASS __attribute__((annotate("moz_heap_class"))) -# define MOZ_NON_TEMPORARY_CLASS __attribute__((annotate("moz_non_temporary_class"))) -# define MOZ_TRIVIAL_CTOR_DTOR __attribute__((annotate("moz_trivial_ctor_dtor"))) -# ifdef DEBUG - /* in debug builds, these classes do have non-trivial constructors. */ -# define MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS __attribute__((annotate("moz_global_class"))) -# else -# define MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS __attribute__((annotate("moz_global_class"))) \ - MOZ_TRIVIAL_CTOR_DTOR -# endif -# define MOZ_IMPLICIT __attribute__((annotate("moz_implicit"))) -# define MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT __attribute__((annotate("moz_no_arith_expr_in_arg"))) -# define MOZ_OWNING_REF __attribute__((annotate("moz_strong_ref"))) -# define MOZ_NON_OWNING_REF __attribute__((annotate("moz_weak_ref"))) -# define MOZ_UNSAFE_REF(reason) __attribute__((annotate("moz_weak_ref"))) -# define MOZ_NO_ADDREF_RELEASE_ON_RETURN __attribute__((annotate("moz_no_addref_release_on_return"))) -# define MOZ_MUST_USE_TYPE __attribute__((annotate("moz_must_use_type"))) -# define MOZ_NEEDS_NO_VTABLE_TYPE __attribute__((annotate("moz_needs_no_vtable_type"))) -# define MOZ_NON_MEMMOVABLE __attribute__((annotate("moz_non_memmovable"))) -# define MOZ_NEEDS_MEMMOVABLE_TYPE __attribute__((annotate("moz_needs_memmovable_type"))) -# define MOZ_NEEDS_MEMMOVABLE_MEMBERS __attribute__((annotate("moz_needs_memmovable_members"))) -# define MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS \ - __attribute__((annotate("moz_inherit_type_annotations_from_template_args"))) -# define MOZ_NON_AUTOABLE __attribute__((annotate("moz_non_autoable"))) -# define MOZ_INIT_OUTSIDE_CTOR \ - __attribute__((annotate("moz_ignore_ctor_initialization"))) -# define MOZ_IS_CLASS_INIT \ - __attribute__((annotate("moz_is_class_init"))) -# define MOZ_NON_PARAM \ - __attribute__((annotate("moz_non_param"))) -# define MOZ_REQUIRED_BASE_METHOD \ - __attribute__((annotate("moz_required_base_method"))) -/* - * It turns out that clang doesn't like void func() __attribute__ {} without a - * warning, so use pragmas to disable the warning. This code won't work on GCC - * anyways, so the warning is safe to ignore. - */ -# define MOZ_HEAP_ALLOCATOR \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((annotate("moz_heap_allocator"))) \ - _Pragma("clang diagnostic pop") -#else -# define MOZ_MUST_OVERRIDE /* nothing */ -# define MOZ_STACK_CLASS /* nothing */ -# define MOZ_NONHEAP_CLASS /* nothing */ -# define MOZ_HEAP_CLASS /* nothing */ -# define MOZ_NON_TEMPORARY_CLASS /* nothing */ -# define MOZ_TRIVIAL_CTOR_DTOR /* nothing */ -# define MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS /* nothing */ -# define MOZ_IMPLICIT /* nothing */ -# define MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT /* nothing */ -# define MOZ_HEAP_ALLOCATOR /* nothing */ -# define MOZ_OWNING_REF /* nothing */ -# define MOZ_NON_OWNING_REF /* nothing */ -# define MOZ_UNSAFE_REF(reason) /* nothing */ -# define MOZ_NO_ADDREF_RELEASE_ON_RETURN /* nothing */ -# define MOZ_MUST_USE_TYPE /* nothing */ -# define MOZ_NEEDS_NO_VTABLE_TYPE /* nothing */ -# define MOZ_NON_MEMMOVABLE /* nothing */ -# define MOZ_NEEDS_MEMMOVABLE_TYPE /* nothing */ -# define MOZ_NEEDS_MEMMOVABLE_MEMBERS /* nothing */ -# define MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS /* nothing */ -# define MOZ_INIT_OUTSIDE_CTOR /* nothing */ -# define MOZ_IS_CLASS_INIT /* nothing */ -# define MOZ_NON_PARAM /* nothing */ -# define MOZ_NON_AUTOABLE /* nothing */ -# define MOZ_REQUIRED_BASE_METHOD /* nothing */ -#endif /* MOZ_CLANG_PLUGIN */ - -#define MOZ_RAII MOZ_NON_TEMPORARY_CLASS MOZ_STACK_CLASS - -/* - * MOZ_HAVE_REF_QUALIFIERS is defined for compilers that support C++11's rvalue - * qualifier, "&&". - */ -#if defined(_MSC_VER) && _MSC_VER >= 1900 -# define MOZ_HAVE_REF_QUALIFIERS -#elif defined(__clang__) -// All supported Clang versions -# define MOZ_HAVE_REF_QUALIFIERS -#elif defined(__GNUC__) -# include "mozilla/Compiler.h" -# if MOZ_GCC_VERSION_AT_LEAST(4, 8, 1) -# define MOZ_HAVE_REF_QUALIFIERS -# endif -#endif - -#endif /* __cplusplus */ - -/** - * Printf style formats. MOZ_FORMAT_PRINTF can be used to annotate a - * function or method that is "printf-like"; this will let (some) - * compilers check that the arguments match the template string. - * - * This macro takes two arguments. The first argument is the argument - * number of the template string. The second argument is the argument - * number of the '...' argument holding the arguments. - * - * Argument numbers start at 1. Note that the implicit "this" - * argument of a non-static member function counts as an argument. - * - * So, for a simple case like: - * void print_something (int whatever, const char *fmt, ...); - * The corresponding annotation would be - * MOZ_FORMAT_PRINTF(2, 3) - * However, if "print_something" were a non-static member function, - * then the annotation would be: - * MOZ_FORMAT_PRINTF(3, 4) - * - * Note that the checking is limited to standards-conforming - * printf-likes, and in particular this should not be used for - * PR_snprintf and friends, which are "printf-like" but which assign - * different meanings to the various formats. - */ -#ifdef __GNUC__ -#define MOZ_FORMAT_PRINTF(stringIndex, firstToCheck) \ - __attribute__ ((format (printf, stringIndex, firstToCheck))) -#else -#define MOZ_FORMAT_PRINTF(stringIndex, firstToCheck) -#endif - -#endif /* mozilla_Attributes_h */ diff --git a/android/x86/include/spidermonkey/mozilla/BinarySearch.h b/android/x86/include/spidermonkey/mozilla/BinarySearch.h deleted file mode 100644 index 1bbe0566..00000000 --- a/android/x86/include/spidermonkey/mozilla/BinarySearch.h +++ /dev/null @@ -1,139 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_BinarySearch_h -#define mozilla_BinarySearch_h - -#include "mozilla/Assertions.h" - -#include - -namespace mozilla { - -/* - * The BinarySearch() algorithm searches the given container |aContainer| over - * the sorted index range [aBegin, aEnd) for an index |i| where - * |aContainer[i] == aTarget|. - * If such an index |i| is found, BinarySearch returns |true| and the index is - * returned via the outparam |aMatchOrInsertionPoint|. If no index is found, - * BinarySearch returns |false| and the outparam returns the first index in - * [aBegin, aEnd] where |aTarget| can be inserted to maintain sorted order. - * - * Example: - * - * Vector sortedInts = ... - * - * size_t match; - * if (BinarySearch(sortedInts, 0, sortedInts.length(), 13, &match)) { - * printf("found 13 at %lu\n", match); - * } - * - * The BinarySearchIf() version behaves similarly, but takes |aComparator|, a - * functor to compare the values with, instead of a value to find. - * That functor should take one argument - the value to compare - and return an - * |int| with the comparison result: - * - * * 0, if the argument is equal to, - * * less than 0, if the argument is greater than, - * * greater than 0, if the argument is less than - * - * the value. - * - * Example: - * - * struct Comparator { - * int operator()(int aVal) const { - * if (mTarget < aVal) { return -1; } - * if (mTarget > aVal) { return 1; } - * return 0; - * } - * explicit Comparator(int aTarget) : mTarget(aTarget) {} - * const int mTarget; - * }; - * - * Vector sortedInts = ... - * - * size_t match; - * if (BinarySearchIf(sortedInts, 0, sortedInts.length(), Comparator(13), &match)) { - * printf("found 13 at %lu\n", match); - * } - * - */ - -template -bool -BinarySearchIf(const Container& aContainer, size_t aBegin, size_t aEnd, - const Comparator& aCompare, size_t* aMatchOrInsertionPoint) -{ - MOZ_ASSERT(aBegin <= aEnd); - - size_t low = aBegin; - size_t high = aEnd; - while (high != low) { - size_t middle = low + (high - low) / 2; - - // Allow any intermediate type so long as it provides a suitable ordering - // relation. - const int result = aCompare(aContainer[middle]); - - if (result == 0) { - *aMatchOrInsertionPoint = middle; - return true; - } - - if (result < 0) { - high = middle; - } else { - low = middle + 1; - } - } - - *aMatchOrInsertionPoint = low; - return false; -} - -namespace detail { - -template -class BinarySearchDefaultComparator -{ -public: - explicit BinarySearchDefaultComparator(const T& aTarget) - : mTarget(aTarget) - {} - - template - int operator()(const U& aVal) const { - if (mTarget == aVal) { - return 0; - } - - if (mTarget < aVal) { - return -1; - } - - return 1; - } - -private: - const T& mTarget; -}; - -} // namespace detail - -template -bool -BinarySearch(const Container& aContainer, size_t aBegin, size_t aEnd, - T aTarget, size_t* aMatchOrInsertionPoint) -{ - return BinarySearchIf(aContainer, aBegin, aEnd, - detail::BinarySearchDefaultComparator(aTarget), - aMatchOrInsertionPoint); -} - -} // namespace mozilla - -#endif // mozilla_BinarySearch_h diff --git a/android/x86/include/spidermonkey/mozilla/BloomFilter.h b/android/x86/include/spidermonkey/mozilla/BloomFilter.h deleted file mode 100644 index 6757e411..00000000 --- a/android/x86/include/spidermonkey/mozilla/BloomFilter.h +++ /dev/null @@ -1,256 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * A counting Bloom filter implementation. This allows consumers to - * do fast probabilistic "is item X in set Y?" testing which will - * never answer "no" when the correct answer is "yes" (but might - * incorrectly answer "yes" when the correct answer is "no"). - */ - -#ifndef mozilla_BloomFilter_h -#define mozilla_BloomFilter_h - -#include "mozilla/Assertions.h" -#include "mozilla/Likely.h" - -#include -#include - -namespace mozilla { - -/* - * This class implements a counting Bloom filter as described at - * , with - * 8-bit counters. This allows quick probabilistic answers to the - * question "is object X in set Y?" where the contents of Y might not - * be time-invariant. The probabilistic nature of the test means that - * sometimes the answer will be "yes" when it should be "no". If the - * answer is "no", then X is guaranteed not to be in Y. - * - * The filter is parametrized on KeySize, which is the size of the key - * generated by each of hash functions used by the filter, in bits, - * and the type of object T being added and removed. T must implement - * a |uint32_t hash() const| method which returns a uint32_t hash key - * that will be used to generate the two separate hash functions for - * the Bloom filter. This hash key MUST be well-distributed for good - * results! KeySize is not allowed to be larger than 16. - * - * The filter uses exactly 2**KeySize bytes of memory. From now on we - * will refer to the memory used by the filter as M. - * - * The expected rate of incorrect "yes" answers depends on M and on - * the number N of objects in set Y. As long as N is small compared - * to M, the rate of such answers is expected to be approximately - * 4*(N/M)**2 for this filter. In practice, if Y has a few hundred - * elements then using a KeySize of 12 gives a reasonably low - * incorrect answer rate. A KeySize of 12 has the additional benefit - * of using exactly one page for the filter in typical hardware - * configurations. - */ - -template -class BloomFilter -{ - /* - * A counting Bloom filter with 8-bit counters. For now we assume - * that having two hash functions is enough, but we may revisit that - * decision later. - * - * The filter uses an array with 2**KeySize entries. - * - * Assuming a well-distributed hash function, a Bloom filter with - * array size M containing N elements and - * using k hash function has expected false positive rate exactly - * - * $ (1 - (1 - 1/M)^{kN})^k $ - * - * because each array slot has a - * - * $ (1 - 1/M)^{kN} $ - * - * chance of being 0, and the expected false positive rate is the - * probability that all of the k hash functions will hit a nonzero - * slot. - * - * For reasonable assumptions (M large, kN large, which should both - * hold if we're worried about false positives) about M and kN this - * becomes approximately - * - * $$ (1 - \exp(-kN/M))^k $$ - * - * For our special case of k == 2, that's $(1 - \exp(-2N/M))^2$, - * or in other words - * - * $$ N/M = -0.5 * \ln(1 - \sqrt(r)) $$ - * - * where r is the false positive rate. This can be used to compute - * the desired KeySize for a given load N and false positive rate r. - * - * If N/M is assumed small, then the false positive rate can - * further be approximated as 4*N^2/M^2. So increasing KeySize by - * 1, which doubles M, reduces the false positive rate by about a - * factor of 4, and a false positive rate of 1% corresponds to - * about M/N == 20. - * - * What this means in practice is that for a few hundred keys using a - * KeySize of 12 gives false positive rates on the order of 0.25-4%. - * - * Similarly, using a KeySize of 10 would lead to a 4% false - * positive rate for N == 100 and to quite bad false positive - * rates for larger N. - */ -public: - BloomFilter() - { - static_assert(KeySize <= kKeyShift, "KeySize too big"); - - // Should we have a custom operator new using calloc instead and - // require that we're allocated via the operator? - clear(); - } - - /* - * Clear the filter. This should be done before reusing it, because - * just removing all items doesn't clear counters that hit the upper - * bound. - */ - void clear(); - - /* - * Add an item to the filter. - */ - void add(const T* aValue); - - /* - * Remove an item from the filter. - */ - void remove(const T* aValue); - - /* - * Check whether the filter might contain an item. This can - * sometimes return true even if the item is not in the filter, - * but will never return false for items that are actually in the - * filter. - */ - bool mightContain(const T* aValue) const; - - /* - * Methods for add/remove/contain when we already have a hash computed - */ - void add(uint32_t aHash); - void remove(uint32_t aHash); - bool mightContain(uint32_t aHash) const; - -private: - static const size_t kArraySize = (1 << KeySize); - static const uint32_t kKeyMask = (1 << KeySize) - 1; - static const uint32_t kKeyShift = 16; - - static uint32_t hash1(uint32_t aHash) - { - return aHash & kKeyMask; - } - static uint32_t hash2(uint32_t aHash) - { - return (aHash >> kKeyShift) & kKeyMask; - } - - uint8_t& firstSlot(uint32_t aHash) - { - return mCounters[hash1(aHash)]; - } - uint8_t& secondSlot(uint32_t aHash) - { - return mCounters[hash2(aHash)]; - } - - const uint8_t& firstSlot(uint32_t aHash) const - { - return mCounters[hash1(aHash)]; - } - const uint8_t& secondSlot(uint32_t aHash) const - { - return mCounters[hash2(aHash)]; - } - - static bool full(const uint8_t& aSlot) { return aSlot == UINT8_MAX; } - - uint8_t mCounters[kArraySize]; -}; - -template -inline void -BloomFilter::clear() -{ - memset(mCounters, 0, kArraySize); -} - -template -inline void -BloomFilter::add(uint32_t aHash) -{ - uint8_t& slot1 = firstSlot(aHash); - if (MOZ_LIKELY(!full(slot1))) { - ++slot1; - } - uint8_t& slot2 = secondSlot(aHash); - if (MOZ_LIKELY(!full(slot2))) { - ++slot2; - } -} - -template -MOZ_ALWAYS_INLINE void -BloomFilter::add(const T* aValue) -{ - uint32_t hash = aValue->hash(); - return add(hash); -} - -template -inline void -BloomFilter::remove(uint32_t aHash) -{ - // If the slots are full, we don't know whether we bumped them to be - // there when we added or not, so just leave them full. - uint8_t& slot1 = firstSlot(aHash); - if (MOZ_LIKELY(!full(slot1))) { - --slot1; - } - uint8_t& slot2 = secondSlot(aHash); - if (MOZ_LIKELY(!full(slot2))) { - --slot2; - } -} - -template -MOZ_ALWAYS_INLINE void -BloomFilter::remove(const T* aValue) -{ - uint32_t hash = aValue->hash(); - remove(hash); -} - -template -MOZ_ALWAYS_INLINE bool -BloomFilter::mightContain(uint32_t aHash) const -{ - // Check that all the slots for this hash contain something - return firstSlot(aHash) && secondSlot(aHash); -} - -template -MOZ_ALWAYS_INLINE bool -BloomFilter::mightContain(const T* aValue) const -{ - uint32_t hash = aValue->hash(); - return mightContain(hash); -} - -} // namespace mozilla - -#endif /* mozilla_BloomFilter_h */ diff --git a/android/x86/include/spidermonkey/mozilla/BufferList.h b/android/x86/include/spidermonkey/mozilla/BufferList.h deleted file mode 100644 index 42aea12d..00000000 --- a/android/x86/include/spidermonkey/mozilla/BufferList.h +++ /dev/null @@ -1,517 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_BufferList_h -#define mozilla_BufferList_h - -#include -#include "mozilla/AllocPolicy.h" -#include "mozilla/Move.h" -#include "mozilla/ScopeExit.h" -#include "mozilla/Types.h" -#include "mozilla/TypeTraits.h" -#include "mozilla/Vector.h" -#include - -// BufferList represents a sequence of buffers of data. A BufferList can choose -// to own its buffers or not. The class handles writing to the buffers, -// iterating over them, and reading data out. Unlike SegmentedVector, the -// buffers may be of unequal size. Like SegmentedVector, BufferList is a nice -// way to avoid large contiguous allocations (which can trigger OOMs). - -namespace mozilla { - -template -class BufferList : private AllocPolicy -{ - // Each buffer in a BufferList has a size and a capacity. The first mSize - // bytes are initialized and the remaining |mCapacity - mSize| bytes are free. - struct Segment - { - char* mData; - size_t mSize; - size_t mCapacity; - - Segment(char* aData, size_t aSize, size_t aCapacity) - : mData(aData), - mSize(aSize), - mCapacity(aCapacity) - { - } - - Segment(const Segment&) = delete; - Segment& operator=(const Segment&) = delete; - - Segment(Segment&&) = default; - Segment& operator=(Segment&&) = default; - - char* Start() const { return mData; } - char* End() const { return mData + mSize; } - }; - - template - friend class BufferList; - - public: - // For the convenience of callers, all segments are required to be a multiple - // of 8 bytes in capacity. Also, every buffer except the last one is required - // to be full (i.e., size == capacity). Therefore, a byte at offset N within - // the BufferList and stored in memory at an address A will satisfy - // (N % Align == A % Align) if Align == 2, 4, or 8. - static const size_t kSegmentAlignment = 8; - - // Allocate a BufferList. The BufferList will free all its buffers when it is - // destroyed. An initial buffer of size aInitialSize and capacity - // aInitialCapacity is allocated automatically. This data will be contiguous - // an can be accessed via |Start()|. Subsequent buffers will be allocated with - // capacity aStandardCapacity. - BufferList(size_t aInitialSize, - size_t aInitialCapacity, - size_t aStandardCapacity, - AllocPolicy aAP = AllocPolicy()) - : AllocPolicy(aAP), - mOwning(true), - mSegments(aAP), - mSize(0), - mStandardCapacity(aStandardCapacity) - { - MOZ_ASSERT(aInitialCapacity % kSegmentAlignment == 0); - MOZ_ASSERT(aStandardCapacity % kSegmentAlignment == 0); - - if (aInitialCapacity) { - AllocateSegment(aInitialSize, aInitialCapacity); - } - } - - BufferList(const BufferList& aOther) = delete; - - BufferList(BufferList&& aOther) - : mOwning(aOther.mOwning), - mSegments(Move(aOther.mSegments)), - mSize(aOther.mSize), - mStandardCapacity(aOther.mStandardCapacity) - { - aOther.mSegments.clear(); - aOther.mSize = 0; - } - - BufferList& operator=(const BufferList& aOther) = delete; - - BufferList& operator=(BufferList&& aOther) - { - Clear(); - - mOwning = aOther.mOwning; - mSegments = Move(aOther.mSegments); - mSize = aOther.mSize; - aOther.mSegments.clear(); - aOther.mSize = 0; - return *this; - } - - ~BufferList() { Clear(); } - - // Returns the sum of the sizes of all the buffers. - size_t Size() const { return mSize; } - - void Clear() - { - if (mOwning) { - for (Segment& segment : mSegments) { - this->free_(segment.mData); - } - } - mSegments.clear(); - - mSize = 0; - } - - // Iterates over bytes in the segments. You can advance it by as many bytes as - // you choose. - class IterImpl - { - // Invariants: - // (0) mSegment <= bufferList.mSegments.size() - // (1) mData <= mDataEnd - // (2) If mSegment is not the last segment, mData < mDataEnd - uintptr_t mSegment; - char* mData; - char* mDataEnd; - - friend class BufferList; - - public: - explicit IterImpl(const BufferList& aBuffers) - : mSegment(0), - mData(nullptr), - mDataEnd(nullptr) - { - if (!aBuffers.mSegments.empty()) { - mData = aBuffers.mSegments[0].Start(); - mDataEnd = aBuffers.mSegments[0].End(); - } - } - - // Returns a pointer to the raw data. It is valid to access up to - // RemainingInSegment bytes of this buffer. - char* Data() const - { - MOZ_RELEASE_ASSERT(!Done()); - return mData; - } - - // Returns true if the memory in the range [Data(), Data() + aBytes) is all - // part of one contiguous buffer. - bool HasRoomFor(size_t aBytes) const - { - MOZ_RELEASE_ASSERT(mData <= mDataEnd); - return size_t(mDataEnd - mData) >= aBytes; - } - - // Returns the maximum value aBytes for which HasRoomFor(aBytes) will be - // true. - size_t RemainingInSegment() const - { - MOZ_RELEASE_ASSERT(mData <= mDataEnd); - return mDataEnd - mData; - } - - // Advances the iterator by aBytes bytes. aBytes must be less than - // RemainingInSegment(). If advancing by aBytes takes the iterator to the - // end of a buffer, it will be moved to the beginning of the next buffer - // unless it is the last buffer. - void Advance(const BufferList& aBuffers, size_t aBytes) - { - const Segment& segment = aBuffers.mSegments[mSegment]; - MOZ_RELEASE_ASSERT(segment.Start() <= mData); - MOZ_RELEASE_ASSERT(mData <= mDataEnd); - MOZ_RELEASE_ASSERT(mDataEnd == segment.End()); - - MOZ_RELEASE_ASSERT(HasRoomFor(aBytes)); - mData += aBytes; - - if (mData == mDataEnd && mSegment + 1 < aBuffers.mSegments.length()) { - mSegment++; - const Segment& nextSegment = aBuffers.mSegments[mSegment]; - mData = nextSegment.Start(); - mDataEnd = nextSegment.End(); - MOZ_RELEASE_ASSERT(mData < mDataEnd); - } - } - - // Advance the iterator by aBytes, possibly crossing segments. This function - // returns false if it runs out of buffers to advance through. Otherwise it - // returns true. - bool AdvanceAcrossSegments(const BufferList& aBuffers, size_t aBytes) - { - size_t bytes = aBytes; - while (bytes) { - size_t toAdvance = std::min(bytes, RemainingInSegment()); - if (!toAdvance) { - return false; - } - Advance(aBuffers, toAdvance); - bytes -= toAdvance; - } - return true; - } - - // Returns true when the iterator reaches the end of the BufferList. - bool Done() const - { - return mData == mDataEnd; - } - - private: - - // Count the bytes we would need to advance in order to reach aTarget. - size_t BytesUntil(const BufferList& aBuffers, const IterImpl& aTarget) const { - size_t offset = 0; - - MOZ_ASSERT(aTarget.IsIn(aBuffers)); - - char* data = mData; - for (uintptr_t segment = mSegment; segment < aTarget.mSegment; segment++) { - offset += aBuffers.mSegments[segment].End() - data; - data = aBuffers.mSegments[segment].mData; - } - - MOZ_RELEASE_ASSERT(IsIn(aBuffers)); - MOZ_RELEASE_ASSERT(aTarget.mData >= data); - - offset += aTarget.mData - data; - return offset; - } - - bool IsIn(const BufferList& aBuffers) const { - return mSegment < aBuffers.mSegments.length() && - mData >= aBuffers.mSegments[mSegment].mData && - mData < aBuffers.mSegments[mSegment].End(); - } - }; - - // Special convenience method that returns Iter().Data(). - char* Start() { return mSegments[0].mData; } - const char* Start() const { return mSegments[0].mData; } - - IterImpl Iter() const { return IterImpl(*this); } - - // Copies aSize bytes from aData into the BufferList. The storage for these - // bytes may be split across multiple buffers. Size() is increased by aSize. - inline bool WriteBytes(const char* aData, size_t aSize); - - // Copies possibly non-contiguous byte range starting at aIter into - // aData. aIter is advanced by aSize bytes. Returns false if it runs out of - // data before aSize. - inline bool ReadBytes(IterImpl& aIter, char* aData, size_t aSize) const; - - // Return a new BufferList that shares storage with this BufferList. The new - // BufferList is read-only. It allows iteration over aSize bytes starting at - // aIter. Borrow can fail, in which case *aSuccess will be false upon - // return. The borrowed BufferList can use a different AllocPolicy than the - // original one. However, it is not responsible for freeing buffers, so the - // AllocPolicy is only used for the buffer vector. - template - BufferList Borrow(IterImpl& aIter, size_t aSize, bool* aSuccess, - BorrowingAllocPolicy aAP = BorrowingAllocPolicy()) const; - - // Return a new BufferList and move storage from this BufferList to it. The - // new BufferList owns the buffers. Move can fail, in which case *aSuccess - // will be false upon return. The new BufferList can use a different - // AllocPolicy than the original one. The new OtherAllocPolicy is responsible - // for freeing buffers, so the OtherAllocPolicy must use freeing method - // compatible to the original one. - template - BufferList MoveFallible(bool* aSuccess, OtherAllocPolicy aAP = OtherAllocPolicy()); - - // Return a new BufferList that adopts the byte range starting at Iter so that - // range [aIter, aIter + aSize) is transplanted to the returned BufferList. - // Contents of the buffer before aIter + aSize is left undefined. - // Extract can fail, in which case *aSuccess will be false upon return. The - // moved buffers are erased from the original BufferList. In case of extract - // fails, the original BufferList is intact. All other iterators except aIter - // are invalidated. - // This method requires aIter and aSize to be 8-byte aligned. - BufferList Extract(IterImpl& aIter, size_t aSize, bool* aSuccess); - - // Return the number of bytes from 'start' to 'end', two iterators within - // this BufferList. - size_t RangeLength(const IterImpl& start, const IterImpl& end) const { - MOZ_ASSERT(start.IsIn(*this) && end.IsIn(*this)); - return start.BytesUntil(*this, end); - } - -private: - explicit BufferList(AllocPolicy aAP) - : AllocPolicy(aAP), - mOwning(false), - mSize(0), - mStandardCapacity(0) - { - } - - void* AllocateSegment(size_t aSize, size_t aCapacity) - { - MOZ_RELEASE_ASSERT(mOwning); - - char* data = this->template pod_malloc(aCapacity); - if (!data) { - return nullptr; - } - if (!mSegments.append(Segment(data, aSize, aCapacity))) { - this->free_(data); - return nullptr; - } - mSize += aSize; - return data; - } - - bool mOwning; - Vector mSegments; - size_t mSize; - size_t mStandardCapacity; -}; - -template -bool -BufferList::WriteBytes(const char* aData, size_t aSize) -{ - MOZ_RELEASE_ASSERT(mOwning); - MOZ_RELEASE_ASSERT(mStandardCapacity); - - size_t copied = 0; - size_t remaining = aSize; - - if (!mSegments.empty()) { - Segment& lastSegment = mSegments.back(); - - size_t toCopy = std::min(aSize, lastSegment.mCapacity - lastSegment.mSize); - memcpy(lastSegment.mData + lastSegment.mSize, aData, toCopy); - lastSegment.mSize += toCopy; - mSize += toCopy; - - copied += toCopy; - remaining -= toCopy; - } - - while (remaining) { - size_t toCopy = std::min(remaining, mStandardCapacity); - - void* data = AllocateSegment(toCopy, mStandardCapacity); - if (!data) { - return false; - } - memcpy(data, aData + copied, toCopy); - - copied += toCopy; - remaining -= toCopy; - } - - return true; -} - -template -bool -BufferList::ReadBytes(IterImpl& aIter, char* aData, size_t aSize) const -{ - size_t copied = 0; - size_t remaining = aSize; - while (remaining) { - size_t toCopy = std::min(aIter.RemainingInSegment(), remaining); - if (!toCopy) { - // We've run out of data in the last segment. - return false; - } - memcpy(aData + copied, aIter.Data(), toCopy); - copied += toCopy; - remaining -= toCopy; - - aIter.Advance(*this, toCopy); - } - - return true; -} - -template template -BufferList -BufferList::Borrow(IterImpl& aIter, size_t aSize, bool* aSuccess, - BorrowingAllocPolicy aAP) const -{ - BufferList result(aAP); - - size_t size = aSize; - while (size) { - size_t toAdvance = std::min(size, aIter.RemainingInSegment()); - - if (!toAdvance || !result.mSegments.append(typename BufferList::Segment(aIter.mData, toAdvance, toAdvance))) { - *aSuccess = false; - return result; - } - aIter.Advance(*this, toAdvance); - size -= toAdvance; - } - - result.mSize = aSize; - *aSuccess = true; - return result; -} - -template template -BufferList -BufferList::MoveFallible(bool* aSuccess, OtherAllocPolicy aAP) -{ - BufferList result(0, 0, mStandardCapacity, aAP); - - IterImpl iter = Iter(); - while (!iter.Done()) { - size_t toAdvance = iter.RemainingInSegment(); - - if (!toAdvance || !result.mSegments.append(typename BufferList::Segment(iter.mData, toAdvance, toAdvance))) { - *aSuccess = false; - result.mSegments.clear(); - return result; - } - iter.Advance(*this, toAdvance); - } - - result.mSize = mSize; - mSegments.clear(); - mSize = 0; - *aSuccess = true; - return result; -} - -template -BufferList -BufferList::Extract(IterImpl& aIter, size_t aSize, bool* aSuccess) -{ - MOZ_RELEASE_ASSERT(aSize); - MOZ_RELEASE_ASSERT(mOwning); - MOZ_ASSERT(aSize % kSegmentAlignment == 0); - MOZ_ASSERT(intptr_t(aIter.mData) % kSegmentAlignment == 0); - - IterImpl iter = aIter; - size_t size = aSize; - size_t toCopy = std::min(size, aIter.RemainingInSegment()); - MOZ_ASSERT(toCopy % kSegmentAlignment == 0); - - BufferList result(0, toCopy, mStandardCapacity); - BufferList error(0, 0, mStandardCapacity); - - // Copy the head - if (!result.WriteBytes(aIter.mData, toCopy)) { - *aSuccess = false; - return error; - } - iter.Advance(*this, toCopy); - size -= toCopy; - - // Move segments to result - auto resultGuard = MakeScopeExit([&] { - *aSuccess = false; - result.mSegments.erase(result.mSegments.begin()+1, result.mSegments.end()); - }); - - size_t movedSize = 0; - uintptr_t toRemoveStart = iter.mSegment; - uintptr_t toRemoveEnd = iter.mSegment; - while (!iter.Done() && - !iter.HasRoomFor(size)) { - if (!result.mSegments.append(Segment(mSegments[iter.mSegment].mData, - mSegments[iter.mSegment].mSize, - mSegments[iter.mSegment].mCapacity))) { - return error; - } - movedSize += iter.RemainingInSegment(); - size -= iter.RemainingInSegment(); - toRemoveEnd++; - iter.Advance(*this, iter.RemainingInSegment()); - } - - if (size) { - if (!iter.HasRoomFor(size) || - !result.WriteBytes(iter.Data(), size)) { - return error; - } - iter.Advance(*this, size); - } - - mSegments.erase(mSegments.begin() + toRemoveStart, mSegments.begin() + toRemoveEnd); - mSize -= movedSize; - aIter.mSegment = iter.mSegment - (toRemoveEnd - toRemoveStart); - aIter.mData = iter.mData; - aIter.mDataEnd = iter.mDataEnd; - MOZ_ASSERT(aIter.mDataEnd == mSegments[aIter.mSegment].End()); - result.mSize = aSize; - - resultGuard.release(); - *aSuccess = true; - return result; -} - -} // namespace mozilla - -#endif /* mozilla_BufferList_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Casting.h b/android/x86/include/spidermonkey/mozilla/Casting.h deleted file mode 100644 index a7d0fb50..00000000 --- a/android/x86/include/spidermonkey/mozilla/Casting.h +++ /dev/null @@ -1,243 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Cast operations to supplement the built-in casting operations. */ - -#ifndef mozilla_Casting_h -#define mozilla_Casting_h - -#include "mozilla/Assertions.h" -#include "mozilla/TypeTraits.h" - -#include - -namespace mozilla { - -/** - * Sets the outparam value of type |To| with the same underlying bit pattern of - * |aFrom|. - * - * |To| and |From| must be types of the same size; be careful of cross-platform - * size differences, or this might fail to compile on some but not all - * platforms. - * - * There is also a variant that returns the value directly. In most cases, the - * two variants should be identical. However, in the specific case of x86 - * chips, the behavior differs: returning floating-point values directly is done - * through the x87 stack, and x87 loads and stores turn signaling NaNs into - * quiet NaNs... silently. Returning floating-point values via outparam, - * however, is done entirely within the SSE registers when SSE2 floating-point - * is enabled in the compiler, which has semantics-preserving behavior you would - * expect. - * - * If preserving the distinction between signaling NaNs and quiet NaNs is - * important to you, you should use the outparam version. In all other cases, - * you should use the direct return version. - */ -template -inline void -BitwiseCast(const From aFrom, To* aResult) -{ - static_assert(sizeof(From) == sizeof(To), - "To and From must have the same size"); - union - { - From mFrom; - To mTo; - } u; - u.mFrom = aFrom; - *aResult = u.mTo; -} - -template -inline To -BitwiseCast(const From aFrom) -{ - To temp; - BitwiseCast(aFrom, &temp); - return temp; -} - -namespace detail { - -enum ToSignedness { ToIsSigned, ToIsUnsigned }; -enum FromSignedness { FromIsSigned, FromIsUnsigned }; - -template::value ? FromIsSigned : FromIsUnsigned, - ToSignedness = IsSigned::value ? ToIsSigned : ToIsUnsigned> -struct BoundsCheckImpl; - -// Implicit conversions on operands to binary operations make this all a bit -// hard to verify. Attempt to ease the pain below by *only* comparing values -// that are obviously the same type (and will undergo no further conversions), -// even when it's not strictly necessary, for explicitness. - -enum UUComparison { FromIsBigger, FromIsNotBigger }; - -// Unsigned-to-unsigned range check - -template sizeof(To)) - ? FromIsBigger - : FromIsNotBigger> -struct UnsignedUnsignedCheck; - -template -struct UnsignedUnsignedCheck -{ -public: - static bool checkBounds(const From aFrom) - { - return aFrom <= From(To(-1)); - } -}; - -template -struct UnsignedUnsignedCheck -{ -public: - static bool checkBounds(const From aFrom) - { - return true; - } -}; - -template -struct BoundsCheckImpl -{ -public: - static bool checkBounds(const From aFrom) - { - return UnsignedUnsignedCheck::checkBounds(aFrom); - } -}; - -// Signed-to-unsigned range check - -template -struct BoundsCheckImpl -{ -public: - static bool checkBounds(const From aFrom) - { - if (aFrom < 0) { - return false; - } - if (sizeof(To) >= sizeof(From)) { - return true; - } - return aFrom <= From(To(-1)); - } -}; - -// Unsigned-to-signed range check - -enum USComparison { FromIsSmaller, FromIsNotSmaller }; - -template -struct UnsignedSignedCheck; - -template -struct UnsignedSignedCheck -{ -public: - static bool checkBounds(const From aFrom) - { - return true; - } -}; - -template -struct UnsignedSignedCheck -{ -public: - static bool checkBounds(const From aFrom) - { - const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); - return aFrom <= From(MaxValue); - } -}; - -template -struct BoundsCheckImpl -{ -public: - static bool checkBounds(const From aFrom) - { - return UnsignedSignedCheck::checkBounds(aFrom); - } -}; - -// Signed-to-signed range check - -template -struct BoundsCheckImpl -{ -public: - static bool checkBounds(const From aFrom) - { - if (sizeof(From) <= sizeof(To)) { - return true; - } - const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); - const To MinValue = -MaxValue - To(1); - return From(MinValue) <= aFrom && - From(aFrom) <= From(MaxValue); - } -}; - -template::value && - IsIntegral::value> -class BoundsChecker; - -template -class BoundsChecker -{ -public: - static bool checkBounds(const From aFrom) { return true; } -}; - -template -class BoundsChecker -{ -public: - static bool checkBounds(const From aFrom) - { - return BoundsCheckImpl::checkBounds(aFrom); - } -}; - -template -inline bool -IsInBounds(const From aFrom) -{ - return BoundsChecker::checkBounds(aFrom); -} - -} // namespace detail - -/** - * Cast a value of integral type |From| to a value of integral type |To|, - * asserting that the cast will be a safe cast per C++ (that is, that |to| is in - * the range of values permitted for the type |From|). - */ -template -inline To -AssertedCast(const From aFrom) -{ - MOZ_ASSERT((detail::IsInBounds(aFrom))); - return static_cast(aFrom); -} - -} // namespace mozilla - -#endif /* mozilla_Casting_h */ diff --git a/android/x86/include/spidermonkey/mozilla/ChaosMode.h b/android/x86/include/spidermonkey/mozilla/ChaosMode.h deleted file mode 100644 index 94833c39..00000000 --- a/android/x86/include/spidermonkey/mozilla/ChaosMode.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_ChaosMode_h -#define mozilla_ChaosMode_h - -#include "mozilla/Atomics.h" -#include "mozilla/EnumSet.h" - -#include -#include - -namespace mozilla { - -enum ChaosFeature { - None = 0x0, - // Altering thread scheduling. - ThreadScheduling = 0x1, - // Altering network request scheduling. - NetworkScheduling = 0x2, - // Altering timer scheduling. - TimerScheduling = 0x4, - // Read and write less-than-requested amounts. - IOAmounts = 0x8, - // Iterate over hash tables in random order. - HashTableIteration = 0x10, - // Randomly refuse to use cached version of image (when allowed by spec). - ImageCache = 0x20, - Any = 0xffffffff, -}; - -namespace detail { -extern MFBT_DATA Atomic gChaosModeCounter; -extern MFBT_DATA ChaosFeature gChaosFeatures; -} // namespace detail - -/** - * When "chaos mode" is activated, code that makes implicitly nondeterministic - * choices is encouraged to make random and extreme choices, to test more - * code paths and uncover bugs. - */ -class ChaosMode -{ -public: - static void SetChaosFeature(ChaosFeature aChaosFeature) - { - detail::gChaosFeatures = aChaosFeature; - } - - static bool isActive(ChaosFeature aFeature) - { - if (detail::gChaosModeCounter > 0) { - return true; - } - return detail::gChaosFeatures & aFeature; - } - - /** - * Increase the chaos mode activation level. An equivalent number of - * calls to leaveChaosMode must be made in order to restore the original - * chaos mode state. If the activation level is nonzero all chaos mode - * features are activated. - */ - static void enterChaosMode() - { - detail::gChaosModeCounter++; - } - - /** - * Decrease the chaos mode activation level. See enterChaosMode(). - */ - static void leaveChaosMode() - { - MOZ_ASSERT(detail::gChaosModeCounter > 0); - detail::gChaosModeCounter--; - } - - /** - * Returns a somewhat (but not uniformly) random uint32_t < aBound. - * Not to be used for anything except ChaosMode, since it's not very random. - */ - static uint32_t randomUint32LessThan(uint32_t aBound) - { - MOZ_ASSERT(aBound != 0); - return uint32_t(rand()) % aBound; - } -}; - -} /* namespace mozilla */ - -#endif /* mozilla_ChaosMode_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Char16.h b/android/x86/include/spidermonkey/mozilla/Char16.h deleted file mode 100644 index 3c2f254a..00000000 --- a/android/x86/include/spidermonkey/mozilla/Char16.h +++ /dev/null @@ -1,194 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implements a UTF-16 character type. */ - -#ifndef mozilla_Char16_h -#define mozilla_Char16_h - -#ifdef __cplusplus - -/* - * C++11 introduces a char16_t type and support for UTF-16 string and character - * literals. C++11's char16_t is a distinct builtin type. Technically, char16_t - * is a 16-bit code unit of a Unicode code point, not a "character". - */ - -#ifdef WIN32 -# define MOZ_USE_CHAR16_WRAPPER -# include - /** - * Win32 API extensively uses wchar_t, which is represented by a separated - * builtin type than char16_t per spec. It's not the case for MSVC prior to - * MSVC 2015, but other compilers follow the spec. We want to mix wchar_t and - * char16_t on Windows builds. This class is supposed to make it easier. It - * stores char16_t const pointer, but provides implicit casts for wchar_t as - * well. On other platforms, we simply use - * |typedef const char16_t* char16ptr_t|. Here, we want to make the class as - * similar to this typedef, including providing some casts that are allowed - * by the typedef. - */ -class char16ptr_t -{ -private: - const char16_t* mPtr; - static_assert(sizeof(char16_t) == sizeof(wchar_t), - "char16_t and wchar_t sizes differ"); - -public: - char16ptr_t(const char16_t* aPtr) : mPtr(aPtr) {} - char16ptr_t(const wchar_t* aPtr) : - mPtr(reinterpret_cast(aPtr)) - {} - - /* Without this, nullptr assignment would be ambiguous. */ - constexpr char16ptr_t(decltype(nullptr)) : mPtr(nullptr) {} - - operator const char16_t*() const - { - return mPtr; - } - operator const wchar_t*() const - { - return reinterpret_cast(mPtr); - } - operator const void*() const - { - return mPtr; - } - operator bool() const - { - return mPtr != nullptr; - } - - /* Explicit cast operators to allow things like (char16_t*)str. */ - explicit operator char16_t*() const - { - return const_cast(mPtr); - } - explicit operator wchar_t*() const - { - return const_cast(static_cast(*this)); - } - explicit operator int() const - { - return reinterpret_cast(mPtr); - } - explicit operator unsigned int() const - { - return reinterpret_cast(mPtr); - } - explicit operator long() const - { - return reinterpret_cast(mPtr); - } - explicit operator unsigned long() const - { - return reinterpret_cast(mPtr); - } - explicit operator long long() const - { - return reinterpret_cast(mPtr); - } - explicit operator unsigned long long() const - { - return reinterpret_cast(mPtr); - } - - /** - * Some Windows API calls accept BYTE* but require that data actually be - * WCHAR*. Supporting this requires explicit operators to support the - * requisite explicit casts. - */ - explicit operator const char*() const - { - return reinterpret_cast(mPtr); - } - explicit operator const unsigned char*() const - { - return reinterpret_cast(mPtr); - } - explicit operator unsigned char*() const - { - return - const_cast(reinterpret_cast(mPtr)); - } - explicit operator void*() const - { - return const_cast(mPtr); - } - - /* Some operators used on pointers. */ - char16_t operator[](size_t aIndex) const - { - return mPtr[aIndex]; - } - bool operator==(const char16ptr_t& aOther) const - { - return mPtr == aOther.mPtr; - } - bool operator==(decltype(nullptr)) const - { - return mPtr == nullptr; - } - bool operator!=(const char16ptr_t& aOther) const - { - return mPtr != aOther.mPtr; - } - bool operator!=(decltype(nullptr)) const - { - return mPtr != nullptr; - } - char16ptr_t operator+(int aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(unsigned int aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(long aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(unsigned long aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(long long aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(unsigned long long aValue) const - { - return char16ptr_t(mPtr + aValue); - } - ptrdiff_t operator-(const char16ptr_t& aOther) const - { - return mPtr - aOther.mPtr; - } -}; - -inline decltype((char*)0-(char*)0) -operator-(const char16_t* aX, const char16ptr_t aY) -{ - return aX - static_cast(aY); -} - -#else - -typedef const char16_t* char16ptr_t; - -#endif - -static_assert(sizeof(char16_t) == 2, "Is char16_t type 16 bits?"); -static_assert(char16_t(-1) > char16_t(0), "Is char16_t type unsigned?"); -static_assert(sizeof(u'A') == 2, "Is unicode char literal 16 bits?"); -static_assert(sizeof(u""[0]) == 2, "Is unicode string char 16 bits?"); - -#endif - -#endif /* mozilla_Char16_h */ diff --git a/android/x86/include/spidermonkey/mozilla/CheckedInt.h b/android/x86/include/spidermonkey/mozilla/CheckedInt.h deleted file mode 100644 index 02ef8d5b..00000000 --- a/android/x86/include/spidermonkey/mozilla/CheckedInt.h +++ /dev/null @@ -1,791 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Provides checked integers, detecting integer overflow and divide-by-0. */ - -#ifndef mozilla_CheckedInt_h -#define mozilla_CheckedInt_h - -#include -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/IntegerTypeTraits.h" - -namespace mozilla { - -template class CheckedInt; - -namespace detail { - -/* - * Step 1: manually record supported types - * - * What's nontrivial here is that there are different families of integer - * types: basic integer types and stdint types. It is merrily undefined which - * types from one family may be just typedefs for a type from another family. - * - * For example, on GCC 4.6, aside from the basic integer types, the only other - * type that isn't just a typedef for some of them, is int8_t. - */ - -struct UnsupportedType {}; - -template -struct IsSupportedPass2 -{ - static const bool value = false; -}; - -template -struct IsSupported -{ - static const bool value = IsSupportedPass2::value; -}; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - -template<> -struct IsSupported -{ static const bool value = true; }; - - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -template<> -struct IsSupportedPass2 -{ static const bool value = true; }; - -/* - * Step 2: Implement the actual validity checks. - * - * Ideas taken from IntegerLib, code different. - */ - -template -struct TwiceBiggerType -{ - typedef typename detail::StdintTypeForSizeAndSignedness< - sizeof(IntegerType) * 2, - IsSigned::value - >::Type Type; -}; - -template -struct TwiceBiggerType -{ - typedef UnsupportedType Type; -}; - -template -inline bool -HasSignBit(T aX) -{ - // In C++, right bit shifts on negative values is undefined by the standard. - // Notice that signed-to-unsigned conversions are always well-defined in the - // standard, as the value congruent modulo 2**n as expected. By contrast, - // unsigned-to-signed is only well-defined if the value is representable. - return bool(typename MakeUnsigned::Type(aX) >> - PositionOfSignBit::value); -} - -// Bitwise ops may return a larger type, so it's good to use this inline -// helper guaranteeing that the result is really of type T. -template -inline T -BinaryComplement(T aX) -{ - return ~aX; -} - -template::value, - bool IsUSigned = IsSigned::value> -struct DoesRangeContainRange -{ -}; - -template -struct DoesRangeContainRange -{ - static const bool value = sizeof(T) >= sizeof(U); -}; - -template -struct DoesRangeContainRange -{ - static const bool value = sizeof(T) > sizeof(U); -}; - -template -struct DoesRangeContainRange -{ - static const bool value = false; -}; - -template::value, - bool IsUSigned = IsSigned::value, - bool DoesTRangeContainURange = DoesRangeContainRange::value> -struct IsInRangeImpl {}; - -template -struct IsInRangeImpl -{ - static bool run(U) - { - return true; - } -}; - -template -struct IsInRangeImpl -{ - static bool run(U aX) - { - return aX <= MaxValue::value && aX >= MinValue::value; - } -}; - -template -struct IsInRangeImpl -{ - static bool run(U aX) - { - return aX <= MaxValue::value; - } -}; - -template -struct IsInRangeImpl -{ - static bool run(U aX) - { - return sizeof(T) > sizeof(U) || aX <= U(MaxValue::value); - } -}; - -template -struct IsInRangeImpl -{ - static bool run(U aX) - { - return sizeof(T) >= sizeof(U) - ? aX >= 0 - : aX >= 0 && aX <= U(MaxValue::value); - } -}; - -template -inline bool -IsInRange(U aX) -{ - return IsInRangeImpl::run(aX); -} - -template -inline bool -IsAddValid(T aX, T aY) -{ - // Addition is valid if the sign of aX+aY is equal to either that of aX or - // that of aY. Since the value of aX+aY is undefined if we have a signed - // type, we compute it using the unsigned type of the same size. Beware! - // These bitwise operations can return a larger integer type, if T was a - // small type like int8_t, so we explicitly cast to T. - - typename MakeUnsigned::Type ux = aX; - typename MakeUnsigned::Type uy = aY; - typename MakeUnsigned::Type result = ux + uy; - return IsSigned::value - ? HasSignBit(BinaryComplement(T((result ^ aX) & (result ^ aY)))) - : BinaryComplement(aX) >= aY; -} - -template -inline bool -IsSubValid(T aX, T aY) -{ - // Subtraction is valid if either aX and aY have same sign, or aX-aY and aX - // have same sign. Since the value of aX-aY is undefined if we have a signed - // type, we compute it using the unsigned type of the same size. - typename MakeUnsigned::Type ux = aX; - typename MakeUnsigned::Type uy = aY; - typename MakeUnsigned::Type result = ux - uy; - - return IsSigned::value - ? HasSignBit(BinaryComplement(T((result ^ aX) & (aX ^ aY)))) - : aX >= aY; -} - -template::value, - bool TwiceBiggerTypeIsSupported = - IsSupported::Type>::value> -struct IsMulValidImpl {}; - -template -struct IsMulValidImpl -{ - static bool run(T aX, T aY) - { - typedef typename TwiceBiggerType::Type TwiceBiggerType; - TwiceBiggerType product = TwiceBiggerType(aX) * TwiceBiggerType(aY); - return IsInRange(product); - } -}; - -template -struct IsMulValidImpl -{ - static bool run(T aX, T aY) - { - const T max = MaxValue::value; - const T min = MinValue::value; - - if (aX == 0 || aY == 0) { - return true; - } - if (aX > 0) { - return aY > 0 - ? aX <= max / aY - : aY >= min / aX; - } - - // If we reach this point, we know that aX < 0. - return aY > 0 - ? aX >= min / aY - : aY >= max / aX; - } -}; - -template -struct IsMulValidImpl -{ - static bool run(T aX, T aY) - { - return aY == 0 || aX <= MaxValue::value / aY; - } -}; - -template -inline bool -IsMulValid(T aX, T aY) -{ - return IsMulValidImpl::run(aX, aY); -} - -template -inline bool -IsDivValid(T aX, T aY) -{ - // Keep in mind that in the signed case, min/-1 is invalid because - // abs(min)>max. - return aY != 0 && - !(IsSigned::value && aX == MinValue::value && aY == T(-1)); -} - -template::value> -struct IsModValidImpl; - -template -inline bool -IsModValid(T aX, T aY) -{ - return IsModValidImpl::run(aX, aY); -} - -/* - * Mod is pretty simple. - * For now, let's just use the ANSI C definition: - * If aX or aY are negative, the results are implementation defined. - * Consider these invalid. - * Undefined for aY=0. - * The result will never exceed either aX or aY. - * - * Checking that aX>=0 is a warning when T is unsigned. - */ - -template -struct IsModValidImpl -{ - static inline bool run(T aX, T aY) - { - return aY >= 1; - } -}; - -template -struct IsModValidImpl -{ - static inline bool run(T aX, T aY) - { - if (aX < 0) { - return false; - } - return aY >= 1; - } -}; - -template::value> -struct NegateImpl; - -template -struct NegateImpl -{ - static CheckedInt negate(const CheckedInt& aVal) - { - // Handle negation separately for signed/unsigned, for simpler code and to - // avoid an MSVC warning negating an unsigned value. - return CheckedInt(0, aVal.isValid() && aVal.mValue == 0); - } -}; - -template -struct NegateImpl -{ - static CheckedInt negate(const CheckedInt& aVal) - { - // Watch out for the min-value, which (with twos-complement) can't be - // negated as -min-value is then (max-value + 1). - if (!aVal.isValid() || aVal.mValue == MinValue::value) { - return CheckedInt(aVal.mValue, false); - } - return CheckedInt(-aVal.mValue, true); - } -}; - -} // namespace detail - - -/* - * Step 3: Now define the CheckedInt class. - */ - -/** - * @class CheckedInt - * @brief Integer wrapper class checking for integer overflow and other errors - * @param T the integer type to wrap. Can be any type among the following: - * - any basic integer type such as |int| - * - any stdint type such as |int8_t| - * - * This class implements guarded integer arithmetic. Do a computation, check - * that isValid() returns true, you then have a guarantee that no problem, such - * as integer overflow, happened during this computation, and you can call - * value() to get the plain integer value. - * - * The arithmetic operators in this class are guaranteed not to raise a signal - * (e.g. in case of a division by zero). - * - * For example, suppose that you want to implement a function that computes - * (aX+aY)/aZ, that doesn't crash if aZ==0, and that reports on error (divide by - * zero or integer overflow). You could code it as follows: - @code - bool computeXPlusYOverZ(int aX, int aY, int aZ, int* aResult) - { - CheckedInt checkedResult = (CheckedInt(aX) + aY) / aZ; - if (checkedResult.isValid()) { - *aResult = checkedResult.value(); - return true; - } else { - return false; - } - } - @endcode - * - * Implicit conversion from plain integers to checked integers is allowed. The - * plain integer is checked to be in range before being casted to the - * destination type. This means that the following lines all compile, and the - * resulting CheckedInts are correctly detected as valid or invalid: - * @code - // 1 is of type int, is found to be in range for uint8_t, x is valid - CheckedInt x(1); - // -1 is of type int, is found not to be in range for uint8_t, x is invalid - CheckedInt x(-1); - // -1 is of type int, is found to be in range for int8_t, x is valid - CheckedInt x(-1); - // 1000 is of type int16_t, is found not to be in range for int8_t, - // x is invalid - CheckedInt x(int16_t(1000)); - // 3123456789 is of type uint32_t, is found not to be in range for int32_t, - // x is invalid - CheckedInt x(uint32_t(3123456789)); - * @endcode - * Implicit conversion from - * checked integers to plain integers is not allowed. As shown in the - * above example, to get the value of a checked integer as a normal integer, - * call value(). - * - * Arithmetic operations between checked and plain integers is allowed; the - * result type is the type of the checked integer. - * - * Checked integers of different types cannot be used in the same arithmetic - * expression. - * - * There are convenience typedefs for all stdint types, of the following form - * (these are just 2 examples): - @code - typedef CheckedInt CheckedInt32; - typedef CheckedInt CheckedUint16; - @endcode - */ -template -class CheckedInt -{ -protected: - T mValue; - bool mIsValid; - - template - CheckedInt(U aValue, bool aIsValid) : mValue(aValue), mIsValid(aIsValid) - { - static_assert(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); - } - - friend struct detail::NegateImpl; - -public: - /** - * Constructs a checked integer with given @a value. The checked integer is - * initialized as valid or invalid depending on whether the @a value - * is in range. - * - * This constructor is not explicit. Instead, the type of its argument is a - * separate template parameter, ensuring that no conversion is performed - * before this constructor is actually called. As explained in the above - * documentation for class CheckedInt, this constructor checks that its - * argument is valid. - */ - template - MOZ_IMPLICIT CheckedInt(U aValue) MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT - : mValue(T(aValue)), - mIsValid(detail::IsInRange(aValue)) - { - static_assert(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); - } - - template - friend class CheckedInt; - - template - CheckedInt toChecked() const - { - CheckedInt ret(mValue); - ret.mIsValid = ret.mIsValid && mIsValid; - return ret; - } - - /** Constructs a valid checked integer with initial value 0 */ - CheckedInt() : mValue(0), mIsValid(true) - { - static_assert(detail::IsSupported::value, - "This type is not supported by CheckedInt"); - } - - /** @returns the actual value */ - T value() const - { - MOZ_ASSERT(mIsValid, "Invalid checked integer (division by zero or integer overflow)"); - return mValue; - } - - /** - * @returns true if the checked integer is valid, i.e. is not the result - * of an invalid operation or of an operation involving an invalid checked - * integer - */ - bool isValid() const - { - return mIsValid; - } - - template - friend CheckedInt operator +(const CheckedInt& aLhs, - const CheckedInt& aRhs); - template - CheckedInt& operator +=(U aRhs); - CheckedInt& operator +=(const CheckedInt& aRhs); - - template - friend CheckedInt operator -(const CheckedInt& aLhs, - const CheckedInt& aRhs); - template - CheckedInt& operator -=(U aRhs); - CheckedInt& operator -=(const CheckedInt& aRhs); - - template - friend CheckedInt operator *(const CheckedInt& aLhs, - const CheckedInt& aRhs); - template - CheckedInt& operator *=(U aRhs); - CheckedInt& operator *=(const CheckedInt& aRhs); - - template - friend CheckedInt operator /(const CheckedInt& aLhs, - const CheckedInt& aRhs); - template - CheckedInt& operator /=(U aRhs); - CheckedInt& operator /=(const CheckedInt& aRhs); - - template - friend CheckedInt operator %(const CheckedInt& aLhs, - const CheckedInt& aRhs); - template - CheckedInt& operator %=(U aRhs); - CheckedInt& operator %=(const CheckedInt& aRhs); - - CheckedInt operator -() const - { - return detail::NegateImpl::negate(*this); - } - - /** - * @returns true if the left and right hand sides are valid - * and have the same value. - * - * Note that these semantics are the reason why we don't offer - * a operator!=. Indeed, we'd want to have a!=b be equivalent to !(a==b) - * but that would mean that whenever a or b is invalid, a!=b - * is always true, which would be very confusing. - * - * For similar reasons, operators <, >, <=, >= would be very tricky to - * specify, so we just avoid offering them. - * - * Notice that these == semantics are made more reasonable by these facts: - * 1. a==b implies equality at the raw data level - * (the converse is false, as a==b is never true among invalids) - * 2. This is similar to the behavior of IEEE floats, where a==b - * means that a and b have the same value *and* neither is NaN. - */ - bool operator ==(const CheckedInt& aOther) const - { - return mIsValid && aOther.mIsValid && mValue == aOther.mValue; - } - - /** prefix ++ */ - CheckedInt& operator++() - { - *this += 1; - return *this; - } - - /** postfix ++ */ - CheckedInt operator++(int) - { - CheckedInt tmp = *this; - *this += 1; - return tmp; - } - - /** prefix -- */ - CheckedInt& operator--() - { - *this -= 1; - return *this; - } - - /** postfix -- */ - CheckedInt operator--(int) - { - CheckedInt tmp = *this; - *this -= 1; - return tmp; - } - -private: - /** - * The !=, <, <=, >, >= operators are disabled: - * see the comment on operator==. - */ - template bool operator !=(U aOther) const = delete; - template bool operator < (U aOther) const = delete; - template bool operator <=(U aOther) const = delete; - template bool operator > (U aOther) const = delete; - template bool operator >=(U aOther) const = delete; -}; - -#define MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(NAME, OP) \ - template \ - inline CheckedInt \ - operator OP(const CheckedInt& aLhs, const CheckedInt& aRhs) \ - { \ - if (!detail::Is##NAME##Valid(aLhs.mValue, aRhs.mValue)) { \ - return CheckedInt(0, false); \ - } \ - return CheckedInt(aLhs.mValue OP aRhs.mValue, \ - aLhs.mIsValid && aRhs.mIsValid); \ - } - -MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Add, +) -MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Sub, -) -MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mul, *) -MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Div, /) -MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mod, %) - -#undef MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR - -// Implement castToCheckedInt(x), making sure that -// - it allows x to be either a CheckedInt or any integer type -// that can be casted to T -// - if x is already a CheckedInt, we just return a reference to it, -// instead of copying it (optimization) - -namespace detail { - -template -struct CastToCheckedIntImpl -{ - typedef CheckedInt ReturnType; - static CheckedInt run(U aU) { return aU; } -}; - -template -struct CastToCheckedIntImpl > -{ - typedef const CheckedInt& ReturnType; - static const CheckedInt& run(const CheckedInt& aU) { return aU; } -}; - -} // namespace detail - -template -inline typename detail::CastToCheckedIntImpl::ReturnType -castToCheckedInt(U aU) -{ - static_assert(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); - return detail::CastToCheckedIntImpl::run(aU); -} - -#define MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(OP, COMPOUND_OP) \ - template \ - template \ - CheckedInt& CheckedInt::operator COMPOUND_OP(U aRhs) \ - { \ - *this = *this OP castToCheckedInt(aRhs); \ - return *this; \ - } \ - template \ - CheckedInt& CheckedInt::operator COMPOUND_OP(const CheckedInt& aRhs) \ - { \ - *this = *this OP aRhs; \ - return *this; \ - } \ - template \ - inline CheckedInt operator OP(const CheckedInt& aLhs, U aRhs) \ - { \ - return aLhs OP castToCheckedInt(aRhs); \ - } \ - template \ - inline CheckedInt operator OP(U aLhs, const CheckedInt& aRhs) \ - { \ - return castToCheckedInt(aLhs) OP aRhs; \ - } - -MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(+, +=) -MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(*, *=) -MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(-, -=) -MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(/, /=) -MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(%, %=) - -#undef MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS - -template -inline bool -operator ==(const CheckedInt& aLhs, U aRhs) -{ - return aLhs == castToCheckedInt(aRhs); -} - -template -inline bool -operator ==(U aLhs, const CheckedInt& aRhs) -{ - return castToCheckedInt(aLhs) == aRhs; -} - -// Convenience typedefs. -typedef CheckedInt CheckedInt8; -typedef CheckedInt CheckedUint8; -typedef CheckedInt CheckedInt16; -typedef CheckedInt CheckedUint16; -typedef CheckedInt CheckedInt32; -typedef CheckedInt CheckedUint32; -typedef CheckedInt CheckedInt64; -typedef CheckedInt CheckedUint64; - -} // namespace mozilla - -#endif /* mozilla_CheckedInt_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Compiler.h b/android/x86/include/spidermonkey/mozilla/Compiler.h deleted file mode 100644 index 1bd34d32..00000000 --- a/android/x86/include/spidermonkey/mozilla/Compiler.h +++ /dev/null @@ -1,113 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Various compiler checks. */ - -#ifndef mozilla_Compiler_h -#define mozilla_Compiler_h - -#define MOZ_IS_GCC 0 -#define MOZ_IS_MSVC 0 - -#if !defined(__clang__) && defined(__GNUC__) - -# undef MOZ_IS_GCC -# define MOZ_IS_GCC 1 - /* - * These macros should simplify gcc version checking. For example, to check - * for gcc 4.7.1 or later, check `#if MOZ_GCC_VERSION_AT_LEAST(4, 7, 1)`. - */ -# define MOZ_GCC_VERSION_AT_LEAST(major, minor, patchlevel) \ - ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) \ - >= ((major) * 10000 + (minor) * 100 + (patchlevel))) -# define MOZ_GCC_VERSION_AT_MOST(major, minor, patchlevel) \ - ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) \ - <= ((major) * 10000 + (minor) * 100 + (patchlevel))) -# if !MOZ_GCC_VERSION_AT_LEAST(4, 8, 0) -# error "mfbt (and Gecko) require at least gcc 4.8 to build." -# endif - -#elif defined(_MSC_VER) - -# undef MOZ_IS_MSVC -# define MOZ_IS_MSVC 1 - -#endif - -/* - * The situation with standard libraries is a lot worse than with compilers, - * particularly as clang and gcc could end up using one of three or so standard - * libraries, and they may not be up-to-snuff with newer C++11 versions. To - * detect the library, we're going to include cstddef (which is a small header - * which will be transitively included by everybody else at some point) to grab - * the version macros and deduce macros from there. - */ -#ifdef __cplusplus -# include -# ifdef _STLPORT_MAJOR -# define MOZ_USING_STLPORT 1 -# define MOZ_STLPORT_VERSION_AT_LEAST(major, minor, patch) \ - (_STLPORT_VERSION >= ((major) << 8 | (minor) << 4 | (patch))) -# elif defined(_LIBCPP_VERSION) - /* - * libc++, unfortunately, doesn't appear to have useful versioning macros. - * Hopefully, the recommendations of N3694 with respect to standard libraries - * will get applied instead and we won't need to worry about version numbers - * here. - */ -# define MOZ_USING_LIBCXX 1 -# elif defined(__GLIBCXX__) -# define MOZ_USING_LIBSTDCXX 1 - /* - * libstdc++ is also annoying and doesn't give us useful versioning macros - * for the library. If we're using gcc, then assume that libstdc++ matches - * the compiler version. If we're using clang, we're going to have to fake - * major/minor combinations by looking for newly-defined config macros. - */ -# if MOZ_IS_GCC -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - MOZ_GCC_VERSION_AT_LEAST(major, minor, patch) -# elif defined(_GLIBCXX_THROW_OR_ABORT) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 8)) -# elif defined(_GLIBCXX_NOEXCEPT) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 7)) -# elif defined(_GLIBCXX_USE_DEPRECATED) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 6)) -# elif defined(_GLIBCXX_PSEUDO_VISIBILITY) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 5)) -# elif defined(_GLIBCXX_BEGIN_EXTERN_C) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 4)) -# elif defined(_GLIBCXX_VISIBILITY_ATTR) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 3)) -# elif defined(_GLIBCXX_VISIBILITY) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 2)) -# else -# error "Your version of libstdc++ is unknown to us and is likely too old." -# endif -# endif - - // Flesh out the defines for everyone else -# ifndef MOZ_USING_STLPORT -# define MOZ_USING_STLPORT 0 -# define MOZ_STLPORT_VERSION_AT_LEAST(major, minor, patch) 0 -# endif -# ifndef MOZ_USING_LIBCXX -# define MOZ_USING_LIBCXX 0 -# endif -# ifndef MOZ_USING_LIBSTDCXX -# define MOZ_USING_LIBSTDCXX 0 -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) 0 -# endif -#endif /* __cplusplus */ - -#endif /* mozilla_Compiler_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Compression.h b/android/x86/include/spidermonkey/mozilla/Compression.h deleted file mode 100644 index aa50211b..00000000 --- a/android/x86/include/spidermonkey/mozilla/Compression.h +++ /dev/null @@ -1,119 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Various simple compression/decompression functions. */ - -#ifndef mozilla_Compression_h_ -#define mozilla_Compression_h_ - -#include "mozilla/Assertions.h" -#include "mozilla/Types.h" - -namespace mozilla { -namespace Compression { - -/** - * LZ4 is a very fast byte-wise compression algorithm. - * - * Compared to Google's Snappy it is faster to compress and decompress and - * generally produces output of about the same size. - * - * Compared to zlib it compresses at about 10x the speed, decompresses at about - * 4x the speed and produces output of about 1.5x the size. - */ - -class LZ4 -{ -public: - /** - * Compresses |aInputSize| bytes from |aSource| into |aDest|. Destination - * buffer must be already allocated, and must be sized to handle worst cases - * situations (input data not compressible). Worst case size evaluation is - * provided by function maxCompressedSize() - * - * @param aInputSize is the input size. Max supported value is ~1.9GB - * @return the number of bytes written in buffer |aDest| - */ - static MFBT_API size_t - compress(const char* aSource, size_t aInputSize, char* aDest); - - /** - * Compress |aInputSize| bytes from |aSource| into an output buffer - * |aDest| of maximum size |aMaxOutputSize|. If it cannot achieve it, - * compression will stop, and result of the function will be zero, - * |aDest| will still be written to, but since the number of input - * bytes consumed is not returned the result is not usable. - * - * This function never writes outside of provided output buffer. - * - * @param aInputSize is the input size. Max supported value is ~1.9GB - * @param aMaxOutputSize is the size of the destination buffer (which must - * be already allocated) - * @return the number of bytes written in buffer |aDest| or 0 if the - * compression fails - */ - static MFBT_API size_t - compressLimitedOutput(const char* aSource, size_t aInputSize, char* aDest, - size_t aMaxOutputSize); - - /** - * If the source stream is malformed, the function will stop decoding - * and return false. - * - * This function never writes outside of provided buffers, and never - * modifies input buffer. - * - * Note: destination buffer must be already allocated, and its size must be a - * minimum of |aOutputSize| bytes. - * - * @param aOutputSize is the output size, therefore the original size - * @return true on success, false on failure - */ - static MFBT_API MOZ_MUST_USE bool - decompress(const char* aSource, char* aDest, size_t aOutputSize); - - /** - * If the source stream is malformed, the function will stop decoding - * and return false. - * - * This function never writes beyond aDest + aMaxOutputSize, and is - * therefore protected against malicious data packets. - * - * Note: Destination buffer must be already allocated. This version is - * slightly slower than the decompress without the aMaxOutputSize. - * - * @param aInputSize is the length of the input compressed data - * @param aMaxOutputSize is the size of the destination buffer (which must be - * already allocated) - * @param aOutputSize the actual number of bytes decoded in the destination - * buffer (necessarily <= aMaxOutputSize) - * @return true on success, false on failure - */ - static MFBT_API MOZ_MUST_USE bool - decompress(const char* aSource, size_t aInputSize, char* aDest, - size_t aMaxOutputSize, size_t* aOutputSize); - - /* - * Provides the maximum size that LZ4 may output in a "worst case" - * scenario (input data not compressible) primarily useful for memory - * allocation of output buffer. - * note : this function is limited by "int" range (2^31-1) - * - * @param aInputSize is the input size. Max supported value is ~1.9GB - * @return maximum output size in a "worst case" scenario - */ - static inline size_t maxCompressedSize(size_t aInputSize) - { - size_t max = (aInputSize + (aInputSize / 255) + 16); - MOZ_ASSERT(max > aInputSize); - return max; - } -}; - -} /* namespace Compression */ -} /* namespace mozilla */ - -#endif /* mozilla_Compression_h_ */ diff --git a/android/x86/include/spidermonkey/mozilla/DebugOnly.h b/android/x86/include/spidermonkey/mozilla/DebugOnly.h deleted file mode 100644 index a1a669db..00000000 --- a/android/x86/include/spidermonkey/mozilla/DebugOnly.h +++ /dev/null @@ -1,92 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Provides DebugOnly, a type for variables used only in debug builds (i.e. by - * assertions). - */ - -#ifndef mozilla_DebugOnly_h -#define mozilla_DebugOnly_h - -#include "mozilla/Attributes.h" - -namespace mozilla { - -/** - * DebugOnly contains a value of type T, but only in debug builds. In release - * builds, it does not contain a value. This helper is intended to be used with - * MOZ_ASSERT()-style macros, allowing one to write: - * - * DebugOnly check = func(); - * MOZ_ASSERT(check); - * - * more concisely than declaring |check| conditional on #ifdef DEBUG. - * - * DebugOnly instances can only be coerced to T in debug builds. In release - * builds they don't have a value, so type coercion is not well defined. - * - * NOTE: DebugOnly instances still take up one byte of space, plus padding, even - * in optimized, non-DEBUG builds (see bug 1253094 comment 37 for more info). - * For this reason the class is MOZ_STACK_CLASS to prevent consumers using - * DebugOnly for struct/class members and unwittingly inflating the size of - * their objects in release builds. - */ -template -class MOZ_STACK_CLASS DebugOnly -{ -public: -#ifdef DEBUG - T value; - - DebugOnly() { } - MOZ_IMPLICIT DebugOnly(const T& aOther) : value(aOther) { } - DebugOnly(const DebugOnly& aOther) : value(aOther.value) { } - DebugOnly& operator=(const T& aRhs) { - value = aRhs; - return *this; - } - - void operator++(int) { value++; } - void operator--(int) { value--; } - - // Do not define operator+=(), etc. here. These will coerce via the - // implicit cast and built-in operators. Defining explicit methods here - // will create ambiguity the compiler can't deal with. - - T* operator&() { return &value; } - - operator T&() { return value; } - operator const T&() const { return value; } - - T& operator->() { return value; } - const T& operator->() const { return value; } - -#else - DebugOnly() { } - MOZ_IMPLICIT DebugOnly(const T&) { } - DebugOnly(const DebugOnly&) { } - DebugOnly& operator=(const T&) { return *this; } - void operator++(int) { } - void operator--(int) { } - DebugOnly& operator+=(const T&) { return *this; } - DebugOnly& operator-=(const T&) { return *this; } - DebugOnly& operator&=(const T&) { return *this; } - DebugOnly& operator|=(const T&) { return *this; } - DebugOnly& operator^=(const T&) { return *this; } -#endif - - /* - * DebugOnly must always have a destructor or else it will - * generate "unused variable" warnings, exactly what it's intended - * to avoid! - */ - ~DebugOnly() {} -}; - -} // namespace mozilla - -#endif /* mozilla_DebugOnly_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Decimal.h b/android/x86/include/spidermonkey/mozilla/Decimal.h deleted file mode 100644 index 10d0e2c7..00000000 --- a/android/x86/include/spidermonkey/mozilla/Decimal.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Imported from: - * https://chromium.googlesource.com/chromium/src.git/+/master/third_party/WebKit/Source/platform/Decimal.h - * Check UPSTREAM-GIT-SHA for the commit ID of the last update from Blink core. - */ - -#ifndef Decimal_h -#define Decimal_h - -#include "mozilla/Assertions.h" -#include -#include "mozilla/Types.h" - -#include - -#ifndef ASSERT -#define DEFINED_ASSERT_FOR_DECIMAL_H 1 -#define ASSERT MOZ_ASSERT -#endif - -#define PLATFORM_EXPORT - -// To use USING_FAST_MALLOC we'd need: -// https://chromium.googlesource.com/chromium/src.git/+/master/third_party/WebKit/Source/wtf/Allocator.h -// Since we don't allocate Decimal objects, no need. -#define USING_FAST_MALLOC(type) \ - void ignore_this_dummy_method() = delete - -#define DISALLOW_NEW() \ - private: \ - void* operator new(size_t) = delete; \ - void* operator new(size_t, void*) = delete; \ - public: - -namespace blink { - -namespace DecimalPrivate { -class SpecialValueHandler; -} - -// This class represents decimal base floating point number. -// -// FIXME: Once all C++ compiler support decimal type, we should replace this -// class to compiler supported one. See below URI for current status of decimal -// type for C++: // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1977.html -class PLATFORM_EXPORT Decimal { - USING_FAST_MALLOC(Decimal); -public: - enum Sign { - Positive, - Negative, - }; - - // You should not use EncodedData other than unit testing. - class EncodedData { - DISALLOW_NEW(); - // For accessing FormatClass. - friend class Decimal; - friend class DecimalPrivate::SpecialValueHandler; - public: - EncodedData(Sign, int exponent, uint64_t coefficient); - - bool operator==(const EncodedData&) const; - bool operator!=(const EncodedData& another) const { return !operator==(another); } - - uint64_t coefficient() const { return m_coefficient; } - int countDigits() const; - int exponent() const { return m_exponent; } - bool isFinite() const { return !isSpecial(); } - bool isInfinity() const { return m_formatClass == ClassInfinity; } - bool isNaN() const { return m_formatClass == ClassNaN; } - bool isSpecial() const { return m_formatClass == ClassInfinity || m_formatClass == ClassNaN; } - bool isZero() const { return m_formatClass == ClassZero; } - Sign sign() const { return m_sign; } - void setSign(Sign sign) { m_sign = sign; } - - private: - enum FormatClass { - ClassInfinity, - ClassNormal, - ClassNaN, - ClassZero, - }; - - EncodedData(Sign, FormatClass); - FormatClass formatClass() const { return m_formatClass; } - - uint64_t m_coefficient; - int16_t m_exponent; - FormatClass m_formatClass; - Sign m_sign; - }; - - MFBT_API explicit Decimal(int32_t = 0); - MFBT_API Decimal(Sign, int exponent, uint64_t coefficient); - MFBT_API Decimal(const Decimal&); - - MFBT_API Decimal& operator=(const Decimal&); - MFBT_API Decimal& operator+=(const Decimal&); - MFBT_API Decimal& operator-=(const Decimal&); - MFBT_API Decimal& operator*=(const Decimal&); - MFBT_API Decimal& operator/=(const Decimal&); - - MFBT_API Decimal operator-() const; - - MFBT_API bool operator==(const Decimal&) const; - MFBT_API bool operator!=(const Decimal&) const; - MFBT_API bool operator<(const Decimal&) const; - MFBT_API bool operator<=(const Decimal&) const; - MFBT_API bool operator>(const Decimal&) const; - MFBT_API bool operator>=(const Decimal&) const; - - MFBT_API Decimal operator+(const Decimal&) const; - MFBT_API Decimal operator-(const Decimal&) const; - MFBT_API Decimal operator*(const Decimal&) const; - MFBT_API Decimal operator/(const Decimal&) const; - - int exponent() const - { - ASSERT(isFinite()); - return m_data.exponent(); - } - - bool isFinite() const { return m_data.isFinite(); } - bool isInfinity() const { return m_data.isInfinity(); } - bool isNaN() const { return m_data.isNaN(); } - bool isNegative() const { return sign() == Negative; } - bool isPositive() const { return sign() == Positive; } - bool isSpecial() const { return m_data.isSpecial(); } - bool isZero() const { return m_data.isZero(); } - - MFBT_API Decimal abs() const; - MFBT_API Decimal ceil() const; - MFBT_API Decimal floor() const; - MFBT_API Decimal remainder(const Decimal&) const; - MFBT_API Decimal round() const; - - MFBT_API double toDouble() const; - // Note: toString method supports infinity and nan but fromString not. - MFBT_API std::string toString() const; - MFBT_API bool toString(char* strBuf, size_t bufLength) const; - - static MFBT_API Decimal fromDouble(double); - // fromString supports following syntax EBNF: - // number ::= sign? digit+ ('.' digit*) (exponent-marker sign? digit+)? - // | sign? '.' digit+ (exponent-marker sign? digit+)? - // sign ::= '+' | '-' - // exponent-marker ::= 'e' | 'E' - // digit ::= '0' | '1' | ... | '9' - // Note: fromString doesn't support "infinity" and "nan". - static MFBT_API Decimal fromString(const std::string& aValue); - static MFBT_API Decimal infinity(Sign); - static MFBT_API Decimal nan(); - static MFBT_API Decimal zero(Sign); - - // You should not use below methods. We expose them for unit testing. - MFBT_API explicit Decimal(const EncodedData&); - const EncodedData& value() const { return m_data; } - -private: - struct AlignedOperands { - uint64_t lhsCoefficient; - uint64_t rhsCoefficient; - int exponent; - }; - - MFBT_API explicit Decimal(double); - MFBT_API Decimal compareTo(const Decimal&) const; - - static MFBT_API AlignedOperands alignOperands(const Decimal& lhs, const Decimal& rhs); - static inline Sign invertSign(Sign sign) { return sign == Negative ? Positive : Negative; } - - Sign sign() const { return m_data.sign(); } - - EncodedData m_data; -}; - -} // namespace blink - -namespace mozilla { -typedef blink::Decimal Decimal; -} // namespace mozilla - -#undef USING_FAST_MALLOC - -#ifdef DEFINED_ASSERT_FOR_DECIMAL_H -#undef DEFINED_ASSERT_FOR_DECIMAL_H -#undef ASSERT -#endif - -#endif // Decimal_h diff --git a/android/x86/include/spidermonkey/mozilla/EndianUtils.h b/android/x86/include/spidermonkey/mozilla/EndianUtils.h deleted file mode 100644 index 00815580..00000000 --- a/android/x86/include/spidermonkey/mozilla/EndianUtils.h +++ /dev/null @@ -1,695 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Functions for reading and writing integers in various endiannesses. */ - -/* - * The classes LittleEndian and BigEndian expose static methods for - * reading and writing 16-, 32-, and 64-bit signed and unsigned integers - * in their respective endianness. The naming scheme is: - * - * {Little,Big}Endian::{read,write}{Uint,Int} - * - * For instance, LittleEndian::readInt32 will read a 32-bit signed - * integer from memory in little endian format. Similarly, - * BigEndian::writeUint16 will write a 16-bit unsigned integer to memory - * in big-endian format. - * - * The class NativeEndian exposes methods for conversion of existing - * data to and from the native endianness. These methods are intended - * for cases where data needs to be transferred, serialized, etc. - * swap{To,From}{Little,Big}Endian byteswap a single value if necessary. - * Bulk conversion functions are also provided which optimize the - * no-conversion-needed case: - * - * - copyAndSwap{To,From}{Little,Big}Endian; - * - swap{To,From}{Little,Big}EndianInPlace. - * - * The *From* variants are intended to be used for reading data and the - * *To* variants for writing data. - * - * Methods on NativeEndian work with integer data of any type. - * Floating-point data is not supported. - * - * For clarity in networking code, "Network" may be used as a synonym - * for "Big" in any of the above methods or class names. - * - * As an example, reading a file format header whose fields are stored - * in big-endian format might look like: - * - * class ExampleHeader - * { - * private: - * uint32_t mMagic; - * uint32_t mLength; - * uint32_t mTotalRecords; - * uint64_t mChecksum; - * - * public: - * ExampleHeader(const void* data) - * { - * const uint8_t* ptr = static_cast(data); - * mMagic = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); - * mLength = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); - * mTotalRecords = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); - * mChecksum = BigEndian::readUint64(ptr); - * } - * ... - * }; - */ - -#ifndef mozilla_EndianUtils_h -#define mozilla_EndianUtils_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Compiler.h" -#include "mozilla/DebugOnly.h" -#include "mozilla/TypeTraits.h" - -#include -#include - -#if defined(_MSC_VER) -# include -# pragma intrinsic(_byteswap_ushort) -# pragma intrinsic(_byteswap_ulong) -# pragma intrinsic(_byteswap_uint64) -#endif - -#if defined(_WIN64) -# if defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_) -# define MOZ_LITTLE_ENDIAN 1 -# else -# error "CPU type is unknown" -# endif -#elif defined(_WIN32) -# if defined(_M_IX86) -# define MOZ_LITTLE_ENDIAN 1 -# elif defined(_M_ARM) -# define MOZ_LITTLE_ENDIAN 1 -# else -# error "CPU type is unknown" -# endif -#elif defined(__APPLE__) || defined(__powerpc__) || defined(__ppc__) -# if __LITTLE_ENDIAN__ -# define MOZ_LITTLE_ENDIAN 1 -# elif __BIG_ENDIAN__ -# define MOZ_BIG_ENDIAN 1 -# endif -#elif defined(__GNUC__) && \ - defined(__BYTE_ORDER__) && \ - defined(__ORDER_LITTLE_ENDIAN__) && \ - defined(__ORDER_BIG_ENDIAN__) - /* - * Some versions of GCC provide architecture-independent macros for - * this. Yes, there are more than two values for __BYTE_ORDER__. - */ -# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -# define MOZ_LITTLE_ENDIAN 1 -# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -# define MOZ_BIG_ENDIAN 1 -# else -# error "Can't handle mixed-endian architectures" -# endif -/* - * We can't include useful headers like or - * here because they're not present on all platforms. Instead we have - * this big conditional that ideally will catch all the interesting - * cases. - */ -#elif defined(__sparc) || defined(__sparc__) || \ - defined(_POWER) || defined(__hppa) || \ - defined(_MIPSEB) || defined(__ARMEB__) || \ - defined(__s390__) || defined(__AARCH64EB__) || \ - (defined(__sh__) && defined(__LITTLE_ENDIAN__)) || \ - (defined(__ia64) && defined(__BIG_ENDIAN__)) -# define MOZ_BIG_ENDIAN 1 -#elif defined(__i386) || defined(__i386__) || \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_MIPSEL) || defined(__ARMEL__) || \ - defined(__alpha__) || defined(__AARCH64EL__) || \ - (defined(__sh__) && defined(__BIG_ENDIAN__)) || \ - (defined(__ia64) && !defined(__BIG_ENDIAN__)) -# define MOZ_LITTLE_ENDIAN 1 -#endif - -#if MOZ_BIG_ENDIAN -# define MOZ_LITTLE_ENDIAN 0 -#elif MOZ_LITTLE_ENDIAN -# define MOZ_BIG_ENDIAN 0 -#else -# error "Cannot determine endianness" -#endif - -#if defined(__clang__) -# if __has_builtin(__builtin_bswap16) -# define MOZ_HAVE_BUILTIN_BYTESWAP16 __builtin_bswap16 -# endif -#elif defined(__GNUC__) -# define MOZ_HAVE_BUILTIN_BYTESWAP16 __builtin_bswap16 -#elif defined(_MSC_VER) -# define MOZ_HAVE_BUILTIN_BYTESWAP16 _byteswap_ushort -#endif - -namespace mozilla { - -namespace detail { - -/* - * We need wrappers here because free functions with default template - * arguments and/or partial specialization of function templates are not - * supported by all the compilers we use. - */ -template -struct Swapper; - -template -struct Swapper -{ - static T swap(T aValue) - { -#if defined(MOZ_HAVE_BUILTIN_BYTESWAP16) - return MOZ_HAVE_BUILTIN_BYTESWAP16(aValue); -#else - return T(((aValue & 0x00ff) << 8) | ((aValue & 0xff00) >> 8)); -#endif - } -}; - -template -struct Swapper -{ - static T swap(T aValue) - { -#if defined(__clang__) || defined(__GNUC__) - return T(__builtin_bswap32(aValue)); -#elif defined(_MSC_VER) - return T(_byteswap_ulong(aValue)); -#else - return T(((aValue & 0x000000ffU) << 24) | - ((aValue & 0x0000ff00U) << 8) | - ((aValue & 0x00ff0000U) >> 8) | - ((aValue & 0xff000000U) >> 24)); -#endif - } -}; - -template -struct Swapper -{ - static inline T swap(T aValue) - { -#if defined(__clang__) || defined(__GNUC__) - return T(__builtin_bswap64(aValue)); -#elif defined(_MSC_VER) - return T(_byteswap_uint64(aValue)); -#else - return T(((aValue & 0x00000000000000ffULL) << 56) | - ((aValue & 0x000000000000ff00ULL) << 40) | - ((aValue & 0x0000000000ff0000ULL) << 24) | - ((aValue & 0x00000000ff000000ULL) << 8) | - ((aValue & 0x000000ff00000000ULL) >> 8) | - ((aValue & 0x0000ff0000000000ULL) >> 24) | - ((aValue & 0x00ff000000000000ULL) >> 40) | - ((aValue & 0xff00000000000000ULL) >> 56)); -#endif - } -}; - -enum Endianness { Little, Big }; - -#if MOZ_BIG_ENDIAN -# define MOZ_NATIVE_ENDIANNESS detail::Big -#else -# define MOZ_NATIVE_ENDIANNESS detail::Little -#endif - -class EndianUtils -{ - /** - * Assert that the memory regions [aDest, aDest+aCount) and - * [aSrc, aSrc+aCount] do not overlap. aCount is given in bytes. - */ - static void assertNoOverlap(const void* aDest, const void* aSrc, - size_t aCount) - { - DebugOnly byteDestPtr = static_cast(aDest); - DebugOnly byteSrcPtr = static_cast(aSrc); - MOZ_ASSERT((byteDestPtr <= byteSrcPtr && - byteDestPtr + aCount <= byteSrcPtr) || - (byteSrcPtr <= byteDestPtr && - byteSrcPtr + aCount <= byteDestPtr)); - } - - template - static void assertAligned(T* aPtr) - { - MOZ_ASSERT((uintptr_t(aPtr) % sizeof(T)) == 0, "Unaligned pointer!"); - } - -protected: - /** - * Return |aValue| converted from SourceEndian encoding to DestEndian - * encoding. - */ - template - static inline T maybeSwap(T aValue) - { - if (SourceEndian == DestEndian) { - return aValue; - } - return Swapper::swap(aValue); - } - - /** - * Convert |aCount| elements at |aPtr| from SourceEndian encoding to - * DestEndian encoding. - */ - template - static inline void maybeSwapInPlace(T* aPtr, size_t aCount) - { - assertAligned(aPtr); - - if (SourceEndian == DestEndian) { - return; - } - for (size_t i = 0; i < aCount; i++) { - aPtr[i] = Swapper::swap(aPtr[i]); - } - } - - /** - * Write |aCount| elements to the unaligned address |aDest| in DestEndian - * format, using elements found at |aSrc| in SourceEndian format. - */ - template - static void copyAndSwapTo(void* aDest, const T* aSrc, size_t aCount) - { - assertNoOverlap(aDest, aSrc, aCount * sizeof(T)); - assertAligned(aSrc); - - if (SourceEndian == DestEndian) { - memcpy(aDest, aSrc, aCount * sizeof(T)); - return; - } - - uint8_t* byteDestPtr = static_cast(aDest); - for (size_t i = 0; i < aCount; ++i) { - union - { - T mVal; - uint8_t mBuffer[sizeof(T)]; - } u; - u.mVal = maybeSwap(aSrc[i]); - memcpy(byteDestPtr, u.mBuffer, sizeof(T)); - byteDestPtr += sizeof(T); - } - } - - /** - * Write |aCount| elements to |aDest| in DestEndian format, using elements - * found at the unaligned address |aSrc| in SourceEndian format. - */ - template - static void copyAndSwapFrom(T* aDest, const void* aSrc, size_t aCount) - { - assertNoOverlap(aDest, aSrc, aCount * sizeof(T)); - assertAligned(aDest); - - if (SourceEndian == DestEndian) { - memcpy(aDest, aSrc, aCount * sizeof(T)); - return; - } - - const uint8_t* byteSrcPtr = static_cast(aSrc); - for (size_t i = 0; i < aCount; ++i) { - union - { - T mVal; - uint8_t mBuffer[sizeof(T)]; - } u; - memcpy(u.mBuffer, byteSrcPtr, sizeof(T)); - aDest[i] = maybeSwap(u.mVal); - byteSrcPtr += sizeof(T); - } - } -}; - -template -class Endian : private EndianUtils -{ -protected: - /** Read a uint16_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE uint16_t readUint16(const void* aPtr) - { - return read(aPtr); - } - - /** Read a uint32_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE uint32_t readUint32(const void* aPtr) - { - return read(aPtr); - } - - /** Read a uint64_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE uint64_t readUint64(const void* aPtr) - { - return read(aPtr); - } - - /** Read an int16_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE int16_t readInt16(const void* aPtr) - { - return read(aPtr); - } - - /** Read an int32_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE int32_t readInt32(const void* aPtr) - { - return read(aPtr); - } - - /** Read an int64_t in ThisEndian endianness from |aPtr| and return it. */ - static MOZ_MUST_USE int64_t readInt64(const void* aPtr) - { - return read(aPtr); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeUint16(void* aPtr, uint16_t aValue) - { - write(aPtr, aValue); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeUint32(void* aPtr, uint32_t aValue) - { - write(aPtr, aValue); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeUint64(void* aPtr, uint64_t aValue) - { - write(aPtr, aValue); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeInt16(void* aPtr, int16_t aValue) - { - write(aPtr, aValue); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeInt32(void* aPtr, int32_t aValue) - { - write(aPtr, aValue); - } - - /** Write |aValue| to |aPtr| using ThisEndian endianness. */ - static void writeInt64(void* aPtr, int64_t aValue) - { - write(aPtr, aValue); - } - - /* - * Converts a value of type T to little-endian format. - * - * This function is intended for cases where you have data in your - * native-endian format and you need it to appear in little-endian - * format for transmission. - */ - template - MOZ_MUST_USE static T swapToLittleEndian(T aValue) - { - return maybeSwap(aValue); - } - - /* - * Copies |aCount| values of type T starting at |aSrc| to |aDest|, converting - * them to little-endian format if ThisEndian is Big. - * As with memcpy, |aDest| and |aSrc| must not overlap. - */ - template - static void copyAndSwapToLittleEndian(void* aDest, const T* aSrc, - size_t aCount) - { - copyAndSwapTo(aDest, aSrc, aCount); - } - - /* - * Likewise, but converts values in place. - */ - template - static void swapToLittleEndianInPlace(T* aPtr, size_t aCount) - { - maybeSwapInPlace(aPtr, aCount); - } - - /* - * Converts a value of type T to big-endian format. - */ - template - MOZ_MUST_USE static T swapToBigEndian(T aValue) - { - return maybeSwap(aValue); - } - - /* - * Copies |aCount| values of type T starting at |aSrc| to |aDest|, converting - * them to big-endian format if ThisEndian is Little. - * As with memcpy, |aDest| and |aSrc| must not overlap. - */ - template - static void copyAndSwapToBigEndian(void* aDest, const T* aSrc, - size_t aCount) - { - copyAndSwapTo(aDest, aSrc, aCount); - } - - /* - * Likewise, but converts values in place. - */ - template - static void swapToBigEndianInPlace(T* aPtr, size_t aCount) - { - maybeSwapInPlace(aPtr, aCount); - } - - /* - * Synonyms for the big-endian functions, for better readability - * in network code. - */ - - template - MOZ_MUST_USE static T swapToNetworkOrder(T aValue) - { - return swapToBigEndian(aValue); - } - - template - static void - copyAndSwapToNetworkOrder(void* aDest, const T* aSrc, size_t aCount) - { - copyAndSwapToBigEndian(aDest, aSrc, aCount); - } - - template - static void - swapToNetworkOrderInPlace(T* aPtr, size_t aCount) - { - swapToBigEndianInPlace(aPtr, aCount); - } - - /* - * Converts a value of type T from little-endian format. - */ - template - MOZ_MUST_USE static T swapFromLittleEndian(T aValue) - { - return maybeSwap(aValue); - } - - /* - * Copies |aCount| values of type T starting at |aSrc| to |aDest|, converting - * them to little-endian format if ThisEndian is Big. - * As with memcpy, |aDest| and |aSrc| must not overlap. - */ - template - static void copyAndSwapFromLittleEndian(T* aDest, const void* aSrc, - size_t aCount) - { - copyAndSwapFrom(aDest, aSrc, aCount); - } - - /* - * Likewise, but converts values in place. - */ - template - static void swapFromLittleEndianInPlace(T* aPtr, size_t aCount) - { - maybeSwapInPlace(aPtr, aCount); - } - - /* - * Converts a value of type T from big-endian format. - */ - template - MOZ_MUST_USE static T swapFromBigEndian(T aValue) - { - return maybeSwap(aValue); - } - - /* - * Copies |aCount| values of type T starting at |aSrc| to |aDest|, converting - * them to big-endian format if ThisEndian is Little. - * As with memcpy, |aDest| and |aSrc| must not overlap. - */ - template - static void copyAndSwapFromBigEndian(T* aDest, const void* aSrc, - size_t aCount) - { - copyAndSwapFrom(aDest, aSrc, aCount); - } - - /* - * Likewise, but converts values in place. - */ - template - static void swapFromBigEndianInPlace(T* aPtr, size_t aCount) - { - maybeSwapInPlace(aPtr, aCount); - } - - /* - * Synonyms for the big-endian functions, for better readability - * in network code. - */ - template - MOZ_MUST_USE static T swapFromNetworkOrder(T aValue) - { - return swapFromBigEndian(aValue); - } - - template - static void copyAndSwapFromNetworkOrder(T* aDest, const void* aSrc, - size_t aCount) - { - copyAndSwapFromBigEndian(aDest, aSrc, aCount); - } - - template - static void swapFromNetworkOrderInPlace(T* aPtr, size_t aCount) - { - swapFromBigEndianInPlace(aPtr, aCount); - } - -private: - /** - * Read a value of type T, encoded in endianness ThisEndian from |aPtr|. - * Return that value encoded in native endianness. - */ - template - static T read(const void* aPtr) - { - union - { - T mVal; - uint8_t mBuffer[sizeof(T)]; - } u; - memcpy(u.mBuffer, aPtr, sizeof(T)); - return maybeSwap(u.mVal); - } - - /** - * Write a value of type T, in native endianness, to |aPtr|, in ThisEndian - * endianness. - */ - template - static void write(void* aPtr, T aValue) - { - T tmp = maybeSwap(aValue); - memcpy(aPtr, &tmp, sizeof(T)); - } - - Endian() = delete; - Endian(const Endian& aTther) = delete; - void operator=(const Endian& aOther) = delete; -}; - -template -class EndianReadWrite : public Endian -{ -private: - typedef Endian super; - -public: - using super::readUint16; - using super::readUint32; - using super::readUint64; - using super::readInt16; - using super::readInt32; - using super::readInt64; - using super::writeUint16; - using super::writeUint32; - using super::writeUint64; - using super::writeInt16; - using super::writeInt32; - using super::writeInt64; -}; - -} /* namespace detail */ - -class LittleEndian final : public detail::EndianReadWrite -{}; - -class BigEndian final : public detail::EndianReadWrite -{}; - -typedef BigEndian NetworkEndian; - -class NativeEndian final : public detail::Endian -{ -private: - typedef detail::Endian super; - -public: - /* - * These functions are intended for cases where you have data in your - * native-endian format and you need the data to appear in the appropriate - * endianness for transmission, serialization, etc. - */ - using super::swapToLittleEndian; - using super::copyAndSwapToLittleEndian; - using super::swapToLittleEndianInPlace; - using super::swapToBigEndian; - using super::copyAndSwapToBigEndian; - using super::swapToBigEndianInPlace; - using super::swapToNetworkOrder; - using super::copyAndSwapToNetworkOrder; - using super::swapToNetworkOrderInPlace; - - /* - * These functions are intended for cases where you have data in the - * given endianness (e.g. reading from disk or a file-format) and you - * need the data to appear in native-endian format for processing. - */ - using super::swapFromLittleEndian; - using super::copyAndSwapFromLittleEndian; - using super::swapFromLittleEndianInPlace; - using super::swapFromBigEndian; - using super::copyAndSwapFromBigEndian; - using super::swapFromBigEndianInPlace; - using super::swapFromNetworkOrder; - using super::copyAndSwapFromNetworkOrder; - using super::swapFromNetworkOrderInPlace; -}; - -#undef MOZ_NATIVE_ENDIANNESS - -} /* namespace mozilla */ - -#endif /* mozilla_EndianUtils_h */ diff --git a/android/x86/include/spidermonkey/mozilla/EnumSet.h b/android/x86/include/spidermonkey/mozilla/EnumSet.h deleted file mode 100644 index 5282ab30..00000000 --- a/android/x86/include/spidermonkey/mozilla/EnumSet.h +++ /dev/null @@ -1,344 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A set abstraction for enumeration values. */ - -#ifndef mozilla_EnumSet_h -#define mozilla_EnumSet_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -#include - -#include - -namespace mozilla { - -/** - * EnumSet is a set of values defined by an enumeration. It is implemented - * using a 32 bit mask for each value so it will only work for enums with an int - * representation less than 32. It works both for enum and enum class types. - */ -template -class EnumSet -{ -public: - EnumSet() - : mBitField(0) - { - initVersion(); - } - - MOZ_IMPLICIT EnumSet(T aEnum) - : mBitField(bitFor(aEnum)) - { } - - EnumSet(T aEnum1, T aEnum2) - : mBitField(bitFor(aEnum1) | - bitFor(aEnum2)) - { - initVersion(); - } - - EnumSet(T aEnum1, T aEnum2, T aEnum3) - : mBitField(bitFor(aEnum1) | - bitFor(aEnum2) | - bitFor(aEnum3)) - { - initVersion(); - } - - EnumSet(T aEnum1, T aEnum2, T aEnum3, T aEnum4) - : mBitField(bitFor(aEnum1) | - bitFor(aEnum2) | - bitFor(aEnum3) | - bitFor(aEnum4)) - { - initVersion(); - } - - MOZ_IMPLICIT EnumSet(std::initializer_list list) - : mBitField(0) - { - for (auto value : list) { - (*this) += value; - } - initVersion(); - } - - EnumSet(const EnumSet& aEnumSet) - : mBitField(aEnumSet.mBitField) - { - initVersion(); - } - - /** - * Add an element - */ - void operator+=(T aEnum) - { - incVersion(); - mBitField |= bitFor(aEnum); - } - - /** - * Add an element - */ - EnumSet operator+(T aEnum) const - { - EnumSet result(*this); - result += aEnum; - return result; - } - - /** - * Union - */ - void operator+=(const EnumSet aEnumSet) - { - incVersion(); - mBitField |= aEnumSet.mBitField; - } - - /** - * Union - */ - EnumSet operator+(const EnumSet aEnumSet) const - { - EnumSet result(*this); - result += aEnumSet; - return result; - } - - /** - * Remove an element - */ - void operator-=(T aEnum) - { - incVersion(); - mBitField &= ~(bitFor(aEnum)); - } - - /** - * Remove an element - */ - EnumSet operator-(T aEnum) const - { - EnumSet result(*this); - result -= aEnum; - return result; - } - - /** - * Remove a set of elements - */ - void operator-=(const EnumSet aEnumSet) - { - incVersion(); - mBitField &= ~(aEnumSet.mBitField); - } - - /** - * Remove a set of elements - */ - EnumSet operator-(const EnumSet aEnumSet) const - { - EnumSet result(*this); - result -= aEnumSet; - return result; - } - - /** - * Clear - */ - void clear() - { - incVersion(); - mBitField = 0; - } - - /** - * Intersection - */ - void operator&=(const EnumSet aEnumSet) - { - incVersion(); - mBitField &= aEnumSet.mBitField; - } - - /** - * Intersection - */ - EnumSet operator&(const EnumSet aEnumSet) const - { - EnumSet result(*this); - result &= aEnumSet; - return result; - } - - /** - * Equality - */ - bool operator==(const EnumSet aEnumSet) const - { - return mBitField == aEnumSet.mBitField; - } - - /** - * Test is an element is contained in the set. - */ - bool contains(T aEnum) const - { - return mBitField & bitFor(aEnum); - } - - /** - * Return the number of elements in the set. - */ - uint8_t size() const - { - uint8_t count = 0; - for (uint32_t bitField = mBitField; bitField; bitField >>= 1) { - if (bitField & 1) { - count++; - } - } - return count; - } - - bool isEmpty() const - { - return mBitField == 0; - } - - uint32_t serialize() const - { - return mBitField; - } - - void deserialize(uint32_t aValue) - { - incVersion(); - mBitField = aValue; - } - - class ConstIterator - { - const EnumSet* mSet; - uint32_t mPos; -#ifdef DEBUG - uint64_t mVersion; -#endif - - void checkVersion() { - // Check that the set has not been modified while being iterated. - MOZ_ASSERT_IF(mSet, mSet->mVersion == mVersion); - } - - public: - ConstIterator(const EnumSet& aSet, uint32_t aPos) - : mSet(&aSet), mPos(aPos) - { -#ifdef DEBUG - mVersion = mSet->mVersion; -#endif - MOZ_ASSERT(aPos <= kMaxBits); - if (aPos != kMaxBits && !mSet->contains(T(mPos))) - ++*this; - } - - ConstIterator(const ConstIterator& aOther) - : mSet(aOther.mSet), mPos(aOther.mPos) - { -#ifdef DEBUG - mVersion = aOther.mVersion; - checkVersion(); -#endif - } - - ConstIterator(ConstIterator&& aOther) - : mSet(aOther.mSet), mPos(aOther.mPos) - { -#ifdef DEBUG - mVersion = aOther.mVersion; - checkVersion(); -#endif - aOther.mSet = nullptr; - } - - ~ConstIterator() { - checkVersion(); - } - - bool operator==(const ConstIterator& other) { - MOZ_ASSERT(mSet == other.mSet); - checkVersion(); - return mPos == other.mPos; - } - - bool operator!=(const ConstIterator& other) { - return !(*this == other); - } - - T operator*() { - MOZ_ASSERT(mSet); - MOZ_ASSERT(mPos < kMaxBits); - MOZ_ASSERT(mSet->contains(T(mPos))); - checkVersion(); - return T(mPos); - } - - ConstIterator& operator++() { - MOZ_ASSERT(mSet); - MOZ_ASSERT(mPos < kMaxBits); - checkVersion(); - do { - mPos++; - } while (mPos < kMaxBits && !mSet->contains(T(mPos))); - return *this; - } - }; - - ConstIterator begin() const { - return ConstIterator(*this, 0); - } - - ConstIterator end() const { - return ConstIterator(*this, kMaxBits); - } - -private: - static uint32_t bitFor(T aEnum) - { - uint32_t bitNumber = (uint32_t)aEnum; - MOZ_ASSERT(bitNumber < kMaxBits); - return 1U << bitNumber; - } - - void initVersion() { -#ifdef DEBUG - mVersion = 0; -#endif - } - - void incVersion() { -#ifdef DEBUG - mVersion++; -#endif - } - - static const size_t kMaxBits = 32; - uint32_t mBitField; - -#ifdef DEBUG - uint64_t mVersion; -#endif -}; - -} // namespace mozilla - -#endif /* mozilla_EnumSet_h_*/ diff --git a/android/x86/include/spidermonkey/mozilla/EnumTypeTraits.h b/android/x86/include/spidermonkey/mozilla/EnumTypeTraits.h deleted file mode 100644 index 223eaf8c..00000000 --- a/android/x86/include/spidermonkey/mozilla/EnumTypeTraits.h +++ /dev/null @@ -1,70 +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/. */ - -/* Type traits for enums. */ - -#ifndef mozilla_EnumTypeTraits_h -#define mozilla_EnumTypeTraits_h - -#include - -namespace mozilla { - -namespace detail { - -template -struct EnumFitsWithinHelper; - -// Signed enum, signed storage. -template -struct EnumFitsWithinHelper - : public std::integral_constant -{}; - -// Signed enum, unsigned storage. -template -struct EnumFitsWithinHelper - : public std::integral_constant -{}; - -// Unsigned enum, signed storage. -template -struct EnumFitsWithinHelper - : public std::integral_constant -{}; - -// Unsigned enum, unsigned storage. -template -struct EnumFitsWithinHelper - : public std::integral_constant -{}; - -} // namespace detail - -/* - * Type trait that determines whether the enum type T can fit within the - * integral type Storage without data loss. This trait should be used with - * caution with an enum type whose underlying type has not been explicitly - * specified: for such enums, the C++ implementation is free to choose a type - * no smaller than int whose range encompasses all possible values of the enum. - * So for an enum with only small non-negative values, the underlying type may - * be either int or unsigned int, depending on the whims of the implementation. - */ -template -struct EnumTypeFitsWithin - : public detail::EnumFitsWithinHelper< - sizeof(T), - std::is_signed::type>::value, - sizeof(Storage), - std::is_signed::value - > -{ - static_assert(std::is_enum::value, "must provide an enum type"); - static_assert(std::is_integral::value, "must provide an integral type"); -}; - -} // namespace mozilla - -#endif /* mozilla_EnumTypeTraits_h */ diff --git a/android/x86/include/spidermonkey/mozilla/EnumeratedArray.h b/android/x86/include/spidermonkey/mozilla/EnumeratedArray.h deleted file mode 100644 index 9e74b772..00000000 --- a/android/x86/include/spidermonkey/mozilla/EnumeratedArray.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* EnumeratedArray is like Array, but indexed by a typed enum. */ - -#ifndef mozilla_EnumeratedArray_h -#define mozilla_EnumeratedArray_h - -#include "mozilla/Array.h" -#include "mozilla/Move.h" - -namespace mozilla { - -/** - * EnumeratedArray is a fixed-size array container for use when an - * array is indexed by a specific enum class. - * - * This provides type safety by guarding at compile time against accidentally - * indexing such arrays with unrelated values. This also removes the need - * for manual casting when using a typed enum value to index arrays. - * - * Aside from the typing of indices, EnumeratedArray is similar to Array. - * - * Example: - * - * enum class AnimalSpecies { - * Cow, - * Sheep, - * Count - * }; - * - * EnumeratedArray headCount; - * - * headCount[AnimalSpecies::Cow] = 17; - * headCount[AnimalSpecies::Sheep] = 30; - * - */ -template -class EnumeratedArray -{ -public: - static const size_t kSize = size_t(SizeAsEnumValue); - -private: - typedef Array ArrayType; - - ArrayType mArray; - -public: - EnumeratedArray() {} - - template - MOZ_IMPLICIT EnumeratedArray(Args&&... aArgs) - : mArray{mozilla::Forward(aArgs)...} - {} - - explicit EnumeratedArray(const EnumeratedArray& aOther) - { - for (size_t i = 0; i < kSize; i++) { - mArray[i] = aOther.mArray[i]; - } - } - - EnumeratedArray(EnumeratedArray&& aOther) - { - for (size_t i = 0; i < kSize; i++) { - mArray[i] = Move(aOther.mArray[i]); - } - } - - ValueType& operator[](IndexType aIndex) - { - return mArray[size_t(aIndex)]; - } - - const ValueType& operator[](IndexType aIndex) const - { - return mArray[size_t(aIndex)]; - } - - typedef typename ArrayType::iterator iterator; - typedef typename ArrayType::const_iterator const_iterator; - typedef typename ArrayType::reverse_iterator reverse_iterator; - typedef typename ArrayType::const_reverse_iterator const_reverse_iterator; - - // Methods for range-based for loops. - iterator begin() { return mArray.begin(); } - const_iterator begin() const { return mArray.begin(); } - const_iterator cbegin() const { return mArray.cbegin(); } - iterator end() { return mArray.end(); } - const_iterator end() const { return mArray.end(); } - const_iterator cend() const { return mArray.cend(); } - - // Methods for reverse iterating. - reverse_iterator rbegin() { return mArray.rbegin(); } - const_reverse_iterator rbegin() const { return mArray.rbegin(); } - const_reverse_iterator crbegin() const { return mArray.crbegin(); } - reverse_iterator rend() { return mArray.rend(); } - const_reverse_iterator rend() const { return mArray.rend(); } - const_reverse_iterator crend() const { return mArray.crend(); } -}; - -} // namespace mozilla - -#endif // mozilla_EnumeratedArray_h diff --git a/android/x86/include/spidermonkey/mozilla/EnumeratedRange.h b/android/x86/include/spidermonkey/mozilla/EnumeratedRange.h deleted file mode 100644 index b158f8a3..00000000 --- a/android/x86/include/spidermonkey/mozilla/EnumeratedRange.h +++ /dev/null @@ -1,201 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Iterator over contiguous enum values */ - -/* - * Implements generator functions that create a range to iterate over the values - * of a scoped or unscoped enum. Unlike IntegerRange, which can only function on - * the underlying integral type, the elements of the generated sequence will - * have the type of the enum in question. - * - * Note that the enum values should be contiguous in the iterated range; - * unfortunately there exists no way for EnumeratedRange to enforce this - * either dynamically or at compile time. - */ - -#ifndef mozilla_EnumeratedRange_h -#define mozilla_EnumeratedRange_h - -#include - -#include "mozilla/ReverseIterator.h" - -namespace mozilla { - -namespace detail { - -template -class EnumeratedIterator -{ -public: - typedef typename std::underlying_type::type IntTypeT; - - template - explicit EnumeratedIterator(EnumType aCurrent) - : mCurrent(aCurrent) { } - - template - explicit EnumeratedIterator(const EnumeratedIterator& aOther) - : mCurrent(aOther.mCurrent) { } - - EnumTypeT operator*() const { return mCurrent; } - - /* Increment and decrement operators */ - - EnumeratedIterator& operator++() - { - mCurrent = EnumTypeT(IntTypeT(mCurrent) + IntTypeT(1)); - return *this; - } - EnumeratedIterator& operator--() - { - mCurrent = EnumTypeT(IntTypeT(mCurrent) - IntTypeT(1)); - return *this; - } - EnumeratedIterator operator++(int) - { - auto ret = *this; - mCurrent = EnumTypeT(IntTypeT(mCurrent) + IntTypeT(1)); - return ret; - } - EnumeratedIterator operator--(int) - { - auto ret = *this; - mCurrent = EnumTypeT(IntTypeT(mCurrent) - IntTypeT(1)); - return ret; - } - - /* Comparison operators */ - - template - friend bool operator==(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - template - friend bool operator!=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - template - friend bool operator<(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - template - friend bool operator<=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - template - friend bool operator>(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - template - friend bool operator>=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2); - -private: - EnumTypeT mCurrent; -}; - -template -bool operator==(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent == aIter2.mCurrent; -} - -template -bool operator!=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent != aIter2.mCurrent; -} - -template -bool operator<(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent < aIter2.mCurrent; -} - -template -bool operator<=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent <= aIter2.mCurrent; -} - -template -bool operator>(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent > aIter2.mCurrent; -} - -template -bool operator>=(const EnumeratedIterator& aIter1, - const EnumeratedIterator& aIter2) -{ - return aIter1.mCurrent >= aIter2.mCurrent; -} - -template -class EnumeratedRange -{ -public: - typedef EnumeratedIterator iterator; - typedef EnumeratedIterator const_iterator; - typedef ReverseIterator reverse_iterator; - typedef ReverseIterator const_reverse_iterator; - - template - EnumeratedRange(EnumType aBegin, EnumType aEnd) - : mBegin(aBegin), mEnd(aEnd) { } - - iterator begin() const { return iterator(mBegin); } - const_iterator cbegin() const { return begin(); } - iterator end() const { return iterator(mEnd); } - const_iterator cend() const { return end(); } - reverse_iterator rbegin() const { return reverse_iterator(mEnd); } - const_reverse_iterator crbegin() const { return rbegin(); } - reverse_iterator rend() const { return reverse_iterator(mBegin); } - const_reverse_iterator crend() const { return rend(); } - -private: - EnumTypeT mBegin; - EnumTypeT mEnd; -}; - -} // namespace detail - -#ifdef __GNUC__ -// Enums can have an unsigned underlying type, which makes some of the -// comparisons below always true or always false. Temporarily disable -// -Wtype-limits to avoid breaking -Werror builds. -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wtype-limits" -#endif - -// Create a range to iterate from aBegin to aEnd, exclusive. -template -inline detail::EnumeratedRange -MakeEnumeratedRange(EnumType aBegin, EnumType aEnd) -{ - MOZ_ASSERT(aBegin <= aEnd, "Cannot generate invalid, unbounded range!"); - return detail::EnumeratedRange(aBegin, aEnd); -} - -// Create a range to iterate from EnumType(0) to aEnd, exclusive. EnumType(0) -// should exist, but note that there is no way for us to ensure that it does! -template -inline detail::EnumeratedRange -MakeEnumeratedRange(EnumType aEnd) -{ - return MakeEnumeratedRange(EnumType(0), aEnd); -} - -#ifdef __GNUC__ -# pragma GCC diagnostic pop -#endif - -} // namespace mozilla - -#endif // mozilla_EnumeratedRange_h - diff --git a/android/x86/include/spidermonkey/mozilla/FastBernoulliTrial.h b/android/x86/include/spidermonkey/mozilla/FastBernoulliTrial.h deleted file mode 100644 index 7e38b70a..00000000 --- a/android/x86/include/spidermonkey/mozilla/FastBernoulliTrial.h +++ /dev/null @@ -1,379 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_FastBernoulliTrial_h -#define mozilla_FastBernoulliTrial_h - -#include "mozilla/Assertions.h" -#include "mozilla/XorShift128PlusRNG.h" - -#include -#include - -namespace mozilla { - -/** - * class FastBernoulliTrial: Efficient sampling with uniform probability - * - * When gathering statistics about a program's behavior, we may be observing - * events that occur very frequently (e.g., function calls or memory - * allocations) and we may be gathering information that is somewhat expensive - * to produce (e.g., call stacks). Sampling all the events could have a - * significant impact on the program's performance. - * - * Why not just sample every N'th event? This technique is called "systematic - * sampling"; it's simple and efficient, and it's fine if we imagine a - * patternless stream of events. But what if we're sampling allocations, and the - * program happens to have a loop where each iteration does exactly N - * allocations? You would end up sampling the same allocation every time through - * the loop; the entire rest of the loop becomes invisible to your measurements! - * More generally, if each iteration does M allocations, and M and N have any - * common divisor at all, most allocation sites will never be sampled. If - * they're both even, say, the odd-numbered allocations disappear from your - * results. - * - * Ideally, we'd like each event to have some probability P of being sampled, - * independent of its neighbors and of its position in the sequence. This is - * called "Bernoulli sampling", and it doesn't suffer from any of the problems - * mentioned above. - * - * One disadvantage of Bernoulli sampling is that you can't be sure exactly how - * many samples you'll get: technically, it's possible that you might sample - * none of them, or all of them. But if the number of events N is large, these - * aren't likely outcomes; you can generally expect somewhere around P * N - * events to be sampled. - * - * The other disadvantage of Bernoulli sampling is that you have to generate a - * random number for every event, which can be slow. - * - * [significant pause] - * - * BUT NOT WITH THIS CLASS! FastBernoulliTrial lets you do true Bernoulli - * sampling, while generating a fresh random number only when we do decide to - * sample an event, not on every trial. When it decides not to sample, a call to - * |FastBernoulliTrial::trial| is nothing but decrementing a counter and - * comparing it to zero. So the lower your sampling probability is, the less - * overhead FastBernoulliTrial imposes. - * - * Probabilities of 0 and 1 are handled efficiently. (In neither case need we - * ever generate a random number at all.) - * - * The essential API: - * - * - FastBernoulliTrial(double P) - * Construct an instance that selects events with probability P. - * - * - FastBernoulliTrial::trial() - * Return true with probability P. Call this each time an event occurs, to - * decide whether to sample it or not. - * - * - FastBernoulliTrial::trial(size_t n) - * Equivalent to calling trial() |n| times, and returning true if any of those - * calls do. However, like trial, this runs in fast constant time. - * - * What is this good for? In some applications, some events are "bigger" than - * others. For example, large allocations are more significant than small - * allocations. Perhaps we'd like to imagine that we're drawing allocations - * from a stream of bytes, and performing a separate Bernoulli trial on every - * byte from the stream. We can accomplish this by calling |t.trial(S)| for - * the number of bytes S, and sampling the event if that returns true. - * - * Of course, this style of sampling needs to be paired with analysis and - * presentation that makes the size of the event apparent, lest trials with - * large values for |n| appear to be indistinguishable from those with small - * values for |n|. - */ -class FastBernoulliTrial { - /* - * This comment should just read, "Generate skip counts with a geometric - * distribution", and leave everyone to go look that up and see why it's the - * right thing to do, if they don't know already. - * - * BUT IF YOU'RE CURIOUS, COMMENTS ARE FREE... - * - * Instead of generating a fresh random number for every trial, we can - * randomly generate a count of how many times we should return false before - * the next time we return true. We call this a "skip count". Once we've - * returned true, we generate a fresh skip count, and begin counting down - * again. - * - * Here's an awesome fact: by exercising a little care in the way we generate - * skip counts, we can produce results indistinguishable from those we would - * get "rolling the dice" afresh for every trial. - * - * In short, skip counts in Bernoulli trials of probability P obey a geometric - * distribution. If a random variable X is uniformly distributed from [0..1), - * then std::floor(std::log(X) / std::log(1-P)) has the appropriate geometric - * distribution for the skip counts. - * - * Why that formula? - * - * Suppose we're to return |true| with some probability P, say, 0.3. Spread - * all possible futures along a line segment of length 1. In portion P of - * those cases, we'll return true on the next call to |trial|; the skip count - * is 0. For the remaining portion 1-P of cases, the skip count is 1 or more. - * - * skip: 0 1 or more - * |------------------^-----------------------------------------| - * portion: 0.3 0.7 - * P 1-P - * - * But the "1 or more" section of the line is subdivided the same way: *within - * that section*, in portion P the second call to |trial()| returns true, and in - * portion 1-P it returns false a second time; the skip count is two or more. - * So we return true on the second call in proportion 0.7 * 0.3, and skip at - * least the first two in proportion 0.7 * 0.7. - * - * skip: 0 1 2 or more - * |------------------^------------^----------------------------| - * portion: 0.3 0.7 * 0.3 0.7 * 0.7 - * P (1-P)*P (1-P)^2 - * - * We can continue to subdivide: - * - * skip >= 0: |------------------------------------------------- (1-P)^0 --| - * skip >= 1: | ------------------------------- (1-P)^1 --| - * skip >= 2: | ------------------ (1-P)^2 --| - * skip >= 3: | ^ ---------- (1-P)^3 --| - * skip >= 4: | . --- (1-P)^4 --| - * . - * ^X, see below - * - * In other words, the likelihood of the next n calls to |trial| returning - * false is (1-P)^n. The longer a run we require, the more the likelihood - * drops. Further calls may return false too, but this is the probability - * we'll skip at least n. - * - * This is interesting, because we can pick a point along this line segment - * and see which skip count's range it falls within; the point X above, for - * example, is within the ">= 2" range, but not within the ">= 3" range, so it - * designates a skip count of 2. So if we pick points on the line at random - * and use the skip counts they fall under, that will be indistinguishable - * from generating a fresh random number between 0 and 1 for each trial and - * comparing it to P. - * - * So to find the skip count for a point X, we must ask: To what whole power - * must we raise 1-P such that we include X, but the next power would exclude - * it? This is exactly std::floor(std::log(X) / std::log(1-P)). - * - * Our algorithm is then, simply: When constructed, compute an initial skip - * count. Return false from |trial| that many times, and then compute a new skip - * count. - * - * For a call to |trial(n)|, if the skip count is greater than n, return false - * and subtract n from the skip count. If the skip count is less than n, - * return true and compute a new skip count. Since each trial is independent, - * it doesn't matter by how much n overshoots the skip count; we can actually - * compute a new skip count at *any* time without affecting the distribution. - * This is really beautiful. - */ - public: - /** - * Construct a fast Bernoulli trial generator. Calls to |trial()| return true - * with probability |aProbability|. Use |aState0| and |aState1| to seed the - * random number generator; both may not be zero. - */ - FastBernoulliTrial(double aProbability, uint64_t aState0, uint64_t aState1) - : mProbability(0) - , mInvLogNotProbability(0) - , mGenerator(aState0, aState1) - , mSkipCount(0) - { - setProbability(aProbability); - } - - /** - * Return true with probability |mProbability|. Call this each time an event - * occurs, to decide whether to sample it or not. The lower |mProbability| is, - * the faster this function runs. - */ - bool trial() { - if (mSkipCount) { - mSkipCount--; - return false; - } - - return chooseSkipCount(); - } - - /** - * Equivalent to calling trial() |n| times, and returning true if any of those - * calls do. However, like trial, this runs in fast constant time. - * - * What is this good for? In some applications, some events are "bigger" than - * others. For example, large allocations are more significant than small - * allocations. Perhaps we'd like to imagine that we're drawing allocations - * from a stream of bytes, and performing a separate Bernoulli trial on every - * byte from the stream. We can accomplish this by calling |t.trial(S)| for - * the number of bytes S, and sampling the event if that returns true. - * - * Of course, this style of sampling needs to be paired with analysis and - * presentation that makes the "size" of the event apparent, lest trials with - * large values for |n| appear to be indistinguishable from those with small - * values for |n|, despite being potentially much more likely to be sampled. - */ - bool trial(size_t aCount) { - if (mSkipCount > aCount) { - mSkipCount -= aCount; - return false; - } - - return chooseSkipCount(); - } - - void setRandomState(uint64_t aState0, uint64_t aState1) { - mGenerator.setState(aState0, aState1); - } - - void setProbability(double aProbability) { - MOZ_ASSERT(0 <= aProbability && aProbability <= 1); - mProbability = aProbability; - if (0 < mProbability && mProbability < 1) { - /* - * Let's look carefully at how this calculation plays out in floating- - * point arithmetic. We'll assume IEEE, but the final C++ code we arrive - * at would still be fine if our numbers were mathematically perfect. So, - * while we've considered IEEE's edge cases, we haven't done anything that - * should be actively bad when using other representations. - * - * (In the below, read comparisons as exact mathematical comparisons: when - * we say something "equals 1", that means it's exactly equal to 1. We - * treat approximation using intervals with open boundaries: saying a - * value is in (0,1) doesn't specify how close to 0 or 1 the value gets. - * When we use closed boundaries like [2**-53, 1], we're careful to ensure - * the boundary values are actually representable.) - * - * - After the comparison above, we know mProbability is in (0,1). - * - * - The gaps below 1 are 2**-53, so that interval is (0, 1-2**-53]. - * - * - Because the floating-point gaps near 1 are wider than those near - * zero, there are many small positive doubles ε such that 1-ε rounds to - * exactly 1. However, 2**-53 can be represented exactly. So - * 1-mProbability is in [2**-53, 1]. - * - * - log(1 - mProbability) is thus in (-37, 0]. - * - * That range includes zero, but when we use mInvLogNotProbability, it - * would be helpful if we could trust that it's negative. So when log(1 - * - mProbability) is 0, we'll just set mProbability to 0, so that - * mInvLogNotProbability is not used in chooseSkipCount. - * - * - How much of the range of mProbability does this cause us to ignore? - * The only value for which log returns 0 is exactly 1; the slope of log - * at 1 is 1, so for small ε such that 1 - ε != 1, log(1 - ε) is -ε, - * never 0. The gaps near one are larger than the gaps near zero, so if - * 1 - ε wasn't 1, then -ε is representable. So if log(1 - mProbability) - * isn't 0, then 1 - mProbability isn't 1, which means that mProbability - * is at least 2**-53, as discussed earlier. This is a sampling - * likelihood of roughly one in ten trillion, which is unlikely to be - * distinguishable from zero in practice. - * - * So by forbidding zero, we've tightened our range to (-37, -2**-53]. - * - * - Finally, 1 / log(1 - mProbability) is in [-2**53, -1/37). This all - * falls readily within the range of an IEEE double. - * - * ALL THAT HAVING BEEN SAID: here are the five lines of actual code: - */ - double logNotProbability = std::log(1 - mProbability); - if (logNotProbability == 0.0) - mProbability = 0.0; - else - mInvLogNotProbability = 1 / logNotProbability; - } - - chooseSkipCount(); - } - - private: - /* The likelihood that any given call to |trial| should return true. */ - double mProbability; - - /* - * The value of 1/std::log(1 - mProbability), cached for repeated use. - * - * If mProbability is exactly 0 or exactly 1, we don't use this value. - * Otherwise, we guarantee this value is in the range [-2**53, -1/37), i.e. - * definitely negative, as required by chooseSkipCount. See setProbability for - * the details. - */ - double mInvLogNotProbability; - - /* Our random number generator. */ - non_crypto::XorShift128PlusRNG mGenerator; - - /* The number of times |trial| should return false before next returning true. */ - size_t mSkipCount; - - /* - * Choose the next skip count. This also returns the value that |trial| should - * return, since we have to check for the extreme values for mProbability - * anyway, and |trial| should never return true at all when mProbability is 0. - */ - bool chooseSkipCount() { - /* - * If the probability is 1.0, every call to |trial| returns true. Make sure - * mSkipCount is 0. - */ - if (mProbability == 1.0) { - mSkipCount = 0; - return true; - } - - /* - * If the probabilility is zero, |trial| never returns true. Don't bother us - * for a while. - */ - if (mProbability == 0.0) { - mSkipCount = SIZE_MAX; - return false; - } - - /* - * What sorts of values can this call to std::floor produce? - * - * Since mGenerator.nextDouble returns a value in [0, 1-2**-53], std::log - * returns a value in the range [-infinity, -2**-53], all negative. Since - * mInvLogNotProbability is negative (see its comments), the product is - * positive and possibly infinite. std::floor returns +infinity unchanged. - * So the result will always be positive. - * - * Converting a double to an integer that is out of range for that integer - * is undefined behavior, so we must clamp our result to SIZE_MAX, to ensure - * we get an acceptable value for mSkipCount. - * - * The clamp is written carefully. Note that if we had said: - * - * if (skipCount > SIZE_MAX) - * skipCount = SIZE_MAX; - * - * that leads to undefined behavior 64-bit machines: SIZE_MAX coerced to - * double is 2^64, not 2^64-1, so this doesn't actually set skipCount to a - * value that can be safely assigned to mSkipCount. - * - * Jakub Oleson cleverly suggested flipping the sense of the comparison: if - * we require that skipCount < SIZE_MAX, then because of the gaps (2048) - * between doubles at that magnitude, the highest double less than 2^64 is - * 2^64 - 2048, which is fine to store in a size_t. - * - * (On 32-bit machines, all size_t values can be represented exactly in - * double, so all is well.) - */ - double skipCount = std::floor(std::log(mGenerator.nextDouble()) - * mInvLogNotProbability); - if (skipCount < SIZE_MAX) - mSkipCount = skipCount; - else - mSkipCount = SIZE_MAX; - - return true; - } -}; - -} /* namespace mozilla */ - -#endif /* mozilla_FastBernoulliTrial_h */ diff --git a/android/x86/include/spidermonkey/mozilla/FloatingPoint.h b/android/x86/include/spidermonkey/mozilla/FloatingPoint.h deleted file mode 100644 index 59afccd1..00000000 --- a/android/x86/include/spidermonkey/mozilla/FloatingPoint.h +++ /dev/null @@ -1,479 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Various predicates and operations on IEEE-754 floating point types. */ - -#ifndef mozilla_FloatingPoint_h -#define mozilla_FloatingPoint_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Casting.h" -#include "mozilla/MathAlgorithms.h" -#include "mozilla/Types.h" - -#include - -namespace mozilla { - -/* - * It's reasonable to ask why we have this header at all. Don't isnan, - * copysign, the built-in comparison operators, and the like solve these - * problems? Unfortunately, they don't. We've found that various compilers - * (MSVC, MSVC when compiling with PGO, and GCC on OS X, at least) miscompile - * the standard methods in various situations, so we can't use them. Some of - * these compilers even have problems compiling seemingly reasonable bitwise - * algorithms! But with some care we've found algorithms that seem to not - * trigger those compiler bugs. - * - * For the aforementioned reasons, be very wary of making changes to any of - * these algorithms. If you must make changes, keep a careful eye out for - * compiler bustage, particularly PGO-specific bustage. - */ - -struct FloatTypeTraits -{ - typedef uint32_t Bits; - - static const unsigned kExponentBias = 127; - static const unsigned kExponentShift = 23; - - static const Bits kSignBit = 0x80000000UL; - static const Bits kExponentBits = 0x7F800000UL; - static const Bits kSignificandBits = 0x007FFFFFUL; -}; - -struct DoubleTypeTraits -{ - typedef uint64_t Bits; - - static const unsigned kExponentBias = 1023; - static const unsigned kExponentShift = 52; - - static const Bits kSignBit = 0x8000000000000000ULL; - static const Bits kExponentBits = 0x7ff0000000000000ULL; - static const Bits kSignificandBits = 0x000fffffffffffffULL; -}; - -template struct SelectTrait; -template<> struct SelectTrait : public FloatTypeTraits {}; -template<> struct SelectTrait : public DoubleTypeTraits {}; - -/* - * This struct contains details regarding the encoding of floating-point - * numbers that can be useful for direct bit manipulation. As of now, the - * template parameter has to be float or double. - * - * The nested typedef |Bits| is the unsigned integral type with the same size - * as T: uint32_t for float and uint64_t for double (static assertions - * double-check these assumptions). - * - * kExponentBias is the offset that is subtracted from the exponent when - * computing the value, i.e. one plus the opposite of the mininum possible - * exponent. - * kExponentShift is the shift that one needs to apply to retrieve the - * exponent component of the value. - * - * kSignBit contains a bits mask. Bit-and-ing with this mask will result in - * obtaining the sign bit. - * kExponentBits contains the mask needed for obtaining the exponent bits and - * kSignificandBits contains the mask needed for obtaining the significand - * bits. - * - * Full details of how floating point number formats are encoded are beyond - * the scope of this comment. For more information, see - * http://en.wikipedia.org/wiki/IEEE_floating_point - * http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers - */ -template -struct FloatingPoint : public SelectTrait -{ - typedef SelectTrait Base; - typedef typename Base::Bits Bits; - - static_assert((Base::kSignBit & Base::kExponentBits) == 0, - "sign bit shouldn't overlap exponent bits"); - static_assert((Base::kSignBit & Base::kSignificandBits) == 0, - "sign bit shouldn't overlap significand bits"); - static_assert((Base::kExponentBits & Base::kSignificandBits) == 0, - "exponent bits shouldn't overlap significand bits"); - - static_assert((Base::kSignBit | Base::kExponentBits | Base::kSignificandBits) == - ~Bits(0), - "all bits accounted for"); - - /* - * These implementations assume float/double are 32/64-bit single/double - * format number types compatible with the IEEE-754 standard. C++ don't - * require this to be the case. But we required this in implementations of - * these algorithms that preceded this header, so we shouldn't break anything - * if we keep doing so. - */ - static_assert(sizeof(T) == sizeof(Bits), "Bits must be same size as T"); -}; - -/** Determines whether a float/double is NaN. */ -template -static MOZ_ALWAYS_INLINE bool -IsNaN(T aValue) -{ - /* - * A float/double is NaN if all exponent bits are 1 and the significand - * contains at least one non-zero bit. - */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - return (BitwiseCast(aValue) & Traits::kExponentBits) == Traits::kExponentBits && - (BitwiseCast(aValue) & Traits::kSignificandBits) != 0; -} - -/** Determines whether a float/double is +Infinity or -Infinity. */ -template -static MOZ_ALWAYS_INLINE bool -IsInfinite(T aValue) -{ - /* Infinities have all exponent bits set to 1 and an all-0 significand. */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return (bits & ~Traits::kSignBit) == Traits::kExponentBits; -} - -/** Determines whether a float/double is not NaN or infinite. */ -template -static MOZ_ALWAYS_INLINE bool -IsFinite(T aValue) -{ - /* - * NaN and Infinities are the only non-finite floats/doubles, and both have - * all exponent bits set to 1. - */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return (bits & Traits::kExponentBits) != Traits::kExponentBits; -} - -/** - * Determines whether a float/double is negative or -0. It is an error - * to call this method on a float/double which is NaN. - */ -template -static MOZ_ALWAYS_INLINE bool -IsNegative(T aValue) -{ - MOZ_ASSERT(!IsNaN(aValue), "NaN does not have a sign"); - - /* The sign bit is set if the double is negative. */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return (bits & Traits::kSignBit) != 0; -} - -/** Determines whether a float/double represents -0. */ -template -static MOZ_ALWAYS_INLINE bool -IsNegativeZero(T aValue) -{ - /* Only the sign bit is set if the value is -0. */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return bits == Traits::kSignBit; -} - -/** Determines wether a float/double represents +0. */ -template -static MOZ_ALWAYS_INLINE bool -IsPositiveZero(T aValue) -{ - /* All bits are zero if the value is +0. */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return bits == 0; -} - -/** - * Returns 0 if a float/double is NaN or infinite; - * otherwise, the float/double is returned. - */ -template -static MOZ_ALWAYS_INLINE T -ToZeroIfNonfinite(T aValue) -{ - return IsFinite(aValue) ? aValue : 0; -} - -/** - * Returns the exponent portion of the float/double. - * - * Zero is not special-cased, so ExponentComponent(0.0) is - * -int_fast16_t(Traits::kExponentBias). - */ -template -static MOZ_ALWAYS_INLINE int_fast16_t -ExponentComponent(T aValue) -{ - /* - * The exponent component of a float/double is an unsigned number, biased - * from its actual value. Subtract the bias to retrieve the actual exponent. - */ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - Bits bits = BitwiseCast(aValue); - return int_fast16_t((bits & Traits::kExponentBits) >> Traits::kExponentShift) - - int_fast16_t(Traits::kExponentBias); -} - -/** Returns +Infinity. */ -template -static MOZ_ALWAYS_INLINE T -PositiveInfinity() -{ - /* - * Positive infinity has all exponent bits set, sign bit set to 0, and no - * significand. - */ - typedef FloatingPoint Traits; - return BitwiseCast(Traits::kExponentBits); -} - -/** Returns -Infinity. */ -template -static MOZ_ALWAYS_INLINE T -NegativeInfinity() -{ - /* - * Negative infinity has all exponent bits set, sign bit set to 1, and no - * significand. - */ - typedef FloatingPoint Traits; - return BitwiseCast(Traits::kSignBit | Traits::kExponentBits); -} - -/** - * Computes the bit pattern for a NaN with the specified sign bit and - * significand bits. - */ -template::Bits Significand> -struct SpecificNaNBits -{ - using Traits = FloatingPoint; - - static_assert(SignBit == 0 || SignBit == 1, "bad sign bit"); - static_assert((Significand & ~Traits::kSignificandBits) == 0, - "significand must only have significand bits set"); - static_assert(Significand & Traits::kSignificandBits, - "significand must be nonzero"); - - static constexpr typename Traits::Bits value = - (SignBit * Traits::kSignBit) | Traits::kExponentBits | Significand; -}; - -/** - * Constructs a NaN value with the specified sign bit and significand bits. - * - * There is also a variant that returns the value directly. In most cases, the - * two variants should be identical. However, in the specific case of x86 - * chips, the behavior differs: returning floating-point values directly is done - * through the x87 stack, and x87 loads and stores turn signaling NaNs into - * quiet NaNs... silently. Returning floating-point values via outparam, - * however, is done entirely within the SSE registers when SSE2 floating-point - * is enabled in the compiler, which has semantics-preserving behavior you would - * expect. - * - * If preserving the distinction between signaling NaNs and quiet NaNs is - * important to you, you should use the outparam version. In all other cases, - * you should use the direct return version. - */ -template -static MOZ_ALWAYS_INLINE void -SpecificNaN(int signbit, typename FloatingPoint::Bits significand, T* result) -{ - typedef FloatingPoint Traits; - MOZ_ASSERT(signbit == 0 || signbit == 1); - MOZ_ASSERT((significand & ~Traits::kSignificandBits) == 0); - MOZ_ASSERT(significand & Traits::kSignificandBits); - - BitwiseCast((signbit ? Traits::kSignBit : 0) | - Traits::kExponentBits | - significand, - result); - MOZ_ASSERT(IsNaN(*result)); -} - -template -static MOZ_ALWAYS_INLINE T -SpecificNaN(int signbit, typename FloatingPoint::Bits significand) -{ - T t; - SpecificNaN(signbit, significand, &t); - return t; -} - -/** Computes the smallest non-zero positive float/double value. */ -template -static MOZ_ALWAYS_INLINE T -MinNumberValue() -{ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - return BitwiseCast(Bits(1)); -} - -/** - * If aValue is equal to some int32_t value, set *aInt32 to that value and - * return true; otherwise return false. - * - * Note that negative zero is "equal" to zero here. To test whether a value can - * be losslessly converted to int32_t and back, use NumberIsInt32 instead. - */ -template -static MOZ_ALWAYS_INLINE bool -NumberEqualsInt32(T aValue, int32_t* aInt32) -{ - /* - * XXX Casting a floating-point value that doesn't truncate to int32_t, to - * int32_t, induces undefined behavior. We should definitely fix this - * (bug 744965), but as apparently it "works" in practice, it's not a - * pressing concern now. - */ - return aValue == (*aInt32 = int32_t(aValue)); -} - -/** - * If d can be converted to int32_t and back to an identical double value, - * set *aInt32 to that value and return true; otherwise return false. - * - * The difference between this and NumberEqualsInt32 is that this method returns - * false for negative zero. - */ -template -static MOZ_ALWAYS_INLINE bool -NumberIsInt32(T aValue, int32_t* aInt32) -{ - return !IsNegativeZero(aValue) && NumberEqualsInt32(aValue, aInt32); -} - -/** - * Computes a NaN value. Do not use this method if you depend upon a particular - * NaN value being returned. - */ -template -static MOZ_ALWAYS_INLINE T -UnspecifiedNaN() -{ - /* - * If we can use any quiet NaN, we might as well use the all-ones NaN, - * since it's cheap to materialize on common platforms (such as x64, where - * this value can be represented in a 32-bit signed immediate field, allowing - * it to be stored to memory in a single instruction). - */ - typedef FloatingPoint Traits; - return SpecificNaN(1, Traits::kSignificandBits); -} - -/** - * Compare two doubles for equality, *without* equating -0 to +0, and equating - * any NaN value to any other NaN value. (The normal equality operators equate - * -0 with +0, and they equate NaN to no other value.) - */ -template -static inline bool -NumbersAreIdentical(T aValue1, T aValue2) -{ - typedef FloatingPoint Traits; - typedef typename Traits::Bits Bits; - if (IsNaN(aValue1)) { - return IsNaN(aValue2); - } - return BitwiseCast(aValue1) == BitwiseCast(aValue2); -} - -namespace detail { - -template -struct FuzzyEqualsEpsilon; - -template<> -struct FuzzyEqualsEpsilon -{ - // A number near 1e-5 that is exactly representable in a float. - static float value() { return 1.0f / (1 << 17); } -}; - -template<> -struct FuzzyEqualsEpsilon -{ - // A number near 1e-12 that is exactly representable in a double. - static double value() { return 1.0 / (1LL << 40); } -}; - -} // namespace detail - -/** - * Compare two floating point values for equality, modulo rounding error. That - * is, the two values are considered equal if they are both not NaN and if they - * are less than or equal to aEpsilon apart. The default value of aEpsilon is - * near 1e-5. - * - * For most scenarios you will want to use FuzzyEqualsMultiplicative instead, - * as it is more reasonable over the entire range of floating point numbers. - * This additive version should only be used if you know the range of the - * numbers you are dealing with is bounded and stays around the same order of - * magnitude. - */ -template -static MOZ_ALWAYS_INLINE bool -FuzzyEqualsAdditive(T aValue1, T aValue2, - T aEpsilon = detail::FuzzyEqualsEpsilon::value()) -{ - static_assert(IsFloatingPoint::value, "floating point type required"); - return Abs(aValue1 - aValue2) <= aEpsilon; -} - -/** - * Compare two floating point values for equality, allowing for rounding error - * relative to the magnitude of the values. That is, the two values are - * considered equal if they are both not NaN and they are less than or equal to - * some aEpsilon apart, where the aEpsilon is scaled by the smaller of the two - * argument values. - * - * In most cases you will want to use this rather than FuzzyEqualsAdditive, as - * this function effectively masks out differences in the bottom few bits of - * the floating point numbers being compared, regardless of what order of - * magnitude those numbers are at. - */ -template -static MOZ_ALWAYS_INLINE bool -FuzzyEqualsMultiplicative(T aValue1, T aValue2, - T aEpsilon = detail::FuzzyEqualsEpsilon::value()) -{ - static_assert(IsFloatingPoint::value, "floating point type required"); - // can't use std::min because of bug 965340 - T smaller = Abs(aValue1) < Abs(aValue2) ? Abs(aValue1) : Abs(aValue2); - return Abs(aValue1 - aValue2) <= aEpsilon * smaller; -} - -/** - * Returns true if the given value can be losslessly represented as an IEEE-754 - * single format number, false otherwise. All NaN values are considered - * representable (notwithstanding that the exact bit pattern of a double format - * NaN value can't be exactly represented in single format). - * - * This function isn't inlined to avoid buggy optimizations by MSVC. - */ -MOZ_MUST_USE -extern MFBT_API bool -IsFloat32Representable(double aFloat32); - -} /* namespace mozilla */ - -#endif /* mozilla_FloatingPoint_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Function.h b/android/x86/include/spidermonkey/mozilla/Function.h deleted file mode 100644 index d6de9c83..00000000 --- a/android/x86/include/spidermonkey/mozilla/Function.h +++ /dev/null @@ -1,223 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A type-erased callable wrapper. */ - -#ifndef mozilla_Function_h -#define mozilla_Function_h - -#include "mozilla/Attributes.h" // for MOZ_IMPLICIT -#include "mozilla/Move.h" -#include "mozilla/RefCounted.h" -#include "mozilla/RefPtr.h" - -// |function| is a wrapper that can hold any type of callable -// object that can be invoked in a way that's compatible with |Signature|. -// The standard "type erasure" technique is used to avoid the type of the -// wrapper depending on the concrete type of the wrapped callable. -// -// Supported callable types include non-member functions, static member -// functions, and function objects (that is to say, objects with an overloaded -// call operator; this includes C++11 lambdas). Member functions aren't -// directly supported; they first need to be wrapped into a function object -// using |std::mem_fn()| or an equivalent. -// -// |Signature| is a type of the form |ReturnType(Arguments...)|. Syntactically, -// this is a function type; it's not used in any way other than serving as a -// vehicle to encode the return and argument types into a single type. -// -// |function| is default-constructible. A default-constructed instance is -// considered "empty". Invoking an empty instance is undefined behaviour. -// An empty instance can be populated with a callable by assigning to it. -// -// This class is intended to provide functionality similar to the C++11 -// standard library class |std::function|. - -namespace mozilla { - -namespace detail { - -template -class FunctionImplBase : public mozilla::RefCounted> -{ -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(FunctionImplBase) - - virtual ~FunctionImplBase() {} - virtual ReturnType call(Arguments... aArguments) = 0; -}; - -// Normal Callable Object. -template -class FunctionImpl : public FunctionImplBase -{ - public: - explicit FunctionImpl(const Callable& aCallable) - : mCallable(aCallable) {} - - ReturnType call(Arguments... aArguments) override - { - return mCallable(Forward(aArguments)...); - } - private: - Callable mCallable; -}; - -// Base class for passing pointer to member function. -template -class MemberFunctionImplBase : public FunctionImplBase -{ -public: - explicit MemberFunctionImplBase(const Callable& aCallable) - : mCallable(aCallable) {} - - ReturnType call(Arguments... aArguments) override - { - return callInternal(Forward(aArguments)...); - } -private: - template - ReturnType callInternal(ThisType* aThis, Args&&... aArguments) - { - return (aThis->*mCallable)(Forward(aArguments)...); - } - - template - ReturnType callInternal(ThisType&& aThis, Args&&... aArguments) - { - return (aThis.*mCallable)(Forward(aArguments)...); - } - Callable mCallable; -}; - -// For non-const member function specialization of FunctionImpl. -template -class FunctionImpl - : public MemberFunctionImplBase -{ -public: - explicit FunctionImpl(ReturnType(ThisType::*aMemberFunc)(Args...)) - : MemberFunctionImplBase(aMemberFunc) - {} -}; - -// For const member function specialization of FunctionImpl. -template -class FunctionImpl - : public MemberFunctionImplBase -{ -public: - explicit FunctionImpl(ReturnType(ThisType::*aConstMemberFunc)(Args...) const) - : MemberFunctionImplBase(aConstMemberFunc) - {} -}; - -} // namespace detail - -// The primary template is never defined. As |Signature| is required to be -// of the form |ReturnType(Arguments...)|, we only define a partial -// specialization that matches this form. This allows us to use |ReturnType| -// and |Arguments| in the definition of the specialization without having to -// introspect |Signature|. -template -class function; - -template -class function -{ -public: - function() {} - - // This constructor is implicit to match the interface of |std::function|. - template - MOZ_IMPLICIT function(const Callable& aCallable) - : mImpl(new detail::FunctionImpl(aCallable)) - {} - MOZ_IMPLICIT function(const function& aFunction) - : mImpl(aFunction.mImpl) - {} - MOZ_IMPLICIT function(decltype(nullptr)) - {} - - // Move constructor and move assingment operator. - // These should be generated automatically, but MSVC doesn't do that yet. - function(function&& aOther) : mImpl(Move(aOther.mImpl)) {} - function& operator=(function&& aOther) { - mImpl = Move(aOther.mImpl); - return *this; - } - - template - function& operator=(const Callable& aCallable) - { - mImpl = new detail::FunctionImpl(aCallable); - return *this; - } - function& operator=(const function& aFunction) - { - mImpl = aFunction.mImpl; - return *this; - } - function& operator=(decltype(nullptr)) - { - mImpl = nullptr; - return *this; - } - - template - ReturnType operator()(Args&&... aArguments) const - { - MOZ_ASSERT(mImpl); - return mImpl->call(Forward(aArguments)...); - } - - explicit operator bool() const - { - return bool(mImpl); - } - -private: - // TODO: Consider implementing a small object optimization. - RefPtr> mImpl; -}; - -template -bool -operator==(const function& aX, decltype(nullptr)) -{ - return !aX; -} - -template -bool -operator==(decltype(nullptr), const function& aX) -{ - return !aX; -} - -template -bool -operator!=(const function& aX, decltype(nullptr)) -{ - return bool(aX); -} - -template -bool -operator!=(decltype(nullptr), const function& aX) -{ - return bool(aX); -} - -} // namespace mozilla - -#endif /* mozilla_Function_h */ diff --git a/android/x86/include/spidermonkey/mozilla/GuardObjects.h b/android/x86/include/spidermonkey/mozilla/GuardObjects.h deleted file mode 100644 index 9440c71c..00000000 --- a/android/x86/include/spidermonkey/mozilla/GuardObjects.h +++ /dev/null @@ -1,167 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implementation of macros to ensure correct use of RAII Auto* objects. */ - -#ifndef mozilla_GuardObjects_h -#define mozilla_GuardObjects_h - -#include "mozilla/Assertions.h" -#include "mozilla/Move.h" -#include "mozilla/Types.h" - -#ifdef __cplusplus - -#ifdef DEBUG - -/** - * A custom define is used rather than |mozPoisonValue()| due to cascading - * build failures relating to how mfbt is linked on different operating - * systems. See bug 1160253. - */ -#define MOZ_POISON uintptr_t(-1) - -namespace mozilla { -namespace detail { - -/* - * The following classes are designed to cause assertions to detect - * inadvertent use of guard objects as temporaries. In other words, - * when we have a guard object whose only purpose is its constructor and - * destructor (and is never otherwise referenced), the intended use - * might be: - * - * AutoRestore savePainting(mIsPainting); - * - * but is is easy to accidentally write: - * - * AutoRestore(mIsPainting); - * - * which compiles just fine, but runs the destructor well before the - * intended time. - * - * They work by adding (#ifdef DEBUG) an additional parameter to the - * guard object's constructor, with a default value, so that users of - * the guard object's API do not need to do anything. The default value - * of this parameter is a temporary object. C++ (ISO/IEC 14882:1998), - * section 12.2 [class.temporary], clauses 4 and 5 seem to assume a - * guarantee that temporaries are destroyed in the reverse of their - * construction order, but I actually can't find a statement that that - * is true in the general case (beyond the two specific cases mentioned - * there). However, it seems to be true. - * - * These classes are intended to be used only via the macros immediately - * below them: - * - * MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER declares (ifdef DEBUG) a member - * variable, and should be put where a declaration of a private - * member variable would be placed. - * MOZ_GUARD_OBJECT_NOTIFIER_PARAM should be placed at the end of the - * parameters to each constructor of the guard object; it declares - * (ifdef DEBUG) an additional parameter. (But use the *_ONLY_PARAM - * variant for constructors that take no other parameters.) - * MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL should likewise be used in - * the implementation of such constructors when they are not inline. - * MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT should be used in - * the implementation of such constructors to pass the parameter to - * a base class that also uses these macros - * MOZ_GUARD_OBJECT_NOTIFIER_INIT is a statement that belongs in each - * constructor. It uses the parameter declared by - * MOZ_GUARD_OBJECT_NOTIFIER_PARAM. - * - * For more details, and examples of using these macros, see - * https://developer.mozilla.org/en/Using_RAII_classes_in_Mozilla - */ -class GuardObjectNotifier -{ -private: - bool* mStatementDone; - -public: - GuardObjectNotifier() - : mStatementDone(reinterpret_cast(MOZ_POISON)) - { - } - - ~GuardObjectNotifier() - { - // Assert that the GuardObjectNotifier has been properly initialized by - // using the |MOZ_GUARD_OBJECT_NOTIFIER_INIT| macro. A poison value is - // used rather than a null check to appease static analyzers that were - // (incorrectly) detecting null pointer dereferences. - MOZ_ASSERT(mStatementDone != reinterpret_cast(MOZ_POISON)); - *mStatementDone = true; - } - - void setStatementDone(bool* aStatementIsDone) - { - mStatementDone = aStatementIsDone; - } -}; - -class GuardObjectNotificationReceiver -{ -private: - bool mStatementDone; - -public: - GuardObjectNotificationReceiver() : mStatementDone(false) { } - - ~GuardObjectNotificationReceiver() { - /* - * Assert that the guard object was not used as a temporary. (Note that - * this assert might also fire if init is not called because the guard - * object's implementation is not using the above macros correctly.) - */ - MOZ_ASSERT(mStatementDone); - } - - void init(GuardObjectNotifier& aNotifier) - { - aNotifier.setStatementDone(&mStatementDone); - } -}; - -} /* namespace detail */ -} /* namespace mozilla */ - -#undef MOZ_POISON - -#endif /* DEBUG */ - -#ifdef DEBUG -# define MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER \ - mozilla::detail::GuardObjectNotificationReceiver _mCheckNotUsedAsTemporary; -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM \ - , mozilla::detail::GuardObjectNotifier&& _notifier = \ - mozilla::detail::GuardObjectNotifier() -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM \ - mozilla::detail::GuardObjectNotifier&& _notifier = \ - mozilla::detail::GuardObjectNotifier() -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL \ - , mozilla::detail::GuardObjectNotifier&& _notifier -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL \ - mozilla::detail::GuardObjectNotifier&& _notifier -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT \ - , mozilla::Move(_notifier) -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT \ - mozilla::Move(_notifier) -# define MOZ_GUARD_OBJECT_NOTIFIER_INIT \ - do { _mCheckNotUsedAsTemporary.init(_notifier); } while (0) -#else -# define MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL -# define MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT -# define MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT -# define MOZ_GUARD_OBJECT_NOTIFIER_INIT do { } while (0) -#endif - -#endif /* __cplusplus */ - -#endif /* mozilla_GuardObjects_h */ diff --git a/android/x86/include/spidermonkey/mozilla/HashFunctions.h b/android/x86/include/spidermonkey/mozilla/HashFunctions.h deleted file mode 100644 index 4ebc1724..00000000 --- a/android/x86/include/spidermonkey/mozilla/HashFunctions.h +++ /dev/null @@ -1,394 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Utilities for hashing. */ - -/* - * This file exports functions for hashing data down to a 32-bit value, - * including: - * - * - HashString Hash a char* or char16_t/wchar_t* of known or unknown - * length. - * - * - HashBytes Hash a byte array of known length. - * - * - HashGeneric Hash one or more values. Currently, we support uint32_t, - * types which can be implicitly cast to uint32_t, data - * pointers, and function pointers. - * - * - AddToHash Add one or more values to the given hash. This supports the - * same list of types as HashGeneric. - * - * - * You can chain these functions together to hash complex objects. For example: - * - * class ComplexObject - * { - * char* mStr; - * uint32_t mUint1, mUint2; - * void (*mCallbackFn)(); - * - * public: - * uint32_t hash() - * { - * uint32_t hash = HashString(mStr); - * hash = AddToHash(hash, mUint1, mUint2); - * return AddToHash(hash, mCallbackFn); - * } - * }; - * - * If you want to hash an nsAString or nsACString, use the HashString functions - * in nsHashKeys.h. - */ - -#ifndef mozilla_HashFunctions_h -#define mozilla_HashFunctions_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Char16.h" -#include "mozilla/MathAlgorithms.h" -#include "mozilla/Types.h" - -#include - -/* Define UINT64_C */ -#ifndef UINT64_C -#define UINT64_C(value) __CONCAT(value,ULL) -#endif - -#ifdef __cplusplus -namespace mozilla { - -/** - * The golden ratio as a 32-bit fixed-point value. - */ -static const uint32_t kGoldenRatioU32 = 0x9E3779B9U; - -inline uint32_t -RotateBitsLeft32(uint32_t aValue, uint8_t aBits) -{ - MOZ_ASSERT(aBits < 32); - return (aValue << aBits) | (aValue >> (32 - aBits)); -} - -namespace detail { - -inline uint32_t -AddU32ToHash(uint32_t aHash, uint32_t aValue) -{ - /* - * This is the meat of all our hash routines. This hash function is not - * particularly sophisticated, but it seems to work well for our mostly - * plain-text inputs. Implementation notes follow. - * - * Our use of the golden ratio here is arbitrary; we could pick almost any - * number which: - * - * * is odd (because otherwise, all our hash values will be even) - * - * * has a reasonably-even mix of 1's and 0's (consider the extreme case - * where we multiply by 0x3 or 0xeffffff -- this will not produce good - * mixing across all bits of the hash). - * - * The rotation length of 5 is also arbitrary, although an odd number is again - * preferable so our hash explores the whole universe of possible rotations. - * - * Finally, we multiply by the golden ratio *after* xor'ing, not before. - * Otherwise, if |aHash| is 0 (as it often is for the beginning of a - * message), the expression - * - * (kGoldenRatioU32 * RotateBitsLeft(aHash, 5)) |xor| aValue - * - * evaluates to |aValue|. - * - * (Number-theoretic aside: Because any odd number |m| is relatively prime to - * our modulus (2^32), the list - * - * [x * m (mod 2^32) for 0 <= x < 2^32] - * - * has no duplicate elements. This means that multiplying by |m| does not - * cause us to skip any possible hash values. - * - * It's also nice if |m| has large-ish order mod 2^32 -- that is, if the - * smallest k such that m^k == 1 (mod 2^32) is large -- so we can safely - * multiply our hash value by |m| a few times without negating the - * multiplicative effect. Our golden ratio constant has order 2^29, which is - * more than enough for our purposes.) - */ - return kGoldenRatioU32 * (RotateBitsLeft32(aHash, 5) ^ aValue); -} - -/** - * AddUintptrToHash takes sizeof(uintptr_t) as a template parameter. - */ -template -inline uint32_t -AddUintptrToHash(uint32_t aHash, uintptr_t aValue); - -template<> -inline uint32_t -AddUintptrToHash<4>(uint32_t aHash, uintptr_t aValue) -{ - return AddU32ToHash(aHash, static_cast(aValue)); -} - -template<> -inline uint32_t -AddUintptrToHash<8>(uint32_t aHash, uintptr_t aValue) -{ - /* - * The static cast to uint64_t below is necessary because this function - * sometimes gets compiled on 32-bit platforms (yes, even though it's a - * template and we never call this particular override in a 32-bit build). If - * we do aValue >> 32 on a 32-bit machine, we're shifting a 32-bit uintptr_t - * right 32 bits, and the compiler throws an error. - */ - uint32_t v1 = static_cast(aValue); - uint32_t v2 = static_cast(static_cast(aValue) >> 32); - return AddU32ToHash(AddU32ToHash(aHash, v1), v2); -} - -} /* namespace detail */ - -/** - * AddToHash takes a hash and some values and returns a new hash based on the - * inputs. - * - * Currently, we support hashing uint32_t's, values which we can implicitly - * convert to uint32_t, data pointers, and function pointers. - */ -template -MOZ_MUST_USE inline uint32_t -AddToHash(uint32_t aHash, A aA) -{ - /* - * Try to convert |A| to uint32_t implicitly. If this works, great. If not, - * we'll error out. - */ - return detail::AddU32ToHash(aHash, aA); -} - -template -MOZ_MUST_USE inline uint32_t -AddToHash(uint32_t aHash, A* aA) -{ - /* - * You might think this function should just take a void*. But then we'd only - * catch data pointers and couldn't handle function pointers. - */ - - static_assert(sizeof(aA) == sizeof(uintptr_t), "Strange pointer!"); - - return detail::AddUintptrToHash(aHash, uintptr_t(aA)); -} - -template<> -MOZ_MUST_USE inline uint32_t -AddToHash(uint32_t aHash, uintptr_t aA) -{ - return detail::AddUintptrToHash(aHash, aA); -} - -template -MOZ_MUST_USE uint32_t -AddToHash(uint32_t aHash, A aArg, Args... aArgs) -{ - return AddToHash(AddToHash(aHash, aArg), aArgs...); -} - -/** - * The HashGeneric class of functions let you hash one or more values. - * - * If you want to hash together two values x and y, calling HashGeneric(x, y) is - * much better than calling AddToHash(x, y), because AddToHash(x, y) assumes - * that x has already been hashed. - */ -template -MOZ_MUST_USE inline uint32_t -HashGeneric(Args... aArgs) -{ - return AddToHash(0, aArgs...); -} - -namespace detail { - -template -uint32_t -HashUntilZero(const T* aStr) -{ - uint32_t hash = 0; - for (T c; (c = *aStr); aStr++) { - hash = AddToHash(hash, c); - } - return hash; -} - -template -uint32_t -HashKnownLength(const T* aStr, size_t aLength) -{ - uint32_t hash = 0; - for (size_t i = 0; i < aLength; i++) { - hash = AddToHash(hash, aStr[i]); - } - return hash; -} - -} /* namespace detail */ - -/** - * The HashString overloads below do just what you'd expect. - * - * If you have the string's length, you might as well call the overload which - * includes the length. It may be marginally faster. - */ -MOZ_MUST_USE inline uint32_t -HashString(const char* aStr) -{ - return detail::HashUntilZero(reinterpret_cast(aStr)); -} - -MOZ_MUST_USE inline uint32_t -HashString(const char* aStr, size_t aLength) -{ - return detail::HashKnownLength(reinterpret_cast(aStr), aLength); -} - -MOZ_MUST_USE -inline uint32_t -HashString(const unsigned char* aStr, size_t aLength) -{ - return detail::HashKnownLength(aStr, aLength); -} - -MOZ_MUST_USE inline uint32_t -HashString(const char16_t* aStr) -{ - return detail::HashUntilZero(aStr); -} - -MOZ_MUST_USE inline uint32_t -HashString(const char16_t* aStr, size_t aLength) -{ - return detail::HashKnownLength(aStr, aLength); -} - -/* - * On Windows, wchar_t is not the same as char16_t, even though it's - * the same width! - */ -#ifdef WIN32 -MOZ_MUST_USE inline uint32_t -HashString(const wchar_t* aStr) -{ - return detail::HashUntilZero(aStr); -} - -MOZ_MUST_USE inline uint32_t -HashString(const wchar_t* aStr, size_t aLength) -{ - return detail::HashKnownLength(aStr, aLength); -} -#endif - -/** - * Hash some number of bytes. - * - * This hash walks word-by-word, rather than byte-by-byte, so you won't get the - * same result out of HashBytes as you would out of HashString. - */ -MOZ_MUST_USE extern MFBT_API uint32_t -HashBytes(const void* bytes, size_t aLength); - -/** - * A pseudorandom function mapping 32-bit integers to 32-bit integers. - * - * This is for when you're feeding private data (like pointer values or credit - * card numbers) to a non-crypto hash function (like HashBytes) and then using - * the hash code for something that untrusted parties could observe (like a JS - * Map). Plug in a HashCodeScrambler before that last step to avoid leaking the - * private data. - * - * By itself, this does not prevent hash-flooding DoS attacks, because an - * attacker can still generate many values with exactly equal hash codes by - * attacking the non-crypto hash function alone. Equal hash codes will, of - * course, still be equal however much you scramble them. - * - * The algorithm is SipHash-1-3. See . - */ -class HashCodeScrambler -{ - struct SipHasher; - - uint64_t mK0, mK1; - -public: - /** Creates a new scrambler with the given 128-bit key. */ - constexpr HashCodeScrambler(uint64_t aK0, uint64_t aK1) : mK0(aK0), mK1(aK1) {} - - /** - * Scramble a hash code. Always produces the same result for the same - * combination of key and hash code. - */ - uint32_t scramble(uint32_t aHashCode) const - { - SipHasher hasher(mK0, mK1); - return uint32_t(hasher.sipHash(aHashCode)); - } - -private: - struct SipHasher - { - SipHasher(uint64_t aK0, uint64_t aK1) - { - // 1. Initialization. - mV0 = aK0 ^ UINT64_C(0x736f6d6570736575); - mV1 = aK1 ^ UINT64_C(0x646f72616e646f6d); - mV2 = aK0 ^ UINT64_C(0x6c7967656e657261); - mV3 = aK1 ^ UINT64_C(0x7465646279746573); - } - - uint64_t sipHash(uint64_t aM) - { - // 2. Compression. - mV3 ^= aM; - sipRound(); - mV0 ^= aM; - - // 3. Finalization. - mV2 ^= 0xff; - for (int i = 0; i < 3; i++) - sipRound(); - return mV0 ^ mV1 ^ mV2 ^ mV3; - } - - void sipRound() - { - mV0 += mV1; - mV1 = RotateLeft(mV1, 13); - mV1 ^= mV0; - mV0 = RotateLeft(mV0, 32); - mV2 += mV3; - mV3 = RotateLeft(mV3, 16); - mV3 ^= mV2; - mV0 += mV3; - mV3 = RotateLeft(mV3, 21); - mV3 ^= mV0; - mV2 += mV1; - mV1 = RotateLeft(mV1, 17); - mV1 ^= mV2; - mV2 = RotateLeft(mV2, 32); - } - - uint64_t mV0, mV1, mV2, mV3; - }; -}; - -} /* namespace mozilla */ -#endif /* __cplusplus */ - -#endif /* mozilla_HashFunctions_h */ diff --git a/android/x86/include/spidermonkey/mozilla/IndexSequence.h b/android/x86/include/spidermonkey/mozilla/IndexSequence.h deleted file mode 100644 index 1ccace02..00000000 --- a/android/x86/include/spidermonkey/mozilla/IndexSequence.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A utility for expanding a tuple into a variadic argument list. - * Based on std::index_sequence. */ - -/** - * Example usage: - * - * Problem: - * - * You have a variadic function Foo: - * - * template void Foo(Args...); - * - * And a variadic function Bar, which contains a tuple: - * - * template - * void Bar() { - * // ... - * Tuple t; - * } - * - * And inside Bar, you want to call Foo with the elements of the tuple as - * arguments to Foo. - * - * You want to write: - * - * Foo(Get<0>(t), Get<1>(t), ..., Get(t)) - * - * but you can't literally write that, because N is different for different - * instantiations of Bar. - * - * Solution: - * - * Write a helper function which takes the tuple, and an index sequence - * containing indices corresponding to the tuple indices. - * - * template - * void Helper(const Tuple& t, IndexSequence) - * { - * Foo(Get(t)...); - * } - * - * Assuming 'Indices...' are 0, 1, ..., N - 1, where N is the size of the - * tuple, pack expansion will expand the pack 'Get(t)...' to - * 'Get<0>(t), Get<1>(t), ..., Get(t)'. - * - * Finally, call the helper, creating the index sequence to pass in like so: - * - * template - * void Bar() { - * // ... - * Tuple t; - * Helper(t, typename IndexSequenceFor::Type()); - * } - */ - -#ifndef mozilla_IndexSequence_h -#define mozilla_IndexSequence_h - -#include "mozilla/Attributes.h" - -#include - -namespace mozilla { - -/** - * Represents a compile-time sequence of integer indices. - */ -template -struct IndexSequence -{ - static constexpr size_t Size() { return sizeof...(Indices); } -}; - -namespace detail { - -// Helpers used by MakeIndexSequence. - -template -struct IndexTuple -{ - typedef IndexTuple Next; -}; - -// Builds IndexTuple<0, 1, ..., N - 1>. -template -struct BuildIndexTuple -{ - typedef typename BuildIndexTuple::Type::Next Type; -}; - -template<> -struct BuildIndexTuple<0> -{ - typedef IndexTuple<> Type; -}; - -template -struct MakeIndexSequenceImpl; - -template -struct MakeIndexSequenceImpl> -{ - typedef IndexSequence Type; -}; - -} // namespace detail - -/** - * A utility for building an IndexSequence of consecutive indices. - * MakeIndexSequence::Type evaluates to IndexSequence<0, 1, .., N - 1>. - * Note: unlike std::make_index_sequence, this is not an alias template - * to work around bugs in MSVC 2013. - */ -template -struct MakeIndexSequence -{ - typedef typename detail::MakeIndexSequenceImpl::Type>::Type Type; -}; - -/** - * A utility for building an IndexSequence of consecutive indices - * corresponding to a variadic argument list. - * IndexSequenceFor evaluates to IndexSequence<0, 1, ..., N - 1> - * where N is the number of types in Types. - * Note: unlike std::index_sequence_for, this is not an alias template - * to work around bugs in MSVC 2013. - */ -template -struct IndexSequenceFor -{ - typedef typename MakeIndexSequence::Type Type; -}; - -} // namespace mozilla - -#endif /* mozilla_IndexSequence_h */ diff --git a/android/x86/include/spidermonkey/mozilla/IntegerPrintfMacros.h b/android/x86/include/spidermonkey/mozilla/IntegerPrintfMacros.h deleted file mode 100644 index c534a0ba..00000000 --- a/android/x86/include/spidermonkey/mozilla/IntegerPrintfMacros.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implements the C99 interface. */ - -#ifndef mozilla_IntegerPrintfMacros_h_ -#define mozilla_IntegerPrintfMacros_h_ - -/* - * These macros should not be used with the NSPR printf-like functions or their - * users, e.g. mozilla/Logging.h. If you need to use NSPR's facilities, see the - * comment on supported formats at the top of nsprpub/pr/include/prprf.h. - */ - -/* - * scanf is a footgun: if the input number exceeds the bounds of the target - * type, behavior is undefined (in the compiler sense: that is, this code - * could overwrite your hard drive with zeroes): - * - * uint8_t u; - * sscanf("256", "%" SCNu8, &u); // BAD - * - * For this reason, *never* use the SCN* macros provided by this header! - */ - -#include - -/* - * Fix up Android's broken [u]intptr_t inttype macros. Android's PRI*PTR - * macros are defined as "ld", but sizeof(long) is 8 and sizeof(intptr_t) - * is 4 on 32-bit Android. TestTypeTraits.cpp asserts that these new macro - * definitions match the actual type sizes seen at compile time. - */ -#if defined(ANDROID) && !defined(__LP64__) -# undef PRIdPTR /* intptr_t */ -# define PRIdPTR "d" /* intptr_t */ -# undef PRIiPTR /* intptr_t */ -# define PRIiPTR "i" /* intptr_t */ -# undef PRIoPTR /* uintptr_t */ -# define PRIoPTR "o" /* uintptr_t */ -# undef PRIuPTR /* uintptr_t */ -# define PRIuPTR "u" /* uintptr_t */ -# undef PRIxPTR /* uintptr_t */ -# define PRIxPTR "x" /* uintptr_t */ -# undef PRIXPTR /* uintptr_t */ -# define PRIXPTR "X" /* uintptr_t */ -#endif - -#endif /* mozilla_IntegerPrintfMacros_h_ */ diff --git a/android/x86/include/spidermonkey/mozilla/IntegerRange.h b/android/x86/include/spidermonkey/mozilla/IntegerRange.h deleted file mode 100644 index 8d5d2e4d..00000000 --- a/android/x86/include/spidermonkey/mozilla/IntegerRange.h +++ /dev/null @@ -1,181 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Iterator over ranges of integers */ - -#ifndef mozilla_IntegerRange_h -#define mozilla_IntegerRange_h - -#include "mozilla/Assertions.h" -#include "mozilla/ReverseIterator.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -namespace detail { - -template -class IntegerIterator -{ -public: - template - explicit IntegerIterator(IntType aCurrent) - : mCurrent(aCurrent) { } - - template - explicit IntegerIterator(const IntegerIterator& aOther) - : mCurrent(aOther.mCurrent) { } - - IntTypeT operator*() const { return mCurrent; } - - /* Increment and decrement operators */ - - IntegerIterator& operator++() { ++mCurrent; return *this; } - IntegerIterator& operator--() { --mCurrent; return *this; } - IntegerIterator operator++(int) { auto ret = *this; ++mCurrent; return ret; } - IntegerIterator operator--(int) { auto ret = *this; --mCurrent; return ret; } - - /* Comparison operators */ - - template - friend bool operator==(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - template - friend bool operator!=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - template - friend bool operator<(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - template - friend bool operator<=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - template - friend bool operator>(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - template - friend bool operator>=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2); - -private: - IntTypeT mCurrent; -}; - -template -bool operator==(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent == aIter2.mCurrent; -} - -template -bool operator!=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent != aIter2.mCurrent; -} - -template -bool operator<(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent < aIter2.mCurrent; -} - -template -bool operator<=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent <= aIter2.mCurrent; -} - -template -bool operator>(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent > aIter2.mCurrent; -} - -template -bool operator>=(const IntegerIterator& aIter1, - const IntegerIterator& aIter2) -{ - return aIter1.mCurrent >= aIter2.mCurrent; -} - -template -class IntegerRange -{ -public: - typedef IntegerIterator iterator; - typedef IntegerIterator const_iterator; - typedef ReverseIterator> reverse_iterator; - typedef ReverseIterator> const_reverse_iterator; - - template - explicit IntegerRange(IntType aEnd) - : mBegin(0), mEnd(aEnd) { } - - template - IntegerRange(IntType1 aBegin, IntType2 aEnd) - : mBegin(aBegin), mEnd(aEnd) { } - - iterator begin() const { return iterator(mBegin); } - const_iterator cbegin() const { return begin(); } - iterator end() const { return iterator(mEnd); } - const_iterator cend() const { return end(); } - reverse_iterator rbegin() const { return reverse_iterator(mEnd); } - const_reverse_iterator crbegin() const { return rbegin(); } - reverse_iterator rend() const { return reverse_iterator(mBegin); } - const_reverse_iterator crend() const { return rend(); } - -private: - IntTypeT mBegin; - IntTypeT mEnd; -}; - -template::value> -struct GeqZero -{ - static bool check(T t) { - return t >= 0; - } -}; - -template -struct GeqZero -{ - static bool check(T t) { - return true; - } -}; - -} // namespace detail - -template -detail::IntegerRange -MakeRange(IntType aEnd) -{ - static_assert(IsIntegral::value, "value must be integral"); - MOZ_ASSERT(detail::GeqZero::check(aEnd), - "Should never have negative value here"); - return detail::IntegerRange(aEnd); -} - -template -detail::IntegerRange -MakeRange(IntType1 aBegin, IntType2 aEnd) -{ - static_assert(IsIntegral::value && IsIntegral::value, - "values must both be integral"); - static_assert(IsSigned::value == IsSigned::value, - "signed/unsigned mismatch"); - MOZ_ASSERT(aEnd >= aBegin, "End value should be larger than begin value"); - return detail::IntegerRange(aBegin, aEnd); -} - -} // namespace mozilla - -#endif // mozilla_IntegerRange_h diff --git a/android/x86/include/spidermonkey/mozilla/IntegerTypeTraits.h b/android/x86/include/spidermonkey/mozilla/IntegerTypeTraits.h deleted file mode 100644 index 6144d208..00000000 --- a/android/x86/include/spidermonkey/mozilla/IntegerTypeTraits.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Helpers to manipulate integer types that don't fit in TypeTraits.h */ - -#ifndef mozilla_IntegerTypeTraits_h -#define mozilla_IntegerTypeTraits_h - -#include "mozilla/TypeTraits.h" -#include - -namespace mozilla { - -namespace detail { - -/** - * StdintTypeForSizeAndSignedness returns the stdint integer type - * of given size (can be 1, 2, 4 or 8) and given signedness - * (false means unsigned, true means signed). - */ -template -struct StdintTypeForSizeAndSignedness; - -template<> -struct StdintTypeForSizeAndSignedness<1, true> -{ - typedef int8_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<1, false> -{ - typedef uint8_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<2, true> -{ - typedef int16_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<2, false> -{ - typedef uint16_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<4, true> -{ - typedef int32_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<4, false> -{ - typedef uint32_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<8, true> -{ - typedef int64_t Type; -}; - -template<> -struct StdintTypeForSizeAndSignedness<8, false> -{ - typedef uint64_t Type; -}; - -} // namespace detail - -template -struct UnsignedStdintTypeForSize - : detail::StdintTypeForSizeAndSignedness -{}; - -template -struct SignedStdintTypeForSize - : detail::StdintTypeForSizeAndSignedness -{}; - -template -struct PositionOfSignBit -{ - static_assert(IsIntegral::value, - "PositionOfSignBit is only for integral types"); - // 8 here should be CHAR_BIT from limits.h, but the world has moved on. - static const size_t value = 8 * sizeof(IntegerType) - 1; -}; - -/** - * MinValue returns the minimum value of the given integer type as a - * compile-time constant, which std::numeric_limits::min() - * cannot do in c++98. - */ -template -struct MinValue -{ -private: - static_assert(IsIntegral::value, - "MinValue is only for integral types"); - - typedef typename MakeUnsigned::Type UnsignedIntegerType; - static const size_t PosOfSignBit = PositionOfSignBit::value; - -public: - // Bitwise ops may return a larger type, that's why we cast explicitly. - // In C++, left bit shifts on signed values is undefined by the standard - // unless the shifted value is representable. - // Notice that signed-to-unsigned conversions are always well-defined in - // the standard as the value congruent to 2**n, as expected. By contrast, - // unsigned-to-signed is only well-defined if the value is representable. - static const IntegerType value = - IsSigned::value - ? IntegerType(UnsignedIntegerType(1) << PosOfSignBit) - : IntegerType(0); -}; - -/** - * MaxValue returns the maximum value of the given integer type as a - * compile-time constant, which std::numeric_limits::max() - * cannot do in c++98. - */ -template -struct MaxValue -{ - static_assert(IsIntegral::value, - "MaxValue is only for integral types"); - - // Tricksy, but covered by the CheckedInt unit test. - // Relies on the type of MinValue::value - // being IntegerType. - static const IntegerType value = ~MinValue::value; -}; - -} // namespace mozilla - -#endif // mozilla_IntegerTypeTraits_h diff --git a/android/x86/include/spidermonkey/mozilla/JSONWriter.h b/android/x86/include/spidermonkey/mozilla/JSONWriter.h deleted file mode 100644 index 7d44dc7f..00000000 --- a/android/x86/include/spidermonkey/mozilla/JSONWriter.h +++ /dev/null @@ -1,460 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A JSON pretty-printer class. */ - -// A typical JSON-writing library requires you to first build up a data -// structure that represents a JSON object and then serialize it (to file, or -// somewhere else). This approach makes for a clean API, but building the data -// structure takes up memory. Sometimes that isn't desirable, such as when the -// JSON data is produced for memory reporting. -// -// The JSONWriter class instead allows JSON data to be written out -// incrementally without building up large data structures. -// -// The API is slightly uglier than you would see in a typical JSON-writing -// library, but still fairly easy to use. It's possible to generate invalid -// JSON with JSONWriter, but typically the most basic testing will identify any -// such problems. -// -// Similarly, there are no RAII facilities for automatically closing objects -// and arrays. These would be nice if you are generating all your code within -// nested functions, but in other cases you'd have to maintain an explicit -// stack of RAII objects and manually unwind it, which is no better than just -// calling "end" functions. Furthermore, the consequences of forgetting to -// close an object or array are obvious and, again, will be identified via -// basic testing, unlike other cases where RAII is typically used (e.g. smart -// pointers) and the consequences of defects are more subtle. -// -// Importantly, the class does solve the two hard problems of JSON -// pretty-printing, which are (a) correctly escaping strings, and (b) adding -// appropriate indentation and commas between items. -// -// By default, every property is placed on its own line. However, it is -// possible to request that objects and arrays be placed entirely on a single -// line, which can reduce output size significantly in some cases. -// -// Strings used (for property names and string property values) are |const -// char*| throughout, and can be ASCII or UTF-8. -// -// EXAMPLE -// ------- -// Assume that |MyWriteFunc| is a class that implements |JSONWriteFunc|. The -// following code: -// -// JSONWriter w(MakeUnique()); -// w.Start(); -// { -// w.NullProperty("null"); -// w.BoolProperty("bool", true); -// w.IntProperty("int", 1); -// w.StartArrayProperty("array"); -// { -// w.StringElement("string"); -// w.StartObjectElement(); -// { -// w.DoubleProperty("double", 3.4); -// w.StartArrayProperty("single-line array", w.SingleLineStyle); -// { -// w.IntElement(1); -// w.StartObjectElement(); // SingleLineStyle is inherited from -// w.EndObjectElement(); // above for this collection -// } -// w.EndArray(); -// } -// w.EndObjectElement(); -// } -// w.EndArrayProperty(); -// } -// w.End(); -// -// will produce pretty-printed output for the following JSON object: -// -// { -// "null": null, -// "bool": true, -// "int": 1, -// "array": [ -// "string", -// { -// "double": 3.4, -// "single-line array": [1, {}] -// } -// ] -// } -// -// The nesting in the example code is obviously optional, but can aid -// readability. - -#ifndef mozilla_JSONWriter_h -#define mozilla_JSONWriter_h - -#include "mozilla/double-conversion.h" -#include "mozilla/IntegerPrintfMacros.h" -#include "mozilla/PodOperations.h" -#include "mozilla/Sprintf.h" -#include "mozilla/UniquePtr.h" -#include "mozilla/Vector.h" - -#include - -namespace mozilla { - -// A quasi-functor for JSONWriter. We don't use a true functor because that -// requires templatizing JSONWriter, and the templatization seeps to lots of -// places we don't want it to. -class JSONWriteFunc -{ -public: - virtual void Write(const char* aStr) = 0; - virtual ~JSONWriteFunc() {} -}; - -// Ideally this would be within |EscapedString| but when compiling with GCC -// on Linux that caused link errors, whereas this formulation didn't. -namespace detail { -extern MFBT_DATA const char gTwoCharEscapes[256]; -} // namespace detail - -class JSONWriter -{ - // From http://www.ietf.org/rfc/rfc4627.txt: - // - // "All Unicode characters may be placed within the quotation marks except - // for the characters that must be escaped: quotation mark, reverse - // solidus, and the control characters (U+0000 through U+001F)." - // - // This implementation uses two-char escape sequences where possible, namely: - // - // \", \\, \b, \f, \n, \r, \t - // - // All control characters not in the above list are represented with a - // six-char escape sequence, e.g. '\u000b' (a.k.a. '\v'). - // - class EscapedString - { - // Only one of |mUnownedStr| and |mOwnedStr| are ever non-null. |mIsOwned| - // indicates which one is in use. They're not within a union because that - // wouldn't work with UniquePtr. - bool mIsOwned; - const char* mUnownedStr; - UniquePtr mOwnedStr; - - void SanityCheck() const - { - MOZ_ASSERT_IF( mIsOwned, mOwnedStr.get() && !mUnownedStr); - MOZ_ASSERT_IF(!mIsOwned, !mOwnedStr.get() && mUnownedStr); - } - - static char hexDigitToAsciiChar(uint8_t u) - { - u = u & 0xf; - return u < 10 ? '0' + u : 'a' + (u - 10); - } - - public: - explicit EscapedString(const char* aStr) - : mUnownedStr(nullptr) - , mOwnedStr(nullptr) - { - const char* p; - - // First, see if we need to modify the string. - size_t nExtra = 0; - p = aStr; - while (true) { - uint8_t u = *p; // ensure it can't be interpreted as negative - if (u == 0) { - break; - } - if (detail::gTwoCharEscapes[u]) { - nExtra += 1; - } else if (u <= 0x1f) { - nExtra += 5; - } - p++; - } - - if (nExtra == 0) { - // No escapes needed. Easy. - mIsOwned = false; - mUnownedStr = aStr; - return; - } - - // Escapes are needed. We'll create a new string. - mIsOwned = true; - size_t len = (p - aStr) + nExtra; - mOwnedStr = MakeUnique(len + 1); - - p = aStr; - size_t i = 0; - - while (true) { - uint8_t u = *p; // ensure it can't be interpreted as negative - if (u == 0) { - mOwnedStr[i] = 0; - break; - } - if (detail::gTwoCharEscapes[u]) { - mOwnedStr[i++] = '\\'; - mOwnedStr[i++] = detail::gTwoCharEscapes[u]; - } else if (u <= 0x1f) { - mOwnedStr[i++] = '\\'; - mOwnedStr[i++] = 'u'; - mOwnedStr[i++] = '0'; - mOwnedStr[i++] = '0'; - mOwnedStr[i++] = hexDigitToAsciiChar((u & 0x00f0) >> 4); - mOwnedStr[i++] = hexDigitToAsciiChar(u & 0x000f); - } else { - mOwnedStr[i++] = u; - } - p++; - } - } - - ~EscapedString() - { - SanityCheck(); - } - - const char* get() const - { - SanityCheck(); - return mIsOwned ? mOwnedStr.get() : mUnownedStr; - } - }; - -public: - // Collections (objects and arrays) are printed in a multi-line style by - // default. This can be changed to a single-line style if SingleLineStyle is - // specified. If a collection is printed in single-line style, every nested - // collection within it is also printed in single-line style, even if - // multi-line style is requested. - enum CollectionStyle { - MultiLineStyle, // the default - SingleLineStyle - }; - -protected: - const UniquePtr mWriter; - Vector mNeedComma; // do we need a comma at depth N? - Vector mNeedNewlines; // do we need newlines at depth N? - size_t mDepth; // the current nesting depth - - void Indent() - { - for (size_t i = 0; i < mDepth; i++) { - mWriter->Write(" "); - } - } - - // Adds whatever is necessary (maybe a comma, and then a newline and - // whitespace) to separate an item (property or element) from what's come - // before. - void Separator() - { - if (mNeedComma[mDepth]) { - mWriter->Write(","); - } - if (mDepth > 0 && mNeedNewlines[mDepth]) { - mWriter->Write("\n"); - Indent(); - } else if (mNeedComma[mDepth]) { - mWriter->Write(" "); - } - } - - void PropertyNameAndColon(const char* aName) - { - EscapedString escapedName(aName); - mWriter->Write("\""); - mWriter->Write(escapedName.get()); - mWriter->Write("\": "); - } - - void Scalar(const char* aMaybePropertyName, const char* aStringValue) - { - Separator(); - if (aMaybePropertyName) { - PropertyNameAndColon(aMaybePropertyName); - } - mWriter->Write(aStringValue); - mNeedComma[mDepth] = true; - } - - void QuotedScalar(const char* aMaybePropertyName, const char* aStringValue) - { - Separator(); - if (aMaybePropertyName) { - PropertyNameAndColon(aMaybePropertyName); - } - mWriter->Write("\""); - mWriter->Write(aStringValue); - mWriter->Write("\""); - mNeedComma[mDepth] = true; - } - - void NewVectorEntries() - { - // If these tiny allocations OOM we might as well just crash because we - // must be in serious memory trouble. - MOZ_RELEASE_ASSERT(mNeedComma.resizeUninitialized(mDepth + 1)); - MOZ_RELEASE_ASSERT(mNeedNewlines.resizeUninitialized(mDepth + 1)); - mNeedComma[mDepth] = false; - mNeedNewlines[mDepth] = true; - } - - void StartCollection(const char* aMaybePropertyName, const char* aStartChar, - CollectionStyle aStyle = MultiLineStyle) - { - Separator(); - if (aMaybePropertyName) { - mWriter->Write("\""); - mWriter->Write(aMaybePropertyName); - mWriter->Write("\": "); - } - mWriter->Write(aStartChar); - mNeedComma[mDepth] = true; - mDepth++; - NewVectorEntries(); - mNeedNewlines[mDepth] = - mNeedNewlines[mDepth - 1] && aStyle == MultiLineStyle; - } - - // Adds the whitespace and closing char necessary to end a collection. - void EndCollection(const char* aEndChar) - { - if (mNeedNewlines[mDepth]) { - mWriter->Write("\n"); - mDepth--; - Indent(); - } else { - mDepth--; - } - mWriter->Write(aEndChar); - } - -public: - explicit JSONWriter(UniquePtr aWriter) - : mWriter(Move(aWriter)) - , mNeedComma() - , mNeedNewlines() - , mDepth(0) - { - NewVectorEntries(); - } - - // Returns the JSONWriteFunc passed in at creation, for temporary use. The - // JSONWriter object still owns the JSONWriteFunc. - JSONWriteFunc* WriteFunc() const { return mWriter.get(); } - - // For all the following functions, the "Prints:" comment indicates what the - // basic output looks like. However, it doesn't indicate the whitespace and - // trailing commas, which are automatically added as required. - // - // All property names and string properties are escaped as necessary. - - // Prints: { - void Start(CollectionStyle aStyle = MultiLineStyle) - { - StartCollection(nullptr, "{", aStyle); - } - - // Prints: } - void End() { EndCollection("}\n"); } - - // Prints: "": null - void NullProperty(const char* aName) - { - Scalar(aName, "null"); - } - - // Prints: null - void NullElement() { NullProperty(nullptr); } - - // Prints: "": - void BoolProperty(const char* aName, bool aBool) - { - Scalar(aName, aBool ? "true" : "false"); - } - - // Prints: - void BoolElement(bool aBool) { BoolProperty(nullptr, aBool); } - - // Prints: "": - void IntProperty(const char* aName, int64_t aInt) - { - char buf[64]; - SprintfLiteral(buf, "%" PRId64, aInt); - Scalar(aName, buf); - } - - // Prints: - void IntElement(int64_t aInt) { IntProperty(nullptr, aInt); } - - // Prints: "": - void DoubleProperty(const char* aName, double aDouble) - { - static const size_t buflen = 64; - char buf[buflen]; - const double_conversion::DoubleToStringConverter &converter = - double_conversion::DoubleToStringConverter::EcmaScriptConverter(); - double_conversion::StringBuilder builder(buf, buflen); - converter.ToShortest(aDouble, &builder); - Scalar(aName, builder.Finalize()); - } - - // Prints: - void DoubleElement(double aDouble) { DoubleProperty(nullptr, aDouble); } - - // Prints: "": "" - void StringProperty(const char* aName, const char* aStr) - { - EscapedString escapedStr(aStr); - QuotedScalar(aName, escapedStr.get()); - } - - // Prints: "" - void StringElement(const char* aStr) { StringProperty(nullptr, aStr); } - - // Prints: "": [ - void StartArrayProperty(const char* aName, - CollectionStyle aStyle = MultiLineStyle) - { - StartCollection(aName, "[", aStyle); - } - - // Prints: [ - void StartArrayElement(CollectionStyle aStyle = MultiLineStyle) - { - StartArrayProperty(nullptr, aStyle); - } - - // Prints: ] - void EndArray() { EndCollection("]"); } - - // Prints: "": { - void StartObjectProperty(const char* aName, - CollectionStyle aStyle = MultiLineStyle) - { - StartCollection(aName, "{", aStyle); - } - - // Prints: { - void StartObjectElement(CollectionStyle aStyle = MultiLineStyle) - { - StartObjectProperty(nullptr, aStyle); - } - - // Prints: } - void EndObject() { EndCollection("}"); } -}; - -} // namespace mozilla - -#endif /* mozilla_JSONWriter_h */ - diff --git a/android/x86/include/spidermonkey/mozilla/Likely.h b/android/x86/include/spidermonkey/mozilla/Likely.h deleted file mode 100644 index 4f216092..00000000 --- a/android/x86/include/spidermonkey/mozilla/Likely.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * MOZ_LIKELY and MOZ_UNLIKELY macros to hint to the compiler how a - * boolean predicate should be branch-predicted. - */ - -#ifndef mozilla_Likely_h -#define mozilla_Likely_h - -#if defined(__clang__) || defined(__GNUC__) -# define MOZ_LIKELY(x) (__builtin_expect(!!(x), 1)) -# define MOZ_UNLIKELY(x) (__builtin_expect(!!(x), 0)) -#else -# define MOZ_LIKELY(x) (!!(x)) -# define MOZ_UNLIKELY(x) (!!(x)) -#endif - -#endif /* mozilla_Likely_h */ diff --git a/android/x86/include/spidermonkey/mozilla/LinkedList.h b/android/x86/include/spidermonkey/mozilla/LinkedList.h deleted file mode 100644 index 6e14aa16..00000000 --- a/android/x86/include/spidermonkey/mozilla/LinkedList.h +++ /dev/null @@ -1,659 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A type-safe doubly-linked list class. */ - -/* - * The classes LinkedList and LinkedListElement together form a - * convenient, type-safe doubly-linked list implementation. - * - * The class T which will be inserted into the linked list must inherit from - * LinkedListElement. A given object may be in only one linked list at a - * time. - * - * A LinkedListElement automatically removes itself from the list upon - * destruction, and a LinkedList will fatally assert in debug builds if it's - * non-empty when it's destructed. - * - * For example, you might use LinkedList in a simple observer list class as - * follows. - * - * class Observer : public LinkedListElement - * { - * public: - * void observe(char* aTopic) { ... } - * }; - * - * class ObserverContainer - * { - * private: - * LinkedList list; - * - * public: - * void addObserver(Observer* aObserver) - * { - * // Will assert if |aObserver| is part of another list. - * list.insertBack(aObserver); - * } - * - * void removeObserver(Observer* aObserver) - * { - * // Will assert if |aObserver| is not part of some list. - * aObserver.remove(); - * // Or, will assert if |aObserver| is not part of |list| specifically. - * // aObserver.removeFrom(list); - * } - * - * void notifyObservers(char* aTopic) - * { - * for (Observer* o = list.getFirst(); o != nullptr; o = o->getNext()) { - * o->observe(aTopic); - * } - * } - * }; - * - * Additionally, the class AutoCleanLinkedList is a LinkedList that will - * remove and delete each element still within itself upon destruction. Note - * that because each element is deleted, elements must have been allocated - * using |new|. - */ - -#ifndef mozilla_LinkedList_h -#define mozilla_LinkedList_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" -#include "mozilla/RefPtr.h" - -#ifdef __cplusplus - -namespace mozilla { - -template -class LinkedListElement; - -namespace detail { - -/** - * LinkedList supports refcounted elements using this adapter class. Clients - * using LinkedList> will get a data structure that holds a strong - * reference to T as long as T is in the list. - */ -template -struct LinkedListElementTraits -{ - typedef T* RawType; - typedef const T* ConstRawType; - typedef T* ClientType; - typedef const T* ConstClientType; - - // These static methods are called when an element is added to or removed from - // a linked list. It can be used to keep track ownership in lists that are - // supposed to own their elements. If elements are transferred from one list - // to another, no enter or exit calls happen since the elements still belong - // to a list. - static void enterList(LinkedListElement* elt) {} - static void exitList(LinkedListElement* elt) {} -}; - -template -struct LinkedListElementTraits> -{ - typedef T* RawType; - typedef const T* ConstRawType; - typedef RefPtr ClientType; - typedef RefPtr ConstClientType; - - static void enterList(LinkedListElement>* elt) { elt->asT()->AddRef(); } - static void exitList(LinkedListElement>* elt) { elt->asT()->Release(); } -}; - -} /* namespace detail */ - -template -class LinkedList; - -template -class LinkedListElement -{ - typedef typename detail::LinkedListElementTraits Traits; - typedef typename Traits::RawType RawType; - typedef typename Traits::ConstRawType ConstRawType; - typedef typename Traits::ClientType ClientType; - typedef typename Traits::ConstClientType ConstClientType; - - /* - * It's convenient that we return nullptr when getNext() or getPrevious() - * hits the end of the list, but doing so costs an extra word of storage in - * each linked list node (to keep track of whether |this| is the sentinel - * node) and a branch on this value in getNext/getPrevious. - * - * We could get rid of the extra word of storage by shoving the "is - * sentinel" bit into one of the pointers, although this would, of course, - * have performance implications of its own. - * - * But the goal here isn't to win an award for the fastest or slimmest - * linked list; rather, we want a *convenient* linked list. So we won't - * waste time guessing which micro-optimization strategy is best. - * - * - * Speaking of unnecessary work, it's worth addressing here why we wrote - * mozilla::LinkedList in the first place, instead of using stl::list. - * - * The key difference between mozilla::LinkedList and stl::list is that - * mozilla::LinkedList stores the mPrev/mNext pointers in the object itself, - * while stl::list stores the mPrev/mNext pointers in a list element which - * itself points to the object being stored. - * - * mozilla::LinkedList's approach makes it harder to store an object in more - * than one list. But the upside is that you can call next() / prev() / - * remove() directly on the object. With stl::list, you'd need to store a - * pointer to its iterator in the object in order to accomplish this. Not - * only would this waste space, but you'd have to remember to update that - * pointer every time you added or removed the object from a list. - * - * In-place, constant-time removal is a killer feature of doubly-linked - * lists, and supporting this painlessly was a key design criterion. - */ - -private: - LinkedListElement* mNext; - LinkedListElement* mPrev; - const bool mIsSentinel; - -public: - LinkedListElement() - : mNext(this), - mPrev(this), - mIsSentinel(false) - { } - - /* - * Moves |aOther| into |*this|. If |aOther| is already in a list, then - * |aOther| is removed from the list and replaced by |*this|. - */ - LinkedListElement(LinkedListElement&& aOther) - : mIsSentinel(aOther.mIsSentinel) - { - adjustLinkForMove(Move(aOther)); - } - - LinkedListElement& operator=(LinkedListElement&& aOther) - { - MOZ_ASSERT(mIsSentinel == aOther.mIsSentinel, "Mismatch NodeKind!"); - MOZ_ASSERT(!isInList(), - "Assigning to an element in a list messes up that list!"); - adjustLinkForMove(Move(aOther)); - return *this; - } - - ~LinkedListElement() - { - if (!mIsSentinel && isInList()) { - remove(); - } - } - - /* - * Get the next element in the list, or nullptr if this is the last element - * in the list. - */ - RawType getNext() { return mNext->asT(); } - ConstRawType getNext() const { return mNext->asT(); } - - /* - * Get the previous element in the list, or nullptr if this is the first - * element in the list. - */ - RawType getPrevious() { return mPrev->asT(); } - ConstRawType getPrevious() const { return mPrev->asT(); } - - /* - * Insert aElem after this element in the list. |this| must be part of a - * linked list when you call setNext(); otherwise, this method will assert. - */ - void setNext(RawType aElem) - { - MOZ_ASSERT(isInList()); - setNextUnsafe(aElem); - } - - /* - * Insert aElem before this element in the list. |this| must be part of a - * linked list when you call setPrevious(); otherwise, this method will - * assert. - */ - void setPrevious(RawType aElem) - { - MOZ_ASSERT(isInList()); - setPreviousUnsafe(aElem); - } - - /* - * Remove this element from the list which contains it. If this element is - * not currently part of a linked list, this method asserts. - */ - void remove() - { - MOZ_ASSERT(isInList()); - - mPrev->mNext = mNext; - mNext->mPrev = mPrev; - mNext = this; - mPrev = this; - - Traits::exitList(this); - } - - /* - * Remove this element from the list containing it. Returns a pointer to the - * element that follows this element (before it was removed). This method - * asserts if the element does not belong to a list. - */ - ClientType removeAndGetNext() - { - ClientType r = getNext(); - remove(); - return r; - } - - /* - * Remove this element from the list containing it. Returns a pointer to the - * previous element in the containing list (before the removal). This method - * asserts if the element does not belong to a list. - */ - ClientType removeAndGetPrevious() - { - ClientType r = getPrevious(); - remove(); - return r; - } - - /* - * Identical to remove(), but also asserts in debug builds that this element - * is in aList. - */ - void removeFrom(const LinkedList& aList) - { - aList.assertContains(asT()); - remove(); - } - - /* - * Return true if |this| part is of a linked list, and false otherwise. - */ - bool isInList() const - { - MOZ_ASSERT((mNext == this) == (mPrev == this)); - return mNext != this; - } - -private: - friend class LinkedList; - friend struct detail::LinkedListElementTraits; - - enum class NodeKind { - Normal, - Sentinel - }; - - explicit LinkedListElement(NodeKind nodeKind) - : mNext(this), - mPrev(this), - mIsSentinel(nodeKind == NodeKind::Sentinel) - { } - - /* - * Return |this| cast to T* if we're a normal node, or return nullptr if - * we're a sentinel node. - */ - RawType asT() - { - return mIsSentinel ? nullptr : static_cast(this); - } - ConstRawType asT() const - { - return mIsSentinel ? nullptr : static_cast(this); - } - - /* - * Insert aElem after this element, but don't check that this element is in - * the list. This is called by LinkedList::insertFront(). - */ - void setNextUnsafe(RawType aElem) - { - LinkedListElement *listElem = static_cast(aElem); - MOZ_ASSERT(!listElem->isInList()); - - listElem->mNext = this->mNext; - listElem->mPrev = this; - this->mNext->mPrev = listElem; - this->mNext = listElem; - - Traits::enterList(aElem); - } - - /* - * Insert aElem before this element, but don't check that this element is in - * the list. This is called by LinkedList::insertBack(). - */ - void setPreviousUnsafe(RawType aElem) - { - LinkedListElement* listElem = static_cast*>(aElem); - MOZ_ASSERT(!listElem->isInList()); - - listElem->mNext = this; - listElem->mPrev = this->mPrev; - this->mPrev->mNext = listElem; - this->mPrev = listElem; - - Traits::enterList(aElem); - } - - /* - * Adjust mNext and mPrev for implementing move constructor and move - * assignment. - */ - void adjustLinkForMove(LinkedListElement&& aOther) - { - if (!aOther.isInList()) { - mNext = this; - mPrev = this; - return; - } - - if (!mIsSentinel) { - Traits::enterList(this); - } - - MOZ_ASSERT(aOther.mNext->mPrev == &aOther); - MOZ_ASSERT(aOther.mPrev->mNext == &aOther); - - /* - * Initialize |this| with |aOther|'s mPrev/mNext pointers, and adjust those - * element to point to this one. - */ - mNext = aOther.mNext; - mPrev = aOther.mPrev; - - mNext->mPrev = this; - mPrev->mNext = this; - - /* - * Adjust |aOther| so it doesn't think it's in a list. This makes it - * safely destructable. - */ - aOther.mNext = &aOther; - aOther.mPrev = &aOther; - - if (!mIsSentinel) { - Traits::exitList(&aOther); - } - } - - LinkedListElement& operator=(const LinkedListElement& aOther) = delete; - LinkedListElement(const LinkedListElement& aOther) = delete; -}; - -template -class LinkedList -{ -private: - typedef typename detail::LinkedListElementTraits Traits; - typedef typename Traits::RawType RawType; - typedef typename Traits::ConstRawType ConstRawType; - typedef typename Traits::ClientType ClientType; - typedef typename Traits::ConstClientType ConstClientType; - - LinkedListElement sentinel; - -public: - class Iterator { - RawType mCurrent; - - public: - explicit Iterator(RawType aCurrent) : mCurrent(aCurrent) {} - - RawType operator *() const { - return mCurrent; - } - - const Iterator& operator++() { - mCurrent = mCurrent->getNext(); - return *this; - } - - bool operator!=(Iterator& aOther) const { - return mCurrent != aOther.mCurrent; - } - }; - - LinkedList() : sentinel(LinkedListElement::NodeKind::Sentinel) { } - - LinkedList(LinkedList&& aOther) - : sentinel(mozilla::Move(aOther.sentinel)) - { } - - LinkedList& operator=(LinkedList&& aOther) - { - MOZ_ASSERT(isEmpty(), "Assigning to a non-empty list leaks elements in that list!"); - sentinel = mozilla::Move(aOther.sentinel); - return *this; - } - - ~LinkedList() { - MOZ_ASSERT(isEmpty(), - "failing this assertion means this LinkedList's creator is " - "buggy: it should have removed all this list's elements before " - "the list's destruction"); - } - - /* - * Add aElem to the front of the list. - */ - void insertFront(RawType aElem) - { - /* Bypass setNext()'s this->isInList() assertion. */ - sentinel.setNextUnsafe(aElem); - } - - /* - * Add aElem to the back of the list. - */ - void insertBack(RawType aElem) - { - sentinel.setPreviousUnsafe(aElem); - } - - /* - * Get the first element of the list, or nullptr if the list is empty. - */ - RawType getFirst() { return sentinel.getNext(); } - ConstRawType getFirst() const { return sentinel.getNext(); } - - /* - * Get the last element of the list, or nullptr if the list is empty. - */ - RawType getLast() { return sentinel.getPrevious(); } - ConstRawType getLast() const { return sentinel.getPrevious(); } - - /* - * Get and remove the first element of the list. If the list is empty, - * return nullptr. - */ - ClientType popFirst() - { - ClientType ret = sentinel.getNext(); - if (ret) { - static_cast*>(RawType(ret))->remove(); - } - return ret; - } - - /* - * Get and remove the last element of the list. If the list is empty, - * return nullptr. - */ - ClientType popLast() - { - ClientType ret = sentinel.getPrevious(); - if (ret) { - static_cast*>(RawType(ret))->remove(); - } - return ret; - } - - /* - * Return true if the list is empty, or false otherwise. - */ - bool isEmpty() const - { - return !sentinel.isInList(); - } - - /* - * Remove all the elements from the list. - * - * This runs in time linear to the list's length, because we have to mark - * each element as not in the list. - */ - void clear() - { - while (popFirst()) { - continue; - } - } - - /* - * Allow range-based iteration: - * - * for (MyElementType* elt : myList) { ... } - */ - Iterator begin() { - return Iterator(getFirst()); - } - Iterator end() { - return Iterator(nullptr); - } - - /* - * Measures the memory consumption of the list excluding |this|. Note that - * it only measures the list elements themselves. If the list elements - * contain pointers to other memory blocks, those blocks must be measured - * separately during a subsequent iteration over the list. - */ - size_t sizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const - { - size_t n = 0; - for (const T* t = getFirst(); t; t = t->getNext()) { - n += aMallocSizeOf(t); - } - return n; - } - - /* - * Like sizeOfExcludingThis(), but measures |this| as well. - */ - size_t sizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const - { - return aMallocSizeOf(this) + sizeOfExcludingThis(aMallocSizeOf); - } - - /* - * In a debug build, make sure that the list is sane (no cycles, consistent - * mNext/mPrev pointers, only one sentinel). Has no effect in release builds. - */ - void debugAssertIsSane() const - { -#ifdef DEBUG - const LinkedListElement* slow; - const LinkedListElement* fast1; - const LinkedListElement* fast2; - - /* - * Check for cycles in the forward singly-linked list using the - * tortoise/hare algorithm. - */ - for (slow = sentinel.mNext, - fast1 = sentinel.mNext->mNext, - fast2 = sentinel.mNext->mNext->mNext; - slow != &sentinel && fast1 != &sentinel && fast2 != &sentinel; - slow = slow->mNext, fast1 = fast2->mNext, fast2 = fast1->mNext) { - MOZ_ASSERT(slow != fast1); - MOZ_ASSERT(slow != fast2); - } - - /* Check for cycles in the backward singly-linked list. */ - for (slow = sentinel.mPrev, - fast1 = sentinel.mPrev->mPrev, - fast2 = sentinel.mPrev->mPrev->mPrev; - slow != &sentinel && fast1 != &sentinel && fast2 != &sentinel; - slow = slow->mPrev, fast1 = fast2->mPrev, fast2 = fast1->mPrev) { - MOZ_ASSERT(slow != fast1); - MOZ_ASSERT(slow != fast2); - } - - /* - * Check that |sentinel| is the only node in the list with - * mIsSentinel == true. - */ - for (const LinkedListElement* elem = sentinel.mNext; - elem != &sentinel; - elem = elem->mNext) { - MOZ_ASSERT(!elem->mIsSentinel); - } - - /* Check that the mNext/mPrev pointers match up. */ - const LinkedListElement* prev = &sentinel; - const LinkedListElement* cur = sentinel.mNext; - do { - MOZ_ASSERT(cur->mPrev == prev); - MOZ_ASSERT(prev->mNext == cur); - - prev = cur; - cur = cur->mNext; - } while (cur != &sentinel); -#endif /* ifdef DEBUG */ - } - -private: - friend class LinkedListElement; - - void assertContains(const RawType aValue) const - { -#ifdef DEBUG - for (ConstRawType elem = getFirst(); elem; elem = elem->getNext()) { - if (elem == aValue) { - return; - } - } - MOZ_CRASH("element wasn't found in this list!"); -#endif - } - - LinkedList& operator=(const LinkedList& aOther) = delete; - LinkedList(const LinkedList& aOther) = delete; -}; - -template -class AutoCleanLinkedList : public LinkedList -{ -public: - ~AutoCleanLinkedList() - { - while (T* element = this->popFirst()) { - delete element; - } - } -}; - -} /* namespace mozilla */ - -#endif /* __cplusplus */ - -#endif /* mozilla_LinkedList_h */ diff --git a/android/x86/include/spidermonkey/mozilla/LinuxSignal.h b/android/x86/include/spidermonkey/mozilla/LinuxSignal.h deleted file mode 100644 index 83c2bf81..00000000 --- a/android/x86/include/spidermonkey/mozilla/LinuxSignal.h +++ /dev/null @@ -1,45 +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/. */ - -#ifndef mozilla_LinuxSignal_h -#define mozilla_LinuxSignal_h - -namespace mozilla { - -#if defined(__arm__) - -// Some (old) Linux kernels on ARM have a bug where a signal handler -// can be called without clearing the IT bits in CPSR first. The result -// is that the first few instructions of the handler could be skipped, -// ultimately resulting in crashes. To workaround this bug, the handler -// on ARM is a trampoline that starts with enough NOP instructions, so -// that even if the IT bits are not cleared, only the NOP instructions -// will be skipped over. - -template -__attribute__((naked)) void -SignalTrampoline(int aSignal, siginfo_t* aInfo, void* aContext) -{ - asm volatile ( - "nop; nop; nop; nop" - : : : "memory"); - - asm volatile ( - "b %0" - : - : "X"(H) - : "memory"); -} - -# define MOZ_SIGNAL_TRAMPOLINE(h) (mozilla::SignalTrampoline) - -#else // __arm__ - -# define MOZ_SIGNAL_TRAMPOLINE(h) (h) - -#endif // __arm__ - -} // namespace mozilla - -#endif // mozilla_LinuxSignal_h diff --git a/android/x86/include/spidermonkey/mozilla/MacroArgs.h b/android/x86/include/spidermonkey/mozilla/MacroArgs.h deleted file mode 100644 index 52ed1e82..00000000 --- a/android/x86/include/spidermonkey/mozilla/MacroArgs.h +++ /dev/null @@ -1,109 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Implements various macros meant to ease the use of variadic macros. - */ - -#ifndef mozilla_MacroArgs_h -#define mozilla_MacroArgs_h - -// Concatenates pre-processor tokens in a way that can be used with __LINE__. -#define MOZ_CONCAT2(x, y) x ## y -#define MOZ_CONCAT(x, y) MOZ_CONCAT2(x, y) - -/* - * MOZ_PASTE_PREFIX_AND_ARG_COUNT(aPrefix, ...) counts the number of variadic - * arguments and prefixes it with |aPrefix|. For example: - * - * MOZ_PASTE_PREFIX_AND_ARG_COUNT(, foo, 42) expands to 2 - * MOZ_PASTE_PREFIX_AND_ARG_COUNT(A, foo, 42, bar) expands to A3 - * - * You must pass in between 1 and 50 (inclusive) variadic arguments, past - * |aPrefix|. It is not legal to do - * - * MOZ_PASTE_PREFIX_AND_ARG_COUNT(prefix) - * - * (that is, pass in 0 variadic arguments). To ensure that a compile-time - * error occurs when these constraints are violated, use the - * MOZ_STATIC_ASSERT_VALID_ARG_COUNT macro with the same variaidc arguments - * wherever this macro is used. - * - * Passing (__VA_ARGS__, ) rather than simply calling - * MOZ_MACROARGS_ARG_COUNT_HELPER2(__VA_ARGS__, ) very - * carefully tiptoes around a MSVC bug where it improperly expands __VA_ARGS__ - * as a single token in argument lists. For details, see: - * - * http://connect.microsoft.com/VisualStudio/feedback/details/380090/variadic-macro-replacement - * http://cplusplus.co.il/2010/07/17/variadic-macro-to-count-number-of-arguments/#comment-644 - */ -#define MOZ_PASTE_PREFIX_AND_ARG_COUNT(aPrefix, ...) \ - MOZ_MACROARGS_ARG_COUNT_HELPER((__VA_ARGS__, \ - aPrefix##50, aPrefix##49, aPrefix##48, aPrefix##47, aPrefix##46, \ - aPrefix##45, aPrefix##44, aPrefix##43, aPrefix##42, aPrefix##41, \ - aPrefix##40, aPrefix##39, aPrefix##38, aPrefix##37, aPrefix##36, \ - aPrefix##35, aPrefix##34, aPrefix##33, aPrefix##32, aPrefix##31, \ - aPrefix##30, aPrefix##29, aPrefix##28, aPrefix##27, aPrefix##26, \ - aPrefix##25, aPrefix##24, aPrefix##23, aPrefix##22, aPrefix##21, \ - aPrefix##20, aPrefix##19, aPrefix##18, aPrefix##17, aPrefix##16, \ - aPrefix##15, aPrefix##14, aPrefix##13, aPrefix##12, aPrefix##11, \ - aPrefix##10, aPrefix##9, aPrefix##8, aPrefix##7, aPrefix##6, \ - aPrefix##5, aPrefix##4, aPrefix##3, aPrefix##2, aPrefix##1, aPrefix##0)) - -#define MOZ_MACROARGS_ARG_COUNT_HELPER(aArgs) \ - MOZ_MACROARGS_ARG_COUNT_HELPER2 aArgs - -#define MOZ_MACROARGS_ARG_COUNT_HELPER2( \ - a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, \ - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, \ - a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, \ - a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, \ - a41, a42, a43, a44, a45, a46, a47, a48, a49, a50, \ - a51, ...) a51 - -/* - * MOZ_STATIC_ASSERT_VALID_ARG_COUNT ensures that a compile-time error occurs - * when the argument count constraints of MOZ_PASTE_PREFIX_AND_ARG_COUNT are - * violated. Use this macro wherever MOZ_PASTE_PREFIX_AND_ARG_COUNT is used - * and pass it the same variadic arguments. - * - * This macro employs a few dirty tricks to function. To detect the zero - * argument case, |(__VA_ARGS__)| is stringified, sizeof-ed, and compared to - * what it should be in the absence of arguments. - * - * Detecting too many arguments is a little trickier. With a valid argument - * count and a prefix of 1, MOZ_PASTE_PREFIX_AND_ARG_COUNT expands to e.g. 14. - * With a prefix of 0.0, it expands to e.g. 0.04. If there are too many - * arguments, it expands to the first argument over the limit. If this - * exceeding argument is a number, the assertion will fail as there is no - * number than can simultaneously be both > 10 and == 0. If the exceeding - * argument is not a number, a compile-time error should still occur due to - * the operations performed on it. - */ -#define MOZ_MACROARGS_STRINGIFY_HELPER(x) #x -#define MOZ_STATIC_ASSERT_VALID_ARG_COUNT(...) \ - static_assert( \ - sizeof(MOZ_MACROARGS_STRINGIFY_HELPER((__VA_ARGS__))) != sizeof("()") && \ - (MOZ_PASTE_PREFIX_AND_ARG_COUNT(1, __VA_ARGS__)) > 10 && \ - (int)(MOZ_PASTE_PREFIX_AND_ARG_COUNT(0.0, __VA_ARGS__)) == 0, \ - "MOZ_STATIC_ASSERT_VALID_ARG_COUNT requires 1 to 50 arguments") /* ; */ - -/* - * MOZ_ARGS_AFTER_N expands to its arguments excluding the first |N| - * arguments. For example: - * - * MOZ_ARGS_AFTER_2(a, b, c, d) expands to: c, d - */ -#define MOZ_ARGS_AFTER_1(a1, ...) __VA_ARGS__ -#define MOZ_ARGS_AFTER_2(a1, a2, ...) __VA_ARGS__ - -/* - * MOZ_ARG_N expands to its |N|th argument. - */ -#define MOZ_ARG_1(a1, ...) a1 -#define MOZ_ARG_2(a1, a2, ...) a2 - -#endif /* mozilla_MacroArgs_h */ diff --git a/android/x86/include/spidermonkey/mozilla/MacroForEach.h b/android/x86/include/spidermonkey/mozilla/MacroForEach.h deleted file mode 100644 index 7c0e3cfb..00000000 --- a/android/x86/include/spidermonkey/mozilla/MacroForEach.h +++ /dev/null @@ -1,158 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Implements a higher-order macro for iteratively calling another macro with - * fixed leading arguments, plus a trailing element picked from a second list - * of arguments. - */ - -#ifndef mozilla_MacroForEach_h -#define mozilla_MacroForEach_h - -#include "mozilla/MacroArgs.h" - -/* - * MOZ_FOR_EACH(aMacro, aFixedArgs, aArgs) expands to N calls to the macro - * |aMacro| where N is equal the number of items in the list |aArgs|. The - * arguments for each |aMacro| call are composed of *all* arguments in the list - * |aFixedArgs| as well as a single argument in the list |aArgs|. For example: - * - * #define MACRO_A(x) x + - * int a = MOZ_FOR_EACH(MACRO_A, (), (1, 2, 3)) 0; - * // Expands to: MACRO_A(1) MACRO_A(2) MACRO_A(3) 0; - * // And further to: 1 + 2 + 3 + 0; - * - * #define MACRO_B(k, x) (k + x) + - * int b = MOZ_FOR_EACH(MACRO_B, (5,), (1, 2)) 0; - * // Expands to: MACRO_B(5, 1) MACRO_B(5, 2) 0; - * - * #define MACRO_C(k1, k2, x) (k1 + k2 + x) + - * int c = MOZ_FOR_EACH(MACRO_C, (5, 8,), (1, 2)) 0; - * // Expands to: MACRO_B(5, 8, 1) MACRO_B(5, 8, 2) 0; - * - * If the |aFixedArgs| list is not empty, a trailing comma must be included. - * - * The |aArgs| list must be not be empty and may be up to 50 items long. Use - * MOZ_STATIC_ASSERT_VALID_ARG_COUNT to ensure that violating this constraint - * results in a compile-time error. - */ -#define MOZ_FOR_EACH_EXPAND_HELPER(...) __VA_ARGS__ -#define MOZ_FOR_EACH_GLUE(a, b) a b -#define MOZ_FOR_EACH(aMacro, aFixedArgs, aArgs) \ - MOZ_FOR_EACH_GLUE( \ - MOZ_PASTE_PREFIX_AND_ARG_COUNT(MOZ_FOR_EACH_, \ - MOZ_FOR_EACH_EXPAND_HELPER aArgs), \ - (aMacro, aFixedArgs, aArgs)) - -#define MOZ_FOR_EACH_HELPER_GLUE(a, b) a b -#define MOZ_FOR_EACH_HELPER(aMacro, aFixedArgs, aArgs) \ - MOZ_FOR_EACH_HELPER_GLUE( \ - aMacro, \ - (MOZ_FOR_EACH_EXPAND_HELPER aFixedArgs MOZ_ARG_1 aArgs)) - -#define MOZ_FOR_EACH_1(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) -#define MOZ_FOR_EACH_2(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_1(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_3(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_2(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_4(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_3(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_5(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_4(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_6(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_5(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_7(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_6(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_8(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_7(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_9(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_8(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_10(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_9(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_11(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_10(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_12(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_11(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_13(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_12(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_14(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_13(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_15(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_14(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_16(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_15(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_17(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_16(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_18(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_17(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_19(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_18(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_20(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_19(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_21(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_20(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_22(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_21(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_23(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_22(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_24(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_23(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_25(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_24(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_26(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_25(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_27(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_26(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_28(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_27(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_29(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_28(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_30(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_29(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_31(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_30(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_32(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_31(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_33(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_32(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_34(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_33(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_35(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_34(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_36(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_35(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_37(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_36(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_38(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_37(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_39(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_38(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_40(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_39(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_41(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_40(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_42(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_41(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_43(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_42(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_44(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_43(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_45(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_44(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_46(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_45(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_47(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_46(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_48(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_47(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_49(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_48(m, fa, (MOZ_ARGS_AFTER_1 a)) -#define MOZ_FOR_EACH_50(m, fa, a) \ - MOZ_FOR_EACH_HELPER(m, fa, a) MOZ_FOR_EACH_49(m, fa, (MOZ_ARGS_AFTER_1 a)) - -#endif /* mozilla_MacroForEach_h */ diff --git a/android/x86/include/spidermonkey/mozilla/MathAlgorithms.h b/android/x86/include/spidermonkey/mozilla/MathAlgorithms.h deleted file mode 100644 index 4db6de49..00000000 --- a/android/x86/include/spidermonkey/mozilla/MathAlgorithms.h +++ /dev/null @@ -1,547 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* mfbt maths algorithms. */ - -#ifndef mozilla_MathAlgorithms_h -#define mozilla_MathAlgorithms_h - -#include "mozilla/Assertions.h" -#include "mozilla/TypeTraits.h" - -#include -#include -#include - -namespace mozilla { - -// Greatest Common Divisor -template -MOZ_ALWAYS_INLINE IntegerType -EuclidGCD(IntegerType aA, IntegerType aB) -{ - // Euclid's algorithm; O(N) in the worst case. (There are better - // ways, but we don't need them for the current use of this algo.) - MOZ_ASSERT(aA > IntegerType(0)); - MOZ_ASSERT(aB > IntegerType(0)); - - while (aA != aB) { - if (aA > aB) { - aA = aA - aB; - } else { - aB = aB - aA; - } - } - - return aA; -} - -// Least Common Multiple -template -MOZ_ALWAYS_INLINE IntegerType -EuclidLCM(IntegerType aA, IntegerType aB) -{ - // Divide first to reduce overflow risk. - return (aA / EuclidGCD(aA, aB)) * aB; -} - -namespace detail { - -template -struct AllowDeprecatedAbsFixed : FalseType {}; - -template<> struct AllowDeprecatedAbsFixed : TrueType {}; -template<> struct AllowDeprecatedAbsFixed : TrueType {}; - -template -struct AllowDeprecatedAbs : AllowDeprecatedAbsFixed {}; - -template<> struct AllowDeprecatedAbs : TrueType {}; -template<> struct AllowDeprecatedAbs : TrueType {}; - -} // namespace detail - -// DO NOT USE DeprecatedAbs. It exists only until its callers can be converted -// to Abs below, and it will be removed when all callers have been changed. -template -inline typename mozilla::EnableIf::value, T>::Type -DeprecatedAbs(const T aValue) -{ - // The absolute value of the smallest possible value of a signed-integer type - // won't fit in that type (on twos-complement systems -- and we're blithely - // assuming we're on such systems, for the non- types listed above), - // so assert that the input isn't that value. - // - // This is the case if: the value is non-negative; or if adding one (giving a - // value in the range [-maxvalue, 0]), then negating (giving a value in the - // range [0, maxvalue]), doesn't produce maxvalue (because in twos-complement, - // (minvalue + 1) == -maxvalue). - MOZ_ASSERT(aValue >= 0 || - -(aValue + 1) != T((1ULL << (CHAR_BIT * sizeof(T) - 1)) - 1), - "You can't negate the smallest possible negative integer!"); - return aValue >= 0 ? aValue : -aValue; -} - -namespace detail { - -// For now mozilla::Abs only takes intN_T, the signed natural types, and -// float/double/long double. Feel free to add overloads for other standard, -// signed types if you need them. - -template -struct AbsReturnTypeFixed; - -template<> struct AbsReturnTypeFixed { typedef uint8_t Type; }; -template<> struct AbsReturnTypeFixed { typedef uint16_t Type; }; -template<> struct AbsReturnTypeFixed { typedef uint32_t Type; }; -template<> struct AbsReturnTypeFixed { typedef uint64_t Type; }; - -template -struct AbsReturnType : AbsReturnTypeFixed {}; - -template<> struct AbsReturnType : - EnableIf {}; -template<> struct AbsReturnType { typedef unsigned char Type; }; -template<> struct AbsReturnType { typedef unsigned short Type; }; -template<> struct AbsReturnType { typedef unsigned int Type; }; -template<> struct AbsReturnType { typedef unsigned long Type; }; -template<> struct AbsReturnType { typedef unsigned long long Type; }; -template<> struct AbsReturnType { typedef float Type; }; -template<> struct AbsReturnType { typedef double Type; }; -template<> struct AbsReturnType { typedef long double Type; }; - -} // namespace detail - -template -inline typename detail::AbsReturnType::Type -Abs(const T aValue) -{ - typedef typename detail::AbsReturnType::Type ReturnType; - return aValue >= 0 ? ReturnType(aValue) : ~ReturnType(aValue) + 1; -} - -template<> -inline float -Abs(const float aFloat) -{ - return std::fabs(aFloat); -} - -template<> -inline double -Abs(const double aDouble) -{ - return std::fabs(aDouble); -} - -template<> -inline long double -Abs(const long double aLongDouble) -{ - return std::fabs(aLongDouble); -} - -} // namespace mozilla - -#if defined(_MSC_VER) && \ - (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) -# define MOZ_BITSCAN_WINDOWS - -# include -# pragma intrinsic(_BitScanForward, _BitScanReverse) - -# if defined(_M_AMD64) || defined(_M_X64) -# define MOZ_BITSCAN_WINDOWS64 -# pragma intrinsic(_BitScanForward64, _BitScanReverse64) -# endif - -#endif - -namespace mozilla { - -namespace detail { - -#if defined(MOZ_BITSCAN_WINDOWS) - -inline uint_fast8_t -CountLeadingZeroes32(uint32_t aValue) -{ - unsigned long index; - if (!_BitScanReverse(&index, static_cast(aValue))) - return 32; - return uint_fast8_t(31 - index); -} - - -inline uint_fast8_t -CountTrailingZeroes32(uint32_t aValue) -{ - unsigned long index; - if (!_BitScanForward(&index, static_cast(aValue))) - return 32; - return uint_fast8_t(index); -} - -inline uint_fast8_t -CountPopulation32(uint32_t aValue) -{ - uint32_t x = aValue - ((aValue >> 1) & 0x55555555); - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - return (((x + (x >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24; -} -inline uint_fast8_t -CountPopulation64(uint64_t aValue) -{ - return uint_fast8_t(CountPopulation32(aValue & 0xffffffff) + - CountPopulation32(aValue >> 32)); -} - -inline uint_fast8_t -CountLeadingZeroes64(uint64_t aValue) -{ -#if defined(MOZ_BITSCAN_WINDOWS64) - unsigned long index; - if (!_BitScanReverse64(&index, static_cast(aValue))) - return 64; - return uint_fast8_t(63 - index); -#else - uint32_t hi = uint32_t(aValue >> 32); - if (hi != 0) { - return CountLeadingZeroes32(hi); - } - return 32u + CountLeadingZeroes32(uint32_t(aValue)); -#endif -} - -inline uint_fast8_t -CountTrailingZeroes64(uint64_t aValue) -{ -#if defined(MOZ_BITSCAN_WINDOWS64) - unsigned long index; - if (!_BitScanForward64(&index, static_cast(aValue))) - return 64; - return uint_fast8_t(index); -#else - uint32_t lo = uint32_t(aValue); - if (lo != 0) { - return CountTrailingZeroes32(lo); - } - return 32u + CountTrailingZeroes32(uint32_t(aValue >> 32)); -#endif -} - -# ifdef MOZ_HAVE_BITSCAN64 -# undef MOZ_HAVE_BITSCAN64 -# endif - -#elif defined(__clang__) || defined(__GNUC__) - -# if defined(__clang__) -# if !__has_builtin(__builtin_ctz) || !__has_builtin(__builtin_clz) -# error "A clang providing __builtin_c[lt]z is required to build" -# endif -# else - // gcc has had __builtin_clz and friends since 3.4: no need to check. -# endif - -inline uint_fast8_t -CountLeadingZeroes32(uint32_t aValue) -{ - return __builtin_clz(aValue); -} - -inline uint_fast8_t -CountTrailingZeroes32(uint32_t aValue) -{ - return __builtin_ctz(aValue); -} - -inline uint_fast8_t -CountPopulation32(uint32_t aValue) -{ - return __builtin_popcount(aValue); -} - -inline uint_fast8_t -CountPopulation64(uint64_t aValue) -{ - return __builtin_popcountll(aValue); -} - -inline uint_fast8_t -CountLeadingZeroes64(uint64_t aValue) -{ - return __builtin_clzll(aValue); -} - -inline uint_fast8_t -CountTrailingZeroes64(uint64_t aValue) -{ - return __builtin_ctzll(aValue); -} - -#else -# error "Implement these!" -inline uint_fast8_t CountLeadingZeroes32(uint32_t aValue) = delete; -inline uint_fast8_t CountTrailingZeroes32(uint32_t aValue) = delete; -inline uint_fast8_t CountPopulation32(uint32_t aValue) = delete; -inline uint_fast8_t CountPopulation64(uint64_t aValue) = delete; -inline uint_fast8_t CountLeadingZeroes64(uint64_t aValue) = delete; -inline uint_fast8_t CountTrailingZeroes64(uint64_t aValue) = delete; -#endif - -} // namespace detail - -/** - * Compute the number of high-order zero bits in the NON-ZERO number |aValue|. - * That is, looking at the bitwise representation of the number, with the - * highest- valued bits at the start, return the number of zeroes before the - * first one is observed. - * - * CountLeadingZeroes32(0xF0FF1000) is 0; - * CountLeadingZeroes32(0x7F8F0001) is 1; - * CountLeadingZeroes32(0x3FFF0100) is 2; - * CountLeadingZeroes32(0x1FF50010) is 3; and so on. - */ -inline uint_fast8_t -CountLeadingZeroes32(uint32_t aValue) -{ - MOZ_ASSERT(aValue != 0); - return detail::CountLeadingZeroes32(aValue); -} - -/** - * Compute the number of low-order zero bits in the NON-ZERO number |aValue|. - * That is, looking at the bitwise representation of the number, with the - * lowest- valued bits at the start, return the number of zeroes before the - * first one is observed. - * - * CountTrailingZeroes32(0x0100FFFF) is 0; - * CountTrailingZeroes32(0x7000FFFE) is 1; - * CountTrailingZeroes32(0x0080FFFC) is 2; - * CountTrailingZeroes32(0x0080FFF8) is 3; and so on. - */ -inline uint_fast8_t -CountTrailingZeroes32(uint32_t aValue) -{ - MOZ_ASSERT(aValue != 0); - return detail::CountTrailingZeroes32(aValue); -} - -/** - * Compute the number of one bits in the number |aValue|, - */ -inline uint_fast8_t -CountPopulation32(uint32_t aValue) -{ - return detail::CountPopulation32(aValue); -} - -/** Analogous to CountPopulation32, but for 64-bit numbers */ -inline uint_fast8_t -CountPopulation64(uint64_t aValue) -{ - return detail::CountPopulation64(aValue); -} - -/** Analogous to CountLeadingZeroes32, but for 64-bit numbers. */ -inline uint_fast8_t -CountLeadingZeroes64(uint64_t aValue) -{ - MOZ_ASSERT(aValue != 0); - return detail::CountLeadingZeroes64(aValue); -} - -/** Analogous to CountTrailingZeroes32, but for 64-bit numbers. */ -inline uint_fast8_t -CountTrailingZeroes64(uint64_t aValue) -{ - MOZ_ASSERT(aValue != 0); - return detail::CountTrailingZeroes64(aValue); -} - -namespace detail { - -template -class CeilingLog2; - -template -class CeilingLog2 -{ -public: - static uint_fast8_t compute(const T aValue) - { - // Check for <= 1 to avoid the == 0 undefined case. - return aValue <= 1 ? 0u : 32u - CountLeadingZeroes32(aValue - 1); - } -}; - -template -class CeilingLog2 -{ -public: - static uint_fast8_t compute(const T aValue) - { - // Check for <= 1 to avoid the == 0 undefined case. - return aValue <= 1 ? 0u : 64u - CountLeadingZeroes64(aValue - 1); - } -}; - -} // namespace detail - -/** - * Compute the log of the least power of 2 greater than or equal to |aValue|. - * - * CeilingLog2(0..1) is 0; - * CeilingLog2(2) is 1; - * CeilingLog2(3..4) is 2; - * CeilingLog2(5..8) is 3; - * CeilingLog2(9..16) is 4; and so on. - */ -template -inline uint_fast8_t -CeilingLog2(const T aValue) -{ - return detail::CeilingLog2::compute(aValue); -} - -/** A CeilingLog2 variant that accepts only size_t. */ -inline uint_fast8_t -CeilingLog2Size(size_t aValue) -{ - return CeilingLog2(aValue); -} - -namespace detail { - -template -class FloorLog2; - -template -class FloorLog2 -{ -public: - static uint_fast8_t compute(const T aValue) - { - return 31u - CountLeadingZeroes32(aValue | 1); - } -}; - -template -class FloorLog2 -{ -public: - static uint_fast8_t compute(const T aValue) - { - return 63u - CountLeadingZeroes64(aValue | 1); - } -}; - -} // namespace detail - -/** - * Compute the log of the greatest power of 2 less than or equal to |aValue|. - * - * FloorLog2(0..1) is 0; - * FloorLog2(2..3) is 1; - * FloorLog2(4..7) is 2; - * FloorLog2(8..15) is 3; and so on. - */ -template -inline uint_fast8_t -FloorLog2(const T aValue) -{ - return detail::FloorLog2::compute(aValue); -} - -/** A FloorLog2 variant that accepts only size_t. */ -inline uint_fast8_t -FloorLog2Size(size_t aValue) -{ - return FloorLog2(aValue); -} - -/* - * Compute the smallest power of 2 greater than or equal to |x|. |x| must not - * be so great that the computed value would overflow |size_t|. - */ -inline size_t -RoundUpPow2(size_t aValue) -{ - MOZ_ASSERT(aValue <= (size_t(1) << (sizeof(size_t) * CHAR_BIT - 1)), - "can't round up -- will overflow!"); - return size_t(1) << CeilingLog2(aValue); -} - -/** - * Rotates the bits of the given value left by the amount of the shift width. - */ -template -inline T -RotateLeft(const T aValue, uint_fast8_t aShift) -{ - MOZ_ASSERT(aShift < sizeof(T) * CHAR_BIT, "Shift value is too large!"); - MOZ_ASSERT(aShift > 0, - "Rotation by value length is undefined behavior, but compilers " - "do not currently fold a test into the rotate instruction. " - "Please remove this restriction when compilers optimize the " - "zero case (http://blog.regehr.org/archives/1063)."); - static_assert(IsUnsigned::value, "Rotates require unsigned values"); - return (aValue << aShift) | (aValue >> (sizeof(T) * CHAR_BIT - aShift)); -} - -/** - * Rotates the bits of the given value right by the amount of the shift width. - */ -template -inline T -RotateRight(const T aValue, uint_fast8_t aShift) -{ - MOZ_ASSERT(aShift < sizeof(T) * CHAR_BIT, "Shift value is too large!"); - MOZ_ASSERT(aShift > 0, - "Rotation by value length is undefined behavior, but compilers " - "do not currently fold a test into the rotate instruction. " - "Please remove this restriction when compilers optimize the " - "zero case (http://blog.regehr.org/archives/1063)."); - static_assert(IsUnsigned::value, "Rotates require unsigned values"); - return (aValue >> aShift) | (aValue << (sizeof(T) * CHAR_BIT - aShift)); -} - -/** - * Returns true if |x| is a power of two. - * Zero is not an integer power of two. (-Inf is not an integer) - */ -template -constexpr bool -IsPowerOfTwo(T x) -{ - static_assert(IsUnsigned::value, - "IsPowerOfTwo requires unsigned values"); - return x && (x & (x - 1)) == 0; -} - -template -inline T -Clamp(const T aValue, const T aMin, const T aMax) -{ - static_assert(IsIntegral::value, - "Clamp accepts only integral types, so that it doesn't have" - " to distinguish differently-signed zeroes (which users may" - " or may not care to distinguish, likely at a perf cost) or" - " to decide how to clamp NaN or a range with a NaN" - " endpoint."); - MOZ_ASSERT(aMin <= aMax); - - if (aValue <= aMin) - return aMin; - if (aValue >= aMax) - return aMax; - return aValue; -} - -} /* namespace mozilla */ - -#endif /* mozilla_MathAlgorithms_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Maybe.h b/android/x86/include/spidermonkey/mozilla/Maybe.h deleted file mode 100644 index 2a601ac4..00000000 --- a/android/x86/include/spidermonkey/mozilla/Maybe.h +++ /dev/null @@ -1,551 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A class for optional values and in-place lazy construction. */ - -#ifndef mozilla_Maybe_h -#define mozilla_Maybe_h - -#include "mozilla/Alignment.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -#include // for placement new -#include - -namespace mozilla { - -struct Nothing { }; - -/* - * Maybe is a container class which contains either zero or one elements. It - * serves two roles. It can represent values which are *semantically* optional, - * augmenting a type with an explicit 'Nothing' value. In this role, it provides - * methods that make it easy to work with values that may be missing, along with - * equality and comparison operators so that Maybe values can be stored in - * containers. Maybe values can be constructed conveniently in expressions using - * type inference, as follows: - * - * void doSomething(Maybe aFoo) { - * if (aFoo) // Make sure that aFoo contains a value... - * aFoo->takeAction(); // and then use |aFoo->| to access it. - * } // |*aFoo| also works! - * - * doSomething(Nothing()); // Passes a Maybe containing no value. - * doSomething(Some(Foo(100))); // Passes a Maybe containing |Foo(100)|. - * - * You'll note that it's important to check whether a Maybe contains a value - * before using it, using conversion to bool, |isSome()|, or |isNothing()|. You - * can avoid these checks, and sometimes write more readable code, using - * |valueOr()|, |ptrOr()|, and |refOr()|, which allow you to retrieve the value - * in the Maybe and provide a default for the 'Nothing' case. You can also use - * |apply()| to call a function only if the Maybe holds a value, and |map()| to - * transform the value in the Maybe, returning another Maybe with a possibly - * different type. - * - * Maybe's other role is to support lazily constructing objects without using - * dynamic storage. A Maybe directly contains storage for a value, but it's - * empty by default. |emplace()|, as mentioned above, can be used to construct a - * value in Maybe's storage. The value a Maybe contains can be destroyed by - * calling |reset()|; this will happen automatically if a Maybe is destroyed - * while holding a value. - * - * It's a common idiom in C++ to use a pointer as a 'Maybe' type, with a null - * value meaning 'Nothing' and any other value meaning 'Some'. You can convert - * from such a pointer to a Maybe value using 'ToMaybe()'. - * - * Maybe is inspired by similar types in the standard library of many other - * languages (e.g. Haskell's Maybe and Rust's Option). In the C++ world it's - * very similar to std::optional, which was proposed for C++14 and originated in - * Boost. The most important differences between Maybe and std::optional are: - * - * - std::optional may be compared with T. We deliberately forbid that. - * - std::optional allows in-place construction without a separate call to - * |emplace()| by using a dummy |in_place_t| value to tag the appropriate - * constructor. - * - std::optional has |valueOr()|, equivalent to Maybe's |valueOr()|, but - * lacks corresponding methods for |refOr()| and |ptrOr()|. - * - std::optional lacks |map()| and |apply()|, making it less suitable for - * functional-style code. - * - std::optional lacks many convenience functions that Maybe has. Most - * unfortunately, it lacks equivalents of the type-inferred constructor - * functions |Some()| and |Nothing()|. - * - * N.B. GCC has missed optimizations with Maybe in the past and may generate - * extra branches/loads/stores. Use with caution on hot paths; it's not known - * whether or not this is still a problem. - */ -template -class Maybe -{ - bool mIsSome; - AlignedStorage2 mStorage; - -public: - typedef T ValueType; - - Maybe() : mIsSome(false) { } - ~Maybe() { reset(); } - - MOZ_IMPLICIT Maybe(Nothing) : mIsSome(false) { } - - Maybe(const Maybe& aOther) - : mIsSome(false) - { - if (aOther.mIsSome) { - emplace(*aOther); - } - } - - /** - * Maybe can be copy-constructed from a Maybe if U* and T* are - * compatible, or from Maybe. - */ - template::value && - (std::is_same::value || - (std::is_pointer::value && - std::is_base_of::type, - typename std::remove_pointer::type>::value))>::type> - MOZ_IMPLICIT - Maybe(const Maybe& aOther) - : mIsSome(false) - { - if (aOther.isSome()) { - emplace(*aOther); - } - } - - Maybe(Maybe&& aOther) - : mIsSome(false) - { - if (aOther.mIsSome) { - emplace(Move(*aOther)); - aOther.reset(); - } - } - - /** - * Maybe can be move-constructed from a Maybe if U* and T* are - * compatible, or from Maybe. - */ - template::value && - (std::is_same::value || - (std::is_pointer::value && - std::is_base_of::type, - typename std::remove_pointer::type>::value))>::type> - MOZ_IMPLICIT - Maybe(Maybe&& aOther) - : mIsSome(false) - { - if (aOther.isSome()) { - emplace(Move(*aOther)); - aOther.reset(); - } - } - - Maybe& operator=(const Maybe& aOther) - { - if (&aOther != this) { - if (aOther.mIsSome) { - if (mIsSome) { - // XXX(seth): The correct code for this branch, below, can't be used - // due to a bug in Visual Studio 2010. See bug 1052940. - /* - ref() = aOther.ref(); - */ - reset(); - emplace(*aOther); - } else { - emplace(*aOther); - } - } else { - reset(); - } - } - return *this; - } - - Maybe& operator=(Maybe&& aOther) - { - MOZ_ASSERT(this != &aOther, "Self-moves are prohibited"); - - if (aOther.mIsSome) { - if (mIsSome) { - ref() = Move(aOther.ref()); - } else { - emplace(Move(*aOther)); - } - aOther.reset(); - } else { - reset(); - } - - return *this; - } - - /* Methods that check whether this Maybe contains a value */ - explicit operator bool() const { return isSome(); } - bool isSome() const { return mIsSome; } - bool isNothing() const { return !mIsSome; } - - /* Returns the contents of this Maybe by value. Unsafe unless |isSome()|. */ - T value() const - { - MOZ_ASSERT(mIsSome); - return ref(); - } - - /* - * Returns the contents of this Maybe by value. If |isNothing()|, returns - * the default value provided. - */ - template - T valueOr(V&& aDefault) const - { - if (isSome()) { - return ref(); - } - return Forward(aDefault); - } - - /* - * Returns the contents of this Maybe by value. If |isNothing()|, returns - * the value returned from the function or functor provided. - */ - template - T valueOrFrom(F&& aFunc) const - { - if (isSome()) { - return ref(); - } - return aFunc(); - } - - /* Returns the contents of this Maybe by pointer. Unsafe unless |isSome()|. */ - T* ptr() - { - MOZ_ASSERT(mIsSome); - return &ref(); - } - - const T* ptr() const - { - MOZ_ASSERT(mIsSome); - return &ref(); - } - - /* - * Returns the contents of this Maybe by pointer. If |isNothing()|, - * returns the default value provided. - */ - T* ptrOr(T* aDefault) - { - if (isSome()) { - return ptr(); - } - return aDefault; - } - - const T* ptrOr(const T* aDefault) const - { - if (isSome()) { - return ptr(); - } - return aDefault; - } - - /* - * Returns the contents of this Maybe by pointer. If |isNothing()|, - * returns the value returned from the function or functor provided. - */ - template - T* ptrOrFrom(F&& aFunc) - { - if (isSome()) { - return ptr(); - } - return aFunc(); - } - - template - const T* ptrOrFrom(F&& aFunc) const - { - if (isSome()) { - return ptr(); - } - return aFunc(); - } - - T* operator->() - { - MOZ_ASSERT(mIsSome); - return ptr(); - } - - const T* operator->() const - { - MOZ_ASSERT(mIsSome); - return ptr(); - } - - /* Returns the contents of this Maybe by ref. Unsafe unless |isSome()|. */ - T& ref() - { - MOZ_ASSERT(mIsSome); - return *mStorage.addr(); - } - - const T& ref() const - { - MOZ_ASSERT(mIsSome); - return *mStorage.addr(); - } - - /* - * Returns the contents of this Maybe by ref. If |isNothing()|, returns - * the default value provided. - */ - T& refOr(T& aDefault) - { - if (isSome()) { - return ref(); - } - return aDefault; - } - - const T& refOr(const T& aDefault) const - { - if (isSome()) { - return ref(); - } - return aDefault; - } - - /* - * Returns the contents of this Maybe by ref. If |isNothing()|, returns the - * value returned from the function or functor provided. - */ - template - T& refOrFrom(F&& aFunc) - { - if (isSome()) { - return ref(); - } - return aFunc(); - } - - template - const T& refOrFrom(F&& aFunc) const - { - if (isSome()) { - return ref(); - } - return aFunc(); - } - - T& operator*() - { - MOZ_ASSERT(mIsSome); - return ref(); - } - - const T& operator*() const - { - MOZ_ASSERT(mIsSome); - return ref(); - } - - /* If |isSome()|, runs the provided function or functor on the contents of - * this Maybe. */ - template - Maybe& apply(Func aFunc) - { - if (isSome()) { - aFunc(ref()); - } - return *this; - } - - template - const Maybe& apply(Func aFunc) const - { - if (isSome()) { - aFunc(ref()); - } - return *this; - } - - /* - * If |isSome()|, runs the provided function and returns the result wrapped - * in a Maybe. If |isNothing()|, returns an empty Maybe value. - */ - template - auto map(Func aFunc) -> Maybe>().ref()))> - { - using ReturnType = decltype(aFunc(ref())); - if (isSome()) { - Maybe val; - val.emplace(aFunc(ref())); - return val; - } - return Maybe(); - } - - template - auto map(Func aFunc) const -> Maybe>().ref()))> - { - using ReturnType = decltype(aFunc(ref())); - if (isSome()) { - Maybe val; - val.emplace(aFunc(ref())); - return val; - } - return Maybe(); - } - - /* If |isSome()|, empties this Maybe and destroys its contents. */ - void reset() - { - if (isSome()) { - ref().T::~T(); - mIsSome = false; - } - } - - /* - * Constructs a T value in-place in this empty Maybe's storage. The - * arguments to |emplace()| are the parameters to T's constructor. - */ - template - void emplace(Args&&... aArgs) - { - MOZ_ASSERT(!mIsSome); - ::new (mStorage.addr()) T(Forward(aArgs)...); - mIsSome = true; - } -}; - -/* - * Some() creates a Maybe value containing the provided T value. If T has a - * move constructor, it's used to make this as efficient as possible. - * - * Some() selects the type of Maybe it returns by removing any const, volatile, - * or reference qualifiers from the type of the value you pass to it. This gives - * it more intuitive behavior when used in expressions, but it also means that - * if you need to construct a Maybe value that holds a const, volatile, or - * reference value, you need to use emplace() instead. - */ -template -Maybe::Type>::Type> -Some(T&& aValue) -{ - typedef typename RemoveCV::Type>::Type U; - Maybe value; - value.emplace(Forward(aValue)); - return value; -} - -template -Maybe::Type>::Type> -ToMaybe(T* aPtr) -{ - if (aPtr) { - return Some(*aPtr); - } - return Nothing(); -} - -/* - * Two Maybe values are equal if - * - both are Nothing, or - * - both are Some, and the values they contain are equal. - */ -template bool -operator==(const Maybe& aLHS, const Maybe& aRHS) -{ - if (aLHS.isNothing() != aRHS.isNothing()) { - return false; - } - return aLHS.isNothing() || *aLHS == *aRHS; -} - -template bool -operator!=(const Maybe& aLHS, const Maybe& aRHS) -{ - return !(aLHS == aRHS); -} - -/* - * We support comparison to Nothing to allow reasonable expressions like: - * if (maybeValue == Nothing()) { ... } - */ -template bool -operator==(const Maybe& aLHS, const Nothing& aRHS) -{ - return aLHS.isNothing(); -} - -template bool -operator!=(const Maybe& aLHS, const Nothing& aRHS) -{ - return !(aLHS == aRHS); -} - -template bool -operator==(const Nothing& aLHS, const Maybe& aRHS) -{ - return aRHS.isNothing(); -} - -template bool -operator!=(const Nothing& aLHS, const Maybe& aRHS) -{ - return !(aLHS == aRHS); -} - -/* - * Maybe values are ordered in the same way T values are ordered, except that - * Nothing comes before anything else. - */ -template bool -operator<(const Maybe& aLHS, const Maybe& aRHS) -{ - if (aLHS.isNothing()) { - return aRHS.isSome(); - } - if (aRHS.isNothing()) { - return false; - } - return *aLHS < *aRHS; -} - -template bool -operator>(const Maybe& aLHS, const Maybe& aRHS) -{ - return !(aLHS < aRHS || aLHS == aRHS); -} - -template bool -operator<=(const Maybe& aLHS, const Maybe& aRHS) -{ - return aLHS < aRHS || aLHS == aRHS; -} - -template bool -operator>=(const Maybe& aLHS, const Maybe& aRHS) -{ - return !(aLHS < aRHS); -} - -} // namespace mozilla - -#endif /* mozilla_Maybe_h */ diff --git a/android/x86/include/spidermonkey/mozilla/MaybeOneOf.h b/android/x86/include/spidermonkey/mozilla/MaybeOneOf.h deleted file mode 100644 index 9c38ff8b..00000000 --- a/android/x86/include/spidermonkey/mozilla/MaybeOneOf.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_MaybeOneOf_h -#define mozilla_MaybeOneOf_h - -#include "mozilla/Alignment.h" -#include "mozilla/Assertions.h" -#include "mozilla/Move.h" -#include "mozilla/TemplateLib.h" - -#include // For placement new - -namespace mozilla { - -/* - * MaybeOneOf is like Maybe, but it supports constructing either T1 - * or T2. When a MaybeOneOf is constructed, it is |empty()|, i.e., - * no value has been constructed and no destructor will be called when the - * MaybeOneOf is destroyed. Upon calling |construct()| or - * |construct()|, a T1 or T2 object will be constructed with the given - * arguments and that object will be destroyed when the owning MaybeOneOf is - * destroyed. - */ -template -class MaybeOneOf -{ - AlignedStorage::value> storage; - - enum State { None, SomeT1, SomeT2 } state; - template struct Type2State {}; - - template - T& as() - { - MOZ_ASSERT(state == Type2State::result); - return *(T*)storage.addr(); - } - - template - const T& as() const - { - MOZ_ASSERT(state == Type2State::result); - return *(T*)storage.addr(); - } - -public: - MaybeOneOf() : state(None) {} - ~MaybeOneOf() { destroyIfConstructed(); } - - MaybeOneOf(MaybeOneOf&& rhs) - : state(None) - { - if (!rhs.empty()) { - if (rhs.constructed()) { - construct(Move(rhs.as())); - rhs.as().~T1(); - } else { - construct(Move(rhs.as())); - rhs.as().~T2(); - } - rhs.state = None; - } - } - - MaybeOneOf &operator=(MaybeOneOf&& rhs) - { - MOZ_ASSERT(this != &rhs, "Self-move is prohibited"); - this->~MaybeOneOf(); - new(this) MaybeOneOf(Move(rhs)); - return *this; - } - - bool empty() const { return state == None; } - - template - bool constructed() const { return state == Type2State::result; } - - template - void construct(Args&&... aArgs) - { - MOZ_ASSERT(state == None); - state = Type2State::result; - ::new (storage.addr()) T(Forward(aArgs)...); - } - - template - T& ref() - { - return as(); - } - - template - const T& ref() const - { - return as(); - } - - void destroy() - { - MOZ_ASSERT(state == SomeT1 || state == SomeT2); - if (state == SomeT1) { - as().~T1(); - } else if (state == SomeT2) { - as().~T2(); - } - state = None; - } - - void destroyIfConstructed() - { - if (!empty()) { - destroy(); - } - } - -private: - MaybeOneOf(const MaybeOneOf& aOther) = delete; - const MaybeOneOf& operator=(const MaybeOneOf& aOther) = delete; -}; - -template -template -struct MaybeOneOf::Type2State -{ - typedef MaybeOneOf Enclosing; - static const typename Enclosing::State result = Enclosing::SomeT1; -}; - -template -template -struct MaybeOneOf::Type2State -{ - typedef MaybeOneOf Enclosing; - static const typename Enclosing::State result = Enclosing::SomeT2; -}; - -} // namespace mozilla - -#endif /* mozilla_MaybeOneOf_h */ diff --git a/android/x86/include/spidermonkey/mozilla/MemoryChecking.h b/android/x86/include/spidermonkey/mozilla/MemoryChecking.h deleted file mode 100644 index ff42d7f1..00000000 --- a/android/x86/include/spidermonkey/mozilla/MemoryChecking.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Provides a common interface to the ASan (AddressSanitizer) and Valgrind - * functions used to mark memory in certain ways. In detail, the following - * three macros are provided: - * - * MOZ_MAKE_MEM_NOACCESS - Mark memory as unsafe to access (e.g. freed) - * MOZ_MAKE_MEM_UNDEFINED - Mark memory as accessible, with content undefined - * MOZ_MAKE_MEM_DEFINED - Mark memory as accessible, with content defined - * - * With Valgrind in use, these directly map to the three respective Valgrind - * macros. With ASan in use, the NOACCESS macro maps to poisoning the memory, - * while the UNDEFINED/DEFINED macros unpoison memory. - * - * With no memory checker available, all macros expand to the empty statement. - */ - -#ifndef mozilla_MemoryChecking_h -#define mozilla_MemoryChecking_h - -#if defined(MOZ_VALGRIND) -#include "valgrind/memcheck.h" -#endif - -#if defined(MOZ_ASAN) || defined(MOZ_VALGRIND) -#define MOZ_HAVE_MEM_CHECKS 1 -#endif - -#if defined(MOZ_ASAN) -#include - -#include "mozilla/Attributes.h" -#include "mozilla/Types.h" - -#ifdef _MSC_VER -// In clang-cl based ASAN, we link against the memory poisoning functions -// statically. -#define MOZ_ASAN_VISIBILITY -#else -#define MOZ_ASAN_VISIBILITY MOZ_EXPORT -#endif - -extern "C" { -/* These definitions are usually provided through the - * sanitizer/asan_interface.h header installed by ASan. - */ -void MOZ_ASAN_VISIBILITY -__asan_poison_memory_region(void const volatile *addr, size_t size); -void MOZ_ASAN_VISIBILITY -__asan_unpoison_memory_region(void const volatile *addr, size_t size); - -#define MOZ_MAKE_MEM_NOACCESS(addr, size) \ - __asan_poison_memory_region((addr), (size)) - -#define MOZ_MAKE_MEM_UNDEFINED(addr, size) \ - __asan_unpoison_memory_region((addr), (size)) - -#define MOZ_MAKE_MEM_DEFINED(addr, size) \ - __asan_unpoison_memory_region((addr), (size)) - -/* - * These definitions are usually provided through the - * sanitizer/lsan_interface.h header installed by LSan. - */ -void MOZ_EXPORT -__lsan_ignore_object(const void *p); - -} -#elif defined(MOZ_MSAN) -#include - -#include "mozilla/Types.h" - -extern "C" { -/* These definitions are usually provided through the - * sanitizer/msan_interface.h header installed by MSan. - */ -void MOZ_EXPORT -__msan_poison(void const volatile *addr, size_t size); -void MOZ_EXPORT -__msan_unpoison(void const volatile *addr, size_t size); - -#define MOZ_MAKE_MEM_NOACCESS(addr, size) \ - __msan_poison((addr), (size)) - -#define MOZ_MAKE_MEM_UNDEFINED(addr, size) \ - __msan_poison((addr), (size)) - -#define MOZ_MAKE_MEM_DEFINED(addr, size) \ - __msan_unpoison((addr), (size)) -} -#elif defined(MOZ_VALGRIND) -#define MOZ_MAKE_MEM_NOACCESS(addr, size) \ - VALGRIND_MAKE_MEM_NOACCESS((addr), (size)) - -#define MOZ_MAKE_MEM_UNDEFINED(addr, size) \ - VALGRIND_MAKE_MEM_UNDEFINED((addr), (size)) - -#define MOZ_MAKE_MEM_DEFINED(addr, size) \ - VALGRIND_MAKE_MEM_DEFINED((addr), (size)) -#else - -#define MOZ_MAKE_MEM_NOACCESS(addr, size) do {} while (0) -#define MOZ_MAKE_MEM_UNDEFINED(addr, size) do {} while (0) -#define MOZ_MAKE_MEM_DEFINED(addr, size) do {} while (0) - -#endif - -/* - * MOZ_LSAN_INTENTIONAL_LEAK(X) is a macro to tell LeakSanitizer that X - * points to a value that will intentionally never be deallocated during - * the execution of the process. - * - * Additional uses of this macro should be reviewed by people - * conversant in leak-checking and/or MFBT peers. - */ -#if defined(MOZ_ASAN) -# define MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(X) __lsan_ignore_object(X) -#else -# define MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(X) /* nothing */ -#endif // defined(MOZ_ASAN) - - -#endif /* mozilla_MemoryChecking_h */ diff --git a/android/x86/include/spidermonkey/mozilla/MemoryReporting.h b/android/x86/include/spidermonkey/mozilla/MemoryReporting.h deleted file mode 100644 index d2340ecf..00000000 --- a/android/x86/include/spidermonkey/mozilla/MemoryReporting.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Memory reporting infrastructure. */ - -#ifndef mozilla_MemoryReporting_h -#define mozilla_MemoryReporting_h - -#include - -#ifdef __cplusplus - -namespace mozilla { - -/* - * This is for functions that are like malloc_usable_size. Such functions are - * used for measuring the size of data structures. - */ -typedef size_t (*MallocSizeOf)(const void* p); - -} /* namespace mozilla */ - -#endif /* __cplusplus */ - -typedef size_t (*MozMallocSizeOf)(const void* p); - -#endif /* mozilla_MemoryReporting_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Move.h b/android/x86/include/spidermonkey/mozilla/Move.h deleted file mode 100644 index f6d0bfc1..00000000 --- a/android/x86/include/spidermonkey/mozilla/Move.h +++ /dev/null @@ -1,238 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* C++11-style, but C++98-usable, "move references" implementation. */ - -#ifndef mozilla_Move_h -#define mozilla_Move_h - -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -/* - * "Move" References - * - * Some types can be copied much more efficiently if we know the original's - * value need not be preserved --- that is, if we are doing a "move", not a - * "copy". For example, if we have: - * - * Vector u; - * Vector v(u); - * - * the constructor for v must apply a copy constructor to each element of u --- - * taking time linear in the length of u. However, if we know we will not need u - * any more once v has been initialized, then we could initialize v very - * efficiently simply by stealing u's dynamically allocated buffer and giving it - * to v --- a constant-time operation, regardless of the size of u. - * - * Moves often appear in container implementations. For example, when we append - * to a vector, we may need to resize its buffer. This entails moving each of - * its extant elements from the old, smaller buffer to the new, larger buffer. - * But once the elements have been migrated, we're just going to throw away the - * old buffer; we don't care if they still have their values. So if the vector's - * element type can implement "move" more efficiently than "copy", the vector - * resizing should by all means use a "move" operation. Hash tables should also - * use moves when resizing their internal array as entries are added and - * removed. - * - * The details of the optimization, and whether it's worth applying, vary - * from one type to the next: copying an 'int' is as cheap as moving it, so - * there's no benefit in distinguishing 'int' moves from copies. And while - * some constructor calls for complex types are moves, many really have to - * be copies, and can't be optimized this way. So we need: - * - * 1) a way for a type (like Vector) to announce that it can be moved more - * efficiently than it can be copied, and provide an implementation of that - * move operation; and - * - * 2) a way for a particular invocation of a copy constructor to say that it's - * really a move, not a copy, and that the value of the original isn't - * important afterwards (although it must still be safe to destroy). - * - * If a constructor has a single argument of type 'T&&' (an 'rvalue reference - * to T'), that indicates that it is a 'move constructor'. That's 1). It should - * move, not copy, its argument into the object being constructed. It may leave - * the original in any safely-destructible state. - * - * If a constructor's argument is an rvalue, as in 'C(f(x))' or 'C(x + y)', as - * opposed to an lvalue, as in 'C(x)', then overload resolution will prefer the - * move constructor, if there is one. The 'mozilla::Move' function, defined in - * this file, is an identity function you can use in a constructor invocation to - * make any argument into an rvalue, like this: C(Move(x)). That's 2). (You - * could use any function that works, but 'Move' indicates your intention - * clearly.) - * - * Where we might define a copy constructor for a class C like this: - * - * C(const C& rhs) { ... copy rhs to this ... } - * - * we would declare a move constructor like this: - * - * C(C&& rhs) { .. move rhs to this ... } - * - * And where we might perform a copy like this: - * - * C c2(c1); - * - * we would perform a move like this: - * - * C c2(Move(c1)); - * - * Note that 'T&&' implicitly converts to 'T&'. So you can pass a 'T&&' to an - * ordinary copy constructor for a type that doesn't support a special move - * constructor, and you'll just get a copy. This means that templates can use - * Move whenever they know they won't use the original value any more, even if - * they're not sure whether the type at hand has a specialized move constructor. - * If it doesn't, the 'T&&' will just convert to a 'T&', and the ordinary copy - * constructor will apply. - * - * A class with a move constructor can also provide a move assignment operator. - * A generic definition would run this's destructor, and then apply the move - * constructor to *this's memory. A typical definition: - * - * C& operator=(C&& rhs) { - * MOZ_ASSERT(&rhs != this, "self-moves are prohibited"); - * this->~C(); - * new(this) C(Move(rhs)); - * return *this; - * } - * - * With that in place, one can write move assignments like this: - * - * c2 = Move(c1); - * - * This destroys c2, moves c1's value to c2, and leaves c1 in an undefined but - * destructible state. - * - * As we say, a move must leave the original in a "destructible" state. The - * original's destructor will still be called, so if a move doesn't - * actually steal all its resources, that's fine. We require only that the - * move destination must take on the original's value; and that destructing - * the original must not break the move destination. - * - * (Opinions differ on whether move assignment operators should deal with move - * assignment of an object onto itself. It seems wise to either handle that - * case, or assert that it does not occur.) - * - * Forwarding: - * - * Sometimes we want copy construction or assignment if we're passed an ordinary - * value, but move construction if passed an rvalue reference. For example, if - * our constructor takes two arguments and either could usefully be a move, it - * seems silly to write out all four combinations: - * - * C::C(X& x, Y& y) : x(x), y(y) { } - * C::C(X& x, Y&& y) : x(x), y(Move(y)) { } - * C::C(X&& x, Y& y) : x(Move(x)), y(y) { } - * C::C(X&& x, Y&& y) : x(Move(x)), y(Move(y)) { } - * - * To avoid this, C++11 has tweaks to make it possible to write what you mean. - * The four constructor overloads above can be written as one constructor - * template like so[0]: - * - * template - * C::C(XArg&& x, YArg&& y) : x(Forward(x)), y(Forward(y)) { } - * - * ("'Don't Repeat Yourself'? What's that?") - * - * This takes advantage of two new rules in C++11: - * - * - First, when a function template takes an argument that is an rvalue - * reference to a template argument (like 'XArg&& x' and 'YArg&& y' above), - * then when the argument is applied to an lvalue, the template argument - * resolves to 'T&'; and when it is applied to an rvalue, the template - * argument resolves to 'T'. Thus, in a call to C::C like: - * - * X foo(int); - * Y yy; - * - * C(foo(5), yy) - * - * XArg would resolve to 'X', and YArg would resolve to 'Y&'. - * - * - Second, Whereas C++ used to forbid references to references, C++11 defines - * 'collapsing rules': 'T& &', 'T&& &', and 'T& &&' (that is, any combination - * involving an lvalue reference) now collapse to simply 'T&'; and 'T&& &&' - * collapses to 'T&&'. - * - * Thus, in the call above, 'XArg&&' is 'X&&'; and 'YArg&&' is 'Y& &&', which - * collapses to 'Y&'. Because the arguments are declared as rvalue references - * to template arguments, the lvalue-ness "shines through" where present. - * - * Then, the 'Forward' function --- you must invoke 'Forward' with its type - * argument --- returns an lvalue reference or an rvalue reference to its - * argument, depending on what T is. In our unified constructor definition, that - * means that we'll invoke either the copy or move constructors for x and y, - * depending on what we gave C's constructor. In our call, we'll move 'foo()' - * into 'x', but copy 'yy' into 'y'. - * - * This header file defines Move and Forward in the mozilla namespace. It's up - * to individual containers to annotate moves as such, by calling Move; and it's - * up to individual types to define move constructors and assignment operators - * when valuable. - * - * (C++11 says that the header file should define 'std::move' and - * 'std::forward', which are just like our 'Move' and 'Forward'; but those - * definitions aren't available in that header on all our platforms, so we - * define them ourselves here.) - * - * 0. This pattern is known as "perfect forwarding". Interestingly, it is not - * actually perfect, and it can't forward all possible argument expressions! - * There is a C++11 issue: you can't form a reference to a bit-field. As a - * workaround, assign the bit-field to a local variable and use that: - * - * // C is as above - * struct S { int x : 1; } s; - * C(s.x, 0); // BAD: s.x is a reference to a bit-field, can't form those - * int tmp = s.x; - * C(tmp, 0); // OK: tmp not a bit-field - */ - -/** - * Identical to std::Move(); this is necessary until our stlport supports - * std::move(). - */ -template -inline typename RemoveReference::Type&& -Move(T&& aX) -{ - return static_cast::Type&&>(aX); -} - -/** - * These two overloads are identical to std::forward(); they are necessary until - * our stlport supports std::forward(). - */ -template -inline T&& -Forward(typename RemoveReference::Type& aX) -{ - return static_cast(aX); -} - -template -inline T&& -Forward(typename RemoveReference::Type&& aX) -{ - static_assert(!IsLvalueReference::value, - "misuse of Forward detected! try the other overload"); - return static_cast(aX); -} - -/** Swap |aX| and |aY| using move-construction if possible. */ -template -inline void -Swap(T& aX, T& aY) -{ - T tmp(Move(aX)); - aX = Move(aY); - aY = Move(tmp); -} - -} // namespace mozilla - -#endif /* mozilla_Move_h */ diff --git a/android/x86/include/spidermonkey/mozilla/NotNull.h b/android/x86/include/spidermonkey/mozilla/NotNull.h deleted file mode 100644 index 0c3c333e..00000000 --- a/android/x86/include/spidermonkey/mozilla/NotNull.h +++ /dev/null @@ -1,209 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_NotNull_h -#define mozilla_NotNull_h - -// It's often unclear if a particular pointer, be it raw (T*) or smart -// (RefPtr, nsCOMPtr, etc.) can be null. This leads to missing null -// checks (which can cause crashes) and unnecessary null checks (which clutter -// the code). -// -// C++ has a built-in alternative that avoids these problems: references. This -// module defines another alternative, NotNull, which can be used in cases -// where references are not suitable. -// -// In the comments below we use the word "handle" to cover all varieties of -// pointers and references. -// -// References -// ---------- -// References are always non-null. (You can do |T& r = *p;| where |p| is null, -// but that's undefined behaviour. C++ doesn't provide any built-in, ironclad -// guarantee of non-nullness.) -// -// A reference works well when you need a temporary handle to an existing -// single object, e.g. for passing a handle to a function, or as a local handle -// within another object. (In Rust parlance, this is a "borrow".) -// -// A reference is less appropriate in the following cases. -// -// - As a primary handle to an object. E.g. code such as this is possible but -// strange: |T& t = *new T(); ...; delete &t;| -// -// - As a handle to an array. It's common for |T*| to refer to either a single -// |T| or an array of |T|, but |T&| cannot refer to an array of |T| because -// you can't index off a reference (at least, not without first converting it -// to a pointer). -// -// - When the handle identity is meaningful, e.g. if you have a hashtable of -// handles, because you have to use |&| on the reference to convert it to a -// pointer. -// -// - Some people don't like using non-const references as function parameters, -// because it is not clear at the call site that the argument might be -// modified. -// -// - When you need "smart" behaviour. E.g. we lack reference equivalents to -// RefPtr and nsCOMPtr. -// -// - When interfacing with code that uses pointers a lot, sometimes using a -// reference just feels like an odd fit. -// -// Furthermore, a reference is impossible in the following cases. -// -// - When the handle is rebound to another object. References don't allow this. -// -// - When the handle has type |void|. |void&| is not allowed. -// -// NotNull is an alternative that can be used in any of the above cases except -// for the last one, where the handle type is |void|. See below. - -#include "mozilla/Assertions.h" - -namespace mozilla { - -// NotNull can be used to wrap a "base" pointer (raw or smart) to indicate it -// is not null. Some examples: -// -// - NotNull -// - NotNull> -// - NotNull> -// -// NotNull has the following notable properties. -// -// - It has zero space overhead. -// -// - It must be initialized explicitly. There is no default initialization. -// -// - It auto-converts to the base pointer type. -// -// - It does not auto-convert from a base pointer. Implicit conversion from a -// less-constrained type (e.g. T*) to a more-constrained type (e.g. -// NotNull) is dangerous. Creation and assignment from a base pointer can -// only be done with WrapNotNull(), which makes them impossible to overlook, -// both when writing and reading code. -// -// - When initialized (or assigned) it is checked, and if it is null we abort. -// This guarantees that it cannot be null. -// -// - |operator bool()| is deleted. This means you cannot check a NotNull in a -// boolean context, which eliminates the possibility of unnecessary null -// checks. -// -// NotNull currently doesn't work with UniquePtr. See -// https://github.com/Microsoft/GSL/issues/89 for some discussion. -// -template -class NotNull -{ - template friend NotNull WrapNotNull(U aBasePtr); - - T mBasePtr; - - // This constructor is only used by WrapNotNull(). - template - explicit NotNull(U aBasePtr) : mBasePtr(aBasePtr) {} - -public: - // Disallow default construction. - NotNull() = delete; - - // Construct/assign from another NotNull with a compatible base pointer type. - template - MOZ_IMPLICIT NotNull(const NotNull& aOther) : mBasePtr(aOther.get()) {} - - // Default copy/move construction and assignment. - NotNull(const NotNull&) = default; - NotNull& operator=(const NotNull&) = default; - NotNull(NotNull&&) = default; - NotNull& operator=(NotNull&&) = default; - - // Disallow null checks, which are unnecessary for this type. - explicit operator bool() const = delete; - - // Explicit conversion to a base pointer. Use only to resolve ambiguity or to - // get a castable pointer. - const T& get() const { return mBasePtr; } - - // Implicit conversion to a base pointer. Preferable to get(). - operator const T&() const { return get(); } - - // Dereference operators. - const T& operator->() const { return get(); } - decltype(*mBasePtr) operator*() const { return *mBasePtr; } -}; - -template -NotNull -WrapNotNull(const T aBasePtr) -{ - NotNull notNull(aBasePtr); - MOZ_RELEASE_ASSERT(aBasePtr); - return notNull; -} - -// Compare two NotNulls. -template -inline bool -operator==(const NotNull& aLhs, const NotNull& aRhs) -{ - return aLhs.get() == aRhs.get(); -} -template -inline bool -operator!=(const NotNull& aLhs, const NotNull& aRhs) -{ - return aLhs.get() != aRhs.get(); -} - -// Compare a NotNull to a base pointer. -template -inline bool -operator==(const NotNull& aLhs, const U& aRhs) -{ - return aLhs.get() == aRhs; -} -template -inline bool -operator!=(const NotNull& aLhs, const U& aRhs) -{ - return aLhs.get() != aRhs; -} - -// Compare a base pointer to a NotNull. -template -inline bool -operator==(const T& aLhs, const NotNull& aRhs) -{ - return aLhs == aRhs.get(); -} -template -inline bool -operator!=(const T& aLhs, const NotNull& aRhs) -{ - return aLhs != aRhs.get(); -} - -// Disallow comparing a NotNull to a nullptr. -template -bool -operator==(const NotNull&, decltype(nullptr)) = delete; -template -bool -operator!=(const NotNull&, decltype(nullptr)) = delete; - -// Disallow comparing a nullptr to a NotNull. -template -bool -operator==(decltype(nullptr), const NotNull&) = delete; -template -bool -operator!=(decltype(nullptr), const NotNull&) = delete; - -} // namespace mozilla - -#endif /* mozilla_NotNull_h */ diff --git a/android/x86/include/spidermonkey/mozilla/NullPtr.h b/android/x86/include/spidermonkey/mozilla/NullPtr.h deleted file mode 100644 index d2248f4b..00000000 --- a/android/x86/include/spidermonkey/mozilla/NullPtr.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implements a mozilla::IsNullPointer type trait. */ - -#ifndef mozilla_NullPtr_h -#define mozilla_NullPtr_h - -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -/** - * IsNullPointer::value is true iff T is decltype(nullptr). - * - * Ideally this would be in TypeTraits.h, but C++11 omitted std::is_null_pointer - * (fixed in C++14), so in the interests of easing a switch to , - * this trait lives elsewhere. - */ -template -struct IsNullPointer : FalseType {}; - -template<> -struct IsNullPointer : TrueType {}; - -} // namespace mozilla - -#endif /* mozilla_NullPtr_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Opaque.h b/android/x86/include/spidermonkey/mozilla/Opaque.h deleted file mode 100644 index d7239ee7..00000000 --- a/android/x86/include/spidermonkey/mozilla/Opaque.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* An opaque integral type supporting only comparison operators. */ - -#ifndef mozilla_Opaque_h -#define mozilla_Opaque_h - -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -/** - * Opaque is a replacement for integral T in cases where only comparisons - * must be supported, and it's desirable to prevent accidental dependency on - * exact values. - */ -template -class Opaque final -{ - static_assert(mozilla::IsIntegral::value, - "mozilla::Opaque only supports integral types"); - - T mValue; - -public: - Opaque() {} - explicit Opaque(T aValue) : mValue(aValue) {} - - bool operator==(const Opaque& aOther) const { - return mValue == aOther.mValue; - } - - bool operator!=(const Opaque& aOther) const { - return !(*this == aOther); - } -}; - -} // namespace mozilla - -#endif /* mozilla_Opaque_h */ diff --git a/android/x86/include/spidermonkey/mozilla/OperatorNewExtensions.h b/android/x86/include/spidermonkey/mozilla/OperatorNewExtensions.h deleted file mode 100644 index 52fd88a6..00000000 --- a/android/x86/include/spidermonkey/mozilla/OperatorNewExtensions.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A version of |operator new| that eschews mandatory null-checks. */ - -#ifndef mozilla_OperatorNewExtensions_h -#define mozilla_OperatorNewExtensions_h - -#include "mozilla/Assertions.h" - -// Credit goes to WebKit for this implementation, cf. -// https://bugs.webkit.org/show_bug.cgi?id=74676 -namespace mozilla { -enum NotNullTag { - KnownNotNull, -}; -} // namespace mozilla - -/* - * The logic here is a little subtle. [expr.new] states that if the allocation - * function being called returns null, then object initialization must not be - * done, and the entirety of the new expression must return null. Non-throwing - * (noexcept) functions are defined to return null to indicate failure. The - * standard placement operator new is defined in such a way, and so it requires - * a null check, even when that null check would be extraneous. Functions - * declared without such a specification are defined to throw std::bad_alloc if - * they fail, and return a non-null pointer otherwise. We compile without - * exceptions, so any placement new overload we define that doesn't declare - * itself as noexcept must therefore avoid generating a null check. Below is - * just such an overload. - * - * You might think that MOZ_NONNULL might perform the same function, but - * MOZ_NONNULL isn't supported on all of our compilers, and even when it is - * supported, doesn't work on all the versions we support. And even keeping - * those limitations in mind, we can't put MOZ_NONNULL on the global, - * standardized placement new function in any event. - * - * We deliberately don't add MOZ_NONNULL(3) to tag |p| as non-null, to benefit - * hypothetical static analyzers. Doing so makes |MOZ_ASSERT(p)|'s internal - * test vacuous, and some compilers warn about such vacuous tests. - */ -inline void* -operator new(size_t, mozilla::NotNullTag, void* p) -{ - MOZ_ASSERT(p); - return p; -} - -#endif // mozilla_OperatorNewExtensions_h diff --git a/android/x86/include/spidermonkey/mozilla/Pair.h b/android/x86/include/spidermonkey/mozilla/Pair.h deleted file mode 100644 index ad7b86a2..00000000 --- a/android/x86/include/spidermonkey/mozilla/Pair.h +++ /dev/null @@ -1,219 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A class holding a pair of objects that tries to conserve storage space. */ - -#ifndef mozilla_Pair_h -#define mozilla_Pair_h - -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -namespace detail { - -enum StorageType { AsBase, AsMember }; - -// Optimize storage using the Empty Base Optimization -- that empty base classes -// don't take up space -- to optimize size when one or the other class is -// stateless and can be used as a base class. -// -// The extra conditions on storage for B are necessary so that PairHelper won't -// ambiguously inherit from either A or B, such that one or the other base class -// would be inaccessible. -template::value ? detail::AsBase : detail::AsMember, - detail::StorageType = - IsEmpty::value && !IsBaseOf::value && !IsBaseOf::value - ? detail::AsBase - : detail::AsMember> -struct PairHelper; - -template -struct PairHelper -{ -protected: - template - PairHelper(AArg&& aA, BArg&& aB) - : mFirstA(Forward(aA)), - mSecondB(Forward(aB)) - {} - - A& first() { return mFirstA; } - const A& first() const { return mFirstA; } - B& second() { return mSecondB; } - const B& second() const { return mSecondB; } - - void swap(PairHelper& aOther) - { - Swap(mFirstA, aOther.mFirstA); - Swap(mSecondB, aOther.mSecondB); - } - -private: - A mFirstA; - B mSecondB; -}; - -template -struct PairHelper : private B -{ -protected: - template - PairHelper(AArg&& aA, BArg&& aB) - : B(Forward(aB)), - mFirstA(Forward(aA)) - {} - - A& first() { return mFirstA; } - const A& first() const { return mFirstA; } - B& second() { return *this; } - const B& second() const { return *this; } - - void swap(PairHelper& aOther) - { - Swap(mFirstA, aOther.mFirstA); - Swap(static_cast(*this), static_cast(aOther)); - } - -private: - A mFirstA; -}; - -template -struct PairHelper : private A -{ -protected: - template - PairHelper(AArg&& aA, BArg&& aB) - : A(Forward(aA)), - mSecondB(Forward(aB)) - {} - - A& first() { return *this; } - const A& first() const { return *this; } - B& second() { return mSecondB; } - const B& second() const { return mSecondB; } - - void swap(PairHelper& aOther) - { - Swap(static_cast(*this), static_cast(aOther)); - Swap(mSecondB, aOther.mSecondB); - } - -private: - B mSecondB; -}; - -template -struct PairHelper : private A, private B -{ -protected: - template - PairHelper(AArg&& aA, BArg&& aB) - : A(Forward(aA)), - B(Forward(aB)) - {} - - A& first() { return static_cast(*this); } - const A& first() const { return static_cast(*this); } - B& second() { return static_cast(*this); } - const B& second() const { return static_cast(*this); } - - void swap(PairHelper& aOther) - { - Swap(static_cast(*this), static_cast(aOther)); - Swap(static_cast(*this), static_cast(aOther)); - } -}; - -} // namespace detail - -/** - * Pair is the logical concatenation of an instance of A with an instance B. - * Space is conserved when possible. Neither A nor B may be a final class. - * - * It's typically clearer to have individual A and B member fields. Except if - * you want the space-conserving qualities of Pair, you're probably better off - * not using this! - * - * No guarantees are provided about the memory layout of A and B, the order of - * initialization or destruction of A and B, and so on. (This is approximately - * required to optimize space usage.) The first/second names are merely - * conceptual! - */ -template -struct Pair - : private detail::PairHelper -{ - typedef typename detail::PairHelper Base; - -public: - template - Pair(AArg&& aA, BArg&& aB) - : Base(Forward(aA), Forward(aB)) - {} - - Pair(Pair&& aOther) - : Base(Move(aOther.first()), Move(aOther.second())) - { } - - Pair(const Pair& aOther) = default; - - Pair& operator=(Pair&& aOther) - { - MOZ_ASSERT(this != &aOther, "Self-moves are prohibited"); - - first() = Move(aOther.first()); - second() = Move(aOther.second()); - - return *this; - } - - Pair& operator=(const Pair& aOther) = default; - - /** The A instance. */ - using Base::first; - /** The B instance. */ - using Base::second; - - /** Swap this pair with another pair. */ - void swap(Pair& aOther) { Base::swap(aOther); } -}; - -template -void -Swap(Pair& aX, Pair& aY) -{ - aX.swap(aY); -} - -/** - * MakePair allows you to construct a Pair instance using type inference. A call - * like this: - * - * MakePair(Foo(), Bar()) - * - * will return a Pair. - */ -template -Pair::Type>::Type, - typename RemoveCV::Type>::Type> -MakePair(A&& aA, B&& aB) -{ - return - Pair::Type>::Type, - typename RemoveCV::Type>::Type>( - Forward(aA), - Forward(aB)); -} - -} // namespace mozilla - -#endif /* mozilla_Pair_h */ diff --git a/android/x86/include/spidermonkey/mozilla/PodOperations.h b/android/x86/include/spidermonkey/mozilla/PodOperations.h deleted file mode 100644 index e6f4df21..00000000 --- a/android/x86/include/spidermonkey/mozilla/PodOperations.h +++ /dev/null @@ -1,196 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Operations for zeroing POD types, arrays, and so on. - * - * These operations are preferable to memset, memcmp, and the like because they - * don't require remembering to multiply by sizeof(T), array lengths, and so on - * everywhere. - */ - -#ifndef mozilla_PodOperations_h -#define mozilla_PodOperations_h - -#include "mozilla/Array.h" -#include "mozilla/ArrayUtils.h" -#include "mozilla/Attributes.h" - -#include -#include - -namespace mozilla { - -/** Set the contents of |aT| to 0. */ -template -static MOZ_ALWAYS_INLINE void -PodZero(T* aT) -{ - memset(aT, 0, sizeof(T)); -} - -/** Set the contents of |aNElem| elements starting at |aT| to 0. */ -template -static MOZ_ALWAYS_INLINE void -PodZero(T* aT, size_t aNElem) -{ - /* - * This function is often called with 'aNElem' small; we use an inline loop - * instead of calling 'memset' with a non-constant length. The compiler - * should inline the memset call with constant size, though. - */ - for (T* end = aT + aNElem; aT < end; aT++) { - memset(aT, 0, sizeof(T)); - } -} - -/* - * Arrays implicitly convert to pointers to their first element, which is - * dangerous when combined with the above PodZero definitions. Adding an - * overload for arrays is ambiguous, so we need another identifier. The - * ambiguous overload is left to catch mistaken uses of PodZero; if you get a - * compile error involving PodZero and array types, use PodArrayZero instead. - */ -template -static void PodZero(T (&aT)[N]) = delete; -template -static void PodZero(T (&aT)[N], size_t aNElem) = delete; - -/** Set the contents of the array |aT| to zero. */ -template -static MOZ_ALWAYS_INLINE void -PodArrayZero(T (&aT)[N]) -{ - memset(aT, 0, N * sizeof(T)); -} - -template -static MOZ_ALWAYS_INLINE void -PodArrayZero(Array& aArr) -{ - memset(&aArr[0], 0, N * sizeof(T)); -} - -/** - * Assign |*aSrc| to |*aDst|. The locations must not be the same and must not - * overlap. - */ -template -static MOZ_ALWAYS_INLINE void -PodAssign(T* aDst, const T* aSrc) -{ - MOZ_ASSERT(aDst + 1 <= aSrc || aSrc + 1 <= aDst, - "destination and source must not overlap"); - memcpy(reinterpret_cast(aDst), reinterpret_cast(aSrc), - sizeof(T)); -} - -/** - * Copy |aNElem| T elements from |aSrc| to |aDst|. The two memory ranges must - * not overlap! - */ -template -static MOZ_ALWAYS_INLINE void -PodCopy(T* aDst, const T* aSrc, size_t aNElem) -{ - MOZ_ASSERT(aDst + aNElem <= aSrc || aSrc + aNElem <= aDst, - "destination and source must not overlap"); - if (aNElem < 128) { - /* - * Avoid using operator= in this loop, as it may have been - * intentionally deleted by the POD type. - */ - for (const T* srcend = aSrc + aNElem; aSrc < srcend; aSrc++, aDst++) { - PodAssign(aDst, aSrc); - } - } else { - memcpy(aDst, aSrc, aNElem * sizeof(T)); - } -} - -template -static MOZ_ALWAYS_INLINE void -PodCopy(volatile T* aDst, const volatile T* aSrc, size_t aNElem) -{ - MOZ_ASSERT(aDst + aNElem <= aSrc || aSrc + aNElem <= aDst, - "destination and source must not overlap"); - - /* - * Volatile |aDst| requires extra work, because it's undefined behavior to - * modify volatile objects using the mem* functions. Just write out the - * loops manually, using operator= rather than memcpy for the same reason, - * and let the compiler optimize to the extent it can. - */ - for (const volatile T* srcend = aSrc + aNElem; - aSrc < srcend; - aSrc++, aDst++) { - *aDst = *aSrc; - } -} - -/* - * Copy the contents of the array |aSrc| into the array |aDst|, both of size N. - * The arrays must not overlap! - */ -template -static MOZ_ALWAYS_INLINE void -PodArrayCopy(T (&aDst)[N], const T (&aSrc)[N]) -{ - PodCopy(aDst, aSrc, N); -} - -/** - * Copy the memory for |aNElem| T elements from |aSrc| to |aDst|. If the two - * memory ranges overlap, then the effect is as if the |aNElem| elements are - * first copied from |aSrc| to a temporary array, and then from the temporary - * array to |aDst|. - */ -template -static MOZ_ALWAYS_INLINE void -PodMove(T* aDst, const T* aSrc, size_t aNElem) -{ - MOZ_ASSERT(aNElem <= SIZE_MAX / sizeof(T), - "trying to move an impossible number of elements"); - memmove(aDst, aSrc, aNElem * sizeof(T)); -} - -/** - * Determine whether the |len| elements at |one| are memory-identical to the - * |len| elements at |two|. - */ -template -static MOZ_ALWAYS_INLINE bool -PodEqual(const T* one, const T* two, size_t len) -{ - if (len < 128) { - const T* p1end = one + len; - const T* p1 = one; - const T* p2 = two; - for (; p1 < p1end; p1++, p2++) { - if (*p1 != *p2) { - return false; - } - } - return true; - } - - return !memcmp(one, two, len * sizeof(T)); -} - -/* - * Determine whether the |N| elements at |one| are memory-identical to the - * |N| elements at |two|. - */ -template -static MOZ_ALWAYS_INLINE bool -PodEqual(const T (&one)[N], const T (&two)[N]) -{ - return PodEqual(one, two, N); -} - -} // namespace mozilla - -#endif /* mozilla_PodOperations_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Poison.h b/android/x86/include/spidermonkey/mozilla/Poison.h deleted file mode 100644 index aae56765..00000000 --- a/android/x86/include/spidermonkey/mozilla/Poison.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * A poison value that can be used to fill a memory space with - * an address that leads to a safe crash when dereferenced. - */ - -#ifndef mozilla_Poison_h -#define mozilla_Poison_h - -#include "mozilla/Assertions.h" -#include "mozilla/Types.h" - -#include - -MOZ_BEGIN_EXTERN_C - -extern MFBT_DATA uintptr_t gMozillaPoisonValue; - -/** - * @return the poison value. - */ -inline uintptr_t mozPoisonValue() -{ - return gMozillaPoisonValue; -} - -/** - * Overwrite the memory block of aSize bytes at aPtr with the poison value. - * aPtr MUST be aligned at a sizeof(uintptr_t) boundary. - * Only an even number of sizeof(uintptr_t) bytes are overwritten, the last - * few bytes (if any) is not overwritten. - */ -inline void mozWritePoison(void* aPtr, size_t aSize) -{ - const uintptr_t POISON = mozPoisonValue(); - char* p = (char*)aPtr; - char* limit = p + aSize; - MOZ_ASSERT((uintptr_t)aPtr % sizeof(uintptr_t) == 0, "bad alignment"); - MOZ_ASSERT(aSize >= sizeof(uintptr_t), "poisoning this object has no effect"); - for (; p < limit; p += sizeof(uintptr_t)) { - *((uintptr_t*)p) = POISON; - } -} - -/** - * Initialize the poison value. - * This should only be called once. - */ -extern MFBT_API void mozPoisonValueInit(); - -/* Values annotated by CrashReporter */ -extern MFBT_DATA uintptr_t gMozillaPoisonBase; -extern MFBT_DATA uintptr_t gMozillaPoisonSize; - -MOZ_END_EXTERN_C - -#if defined(__cplusplus) - -namespace mozilla { - -/** - * This class is designed to cause crashes when various kinds of memory - * corruption are observed. For instance, let's say we have a class C where we - * suspect out-of-bounds writes to some members. We can insert a member of type - * Poison near the members we suspect are being corrupted by out-of-bounds - * writes. Or perhaps we have a class K we suspect is subject to use-after-free - * violations, in which case it doesn't particularly matter where in the class - * we add the member of type Poison. - * - * In either case, we then insert calls to Check() throughout the code. Doing - * so enables us to narrow down the location where the corruption is occurring. - * A pleasant side-effect of these additional Check() calls is that crash - * signatures may become more regular, as crashes will ideally occur - * consolidated at the point of a Check(), rather than scattered about at - * various uses of the corrupted memory. - */ -class CorruptionCanary { -public: - CorruptionCanary() { - mValue = kCanarySet; - } - - ~CorruptionCanary() { - Check(); - mValue = mozPoisonValue(); - } - - void Check() const { - if (mValue != kCanarySet) { - MOZ_CRASH("Canary check failed, check lifetime"); - } - } - -private: - static const uintptr_t kCanarySet = 0x0f0b0f0b; - uintptr_t mValue; -}; - -} // mozilla - -#endif - -#endif /* mozilla_Poison_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Range.h b/android/x86/include/spidermonkey/mozilla/Range.h deleted file mode 100644 index 47d91bb0..00000000 --- a/android/x86/include/spidermonkey/mozilla/Range.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_Range_h -#define mozilla_Range_h - -#include "mozilla/RangedPtr.h" -#include "mozilla/TypeTraits.h" - -#include - -namespace mozilla { - -// Range is a tuple containing a pointer and a length. -template -class Range -{ - const RangedPtr mStart; - const RangedPtr mEnd; - -public: - Range() : mStart(nullptr, 0), mEnd(nullptr, 0) {} - Range(T* aPtr, size_t aLength) - : mStart(aPtr, aPtr, aPtr + aLength), - mEnd(aPtr + aLength, aPtr, aPtr + aLength) - {} - Range(const RangedPtr& aStart, const RangedPtr& aEnd) - : mStart(aStart.get(), aStart.get(), aEnd.get()), - mEnd(aEnd.get(), aStart.get(), aEnd.get()) - { - // Only accept two RangedPtrs within the same range. - aStart.checkIdenticalRange(aEnd); - MOZ_ASSERT(aStart <= aEnd); - } - - template::value, - int>::Type> - MOZ_IMPLICIT Range(const Range& aOther) - : mStart(aOther.mStart), - mEnd(aOther.mEnd) - {} - - RangedPtr begin() const { return mStart; } - RangedPtr end() const { return mEnd; } - size_t length() const { return mEnd - mStart; } - - T& operator[](size_t aOffset) const { return mStart[aOffset]; } - - explicit operator bool() const { return mStart != nullptr; } -}; - -} // namespace mozilla - -#endif /* mozilla_Range_h */ diff --git a/android/x86/include/spidermonkey/mozilla/RangedArray.h b/android/x86/include/spidermonkey/mozilla/RangedArray.h deleted file mode 100644 index afe6267f..00000000 --- a/android/x86/include/spidermonkey/mozilla/RangedArray.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * A compile-time constant-length array, with bounds-checking assertions -- but - * unlike mozilla::Array, with indexes biased by a constant. - * - * Thus where mozilla::Array is a three-element array indexed by [0, 3), - * mozilla::RangedArray is a three-element array indexed by [8, 11). - */ - -#ifndef mozilla_RangedArray_h -#define mozilla_RangedArray_h - -#include "mozilla/Array.h" - -namespace mozilla { - -template -class RangedArray -{ -private: - typedef Array ArrayType; - ArrayType mArr; - -public: - T& operator[](size_t aIndex) - { - MOZ_ASSERT(aIndex == MinIndex || aIndex > MinIndex); - return mArr[aIndex - MinIndex]; - } - - const T& operator[](size_t aIndex) const - { - MOZ_ASSERT(aIndex == MinIndex || aIndex > MinIndex); - return mArr[aIndex - MinIndex]; - } - - typedef typename ArrayType::iterator iterator; - typedef typename ArrayType::const_iterator const_iterator; - typedef typename ArrayType::reverse_iterator reverse_iterator; - typedef typename ArrayType::const_reverse_iterator const_reverse_iterator; - - // Methods for range-based for loops. - iterator begin() { return mArr.begin(); } - const_iterator begin() const { return mArr.begin(); } - const_iterator cbegin() const { return mArr.cbegin(); } - iterator end() { return mArr.end(); } - const_iterator end() const { return mArr.end(); } - const_iterator cend() const { return mArr.cend(); } - - // Methods for reverse iterating. - reverse_iterator rbegin() { return mArr.rbegin(); } - const_reverse_iterator rbegin() const { return mArr.rbegin(); } - const_reverse_iterator crbegin() const { return mArr.crbegin(); } - reverse_iterator rend() { return mArr.rend(); } - const_reverse_iterator rend() const { return mArr.rend(); } - const_reverse_iterator crend() const { return mArr.crend(); } -}; - -} // namespace mozilla - -#endif // mozilla_RangedArray_h diff --git a/android/x86/include/spidermonkey/mozilla/RangedPtr.h b/android/x86/include/spidermonkey/mozilla/RangedPtr.h deleted file mode 100644 index a07c1f4f..00000000 --- a/android/x86/include/spidermonkey/mozilla/RangedPtr.h +++ /dev/null @@ -1,292 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Implements a smart pointer asserted to remain within a range specified at - * construction. - */ - -#ifndef mozilla_RangedPtr_h -#define mozilla_RangedPtr_h - -#include "mozilla/ArrayUtils.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -#include - -namespace mozilla { - -/* - * RangedPtr is a smart pointer restricted to an address range specified at - * creation. The pointer (and any smart pointers derived from it) must remain - * within the range [start, end] (inclusive of end to facilitate use as - * sentinels). Dereferencing or indexing into the pointer (or pointers derived - * from it) must remain within the range [start, end). All the standard pointer - * operators are defined on it; in debug builds these operations assert that the - * range specified at construction is respected. - * - * In theory passing a smart pointer instance as an argument can be slightly - * slower than passing a T* (due to ABI requirements for passing structs versus - * passing pointers), if the method being called isn't inlined. If you are in - * extremely performance-critical code, you may want to be careful using this - * smart pointer as an argument type. - * - * RangedPtr intentionally does not implicitly convert to T*. Use get() to - * explicitly convert to T*. Keep in mind that the raw pointer of course won't - * implement bounds checking in debug builds. - */ -template -class RangedPtr -{ - T* mPtr; - -#ifdef DEBUG - T* const mRangeStart; - T* const mRangeEnd; -#endif - - void checkSanity() - { - MOZ_ASSERT(mRangeStart <= mPtr); - MOZ_ASSERT(mPtr <= mRangeEnd); - } - - /* Creates a new pointer for |aPtr|, restricted to this pointer's range. */ - RangedPtr create(T* aPtr) const - { -#ifdef DEBUG - return RangedPtr(aPtr, mRangeStart, mRangeEnd); -#else - return RangedPtr(aPtr, nullptr, size_t(0)); -#endif - } - - uintptr_t asUintptr() const { return reinterpret_cast(mPtr); } - -public: - RangedPtr(T* aPtr, T* aStart, T* aEnd) - : mPtr(aPtr) -#ifdef DEBUG - , mRangeStart(aStart), mRangeEnd(aEnd) -#endif - { - MOZ_ASSERT(mRangeStart <= mRangeEnd); - checkSanity(); - } - RangedPtr(T* aPtr, T* aStart, size_t aLength) - : mPtr(aPtr) -#ifdef DEBUG - , mRangeStart(aStart), mRangeEnd(aStart + aLength) -#endif - { - MOZ_ASSERT(aLength <= size_t(-1) / sizeof(T)); - MOZ_ASSERT(reinterpret_cast(mRangeStart) + aLength * sizeof(T) >= - reinterpret_cast(mRangeStart)); - checkSanity(); - } - - /* Equivalent to RangedPtr(aPtr, aPtr, aLength). */ - RangedPtr(T* aPtr, size_t aLength) - : mPtr(aPtr) -#ifdef DEBUG - , mRangeStart(aPtr), mRangeEnd(aPtr + aLength) -#endif - { - MOZ_ASSERT(aLength <= size_t(-1) / sizeof(T)); - MOZ_ASSERT(reinterpret_cast(mRangeStart) + aLength * sizeof(T) >= - reinterpret_cast(mRangeStart)); - checkSanity(); - } - - /* Equivalent to RangedPtr(aArr, aArr, N). */ - template - explicit RangedPtr(T (&aArr)[N]) - : mPtr(aArr) -#ifdef DEBUG - , mRangeStart(aArr), mRangeEnd(aArr + N) -#endif - { - checkSanity(); - } - - T* get() const { return mPtr; } - - explicit operator bool() const { return mPtr != nullptr; } - - void checkIdenticalRange(const RangedPtr& aOther) const - { - MOZ_ASSERT(mRangeStart == aOther.mRangeStart); - MOZ_ASSERT(mRangeEnd == aOther.mRangeEnd); - } - - /* - * You can only assign one RangedPtr into another if the two pointers have - * the same valid range: - * - * char arr1[] = "hi"; - * char arr2[] = "bye"; - * RangedPtr p1(arr1, 2); - * p1 = RangedPtr(arr1 + 1, arr1, arr1 + 2); // works - * p1 = RangedPtr(arr2, 3); // asserts - */ - RangedPtr& operator=(const RangedPtr& aOther) - { - checkIdenticalRange(aOther); - mPtr = aOther.mPtr; - checkSanity(); - return *this; - } - - RangedPtr operator+(size_t aInc) const - { - MOZ_ASSERT(aInc <= size_t(-1) / sizeof(T)); - MOZ_ASSERT(asUintptr() + aInc * sizeof(T) >= asUintptr()); - return create(mPtr + aInc); - } - - RangedPtr operator-(size_t aDec) const - { - MOZ_ASSERT(aDec <= size_t(-1) / sizeof(T)); - MOZ_ASSERT(asUintptr() - aDec * sizeof(T) <= asUintptr()); - return create(mPtr - aDec); - } - - /* - * You can assign a raw pointer into a RangedPtr if the raw pointer is - * within the range specified at creation. - */ - template - RangedPtr& operator=(U* aPtr) - { - *this = create(aPtr); - return *this; - } - - template - RangedPtr& operator=(const RangedPtr& aPtr) - { - MOZ_ASSERT(mRangeStart <= aPtr.mPtr); - MOZ_ASSERT(aPtr.mPtr <= mRangeEnd); - mPtr = aPtr.mPtr; - checkSanity(); - return *this; - } - - RangedPtr& operator++() - { - return (*this += 1); - } - - RangedPtr operator++(int) - { - RangedPtr rcp = *this; - ++*this; - return rcp; - } - - RangedPtr& operator--() - { - return (*this -= 1); - } - - RangedPtr operator--(int) - { - RangedPtr rcp = *this; - --*this; - return rcp; - } - - RangedPtr& operator+=(size_t aInc) - { - *this = *this + aInc; - return *this; - } - - RangedPtr& operator-=(size_t aDec) - { - *this = *this - aDec; - return *this; - } - - T& operator[](int aIndex) const - { - MOZ_ASSERT(size_t(aIndex > 0 ? aIndex : -aIndex) <= size_t(-1) / sizeof(T)); - return *create(mPtr + aIndex); - } - - T& operator*() const - { - MOZ_ASSERT(mPtr >= mRangeStart); - MOZ_ASSERT(mPtr < mRangeEnd); - return *mPtr; - } - - T* operator->() const - { - MOZ_ASSERT(mPtr >= mRangeStart); - MOZ_ASSERT(mPtr < mRangeEnd); - return mPtr; - } - - template - bool operator==(const RangedPtr& aOther) const - { - return mPtr == aOther.mPtr; - } - template - bool operator!=(const RangedPtr& aOther) const - { - return !(*this == aOther); - } - - template - bool operator==(const U* u) const - { - return mPtr == u; - } - template - bool operator!=(const U* u) const - { - return !(*this == u); - } - - template - bool operator<(const RangedPtr& aOther) const - { - return mPtr < aOther.mPtr; - } - template - bool operator<=(const RangedPtr& aOther) const - { - return mPtr <= aOther.mPtr; - } - - template - bool operator>(const RangedPtr& aOther) const - { - return mPtr > aOther.mPtr; - } - template - bool operator>=(const RangedPtr& aOther) const - { - return mPtr >= aOther.mPtr; - } - - size_t operator-(const RangedPtr& aOther) const - { - MOZ_ASSERT(mPtr >= aOther.mPtr); - return PointerRangeSize(aOther.mPtr, mPtr); - } - -private: - RangedPtr() = delete; - T* operator&() = delete; -}; - -} /* namespace mozilla */ - -#endif /* mozilla_RangedPtr_h */ diff --git a/android/x86/include/spidermonkey/mozilla/ReentrancyGuard.h b/android/x86/include/spidermonkey/mozilla/ReentrancyGuard.h deleted file mode 100644 index 9963974e..00000000 --- a/android/x86/include/spidermonkey/mozilla/ReentrancyGuard.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Small helper class for asserting uses of a class are non-reentrant. */ - -#ifndef mozilla_ReentrancyGuard_h -#define mozilla_ReentrancyGuard_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/GuardObjects.h" - -namespace mozilla { - -/* Useful for implementing containers that assert non-reentrancy */ -class MOZ_RAII ReentrancyGuard -{ - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -#ifdef DEBUG - bool& mEntered; -#endif - -public: - template -#ifdef DEBUG - explicit ReentrancyGuard(T& aObj - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mEntered(aObj.mEntered) -#else - explicit ReentrancyGuard(T& - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) -#endif - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; -#ifdef DEBUG - MOZ_ASSERT(!mEntered); - mEntered = true; -#endif - } - ~ReentrancyGuard() - { -#ifdef DEBUG - mEntered = false; -#endif - } - -private: - ReentrancyGuard(const ReentrancyGuard&) = delete; - void operator=(const ReentrancyGuard&) = delete; -}; - -} // namespace mozilla - -#endif /* mozilla_ReentrancyGuard_h */ diff --git a/android/x86/include/spidermonkey/mozilla/RefCountType.h b/android/x86/include/spidermonkey/mozilla/RefCountType.h deleted file mode 100644 index e95a22a0..00000000 --- a/android/x86/include/spidermonkey/mozilla/RefCountType.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_RefCountType_h -#define mozilla_RefCountType_h - -#include - -/** - * MozRefCountType is Mozilla's reference count type. - * - * We use the same type to represent the refcount of RefCounted objects - * as well, in order to be able to use the leak detection facilities - * that are implemented by XPCOM. - * - * Note that this type is not in the mozilla namespace so that it is - * usable for both C and C++ code. - */ -typedef uintptr_t MozRefCountType; - -/* - * This is the return type for AddRef() and Release() in nsISupports. - * IUnknown of COM returns an unsigned long from equivalent functions. - * - * The following ifdef exists to maintain binary compatibility with - * IUnknown, the base interface in Microsoft COM. - */ -#ifdef XP_WIN -typedef unsigned long MozExternalRefCountType; -#else -typedef uint32_t MozExternalRefCountType; -#endif - -#endif diff --git a/android/x86/include/spidermonkey/mozilla/RefCounted.h b/android/x86/include/spidermonkey/mozilla/RefCounted.h deleted file mode 100644 index ae05f1e0..00000000 --- a/android/x86/include/spidermonkey/mozilla/RefCounted.h +++ /dev/null @@ -1,210 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* CRTP refcounting templates. Do not use unless you are an Expert. */ - -#ifndef mozilla_RefCounted_h -#define mozilla_RefCounted_h - -#include "mozilla/AlreadyAddRefed.h" -#include "mozilla/Assertions.h" -#include "mozilla/Atomics.h" -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" -#include "mozilla/RefCountType.h" -#include "mozilla/TypeTraits.h" - -#if defined(MOZILLA_INTERNAL_API) -#include "nsXPCOM.h" -#endif - -#if defined(MOZILLA_INTERNAL_API) && \ - (defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING)) -#define MOZ_REFCOUNTED_LEAK_CHECKING -#endif - -namespace mozilla { - -/** - * RefCounted is a sort of a "mixin" for a class T. RefCounted - * manages, well, refcounting for T, and because RefCounted is - * parameterized on T, RefCounted can call T's destructor directly. - * This means T doesn't need to have a virtual dtor and so doesn't - * need a vtable. - * - * RefCounted is created with refcount == 0. Newly-allocated - * RefCounted must immediately be assigned to a RefPtr to make the - * refcount > 0. It's an error to allocate and free a bare - * RefCounted, i.e. outside of the RefPtr machinery. Attempts to - * do so will abort DEBUG builds. - * - * Live RefCounted have refcount > 0. The lifetime (refcounts) of - * live RefCounted are controlled by RefPtr and - * RefPtr. Upon a transition from refcounted==1 - * to 0, the RefCounted "dies" and is destroyed. The "destroyed" - * state is represented in DEBUG builds by refcount==0xffffdead. This - * state distinguishes use-before-ref (refcount==0) from - * use-after-destroy (refcount==0xffffdead). - * - * Note that when deriving from RefCounted or AtomicRefCounted, you - * should add MOZ_DECLARE_REFCOUNTED_TYPENAME(ClassName) to the public - * section of your class, where ClassName is the name of your class. - */ -namespace detail { -const MozRefCountType DEAD = 0xffffdead; - -// When building code that gets compiled into Gecko, try to use the -// trace-refcount leak logging facilities. -#ifdef MOZ_REFCOUNTED_LEAK_CHECKING -class RefCountLogger -{ -public: - static void logAddRef(const void* aPointer, MozRefCountType aRefCount, - const char* aTypeName, uint32_t aInstanceSize) - { - MOZ_ASSERT(aRefCount != DEAD); - NS_LogAddRef(const_cast(aPointer), aRefCount, aTypeName, - aInstanceSize); - } - - static void logRelease(const void* aPointer, MozRefCountType aRefCount, - const char* aTypeName) - { - MOZ_ASSERT(aRefCount != DEAD); - NS_LogRelease(const_cast(aPointer), aRefCount, aTypeName); - } -}; -#endif - -// This is used WeakPtr.h as well as this file. -enum RefCountAtomicity -{ - AtomicRefCount, - NonAtomicRefCount -}; - -template -class RefCounted -{ -protected: - RefCounted() : mRefCnt(0) {} - ~RefCounted() { MOZ_ASSERT(mRefCnt == detail::DEAD); } - -public: - // Compatibility with nsRefPtr. - void AddRef() const - { - // Note: this method must be thread safe for AtomicRefCounted. - MOZ_ASSERT(int32_t(mRefCnt) >= 0); -#ifndef MOZ_REFCOUNTED_LEAK_CHECKING - ++mRefCnt; -#else - const char* type = static_cast(this)->typeName(); - uint32_t size = static_cast(this)->typeSize(); - const void* ptr = static_cast(this); - MozRefCountType cnt = ++mRefCnt; - detail::RefCountLogger::logAddRef(ptr, cnt, type, size); -#endif - } - - void Release() const - { - // Note: this method must be thread safe for AtomicRefCounted. - MOZ_ASSERT(int32_t(mRefCnt) > 0); -#ifndef MOZ_REFCOUNTED_LEAK_CHECKING - MozRefCountType cnt = --mRefCnt; -#else - const char* type = static_cast(this)->typeName(); - const void* ptr = static_cast(this); - MozRefCountType cnt = --mRefCnt; - // Note: it's not safe to touch |this| after decrementing the refcount, - // except for below. - detail::RefCountLogger::logRelease(ptr, cnt, type); -#endif - if (0 == cnt) { - // Because we have atomically decremented the refcount above, only - // one thread can get a 0 count here, so as long as we can assume that - // everything else in the system is accessing this object through - // RefPtrs, it's safe to access |this| here. -#ifdef DEBUG - mRefCnt = detail::DEAD; -#endif - delete static_cast(this); - } - } - - // Compatibility with wtf::RefPtr. - void ref() { AddRef(); } - void deref() { Release(); } - MozRefCountType refCount() const { return mRefCnt; } - bool hasOneRef() const - { - MOZ_ASSERT(mRefCnt > 0); - return mRefCnt == 1; - } - -private: - mutable typename Conditional, - MozRefCountType>::Type mRefCnt; -}; - -#ifdef MOZ_REFCOUNTED_LEAK_CHECKING -// Passing override for the optional argument marks the typeName and -// typeSize functions defined by this macro as overrides. -#define MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(T, ...) \ - virtual const char* typeName() const __VA_ARGS__ { return #T; } \ - virtual size_t typeSize() const __VA_ARGS__ { return sizeof(*this); } -#else -#define MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(T, ...) -#endif - -// Note that this macro is expanded unconditionally because it declares only -// two small inline functions which will hopefully get eliminated by the linker -// in non-leak-checking builds. -#define MOZ_DECLARE_REFCOUNTED_TYPENAME(T) \ - const char* typeName() const { return #T; } \ - size_t typeSize() const { return sizeof(*this); } - -} // namespace detail - -template -class RefCounted : public detail::RefCounted -{ -public: - ~RefCounted() - { - static_assert(IsBaseOf::value, - "T must derive from RefCounted"); - } -}; - -namespace external { - -/** - * AtomicRefCounted is like RefCounted, with an atomically updated - * reference counter. - * - * NOTE: Please do not use this class, use NS_INLINE_DECL_THREADSAFE_REFCOUNTING - * instead. - */ -template -class AtomicRefCounted : - public mozilla::detail::RefCounted -{ -public: - ~AtomicRefCounted() - { - static_assert(IsBaseOf::value, - "T must derive from AtomicRefCounted"); - } -}; - -} // namespace external - -} // namespace mozilla - -#endif // mozilla_RefCounted_h diff --git a/android/x86/include/spidermonkey/mozilla/RefPtr.h b/android/x86/include/spidermonkey/mozilla/RefPtr.h deleted file mode 100644 index bfa8f6e0..00000000 --- a/android/x86/include/spidermonkey/mozilla/RefPtr.h +++ /dev/null @@ -1,656 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_RefPtr_h -#define mozilla_RefPtr_h - -#include "mozilla/AlreadyAddRefed.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -/*****************************************************************************/ - -// template class RefPtrGetterAddRefs; - -class nsCOMPtr_helper; - -namespace mozilla { -template class OwningNonNull; -template class StaticRefPtr; - -// Traditionally, RefPtr supports automatic refcounting of any pointer type -// with AddRef() and Release() methods that follow the traditional semantics. -// -// This traits class can be specialized to operate on other pointer types. For -// example, we specialize this trait for opaque FFI types that represent -// refcounted objects in Rust. -// -// Given the use of ConstRemovingRefPtrTraits below, U should not be a const- -// qualified type. -template -struct RefPtrTraits -{ - static void AddRef(U* aPtr) { - aPtr->AddRef(); - } - static void Release(U* aPtr) { - aPtr->Release(); - } -}; - -} // namespace mozilla - -template -class RefPtr -{ -private: - void - assign_with_AddRef(T* aRawPtr) - { - if (aRawPtr) { - ConstRemovingRefPtrTraits::AddRef(aRawPtr); - } - assign_assuming_AddRef(aRawPtr); - } - - void - assign_assuming_AddRef(T* aNewPtr) - { - T* oldPtr = mRawPtr; - mRawPtr = aNewPtr; - if (oldPtr) { - ConstRemovingRefPtrTraits::Release(oldPtr); - } - } - -private: - T* MOZ_OWNING_REF mRawPtr; - -public: - typedef T element_type; - - ~RefPtr() - { - if (mRawPtr) { - ConstRemovingRefPtrTraits::Release(mRawPtr); - } - } - - // Constructors - - RefPtr() - : mRawPtr(nullptr) - // default constructor - { - } - - RefPtr(const RefPtr& aSmartPtr) - : mRawPtr(aSmartPtr.mRawPtr) - // copy-constructor - { - if (mRawPtr) { - ConstRemovingRefPtrTraits::AddRef(mRawPtr); - } - } - - RefPtr(RefPtr&& aRefPtr) - : mRawPtr(aRefPtr.mRawPtr) - { - aRefPtr.mRawPtr = nullptr; - } - - // construct from a raw pointer (of the right type) - - MOZ_IMPLICIT RefPtr(T* aRawPtr) - : mRawPtr(aRawPtr) - { - if (mRawPtr) { - ConstRemovingRefPtrTraits::AddRef(mRawPtr); - } - } - - MOZ_IMPLICIT RefPtr(decltype(nullptr)) - : mRawPtr(nullptr) - { - } - - template - MOZ_IMPLICIT RefPtr(already_AddRefed& aSmartPtr) - : mRawPtr(aSmartPtr.take()) - // construct from |already_AddRefed| - { - } - - template - MOZ_IMPLICIT RefPtr(already_AddRefed&& aSmartPtr) - : mRawPtr(aSmartPtr.take()) - // construct from |otherRefPtr.forget()| - { - } - - template - MOZ_IMPLICIT RefPtr(const RefPtr& aSmartPtr) - : mRawPtr(aSmartPtr.get()) - // copy-construct from a smart pointer with a related pointer type - { - if (mRawPtr) { - ConstRemovingRefPtrTraits::AddRef(mRawPtr); - } - } - - template - MOZ_IMPLICIT RefPtr(RefPtr&& aSmartPtr) - : mRawPtr(aSmartPtr.forget().take()) - // construct from |Move(RefPtr)|. - { - } - - MOZ_IMPLICIT RefPtr(const nsCOMPtr_helper& aHelper); - - // Defined in OwningNonNull.h - template - MOZ_IMPLICIT RefPtr(const mozilla::OwningNonNull& aOther); - - // Defined in StaticPtr.h - template - MOZ_IMPLICIT RefPtr(const mozilla::StaticRefPtr& aOther); - - // Assignment operators - - RefPtr& - operator=(decltype(nullptr)) - { - assign_assuming_AddRef(nullptr); - return *this; - } - - RefPtr& - operator=(const RefPtr& aRhs) - // copy assignment operator - { - assign_with_AddRef(aRhs.mRawPtr); - return *this; - } - - template - RefPtr& - operator=(const RefPtr& aRhs) - // assign from an RefPtr of a related pointer type - { - assign_with_AddRef(aRhs.get()); - return *this; - } - - RefPtr& - operator=(T* aRhs) - // assign from a raw pointer (of the right type) - { - assign_with_AddRef(aRhs); - return *this; - } - - template - RefPtr& - operator=(already_AddRefed& aRhs) - // assign from |already_AddRefed| - { - assign_assuming_AddRef(aRhs.take()); - return *this; - } - - template - RefPtr& - operator=(already_AddRefed && aRhs) - // assign from |otherRefPtr.forget()| - { - assign_assuming_AddRef(aRhs.take()); - return *this; - } - - RefPtr& operator=(const nsCOMPtr_helper& aHelper); - - RefPtr& - operator=(RefPtr && aRefPtr) - { - assign_assuming_AddRef(aRefPtr.mRawPtr); - aRefPtr.mRawPtr = nullptr; - return *this; - } - - // Defined in OwningNonNull.h - template - RefPtr& - operator=(const mozilla::OwningNonNull& aOther); - - // Defined in StaticPtr.h - template - RefPtr& - operator=(const mozilla::StaticRefPtr& aOther); - - // Other pointer operators - - void - swap(RefPtr& aRhs) - // ...exchange ownership with |aRhs|; can save a pair of refcount operations - { - T* temp = aRhs.mRawPtr; - aRhs.mRawPtr = mRawPtr; - mRawPtr = temp; - } - - void - swap(T*& aRhs) - // ...exchange ownership with |aRhs|; can save a pair of refcount operations - { - T* temp = aRhs; - aRhs = mRawPtr; - mRawPtr = temp; - } - - already_AddRefed - forget() - // return the value of mRawPtr and null out mRawPtr. Useful for - // already_AddRefed return values. - { - T* temp = nullptr; - swap(temp); - return already_AddRefed(temp); - } - - template - void - forget(I** aRhs) - // Set the target of aRhs to the value of mRawPtr and null out mRawPtr. - // Useful to avoid unnecessary AddRef/Release pairs with "out" - // parameters where aRhs bay be a T** or an I** where I is a base class - // of T. - { - MOZ_ASSERT(aRhs, "Null pointer passed to forget!"); - *aRhs = mRawPtr; - mRawPtr = nullptr; - } - - T* - get() const - /* - Prefer the implicit conversion provided automatically by |operator T*() const|. - Use |get()| to resolve ambiguity or to get a castable pointer. - */ - { - return const_cast(mRawPtr); - } - - operator T*() const -#ifdef MOZ_HAVE_REF_QUALIFIERS - & -#endif - /* - ...makes an |RefPtr| act like its underlying raw pointer type whenever it - is used in a context where a raw pointer is expected. It is this operator - that makes an |RefPtr| substitutable for a raw pointer. - - Prefer the implicit use of this operator to calling |get()|, except where - necessary to resolve ambiguity. - */ - { - return get(); - } - -#ifdef MOZ_HAVE_REF_QUALIFIERS - // Don't allow implicit conversion of temporary RefPtr to raw pointer, - // because the refcount might be one and the pointer will immediately become - // invalid. - operator T*() const && = delete; - - // These are needed to avoid the deleted operator above. XXX Why is operator! - // needed separately? Shouldn't the compiler prefer using the non-deleted - // operator bool instead of the deleted operator T*? - explicit operator bool() const { return !!mRawPtr; } - bool operator!() const { return !mRawPtr; } -#endif - - T* - operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN - { - MOZ_ASSERT(mRawPtr != nullptr, - "You can't dereference a NULL RefPtr with operator->()."); - return get(); - } - - template - class Proxy - { - typedef R (T::*member_function)(Args...); - T* mRawPtr; - member_function mFunction; - public: - Proxy(T* aRawPtr, member_function aFunction) - : mRawPtr(aRawPtr), - mFunction(aFunction) - { - } - template - R operator()(ActualArgs&&... aArgs) - { - return ((*mRawPtr).*mFunction)(mozilla::Forward(aArgs)...); - } - }; - - template - Proxy operator->*(R (T::*aFptr)(Args...)) const - { - MOZ_ASSERT(mRawPtr != nullptr, - "You can't dereference a NULL RefPtr with operator->*()."); - return Proxy(get(), aFptr); - } - - RefPtr* - get_address() - // This is not intended to be used by clients. See |address_of| - // below. - { - return this; - } - - const RefPtr* - get_address() const - // This is not intended to be used by clients. See |address_of| - // below. - { - return this; - } - -public: - T& - operator*() const - { - MOZ_ASSERT(mRawPtr != nullptr, - "You can't dereference a NULL RefPtr with operator*()."); - return *get(); - } - - T** - StartAssignment() - { - assign_assuming_AddRef(nullptr); - return reinterpret_cast(&mRawPtr); - } -private: - // This helper class makes |RefPtr| possible by casting away - // the constness from the pointer when calling AddRef() and Release(). - // - // This is necessary because AddRef() and Release() implementations can't - // generally expected to be const themselves (without heavy use of |mutable| - // and |const_cast| in their own implementations). - // - // This should be sound because while |RefPtr| provides a - // const view of an object, the object itself should not be const (it - // would have to be allocated as |new const T| or similar to be const). - template - struct ConstRemovingRefPtrTraits - { - static void AddRef(U* aPtr) { - mozilla::RefPtrTraits::AddRef(aPtr); - } - static void Release(U* aPtr) { - mozilla::RefPtrTraits::Release(aPtr); - } - }; - template - struct ConstRemovingRefPtrTraits - { - static void AddRef(const U* aPtr) { - mozilla::RefPtrTraits::AddRef(const_cast(aPtr)); - } - static void Release(const U* aPtr) { - mozilla::RefPtrTraits::Release(const_cast(aPtr)); - } - }; -}; - -class nsCycleCollectionTraversalCallback; -template -void -CycleCollectionNoteChild(nsCycleCollectionTraversalCallback& aCallback, - T* aChild, const char* aName, uint32_t aFlags); - -template -inline void -ImplCycleCollectionUnlink(RefPtr& aField) -{ - aField = nullptr; -} - -template -inline void -ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, - RefPtr& aField, - const char* aName, - uint32_t aFlags = 0) -{ - CycleCollectionNoteChild(aCallback, aField.get(), aName, aFlags); -} - -template -inline RefPtr* -address_of(RefPtr& aPtr) -{ - return aPtr.get_address(); -} - -template -inline const RefPtr* -address_of(const RefPtr& aPtr) -{ - return aPtr.get_address(); -} - -template -class RefPtrGetterAddRefs -/* - ... - - This class is designed to be used for anonymous temporary objects in the - argument list of calls that return COM interface pointers, e.g., - - RefPtr fooP; - ...->GetAddRefedPointer(getter_AddRefs(fooP)) - - DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_AddRefs()| instead. - - When initialized with a |RefPtr|, as in the example above, it returns - a |void**|, a |T**|, or an |nsISupports**| as needed, that the - outer call (|GetAddRefedPointer| in this case) can fill in. - - This type should be a nested class inside |RefPtr|. -*/ -{ -public: - explicit - RefPtrGetterAddRefs(RefPtr& aSmartPtr) - : mTargetSmartPtr(aSmartPtr) - { - // nothing else to do - } - - operator void**() - { - return reinterpret_cast(mTargetSmartPtr.StartAssignment()); - } - - operator T**() - { - return mTargetSmartPtr.StartAssignment(); - } - - T*& - operator*() - { - return *(mTargetSmartPtr.StartAssignment()); - } - -private: - RefPtr& mTargetSmartPtr; -}; - -template -inline RefPtrGetterAddRefs -getter_AddRefs(RefPtr& aSmartPtr) -/* - Used around a |RefPtr| when - ...makes the class |RefPtrGetterAddRefs| invisible. -*/ -{ - return RefPtrGetterAddRefs(aSmartPtr); -} - - -// Comparing two |RefPtr|s - -template -inline bool -operator==(const RefPtr& aLhs, const RefPtr& aRhs) -{ - return static_cast(aLhs.get()) == static_cast(aRhs.get()); -} - - -template -inline bool -operator!=(const RefPtr& aLhs, const RefPtr& aRhs) -{ - return static_cast(aLhs.get()) != static_cast(aRhs.get()); -} - - -// Comparing an |RefPtr| to a raw pointer - -template -inline bool -operator==(const RefPtr& aLhs, const U* aRhs) -{ - return static_cast(aLhs.get()) == static_cast(aRhs); -} - -template -inline bool -operator==(const U* aLhs, const RefPtr& aRhs) -{ - return static_cast(aLhs) == static_cast(aRhs.get()); -} - -template -inline bool -operator!=(const RefPtr& aLhs, const U* aRhs) -{ - return static_cast(aLhs.get()) != static_cast(aRhs); -} - -template -inline bool -operator!=(const U* aLhs, const RefPtr& aRhs) -{ - return static_cast(aLhs) != static_cast(aRhs.get()); -} - -template -inline bool -operator==(const RefPtr& aLhs, U* aRhs) -{ - return static_cast(aLhs.get()) == const_cast(aRhs); -} - -template -inline bool -operator==(U* aLhs, const RefPtr& aRhs) -{ - return const_cast(aLhs) == static_cast(aRhs.get()); -} - -template -inline bool -operator!=(const RefPtr& aLhs, U* aRhs) -{ - return static_cast(aLhs.get()) != const_cast(aRhs); -} - -template -inline bool -operator!=(U* aLhs, const RefPtr& aRhs) -{ - return const_cast(aLhs) != static_cast(aRhs.get()); -} - -// Comparing an |RefPtr| to |nullptr| - -template -inline bool -operator==(const RefPtr& aLhs, decltype(nullptr)) -{ - return aLhs.get() == nullptr; -} - -template -inline bool -operator==(decltype(nullptr), const RefPtr& aRhs) -{ - return nullptr == aRhs.get(); -} - -template -inline bool -operator!=(const RefPtr& aLhs, decltype(nullptr)) -{ - return aLhs.get() != nullptr; -} - -template -inline bool -operator!=(decltype(nullptr), const RefPtr& aRhs) -{ - return nullptr != aRhs.get(); -} - -/*****************************************************************************/ - -template -inline already_AddRefed -do_AddRef(T* aObj) -{ - RefPtr ref(aObj); - return ref.forget(); -} - -template -inline already_AddRefed -do_AddRef(const RefPtr& aObj) -{ - RefPtr ref(aObj); - return ref.forget(); -} - -namespace mozilla { - -/** - * Helper function to be able to conveniently write things like: - * - * already_AddRefed - * f(...) - * { - * return MakeAndAddRef(...); - * } - */ -template -already_AddRefed -MakeAndAddRef(Args&&... aArgs) -{ - RefPtr p(new T(Forward(aArgs)...)); - return p.forget(); -} - -} // namespace mozilla - -#endif /* mozilla_RefPtr_h */ diff --git a/android/x86/include/spidermonkey/mozilla/ReverseIterator.h b/android/x86/include/spidermonkey/mozilla/ReverseIterator.h deleted file mode 100644 index 49c2e279..00000000 --- a/android/x86/include/spidermonkey/mozilla/ReverseIterator.h +++ /dev/null @@ -1,168 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* An iterator that acts like another iterator, but iterating in - * the negative direction. (Note that not all iterators can iterate - * in the negative direction.) */ - -#ifndef mozilla_ReverseIterator_h -#define mozilla_ReverseIterator_h - -#include "mozilla/Attributes.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -template -class ReverseIterator -{ -public: - template - explicit ReverseIterator(Iterator aIter) - : mCurrent(aIter) { } - - template - MOZ_IMPLICIT ReverseIterator(const ReverseIterator& aOther) - : mCurrent(aOther.mCurrent) { } - - decltype(*DeclVal()) operator*() const - { - IteratorT tmp = mCurrent; - return *--tmp; - } - - /* Increments and decrements operators */ - - ReverseIterator& operator++() { --mCurrent; return *this; } - ReverseIterator& operator--() { ++mCurrent; return *this; } - ReverseIterator operator++(int) { auto ret = *this; mCurrent--; return ret; } - ReverseIterator operator--(int) { auto ret = *this; mCurrent++; return ret; } - - /* Comparison operators */ - - template - friend bool operator==(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - template - friend bool operator!=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - template - friend bool operator<(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - template - friend bool operator<=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - template - friend bool operator>(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - template - friend bool operator>=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2); - -private: - IteratorT mCurrent; -}; - -template -bool -operator==(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent == aIter2.mCurrent; -} - -template -bool -operator!=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent != aIter2.mCurrent; -} - -template -bool -operator<(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent > aIter2.mCurrent; -} - -template -bool -operator<=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent >= aIter2.mCurrent; -} - -template -bool -operator>(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent < aIter2.mCurrent; -} - -template -bool -operator>=(const ReverseIterator& aIter1, - const ReverseIterator& aIter2) -{ - return aIter1.mCurrent <= aIter2.mCurrent; -} - -namespace detail { - -template -class IteratorRange -{ -public: - typedef IteratorT iterator; - typedef IteratorT const_iterator; - typedef ReverseIterator reverse_iterator; - typedef ReverseIterator const_reverse_iterator; - - template - MOZ_IMPLICIT IteratorRange(Iterator1 aIterBegin, Iterator2 aIterEnd) - : mIterBegin(aIterBegin), mIterEnd(aIterEnd) { } - - template - MOZ_IMPLICIT IteratorRange(const IteratorRange& aOther) - : mIterBegin(aOther.mIterBegin), mIterEnd(aOther.mIterEnd) { } - - iterator begin() const { return mIterBegin; } - const_iterator cbegin() const { return begin(); } - iterator end() const { return mIterEnd; } - const_iterator cend() const { return end(); } - reverse_iterator rbegin() const { return reverse_iterator(mIterEnd); } - const_reverse_iterator crbegin() const { return rbegin(); } - reverse_iterator rend() const { return reverse_iterator(mIterBegin); } - const_reverse_iterator crend() const { return rend(); } - -private: - IteratorT mIterBegin; - IteratorT mIterEnd; -}; - -} // namespace detail - -template -detail::IteratorRange -Reversed(Range& aRange) -{ - return {aRange.rbegin(), aRange.rend()}; -} - -template -detail::IteratorRange -Reversed(const Range& aRange) -{ - return {aRange.rbegin(), aRange.rend()}; -} - -} // namespace mozilla - -#endif // mozilla_ReverseIterator_h diff --git a/android/x86/include/spidermonkey/mozilla/RollingMean.h b/android/x86/include/spidermonkey/mozilla/RollingMean.h deleted file mode 100644 index 8cc3148e..00000000 --- a/android/x86/include/spidermonkey/mozilla/RollingMean.h +++ /dev/null @@ -1,115 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A set abstraction for enumeration values. */ - -#ifndef mozilla_RollingMean_h_ -#define mozilla_RollingMean_h_ - -#include "mozilla/Assertions.h" -#include "mozilla/TypeTraits.h" -#include "mozilla/Vector.h" - -#include - -namespace mozilla { - -/** - * RollingMean calculates a rolling mean of the values it is given. It - * accumulates the total as values are added and removed. The second type - * argument S specifies the type of the total. This may need to be a bigger - * type in order to maintain that the sum of all values in the average doesn't - * exceed the maximum input value. - * - * WARNING: Float types are not supported due to rounding errors. - */ -template -class RollingMean -{ -private: - size_t mInsertIndex; - size_t mMaxValues; - Vector mValues; - S mTotal; - -public: - static_assert(!IsFloatingPoint::value, - "floating-point types are unsupported due to rounding " - "errors"); - - explicit RollingMean(size_t aMaxValues) - : mInsertIndex(0), - mMaxValues(aMaxValues), - mTotal(0) - { - MOZ_ASSERT(aMaxValues > 0); - } - - RollingMean& operator=(RollingMean&& aOther) - { - MOZ_ASSERT(this != &aOther, "self-assignment is forbidden"); - this->~RollingMean(); - new(this) RollingMean(aOther.mMaxValues); - mInsertIndex = aOther.mInsertIndex; - mTotal = aOther.mTotal; - mValues.swap(aOther.mValues); - return *this; - } - - /** - * Insert a value into the rolling mean. - */ - bool insert(T aValue) - { - MOZ_ASSERT(mValues.length() <= mMaxValues); - - if (mValues.length() == mMaxValues) { - mTotal = mTotal - mValues[mInsertIndex] + aValue; - mValues[mInsertIndex] = aValue; - } else { - if (!mValues.append(aValue)) { - return false; - } - mTotal = mTotal + aValue; - } - - mInsertIndex = (mInsertIndex + 1) % mMaxValues; - return true; - } - - /** - * Calculate the rolling mean. - */ - T mean() - { - MOZ_ASSERT(!empty()); - return T(mTotal / int64_t(mValues.length())); - } - - bool empty() - { - return mValues.empty(); - } - - /** - * Remove all values from the rolling mean. - */ - void clear() - { - mValues.clear(); - mInsertIndex = 0; - mTotal = T(0); - } - - size_t maxValues() - { - return mMaxValues; - } -}; - -} // namespace mozilla - -#endif // mozilla_RollingMean_h_ diff --git a/android/x86/include/spidermonkey/mozilla/SHA1.h b/android/x86/include/spidermonkey/mozilla/SHA1.h deleted file mode 100644 index ddccaa67..00000000 --- a/android/x86/include/spidermonkey/mozilla/SHA1.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Simple class for computing SHA1. */ - -#ifndef mozilla_SHA1_h -#define mozilla_SHA1_h - -#include "mozilla/Types.h" - -#include -#include - -namespace mozilla { - -/** - * This class computes the SHA1 hash of a byte sequence, or of the concatenation - * of multiple sequences. For example, computing the SHA1 of two sequences of - * bytes could be done as follows: - * - * void SHA1(const uint8_t* buf1, uint32_t size1, - * const uint8_t* buf2, uint32_t size2, - * SHA1Sum::Hash& hash) - * { - * SHA1Sum s; - * s.update(buf1, size1); - * s.update(buf2, size2); - * s.finish(hash); - * } - * - * The finish method may only be called once and cannot be followed by calls - * to update. - */ -class SHA1Sum -{ - union - { - uint32_t mW[16]; /* input buffer */ - uint8_t mB[64]; - } mU; - uint64_t mSize; /* count of hashed bytes. */ - unsigned mH[22]; /* 5 state variables, 16 tmp values, 1 extra */ - bool mDone; - -public: - MFBT_API SHA1Sum(); - - static const size_t kHashSize = 20; - typedef uint8_t Hash[kHashSize]; - - /* Add len bytes of dataIn to the data sequence being hashed. */ - MFBT_API void update(const void* aData, uint32_t aLength); - - /* Compute the final hash of all data into hashOut. */ - MFBT_API void finish(SHA1Sum::Hash& aHashOut); -}; - -} /* namespace mozilla */ - -#endif /* mozilla_SHA1_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Saturate.h b/android/x86/include/spidermonkey/mozilla/Saturate.h deleted file mode 100644 index b79364d2..00000000 --- a/android/x86/include/spidermonkey/mozilla/Saturate.h +++ /dev/null @@ -1,288 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Provides saturation arithmetics for scalar types. */ - -#ifndef mozilla_Saturate_h -#define mozilla_Saturate_h - -#include "mozilla/Attributes.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -#include - -namespace mozilla { -namespace detail { - -/** - * |SaturateOp| wraps scalar values for saturation arithmetics. Usage: - * - * uint32_t value = 1; - * - * ++SaturateOp(value); // value is 2 - * --SaturateOp(value); // value is 1 - * --SaturateOp(value); // value is 0 - * --SaturateOp(value); // value is still 0 - * - * Please add new operators when required. - * - * |SaturateOp| will saturate at the minimum and maximum values of - * type T. If you need other bounds, implement a clamped-type class and - * specialize the type traits accordingly. - */ -template -class SaturateOp -{ -public: - explicit SaturateOp(T& aValue) - : mValue(aValue) - { - // We should actually check for |std::is_scalar::value| to be - // true, but this type trait is not available everywhere. Relax - // this assertion if you want to use floating point values as well. - static_assert(IsIntegral::value, - "Integral type required in instantiation"); - } - - // Add and subtract operators - - T operator+(const T& aRhs) const - { - return T(mValue) += aRhs; - } - - T operator-(const T& aRhs) const - { - return T(mValue) -= aRhs; - } - - // Compound operators - - const T& operator+=(const T& aRhs) const - { - const T min = std::numeric_limits::min(); - const T max = std::numeric_limits::max(); - - if (aRhs > static_cast(0)) { - mValue = (max - aRhs) < mValue ? max : mValue + aRhs; - } else { - mValue = (min - aRhs) > mValue ? min : mValue + aRhs; - } - return mValue; - } - - const T& operator-=(const T& aRhs) const - { - const T min = std::numeric_limits::min(); - const T max = std::numeric_limits::max(); - - if (aRhs > static_cast(0)) { - mValue = (min + aRhs) > mValue ? min : mValue - aRhs; - } else { - mValue = (max + aRhs) < mValue ? max : mValue - aRhs; - } - return mValue; - } - - // Increment and decrement operators - - const T& operator++() const // prefix - { - return operator+=(static_cast(1)); - } - - T operator++(int) const // postfix - { - const T value(mValue); - operator++(); - return value; - } - - const T& operator--() const // prefix - { - return operator-=(static_cast(1)); - } - - T operator--(int) const // postfix - { - const T value(mValue); - operator--(); - return value; - } - -private: - SaturateOp(const SaturateOp&) = delete; - SaturateOp(SaturateOp&&) = delete; - SaturateOp& operator=(const SaturateOp&) = delete; - SaturateOp& operator=(SaturateOp&&) = delete; - - T& mValue; -}; - -/** - * |Saturate| is a value type for saturation arithmetics. It's - * build on top of |SaturateOp|. - */ -template -class Saturate -{ -public: - Saturate() = default; - MOZ_IMPLICIT Saturate(const Saturate&) = default; - - MOZ_IMPLICIT Saturate(Saturate&& aValue) - { - mValue = Move(aValue.mValue); - } - - explicit Saturate(const T& aValue) - : mValue(aValue) - { } - - const T& value() const - { - return mValue; - } - - // Compare operators - - bool operator==(const Saturate& aRhs) const - { - return mValue == aRhs.mValue; - } - - bool operator!=(const Saturate& aRhs) const - { - return !operator==(aRhs); - } - - bool operator==(const T& aRhs) const - { - return mValue == aRhs; - } - - bool operator!=(const T& aRhs) const - { - return !operator==(aRhs); - } - - // Assignment operators - - Saturate& operator=(const Saturate&) = default; - - Saturate& operator=(Saturate&& aRhs) - { - mValue = Move(aRhs.mValue); - return *this; - } - - // Add and subtract operators - - Saturate operator+(const Saturate& aRhs) const - { - Saturate lhs(mValue); - return lhs += aRhs.mValue; - } - - Saturate operator+(const T& aRhs) const - { - Saturate lhs(mValue); - return lhs += aRhs; - } - - Saturate operator-(const Saturate& aRhs) const - { - Saturate lhs(mValue); - return lhs -= aRhs.mValue; - } - - Saturate operator-(const T& aRhs) const - { - Saturate lhs(mValue); - return lhs -= aRhs; - } - - // Compound operators - - Saturate& operator+=(const Saturate& aRhs) - { - SaturateOp(mValue) += aRhs.mValue; - return *this; - } - - Saturate& operator+=(const T& aRhs) - { - SaturateOp(mValue) += aRhs; - return *this; - } - - Saturate& operator-=(const Saturate& aRhs) - { - SaturateOp(mValue) -= aRhs.mValue; - return *this; - } - - Saturate& operator-=(const T& aRhs) - { - SaturateOp(mValue) -= aRhs; - return *this; - } - - // Increment and decrement operators - - Saturate& operator++() // prefix - { - ++SaturateOp(mValue); - return *this; - } - - Saturate operator++(int) // postfix - { - return Saturate(SaturateOp(mValue)++); - } - - Saturate& operator--() // prefix - { - --SaturateOp(mValue); - return *this; - } - - Saturate operator--(int) // postfix - { - return Saturate(SaturateOp(mValue)--); - } - -private: - T mValue; -}; - -} // namespace detail - -typedef detail::Saturate SaturateInt8; -typedef detail::Saturate SaturateInt16; -typedef detail::Saturate SaturateInt32; -typedef detail::Saturate SaturateUint8; -typedef detail::Saturate SaturateUint16; -typedef detail::Saturate SaturateUint32; - -} // namespace mozilla - -template -bool -operator==(LhsT aLhs, const mozilla::detail::Saturate& aRhs) -{ - return aRhs.operator==(static_cast(aLhs)); -} - -template -bool -operator!=(LhsT aLhs, const mozilla::detail::Saturate& aRhs) -{ - return !(aLhs == aRhs); -} - -#endif // mozilla_Saturate_h diff --git a/android/x86/include/spidermonkey/mozilla/ScopeExit.h b/android/x86/include/spidermonkey/mozilla/ScopeExit.h deleted file mode 100644 index 7aff82d8..00000000 --- a/android/x86/include/spidermonkey/mozilla/ScopeExit.h +++ /dev/null @@ -1,135 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* RAII class for executing arbitrary actions at scope end. */ - -#ifndef mozilla_ScopeExit_h -#define mozilla_ScopeExit_h - -/* - * See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4189.pdf for a - * standards-track version of this. - * - * Error handling can be complex when various actions need to be performed that - * need to be undone if an error occurs midway. This can be handled with a - * collection of boolean state variables and gotos, which can get clunky and - * error-prone: - * - * { - * if (!a.setup()) - * goto fail; - * isASetup = true; - * - * if (!b.setup()) - * goto fail; - * isBSetup = true; - * - * ... - * return true; - * - * fail: - * if (isASetup) - * a.teardown(); - * if (isBSetup) - * b.teardown(); - * return false; - * } - * - * ScopeExit is a mechanism to simplify this pattern by keeping an RAII guard - * class that will perform the teardown on destruction, unless released. So the - * above would become: - * - * { - * if (!a.setup()) { - * return false; - * } - * auto guardA = MakeScopeExit([&] { - * a.teardown(); - * }); - * - * if (!b.setup()) { - * return false; - * } - * auto guardB = MakeScopeExit([&] { - * b.teardown(); - * }); - * - * ... - * guardA.release(); - * guardB.release(); - * return true; - * } - * - * This header provides: - * - * - |ScopeExit| - a container for a cleanup call, automically called at the - * end of the scope; - * - |MakeScopeExit| - a convenience function for constructing a |ScopeExit| - * with a given cleanup routine, commonly used with a lambda function. - * - * Note that the RAII classes defined in this header do _not_ perform any form - * of reference-counting or garbage-collection. These classes have exactly two - * behaviors: - * - * - if |release()| has not been called, the cleanup is always performed at - * the end of the scope; - * - if |release()| has been called, nothing will happen at the end of the - * scope. - */ - -#include "mozilla/GuardObjects.h" -#include "mozilla/Move.h" - -namespace mozilla { - -template -class MOZ_STACK_CLASS ScopeExit { - ExitFunction mExitFunction; - bool mExecuteOnDestruction; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - -public: - explicit ScopeExit(ExitFunction&& cleanup - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mExitFunction(cleanup) - , mExecuteOnDestruction(true) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - ScopeExit(ScopeExit&& rhs) - : mExitFunction(mozilla::Move(rhs.mExitFunction)) - , mExecuteOnDestruction(rhs.mExecuteOnDestruction) - { - rhs.release(); - } - - ~ScopeExit() { - if (mExecuteOnDestruction) { - mExitFunction(); - } - } - - void release() { - mExecuteOnDestruction = false; - } - -private: - explicit ScopeExit(const ScopeExit&) = delete; - ScopeExit& operator=(const ScopeExit&) = delete; - ScopeExit& operator=(ScopeExit&&) = delete; -}; - -template -ScopeExit -MakeScopeExit(ExitFunction&& exitFunction) -{ - return ScopeExit(mozilla::Move(exitFunction)); -} - -} /* namespace mozilla */ - -#endif /* mozilla_ScopeExit_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Scoped.h b/android/x86/include/spidermonkey/mozilla/Scoped.h deleted file mode 100644 index c935434a..00000000 --- a/android/x86/include/spidermonkey/mozilla/Scoped.h +++ /dev/null @@ -1,255 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* DEPRECATED: Use UniquePtr.h instead. */ - -#ifndef mozilla_Scoped_h -#define mozilla_Scoped_h - -/* - * DEPRECATED: Use UniquePtr.h instead. - * - * Resource Acquisition Is Initialization is a programming idiom used - * to write robust code that is able to deallocate resources properly, - * even in presence of execution errors or exceptions that need to be - * propagated. The Scoped* classes defined via the |SCOPED_TEMPLATE| - * and |MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLTE| macros perform the - * deallocation of the resource they hold once program execution - * reaches the end of the scope for which they have been defined. - * These macros have been used to automatically close file - * descriptors/file handles when reaching the end of the scope, - * graphics contexts, etc. - * - * The general scenario for RAII classes created by the above macros - * is the following: - * - * ScopedClass foo(create_value()); - * // ... In this scope, |foo| is defined. Use |foo.get()| or |foo.rwget()| - * to access the value. - * // ... In case of |return| or |throw|, |foo| is deallocated automatically. - * // ... If |foo| needs to be returned or stored, use |foo.forget()| - * - * Note that the RAII classes defined in this header do _not_ perform any form - * of reference-counting or garbage-collection. These classes have exactly two - * behaviors: - * - * - if |forget()| has not been called, the resource is always deallocated at - * the end of the scope; - * - if |forget()| has been called, any control on the resource is unbound - * and the resource is not deallocated by the class. - */ - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/GuardObjects.h" -#include "mozilla/Move.h" - -namespace mozilla { - -/* - * Scoped is a helper to create RAII wrappers - * Type argument |Traits| is expected to have the following structure: - * - * struct Traits - * { - * // Define the type of the value stored in the wrapper - * typedef value_type type; - * // Returns the value corresponding to the uninitialized or freed state - * const static type empty(); - * // Release resources corresponding to the wrapped value - * // This function is responsible for not releasing an |empty| value - * const static void release(type); - * } - */ -template -class MOZ_NON_TEMPORARY_CLASS Scoped -{ -public: - typedef typename Traits::type Resource; - - explicit Scoped(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) - : mValue(Traits::empty()) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - explicit Scoped(const Resource& aValue - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mValue(aValue) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - /* Move constructor. */ - Scoped(Scoped&& aOther - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mValue(Move(aOther.mValue)) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - aOther.mValue = Traits::empty(); - } - - ~Scoped() { Traits::release(mValue); } - - // Constant getter - operator const Resource&() const { return mValue; } - const Resource& operator->() const { return mValue; } - const Resource& get() const { return mValue; } - // Non-constant getter. - Resource& rwget() { return mValue; } - - /* - * Forget the resource. - * - * Once |forget| has been called, the |Scoped| is neutralized, i.e. it will - * have no effect at destruction (unless it is reset to another resource by - * |operator=|). - * - * @return The original resource. - */ - Resource forget() - { - Resource tmp = mValue; - mValue = Traits::empty(); - return tmp; - } - - /* - * Perform immediate clean-up of this |Scoped|. - * - * If this |Scoped| is currently empty, this method has no effect. - */ - void dispose() - { - Traits::release(mValue); - mValue = Traits::empty(); - } - - bool operator==(const Resource& aOther) const { return mValue == aOther; } - - /* - * Replace the resource with another resource. - * - * Calling |operator=| has the side-effect of triggering clean-up. If you do - * not want to trigger clean-up, you should first invoke |forget|. - * - * @return this - */ - Scoped& operator=(const Resource& aOther) { return reset(aOther); } - - Scoped& reset(const Resource& aOther) - { - Traits::release(mValue); - mValue = aOther; - return *this; - } - - /* Move assignment operator. */ - Scoped& operator=(Scoped&& aRhs) - { - MOZ_ASSERT(&aRhs != this, "self-move-assignment not allowed"); - this->~Scoped(); - new(this) Scoped(Move(aRhs)); - return *this; - } - -private: - explicit Scoped(const Scoped& aValue) = delete; - Scoped& operator=(const Scoped& aValue) = delete; - -private: - Resource mValue; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -/* - * SCOPED_TEMPLATE defines a templated class derived from Scoped - * This allows to implement templates such as ScopedFreePtr. - * - * @param name The name of the class to define. - * @param Traits A struct implementing clean-up. See the implementations - * for more details. - */ -#define SCOPED_TEMPLATE(name, Traits) \ -template \ -struct MOZ_NON_TEMPORARY_CLASS name : public mozilla::Scoped > \ -{ \ - typedef mozilla::Scoped > Super; \ - typedef typename Super::Resource Resource; \ - name& operator=(Resource aRhs) \ - { \ - Super::operator=(aRhs); \ - return *this; \ - } \ - name& operator=(name&& aRhs) \ - { \ - Super::operator=(Move(aRhs)); \ - return *this; \ - } \ - explicit name(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) \ - : Super(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT) \ - {} \ - explicit name(Resource aRhs \ - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \ - : Super(aRhs \ - MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \ - {} \ - name(name&& aRhs \ - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \ - : Super(Move(aRhs) \ - MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \ - {} \ -private: \ - explicit name(name&) = delete; \ - name& operator=(name&) = delete; \ -}; - -/* - * MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE makes it easy to create scoped - * pointers for types with custom deleters; just overload - * TypeSpecificDelete(T*) in the same namespace as T to call the deleter for - * type T. - * - * @param name The name of the class to define. - * @param Type A struct implementing clean-up. See the implementations - * for more details. - * *param Deleter The function that is used to delete/destroy/free a - * non-null value of Type*. - * - * Example: - * - * MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRFileDesc, PRFileDesc, \ - * PR_Close) - * ... - * { - * ScopedPRFileDesc file(PR_OpenFile(...)); - * ... - * } // file is closed with PR_Close here - */ -#define MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(name, Type, Deleter) \ -template <> inline void TypeSpecificDelete(Type* aValue) { Deleter(aValue); } \ -typedef ::mozilla::TypeSpecificScopedPointer name; - -template void TypeSpecificDelete(T* aValue); - -template -struct TypeSpecificScopedPointerTraits -{ - typedef T* type; - static type empty() { return nullptr; } - static void release(type aValue) - { - if (aValue) { - TypeSpecificDelete(aValue); - } - } -}; - -SCOPED_TEMPLATE(TypeSpecificScopedPointer, TypeSpecificScopedPointerTraits) - -} /* namespace mozilla */ - -#endif /* mozilla_Scoped_h */ diff --git a/android/x86/include/spidermonkey/mozilla/SegmentedVector.h b/android/x86/include/spidermonkey/mozilla/SegmentedVector.h deleted file mode 100644 index 1bf60e46..00000000 --- a/android/x86/include/spidermonkey/mozilla/SegmentedVector.h +++ /dev/null @@ -1,339 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -// A simple segmented vector class. -// -// This class should be used in preference to mozilla::Vector or nsTArray when -// you are simply gathering items in order to later iterate over them. -// -// - In the case where you don't know the final size in advance, using -// SegmentedVector avoids the need to repeatedly allocate increasingly large -// buffers and copy the data into them. -// -// - In the case where you know the final size in advance and so can set the -// capacity appropriately, using SegmentedVector still avoids the need for -// large allocations (which can trigger OOMs). - -#ifndef mozilla_SegmentedVector_h -#define mozilla_SegmentedVector_h - -#include "mozilla/Alignment.h" -#include "mozilla/AllocPolicy.h" -#include "mozilla/Array.h" -#include "mozilla/LinkedList.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -#include // for placement new - -namespace mozilla { - -// |IdealSegmentSize| specifies how big each segment will be in bytes (or as -// close as is possible). Use the following guidelines to choose a size. -// -// - It should be a power-of-two, to avoid slop. -// -// - It should not be too small, so that segment allocations are infrequent, -// and so that per-segment bookkeeping overhead is low. Typically each -// segment should be able to hold hundreds of elements, at least. -// -// - It should not be too large, so that OOMs are unlikely when allocating -// segments, and so that not too much space is wasted when the final segment -// is not full. -// -// The ideal size depends on how the SegmentedVector is used and the size of -// |T|, but reasonable sizes include 1024, 4096 (the default), 8192, and 16384. -// -template -class SegmentedVector : private AllocPolicy -{ - template - struct SegmentImpl - : public mozilla::LinkedListElement> - { - SegmentImpl() : mLength(0) {} - - ~SegmentImpl() - { - for (uint32_t i = 0; i < mLength; i++) { - (*this)[i].~T(); - } - } - - uint32_t Length() const { return mLength; } - - T* Elems() { return reinterpret_cast(&mStorage.mBuf); } - - T& operator[](size_t aIndex) - { - MOZ_ASSERT(aIndex < mLength); - return Elems()[aIndex]; - } - - const T& operator[](size_t aIndex) const - { - MOZ_ASSERT(aIndex < mLength); - return Elems()[aIndex]; - } - - template - void Append(U&& aU) - { - MOZ_ASSERT(mLength < SegmentCapacity); - // Pre-increment mLength so that the bounds-check in operator[] passes. - mLength++; - T* elem = &(*this)[mLength - 1]; - new (elem) T(mozilla::Forward(aU)); - } - - void PopLast() - { - MOZ_ASSERT(mLength > 0); - (*this)[mLength - 1].~T(); - mLength--; - } - - uint32_t mLength; - - // The union ensures that the elements are appropriately aligned. - union Storage - { - char mBuf[sizeof(T) * SegmentCapacity]; - mozilla::AlignedElem mAlign; - } mStorage; - - static_assert(MOZ_ALIGNOF(T) == MOZ_ALIGNOF(Storage), - "SegmentedVector provides incorrect alignment"); - }; - - // See how many we elements we can fit in a segment of IdealSegmentSize. If - // IdealSegmentSize is too small, it'll be just one. The +1 is because - // kSingleElementSegmentSize already accounts for one element. - static const size_t kSingleElementSegmentSize = sizeof(SegmentImpl<1>); - static const size_t kSegmentCapacity = - kSingleElementSegmentSize <= IdealSegmentSize - ? (IdealSegmentSize - kSingleElementSegmentSize) / sizeof(T) + 1 - : 1; - - typedef SegmentImpl Segment; - -public: - // The |aIdealSegmentSize| is only for sanity checking. If it's specified, we - // check that the actual segment size is as close as possible to it. This - // serves as a sanity check for SegmentedVectorCapacity's capacity - // computation. - explicit SegmentedVector(size_t aIdealSegmentSize = 0) - { - // The difference between the actual segment size and the ideal segment - // size should be less than the size of a single element... unless the - // ideal size was too small, in which case the capacity should be one. - MOZ_ASSERT_IF( - aIdealSegmentSize != 0, - (sizeof(Segment) > aIdealSegmentSize && kSegmentCapacity == 1) || - aIdealSegmentSize - sizeof(Segment) < sizeof(T)); - } - - ~SegmentedVector() { Clear(); } - - bool IsEmpty() const { return !mSegments.getFirst(); } - - // Note that this is O(n) rather than O(1), but the constant factor is very - // small because it only has to do one addition per segment. - size_t Length() const - { - size_t n = 0; - for (auto segment = mSegments.getFirst(); - segment; - segment = segment->getNext()) { - n += segment->Length(); - } - return n; - } - - // Returns false if the allocation failed. (If you are using an infallible - // allocation policy, use InfallibleAppend() instead.) - template - MOZ_MUST_USE bool Append(U&& aU) - { - Segment* last = mSegments.getLast(); - if (!last || last->Length() == kSegmentCapacity) { - last = this->template pod_malloc(1); - if (!last) { - return false; - } - new (last) Segment(); - mSegments.insertBack(last); - } - last->Append(mozilla::Forward(aU)); - return true; - } - - // You should probably only use this instead of Append() if you are using an - // infallible allocation policy. It will crash if the allocation fails. - template - void InfallibleAppend(U&& aU) - { - bool ok = Append(mozilla::Forward(aU)); - MOZ_RELEASE_ASSERT(ok); - } - - void Clear() - { - Segment* segment; - while ((segment = mSegments.popFirst())) { - segment->~Segment(); - this->free_(segment); - } - } - - T& GetLast() - { - MOZ_ASSERT(!IsEmpty()); - Segment* last = mSegments.getLast(); - return (*last)[last->Length() - 1]; - } - - const T& GetLast() const - { - MOZ_ASSERT(!IsEmpty()); - Segment* last = mSegments.getLast(); - return (*last)[last->Length() - 1]; - } - - void PopLast() - { - MOZ_ASSERT(!IsEmpty()); - Segment* last = mSegments.getLast(); - last->PopLast(); - if (!last->Length()) { - mSegments.popLast(); - last->~Segment(); - this->free_(last); - } - } - - // Equivalent to calling |PopLast| |aNumElements| times, but potentially - // more efficient. - void PopLastN(uint32_t aNumElements) - { - MOZ_ASSERT(aNumElements <= Length()); - - Segment* last; - - // Pop full segments for as long as we can. Note that this loop - // cleanly handles the case when the initial last segment is not - // full and we are popping more elements than said segment contains. - do { - last = mSegments.getLast(); - - // The list is empty. We're all done. - if (!last) { - return; - } - - // Check to see if the list contains too many elements. Handle - // that in the epilogue. - uint32_t segmentLen = last->Length(); - if (segmentLen > aNumElements) { - break; - } - - // Destroying the segment destroys all elements contained therein. - mSegments.popLast(); - last->~Segment(); - this->free_(last); - - MOZ_ASSERT(aNumElements >= segmentLen); - aNumElements -= segmentLen; - if (aNumElements == 0) { - return; - } - } while (true); - - // Handle the case where the last segment contains more elements - // than we want to pop. - MOZ_ASSERT(last); - MOZ_ASSERT(last == mSegments.getLast()); - MOZ_ASSERT(aNumElements != 0); - MOZ_ASSERT(aNumElements < last->Length()); - for (uint32_t i = 0; i < aNumElements; ++i) { - last->PopLast(); - } - MOZ_ASSERT(last->Length() != 0); - } - - // Use this class to iterate over a SegmentedVector, like so: - // - // for (auto iter = v.Iter(); !iter.Done(); iter.Next()) { - // MyElem& elem = iter.Get(); - // f(elem); - // } - // - class IterImpl - { - friend class SegmentedVector; - - Segment* mSegment; - size_t mIndex; - - explicit IterImpl(SegmentedVector* aVector) - : mSegment(aVector->mSegments.getFirst()) - , mIndex(0) - {} - - public: - bool Done() const { return !mSegment; } - - T& Get() - { - MOZ_ASSERT(!Done()); - return (*mSegment)[mIndex]; - } - - const T& Get() const - { - MOZ_ASSERT(!Done()); - return (*mSegment)[mIndex]; - } - - void Next() - { - MOZ_ASSERT(!Done()); - mIndex++; - if (mIndex == mSegment->Length()) { - mSegment = mSegment->getNext(); - mIndex = 0; - } - } - }; - - IterImpl Iter() { return IterImpl(this); } - - // Measure the memory consumption of the vector excluding |this|. Note that - // it only measures the vector itself. If the vector elements contain - // pointers to other memory blocks, those blocks must be measured separately - // during a subsequent iteration over the vector. - size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const - { - return mSegments.sizeOfExcludingThis(aMallocSizeOf); - } - - // Like sizeOfExcludingThis(), but measures |this| as well. - size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const - { - return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); - } - -private: - mozilla::LinkedList mSegments; -}; - -} // namespace mozilla - -#endif /* mozilla_SegmentedVector_h */ diff --git a/android/x86/include/spidermonkey/mozilla/SizePrintfMacros.h b/android/x86/include/spidermonkey/mozilla/SizePrintfMacros.h deleted file mode 100644 index ec55c62c..00000000 --- a/android/x86/include/spidermonkey/mozilla/SizePrintfMacros.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Implements (nonstandard) PRI{ouxX}SIZE format macros for size_t types. */ - -#ifndef mozilla_SizePrintfMacros_h_ -#define mozilla_SizePrintfMacros_h_ - -/* - * MSVC's libc does not support C99's %z format length modifier for size_t - * types. Instead, we use Microsoft's nonstandard %I modifier for size_t, which - * is unsigned __int32 on 32-bit platforms and unsigned __int64 on 64-bit - * platforms: - * - * http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx - */ - -#if defined(XP_WIN) -# define PRIoSIZE "Io" -# define PRIuSIZE "Iu" -# define PRIxSIZE "Ix" -# define PRIXSIZE "IX" -#else -# define PRIoSIZE "zo" -# define PRIuSIZE "zu" -# define PRIxSIZE "zx" -# define PRIXSIZE "zX" -#endif - -#endif /* mozilla_SizePrintfMacros_h_ */ diff --git a/android/x86/include/spidermonkey/mozilla/SplayTree.h b/android/x86/include/spidermonkey/mozilla/SplayTree.h deleted file mode 100644 index 2b3b838b..00000000 --- a/android/x86/include/spidermonkey/mozilla/SplayTree.h +++ /dev/null @@ -1,330 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/** - * A sorted tree with optimal access times, where recently-accessed elements - * are faster to access again. - */ - -#ifndef mozilla_SplayTree_h -#define mozilla_SplayTree_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -namespace mozilla { - -template -class SplayTree; - -template -class SplayTreeNode -{ -public: - template - friend class SplayTree; - - SplayTreeNode() - : mLeft(nullptr) - , mRight(nullptr) - , mParent(nullptr) - {} - -private: - T* mLeft; - T* mRight; - T* mParent; -}; - - -/** - * Class which represents a splay tree. - * Splay trees are balanced binary search trees for which search, insert and - * remove are all amortized O(log n), but where accessing a node makes it - * faster to access that node in the future. - * - * T indicates the type of tree elements, Comparator must have a static - * compare(const T&, const T&) method ordering the elements. The compare - * method must be free from side effects. - */ -template -class SplayTree -{ - T* mRoot; - -public: - constexpr SplayTree() - : mRoot(nullptr) - {} - - bool empty() const - { - return !mRoot; - } - - T* find(const T& aValue) - { - if (empty()) { - return nullptr; - } - - T* last = lookup(aValue); - splay(last); - return Comparator::compare(aValue, *last) == 0 ? last : nullptr; - } - - void insert(T* aValue) - { - MOZ_ASSERT(!find(*aValue), "Duplicate elements are not allowed."); - - if (!mRoot) { - mRoot = aValue; - return; - } - T* last = lookup(*aValue); - int cmp = Comparator::compare(*aValue, *last); - - finishInsertion(last, cmp, aValue); - return; - } - - T* findOrInsert(const T& aValue); - - T* remove(const T& aValue) - { - T* last = lookup(aValue); - MOZ_ASSERT(last, "This tree must contain the element being removed."); - MOZ_ASSERT(Comparator::compare(aValue, *last) == 0); - - // Splay the tree so that the item to remove is the root. - splay(last); - MOZ_ASSERT(last == mRoot); - - // Find another node which can be swapped in for the root: either the - // rightmost child of the root's left, or the leftmost child of the - // root's right. - T* swap; - T* swapChild; - if (mRoot->mLeft) { - swap = mRoot->mLeft; - while (swap->mRight) { - swap = swap->mRight; - } - swapChild = swap->mLeft; - } else if (mRoot->mRight) { - swap = mRoot->mRight; - while (swap->mLeft) { - swap = swap->mLeft; - } - swapChild = swap->mRight; - } else { - T* result = mRoot; - mRoot = nullptr; - return result; - } - - // The selected node has at most one child, in swapChild. Detach it - // from the subtree by replacing it with that child. - if (swap == swap->mParent->mLeft) { - swap->mParent->mLeft = swapChild; - } else { - swap->mParent->mRight = swapChild; - } - if (swapChild) { - swapChild->mParent = swap->mParent; - } - - // Make the selected node the new root. - mRoot = swap; - mRoot->mParent = nullptr; - mRoot->mLeft = last->mLeft; - mRoot->mRight = last->mRight; - if (mRoot->mLeft) { - mRoot->mLeft->mParent = mRoot; - } - if (mRoot->mRight) { - mRoot->mRight->mParent = mRoot; - } - - return last; - } - - T* removeMin() - { - MOZ_ASSERT(mRoot, "No min to remove!"); - - T* min = mRoot; - while (min->mLeft) { - min = min->mLeft; - } - return remove(*min); - } - - // For testing purposes only. - void checkCoherency() - { - checkCoherency(mRoot, nullptr); - } - -private: - /** - * Returns the node in this comparing equal to |aValue|, or a node just - * greater or just less than |aValue| if there is no such node. - */ - T* lookup(const T& aValue) - { - MOZ_ASSERT(!empty()); - - T* node = mRoot; - T* parent; - do { - parent = node; - int c = Comparator::compare(aValue, *node); - if (c == 0) { - return node; - } else if (c < 0) { - node = node->mLeft; - } else { - node = node->mRight; - } - } while (node); - return parent; - } - - void finishInsertion(T* aLast, int32_t aCmp, T* aNew) - { - MOZ_ASSERT(aCmp, "Nodes shouldn't be equal!"); - - T** parentPointer = (aCmp < 0) ? &aLast->mLeft : &aLast->mRight; - MOZ_ASSERT(!*parentPointer); - *parentPointer = aNew; - aNew->mParent = aLast; - - splay(aNew); - } - - /** - * Rotate the tree until |node| is at the root of the tree. Performing - * the rotations in this fashion preserves the amortized balancing of - * the tree. - */ - void splay(T* aNode) - { - MOZ_ASSERT(aNode); - - while (aNode != mRoot) { - T* parent = aNode->mParent; - if (parent == mRoot) { - // Zig rotation. - rotate(aNode); - MOZ_ASSERT(aNode == mRoot); - return; - } - T* grandparent = parent->mParent; - if ((parent->mLeft == aNode) == (grandparent->mLeft == parent)) { - // Zig-zig rotation. - rotate(parent); - rotate(aNode); - } else { - // Zig-zag rotation. - rotate(aNode); - rotate(aNode); - } - } - } - - void rotate(T* aNode) - { - // Rearrange nodes so that aNode becomes the parent of its current - // parent, while preserving the sortedness of the tree. - T* parent = aNode->mParent; - if (parent->mLeft == aNode) { - // x y - // y c ==> a x - // a b b c - parent->mLeft = aNode->mRight; - if (aNode->mRight) { - aNode->mRight->mParent = parent; - } - aNode->mRight = parent; - } else { - MOZ_ASSERT(parent->mRight == aNode); - // x y - // a y ==> x c - // b c a b - parent->mRight = aNode->mLeft; - if (aNode->mLeft) { - aNode->mLeft->mParent = parent; - } - aNode->mLeft = parent; - } - aNode->mParent = parent->mParent; - parent->mParent = aNode; - if (T* grandparent = aNode->mParent) { - if (grandparent->mLeft == parent) { - grandparent->mLeft = aNode; - } else { - grandparent->mRight = aNode; - } - } else { - mRoot = aNode; - } - } - - T* checkCoherency(T* aNode, T* aMinimum) - { - if (mRoot) { - MOZ_RELEASE_ASSERT(!mRoot->mParent); - } - if (!aNode) { - MOZ_RELEASE_ASSERT(!mRoot); - return nullptr; - } - if (!aNode->mParent) { - MOZ_RELEASE_ASSERT(aNode == mRoot); - } - if (aMinimum) { - MOZ_RELEASE_ASSERT(Comparator::compare(*aMinimum, *aNode) < 0); - } - if (aNode->mLeft) { - MOZ_RELEASE_ASSERT(aNode->mLeft->mParent == aNode); - T* leftMaximum = checkCoherency(aNode->mLeft, aMinimum); - MOZ_RELEASE_ASSERT(Comparator::compare(*leftMaximum, *aNode) < 0); - } - if (aNode->mRight) { - MOZ_RELEASE_ASSERT(aNode->mRight->mParent == aNode); - return checkCoherency(aNode->mRight, aNode); - } - return aNode; - } - - SplayTree(const SplayTree&) = delete; - void operator=(const SplayTree&) = delete; -}; - -template -T* -SplayTree::findOrInsert(const T& aValue) -{ - if (!mRoot) { - mRoot = new T(aValue); - return mRoot; - } - - T* last = lookup(aValue); - int cmp = Comparator::compare(aValue, *last); - if (!cmp) { - return last; - } - - T* t = new T(aValue); - finishInsertion(last, cmp, t); - return t; -} - -} /* namespace mozilla */ - -#endif /* mozilla_SplayTree_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Sprintf.h b/android/x86/include/spidermonkey/mozilla/Sprintf.h deleted file mode 100644 index e0be271e..00000000 --- a/android/x86/include/spidermonkey/mozilla/Sprintf.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Provides a safer sprintf for printing to fixed-size character arrays. */ - -#ifndef mozilla_Sprintf_h_ -#define mozilla_Sprintf_h_ - -#include -#include - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -#ifdef __cplusplus - -template -int VsprintfLiteral(char (&buffer)[N], const char* format, va_list args) -{ - MOZ_ASSERT(format != buffer); - int result = vsnprintf(buffer, N, format, args); - buffer[N - 1] = '\0'; - return result; -} - -template -MOZ_FORMAT_PRINTF(2, 3) -int SprintfLiteral(char (&buffer)[N], const char* format, ...) -{ - va_list args; - va_start(args, format); - int result = VsprintfLiteral(buffer, format, args); - va_end(args); - return result; -} - -#endif -#endif /* mozilla_Sprintf_h_ */ diff --git a/android/x86/include/spidermonkey/mozilla/StackWalk.h b/android/x86/include/spidermonkey/mozilla/StackWalk.h deleted file mode 100644 index 534c0bd8..00000000 --- a/android/x86/include/spidermonkey/mozilla/StackWalk.h +++ /dev/null @@ -1,163 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* API for getting a stack trace of the C/C++ stack on the current thread */ - -#ifndef mozilla_StackWalk_h -#define mozilla_StackWalk_h - -/* WARNING: This file is intended to be included from C or C++ files. */ - -#include "mozilla/Types.h" -#include - -/** - * The callback for MozStackWalk. - * - * @param aFrameNumber The frame number (starts at 1, not 0). - * @param aPC The program counter value. - * @param aSP The best approximation possible of what the stack - * pointer will be pointing to when the execution returns - * to executing that at aPC. If no approximation can - * be made it will be nullptr. - * @param aClosure Extra data passed in via MozStackWalk(). - */ -typedef void -(*MozWalkStackCallback)(uint32_t aFrameNumber, void* aPC, void* aSP, - void* aClosure); - -/** - * Call aCallback for the C/C++ stack frames on the current thread, from - * the caller of MozStackWalk to main (or above). - * - * @param aCallback Callback function, called once per frame. - * @param aSkipFrames Number of initial frames to skip. 0 means that - * the first callback will be for the caller of - * MozStackWalk. - * @param aMaxFrames Maximum number of frames to trace. 0 means no limit. - * @param aClosure Caller-supplied data passed through to aCallback. - * @param aThread The thread for which the stack is to be retrieved. - * Passing null causes us to walk the stack of the - * current thread. On Windows, this is a thread HANDLE. - * It is currently not supported on any other platform. - * @param aPlatformData Platform specific data that can help in walking the - * stack, this should be nullptr unless you really know - * what you're doing! This needs to be a pointer to a - * CONTEXT on Windows and should not be passed on other - * platforms. - * - * May skip some stack frames due to compiler optimizations or code - * generation. - * - */ -MFBT_API bool -MozStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames, - uint32_t aMaxFrames, void* aClosure, uintptr_t aThread, - void* aPlatformData); - -typedef struct -{ - /* - * The name of the shared library or executable containing an - * address and the address's offset within that library, or empty - * string and zero if unknown. - */ - char library[256]; - ptrdiff_t loffset; - /* - * The name of the file name and line number of the code - * corresponding to the address, or empty string and zero if - * unknown. - */ - char filename[256]; - unsigned long lineno; - /* - * The name of the function containing an address and the address's - * offset within that function, or empty string and zero if unknown. - */ - char function[256]; - ptrdiff_t foffset; -} MozCodeAddressDetails; - -/** - * For a given pointer to code, fill in the pieces of information used - * when printing a stack trace. - * - * @param aPC The code address. - * @param aDetails A structure to be filled in with the result. - */ -MFBT_API bool -MozDescribeCodeAddress(void* aPC, MozCodeAddressDetails* aDetails); - -/** - * Format the information about a code address in a format suitable for - * stack traces on the current platform. When available, this string - * should contain the function name, source file, and line number. When - * these are not available, library and offset should be reported, if - * possible. - * - * Note that this output is parsed by several scripts including the fix*.py and - * make-tree.pl scripts in tools/rb/. It should only be change with care, and - * in conjunction with those scripts. - * - * @param aBuffer A string to be filled in with the description. - * The string will always be null-terminated. - * @param aBufferSize The size, in bytes, of aBuffer, including - * room for the terminating null. If the information - * to be printed would be larger than aBuffer, it - * will be truncated so that aBuffer[aBufferSize-1] - * is the terminating null. - * @param aFrameNumber The frame number. - * @param aPC The code address. - * @param aFunction The function name. Possibly null or the empty string. - * @param aLibrary The library name. Possibly null or the empty string. - * @param aLOffset The library offset. - * @param aFileName The filename. Possibly null or the empty string. - * @param aLineNo The line number. Possibly zero. - */ -MFBT_API void -MozFormatCodeAddress(char* aBuffer, uint32_t aBufferSize, uint32_t aFrameNumber, - const void* aPC, const char* aFunction, - const char* aLibrary, ptrdiff_t aLOffset, - const char* aFileName, uint32_t aLineNo); - -/** - * Format the information about a code address in the same fashion as - * MozFormatCodeAddress. - * - * @param aBuffer A string to be filled in with the description. - * The string will always be null-terminated. - * @param aBufferSize The size, in bytes, of aBuffer, including - * room for the terminating null. If the information - * to be printed would be larger than aBuffer, it - * will be truncated so that aBuffer[aBufferSize-1] - * is the terminating null. - * @param aFrameNumber The frame number. - * @param aPC The code address. - * @param aDetails The value filled in by MozDescribeCodeAddress(aPC). - */ -MFBT_API void -MozFormatCodeAddressDetails(char* aBuffer, uint32_t aBufferSize, - uint32_t aFrameNumber, void* aPC, - const MozCodeAddressDetails* aDetails); - -namespace mozilla { - -MFBT_API bool -FramePointerStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames, - uint32_t aMaxFrames, void* aClosure, void** aBp, - void* aStackEnd); - -} // namespace mozilla - -/** - * Initialize the critical sections for this platform so that we can - * abort stack walks when needed. - */ -MFBT_API void -StackWalkInitCriticalAddress(void); - -#endif diff --git a/android/x86/include/spidermonkey/mozilla/StaticAnalysisFunctions.h b/android/x86/include/spidermonkey/mozilla/StaticAnalysisFunctions.h deleted file mode 100644 index a06809dc..00000000 --- a/android/x86/include/spidermonkey/mozilla/StaticAnalysisFunctions.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_StaticAnalysisFunctions_h -#define mozilla_StaticAnalysisFunctions_h - -#ifndef __cplusplus -#ifndef bool -#include -#endif -#endif -/* - * Functions that are used as markers in Gecko code for static analysis. Their - * purpose is to have different AST nodes generated during compile time and to - * match them based on different checkers implemented in build/clang-plugin - */ - -#ifdef MOZ_CLANG_PLUGIN - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * MOZ_AssertAssignmentTest - used in MOZ_ASSERT in order to test the possible - * presence of assignment instead of logical comparisons. - * - * Example: - * MOZ_ASSERT(retVal = true); - */ -static MOZ_ALWAYS_INLINE bool MOZ_AssertAssignmentTest(bool exprResult) { - return exprResult; -} - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#define MOZ_CHECK_ASSERT_ASSIGNMENT(expr) MOZ_AssertAssignmentTest(!!(expr)) - -#else - -#define MOZ_CHECK_ASSERT_ASSIGNMENT(expr) (!!(expr)) - -#endif /* MOZ_CLANG_PLUGIN */ -#endif /* StaticAnalysisFunctions_h */ \ No newline at end of file diff --git a/android/x86/include/spidermonkey/mozilla/TaggedAnonymousMemory.h b/android/x86/include/spidermonkey/mozilla/TaggedAnonymousMemory.h deleted file mode 100644 index d26b06df..00000000 --- a/android/x86/include/spidermonkey/mozilla/TaggedAnonymousMemory.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -// Some Linux kernels -- specifically, newer versions of Android and -// some B2G devices -- have a feature for assigning names to ranges of -// anonymous memory (i.e., memory that doesn't have a "name" in the -// form of an underlying mapped file). These names are reported in -// /proc//smaps alongside system-level memory usage information -// such as Proportional Set Size (memory usage adjusted for sharing -// between processes), which allows reporting this information at a -// finer granularity than would otherwise be possible (e.g., -// separating malloc() heap from JS heap). -// -// Existing memory can be tagged with MozTagAnonymousMemory(); it will -// tag the range of complete pages containing the given interval, so -// the results may be inexact if the range isn't page-aligned. -// MozTaggedAnonymousMmap() can be used like mmap() with an extra -// parameter, and will tag the returned memory if the mapping was -// successful (and if it was in fact anonymous). -// -// NOTE: The pointer given as the "tag" argument MUST remain valid as -// long as the mapping exists. The referenced string is read when -// /proc//smaps or /proc//maps is read, not when the tag is -// established, so freeing it or changing its contents will have -// unexpected results. Using a static string is probably best. -// -// Also note that this header can be used by both C and C++ code. - -#ifndef mozilla_TaggedAnonymousMemory_h -#define mozilla_TaggedAnonymousMemory_h - -#ifndef XP_WIN - -#include -#include - -#include "mozilla/Types.h" - -#ifdef ANDROID - -#ifdef __cplusplus -extern "C" { -#endif - -MFBT_API void -MozTagAnonymousMemory(const void* aPtr, size_t aLength, const char* aTag); - -MFBT_API void* -MozTaggedAnonymousMmap(void* aAddr, size_t aLength, int aProt, int aFlags, - int aFd, off_t aOffset, const char* aTag); - -MFBT_API int -MozTaggedMemoryIsSupported(void); - -#ifdef __cplusplus -} // extern "C" -#endif - -#else // ANDROID - -static inline void -MozTagAnonymousMemory(const void* aPtr, size_t aLength, const char* aTag) -{ -} - -static inline void* -MozTaggedAnonymousMmap(void* aAddr, size_t aLength, int aProt, int aFlags, - int aFd, off_t aOffset, const char* aTag) -{ - return mmap(aAddr, aLength, aProt, aFlags, aFd, aOffset); -} - -static inline int -MozTaggedMemoryIsSupported(void) -{ - return 0; -} - -#endif // ANDROID - -#endif // !XP_WIN - -#endif // mozilla_TaggedAnonymousMemory_h diff --git a/android/x86/include/spidermonkey/mozilla/TemplateLib.h b/android/x86/include/spidermonkey/mozilla/TemplateLib.h deleted file mode 100644 index 6286452d..00000000 --- a/android/x86/include/spidermonkey/mozilla/TemplateLib.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * Reusable template meta-functions on types and compile-time values. Meta- - * functions are placed inside the 'tl' namespace to avoid conflict with non- - * meta functions of the same name (e.g., mozilla::tl::FloorLog2 vs. - * mozilla::FloorLog2). - * - * When constexpr support becomes universal, we should probably use that instead - * of some of these templates, for simplicity. - */ - -#ifndef mozilla_TemplateLib_h -#define mozilla_TemplateLib_h - -#include -#include - -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -namespace tl { - -/** Compute min/max. */ -template -struct Min -{ - static const size_t value = I < J ? I : J; -}; -template -struct Max -{ - static const size_t value = I > J ? I : J; -}; - -/** Compute floor(log2(i)). */ -template -struct FloorLog2 -{ - static const size_t value = 1 + FloorLog2::value; -}; -template<> struct FloorLog2<0> { /* Error */ }; -template<> struct FloorLog2<1> { static const size_t value = 0; }; - -/** Compute ceiling(log2(i)). */ -template -struct CeilingLog2 -{ - static const size_t value = FloorLog2<2 * I - 1>::value; -}; - -/** Round up to the nearest power of 2. */ -template -struct RoundUpPow2 -{ - static const size_t value = size_t(1) << CeilingLog2::value; -}; -template<> -struct RoundUpPow2<0> -{ - static const size_t value = 1; -}; - -/** Compute the number of bits in the given unsigned type. */ -template -struct BitSize -{ - static const size_t value = sizeof(T) * CHAR_BIT; -}; - -/** - * Produce an N-bit mask, where N <= BitSize::value. Handle the - * language-undefined edge case when N = BitSize::value. - */ -template -struct NBitMask -{ - // Assert the precondition. On success this evaluates to 0. Otherwise it - // triggers divide-by-zero at compile time: a guaranteed compile error in - // C++11, and usually one in C++98. Add this value to |value| to assure - // its computation. - static const size_t checkPrecondition = - 0 / size_t(N < BitSize::value); - static const size_t value = (size_t(1) << N) - 1 + checkPrecondition; -}; -template<> -struct NBitMask::value> -{ - static const size_t value = size_t(-1); -}; - -/** - * For the unsigned integral type size_t, compute a mask M for N such that - * for all X, !(X & M) implies X * N will not overflow (w.r.t size_t) - */ -template -struct MulOverflowMask -{ - static const size_t value = - ~NBitMask::value - CeilingLog2::value>::value; -}; -template<> struct MulOverflowMask<0> { /* Error */ }; -template<> struct MulOverflowMask<1> { static const size_t value = 0; }; - -/** - * And computes the logical 'and' of its argument booleans. - * - * Examples: - * mozilla::t1::And::value is true. - * mozilla::t1::And::value is false. - * mozilla::t1::And<>::value is true. - */ - -template -struct And; - -template<> -struct And<> : public TrueType { }; - -template -struct And - : public Conditional, FalseType>::Type { }; - -} // namespace tl - -} // namespace mozilla - -#endif /* mozilla_TemplateLib_h */ diff --git a/android/x86/include/spidermonkey/mozilla/ThreadLocal.h b/android/x86/include/spidermonkey/mozilla/ThreadLocal.h deleted file mode 100644 index 880e6773..00000000 --- a/android/x86/include/spidermonkey/mozilla/ThreadLocal.h +++ /dev/null @@ -1,222 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Cross-platform lightweight thread local data wrappers. */ - -#ifndef mozilla_ThreadLocal_h -#define mozilla_ThreadLocal_h - -#if defined(XP_WIN) -// This file will get included in any file that wants to add a profiler mark. -// In order to not bring together we could include windef.h and -// winbase.h which are sufficient to get the prototypes for the Tls* functions. -// # include -// # include -// Unfortunately, even including these headers causes us to add a bunch of ugly -// stuff to our namespace e.g #define CreateEvent CreateEventW -extern "C" { -__declspec(dllimport) void* __stdcall TlsGetValue(unsigned long); -__declspec(dllimport) int __stdcall TlsSetValue(unsigned long, void*); -__declspec(dllimport) unsigned long __stdcall TlsAlloc(); -} -#else -# include -# include -#endif - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -// sig_safe_t denotes an atomic type which can be read or stored in a single -// instruction. This means that data of this type is safe to be manipulated -// from a signal handler, or other similar asynchronous execution contexts. -#if defined(XP_WIN) -typedef unsigned long sig_safe_t; -#else -typedef sig_atomic_t sig_safe_t; -#endif - -namespace detail { - -#if defined(HAVE_THREAD_TLS_KEYWORD) -#define MOZ_HAS_THREAD_LOCAL -#endif - -/* - * Thread Local Storage helpers. - * - * Usage: - * - * Do not directly instantiate this class. Instead, use the - * MOZ_THREAD_LOCAL macro to declare or define instances. The macro - * takes a type name as its argument. - * - * Declare like this: - * extern MOZ_THREAD_LOCAL(int) tlsInt; - * Define like this: - * MOZ_THREAD_LOCAL(int) tlsInt; - * or: - * static MOZ_THREAD_LOCAL(int) tlsInt; - * - * Only static-storage-duration (e.g. global variables, or static class members) - * objects of this class should be instantiated. This class relies on - * zero-initialization, which is implicit for static-storage-duration objects. - * It doesn't have a custom default constructor, to avoid static initializers. - * - * API usage: - * - * // Create a TLS item. - * // - * // Note that init() should be invoked before the first use of set() - * // or get(). It is ok to call it multiple times. This must be - * // called in a way that avoids possible races with other threads. - * MOZ_THREAD_LOCAL(int) tlsKey; - * if (!tlsKey.init()) { - * // deal with the error - * } - * - * // Set the TLS value - * tlsKey.set(123); - * - * // Get the TLS value - * int value = tlsKey.get(); - */ -template -class ThreadLocal -{ -#ifndef MOZ_HAS_THREAD_LOCAL -#if defined(XP_WIN) - typedef unsigned long key_t; -#else - typedef pthread_key_t key_t; -#endif - - // Integral types narrower than void* must be extended to avoid - // warnings from valgrind on some platforms. This helper type - // achieves that without penalizing the common case of ThreadLocals - // instantiated using a pointer type. - template - struct Helper - { - typedef uintptr_t Type; - }; - - template - struct Helper - { - typedef S *Type; - }; -#endif - - bool initialized() const { -#ifdef MOZ_HAS_THREAD_LOCAL - return true; -#else - return mInited; -#endif - } - -public: - // __thread does not allow non-trivial constructors, but we can - // instead rely on zero-initialization. -#ifndef MOZ_HAS_THREAD_LOCAL - ThreadLocal() - : mKey(0), mInited(false) - {} -#endif - - MOZ_MUST_USE inline bool init(); - - inline T get() const; - - inline void set(const T aValue); - -private: -#ifdef MOZ_HAS_THREAD_LOCAL - T mValue; -#else - key_t mKey; - bool mInited; -#endif -}; - -template -inline bool -ThreadLocal::init() -{ - static_assert(mozilla::IsPointer::value || mozilla::IsIntegral::value, - "mozilla::ThreadLocal must be used with a pointer or " - "integral type"); - static_assert(sizeof(T) <= sizeof(void*), - "mozilla::ThreadLocal can't be used for types larger than " - "a pointer"); - -#ifdef MOZ_HAS_THREAD_LOCAL - return true; -#else - if (!initialized()) { -#ifdef XP_WIN - mKey = TlsAlloc(); - mInited = mKey != 0xFFFFFFFFUL; // TLS_OUT_OF_INDEXES -#else - mInited = !pthread_key_create(&mKey, nullptr); -#endif - } - return mInited; -#endif -} - -template -inline T -ThreadLocal::get() const -{ -#ifdef MOZ_HAS_THREAD_LOCAL - return mValue; -#else - MOZ_ASSERT(initialized()); - void* h; -#ifdef XP_WIN - h = TlsGetValue(mKey); -#else - h = pthread_getspecific(mKey); -#endif - return static_cast(reinterpret_cast::Type>(h)); -#endif -} - -template -inline void -ThreadLocal::set(const T aValue) -{ -#ifdef MOZ_HAS_THREAD_LOCAL - mValue = aValue; -#else - MOZ_ASSERT(initialized()); - void* h = reinterpret_cast(static_cast::Type>(aValue)); -#ifdef XP_WIN - bool succeeded = TlsSetValue(mKey, h); -#else - bool succeeded = !pthread_setspecific(mKey, h); -#endif - if (!succeeded) { - MOZ_CRASH(); - } -#endif -} - -#ifdef MOZ_HAS_THREAD_LOCAL -#define MOZ_THREAD_LOCAL(TYPE) __thread mozilla::detail::ThreadLocal -#else -#define MOZ_THREAD_LOCAL(TYPE) mozilla::detail::ThreadLocal -#endif - -} // namespace detail -} // namespace mozilla - -#endif /* mozilla_ThreadLocal_h */ diff --git a/android/x86/include/spidermonkey/mozilla/TimeStamp.h b/android/x86/include/spidermonkey/mozilla/TimeStamp.h deleted file mode 100644 index a1a0eb36..00000000 --- a/android/x86/include/spidermonkey/mozilla/TimeStamp.h +++ /dev/null @@ -1,609 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_TimeStamp_h -#define mozilla_TimeStamp_h - -#include -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/FloatingPoint.h" -#include "mozilla/TypeTraits.h" -#include "mozilla/Types.h" - -namespace IPC { -template struct ParamTraits; -} // namespace IPC - -#ifdef XP_WIN -// defines TimeStampValue as a complex value keeping both -// GetTickCount and QueryPerformanceCounter values -#include "TimeStamp_windows.h" -#endif - -namespace mozilla { - -#ifndef XP_WIN -typedef uint64_t TimeStampValue; -#endif - -class TimeStamp; - -/** - * Platform-specific implementation details of BaseTimeDuration. - */ -class BaseTimeDurationPlatformUtils -{ -public: - static MFBT_API double ToSeconds(int64_t aTicks); - static MFBT_API double ToSecondsSigDigits(int64_t aTicks); - static MFBT_API int64_t TicksFromMilliseconds(double aMilliseconds); - static MFBT_API int64_t ResolutionInTicks(); -}; - -/** - * Instances of this class represent the length of an interval of time. - * Negative durations are allowed, meaning the end is before the start. - * - * Internally the duration is stored as a int64_t in units of - * PR_TicksPerSecond() when building with NSPR interval timers, or a - * system-dependent unit when building with system clocks. The - * system-dependent unit must be constant, otherwise the semantics of - * this class would be broken. - * - * The ValueCalculator template parameter determines how arithmetic - * operations are performed on the integer count of ticks (mValue). - */ -template -class BaseTimeDuration -{ -public: - // The default duration is 0. - constexpr BaseTimeDuration() : mValue(0) {} - // Allow construction using '0' as the initial value, for readability, - // but no other numbers (so we don't have any implicit unit conversions). - struct _SomethingVeryRandomHere; - MOZ_IMPLICIT BaseTimeDuration(_SomethingVeryRandomHere* aZero) : mValue(0) - { - MOZ_ASSERT(!aZero, "Who's playing funny games here?"); - } - // Default copy-constructor and assignment are OK - - // Converting copy-constructor and assignment operator - template - explicit BaseTimeDuration(const BaseTimeDuration& aOther) - : mValue(aOther.mValue) - { } - - template - BaseTimeDuration& operator=(const BaseTimeDuration& aOther) - { - mValue = aOther.mValue; - return *this; - } - - double ToSeconds() const - { - if (mValue == INT64_MAX) { - return PositiveInfinity(); - } - if (mValue == INT64_MIN) { - return NegativeInfinity(); - } - return BaseTimeDurationPlatformUtils::ToSeconds(mValue); - } - // Return a duration value that includes digits of time we think to - // be significant. This method should be used when displaying a - // time to humans. - double ToSecondsSigDigits() const - { - if (mValue == INT64_MAX) { - return PositiveInfinity(); - } - if (mValue == INT64_MIN) { - return NegativeInfinity(); - } - return BaseTimeDurationPlatformUtils::ToSecondsSigDigits(mValue); - } - double ToMilliseconds() const { return ToSeconds() * 1000.0; } - double ToMicroseconds() const { return ToMilliseconds() * 1000.0; } - - // Using a double here is safe enough; with 53 bits we can represent - // durations up to over 280,000 years exactly. If the units of - // mValue do not allow us to represent durations of that length, - // long durations are clamped to the max/min representable value - // instead of overflowing. - static inline BaseTimeDuration FromSeconds(double aSeconds) - { - return FromMilliseconds(aSeconds * 1000.0); - } - static BaseTimeDuration FromMilliseconds(double aMilliseconds) - { - if (aMilliseconds == PositiveInfinity()) { - return Forever(); - } - if (aMilliseconds == NegativeInfinity()) { - return FromTicks(INT64_MIN); - } - return FromTicks( - BaseTimeDurationPlatformUtils::TicksFromMilliseconds(aMilliseconds)); - } - static inline BaseTimeDuration FromMicroseconds(double aMicroseconds) - { - return FromMilliseconds(aMicroseconds / 1000.0); - } - - static BaseTimeDuration Forever() - { - return FromTicks(INT64_MAX); - } - - BaseTimeDuration operator+(const BaseTimeDuration& aOther) const - { - return FromTicks(ValueCalculator::Add(mValue, aOther.mValue)); - } - BaseTimeDuration operator-(const BaseTimeDuration& aOther) const - { - return FromTicks(ValueCalculator::Subtract(mValue, aOther.mValue)); - } - BaseTimeDuration& operator+=(const BaseTimeDuration& aOther) - { - mValue = ValueCalculator::Add(mValue, aOther.mValue); - return *this; - } - BaseTimeDuration& operator-=(const BaseTimeDuration& aOther) - { - mValue = ValueCalculator::Subtract(mValue, aOther.mValue); - return *this; - } - BaseTimeDuration operator-() const - { - // We don't just use FromTicks(ValueCalculator::Subtract(0, mValue)) - // since that won't give the correct result for -TimeDuration::Forever(). - int64_t ticks; - if (mValue == INT64_MAX) { - ticks = INT64_MIN; - } else if (mValue == INT64_MIN) { - ticks = INT64_MAX; - } else { - ticks = -mValue; - } - - return FromTicks(ticks); - } - -private: - // Block double multiplier (slower, imprecise if long duration) - Bug 853398. - // If required, use MultDouble explicitly and with care. - BaseTimeDuration operator*(const double aMultiplier) const = delete; - - // Block double divisor (for the same reason, and because dividing by - // fractional values would otherwise invoke the int64_t variant, and rounding - // the passed argument can then cause divide-by-zero) - Bug 1147491. - BaseTimeDuration operator/(const double aDivisor) const = delete; - -public: - BaseTimeDuration MultDouble(double aMultiplier) const - { - return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); - } - BaseTimeDuration operator*(const int32_t aMultiplier) const - { - return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); - } - BaseTimeDuration operator*(const uint32_t aMultiplier) const - { - return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); - } - BaseTimeDuration operator*(const int64_t aMultiplier) const - { - return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); - } - BaseTimeDuration operator*(const uint64_t aMultiplier) const - { - if (aMultiplier > INT64_MAX) { - return Forever(); - } - return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); - } - BaseTimeDuration operator/(const int64_t aDivisor) const - { - MOZ_ASSERT(aDivisor != 0, "Division by zero"); - return FromTicks(ValueCalculator::Divide(mValue, aDivisor)); - } - double operator/(const BaseTimeDuration& aOther) const - { -#ifndef MOZ_B2G - // Bug 1066388 - This fails on B2G ICS Emulator - MOZ_ASSERT(aOther.mValue != 0, "Division by zero"); -#endif - return ValueCalculator::DivideDouble(mValue, aOther.mValue); - } - BaseTimeDuration operator%(const BaseTimeDuration& aOther) const - { - MOZ_ASSERT(aOther.mValue != 0, "Division by zero"); - return FromTicks(ValueCalculator::Modulo(mValue, aOther.mValue)); - } - - template - bool operator<(const BaseTimeDuration& aOther) const - { - return mValue < aOther.mValue; - } - template - bool operator<=(const BaseTimeDuration& aOther) const - { - return mValue <= aOther.mValue; - } - template - bool operator>=(const BaseTimeDuration& aOther) const - { - return mValue >= aOther.mValue; - } - template - bool operator>(const BaseTimeDuration& aOther) const - { - return mValue > aOther.mValue; - } - template - bool operator==(const BaseTimeDuration& aOther) const - { - return mValue == aOther.mValue; - } - template - bool operator!=(const BaseTimeDuration& aOther) const - { - return mValue != aOther.mValue; - } - bool IsZero() const - { - return mValue == 0; - } - explicit operator bool() const - { - return mValue != 0; - } - - // Return a best guess at the system's current timing resolution, - // which might be variable. BaseTimeDurations below this order of - // magnitude are meaningless, and those at the same order of - // magnitude or just above are suspect. - static BaseTimeDuration Resolution() { - return FromTicks(BaseTimeDurationPlatformUtils::ResolutionInTicks()); - } - - // We could define additional operators here: - // -- convert to/from other time units - // -- scale duration by a float - // but let's do that on demand. - // Comparing durations for equality will only lead to bugs on - // platforms with high-resolution timers. - -private: - friend class TimeStamp; - friend struct IPC::ParamTraits>; - template - friend class BaseTimeDuration; - - static BaseTimeDuration FromTicks(int64_t aTicks) - { - BaseTimeDuration t; - t.mValue = aTicks; - return t; - } - - static BaseTimeDuration FromTicks(double aTicks) - { - // NOTE: this MUST be a >= test, because int64_t(double(INT64_MAX)) - // overflows and gives INT64_MIN. - if (aTicks >= double(INT64_MAX)) { - return FromTicks(INT64_MAX); - } - - // This MUST be a <= test. - if (aTicks <= double(INT64_MIN)) { - return FromTicks(INT64_MIN); - } - - return FromTicks(int64_t(aTicks)); - } - - // Duration, result is implementation-specific difference of two TimeStamps - int64_t mValue; -}; - -/** - * Perform arithmetic operations on the value of a BaseTimeDuration without - * doing strict checks on the range of values. - */ -class TimeDurationValueCalculator -{ -public: - static int64_t Add(int64_t aA, int64_t aB) { return aA + aB; } - static int64_t Subtract(int64_t aA, int64_t aB) { return aA - aB; } - - template - static int64_t Multiply(int64_t aA, T aB) - { - static_assert(IsIntegral::value, - "Using integer multiplication routine with non-integer type." - " Further specialization required"); - return aA * static_cast(aB); - } - - static int64_t Divide(int64_t aA, int64_t aB) { return aA / aB; } - static double DivideDouble(int64_t aA, int64_t aB) - { - return static_cast(aA) / aB; - } - static int64_t Modulo(int64_t aA, int64_t aB) { return aA % aB; } -}; - -template <> -inline int64_t -TimeDurationValueCalculator::Multiply(int64_t aA, double aB) -{ - return static_cast(aA * aB); -} - -/** - * Specialization of BaseTimeDuration that uses TimeDurationValueCalculator for - * arithmetic on the mValue member. - * - * Use this class for time durations that are *not* expected to hold values of - * Forever (or the negative equivalent) or when such time duration are *not* - * expected to be used in arithmetic operations. - */ -typedef BaseTimeDuration TimeDuration; - -/** - * Instances of this class represent moments in time, or a special - * "null" moment. We do not use the non-monotonic system clock or - * local time, since they can be reset, causing apparent backward - * travel in time, which can confuse algorithms. Instead we measure - * elapsed time according to the system. This time can never go - * backwards (i.e. it never wraps around, at least not in less than - * five million years of system elapsed time). It might not advance - * while the system is sleeping. If TimeStamp::SetNow() is not called - * at all for hours or days, we might not notice the passage of some - * of that time. - * - * We deliberately do not expose a way to convert TimeStamps to some - * particular unit. All you can do is compute a difference between two - * TimeStamps to get a TimeDuration. You can also add a TimeDuration - * to a TimeStamp to get a new TimeStamp. You can't do something - * meaningless like add two TimeStamps. - * - * Internally this is implemented as either a wrapper around - * - high-resolution, monotonic, system clocks if they exist on this - * platform - * - PRIntervalTime otherwise. We detect wraparounds of - * PRIntervalTime and work around them. - * - * This class is similar to C++11's time_point, however it is - * explicitly nullable and provides an IsNull() method. time_point - * is initialized to the clock's epoch and provides a - * time_since_epoch() method that functions similiarly. i.e. - * t.IsNull() is equivalent to t.time_since_epoch() == decltype(t)::duration::zero(); - */ -class TimeStamp -{ -public: - /** - * Initialize to the "null" moment - */ - constexpr TimeStamp() : mValue(0) {} - // Default copy-constructor and assignment are OK - - /** - * The system timestamps are the same as the TimeStamp - * retrieved by mozilla::TimeStamp. Since we need this for - * vsync timestamps, we enable the creation of mozilla::TimeStamps - * on platforms that support vsync aligned refresh drivers / compositors - * Verified true as of Jan 31, 2015: B2G and OS X - * False on Windows 7 - * UNTESTED ON OTHER PLATFORMS - */ -#if defined(MOZ_WIDGET_GONK) || defined(XP_DARWIN) - static TimeStamp FromSystemTime(int64_t aSystemTime) - { - static_assert(sizeof(aSystemTime) == sizeof(TimeStampValue), - "System timestamp should be same units as TimeStampValue"); - return TimeStamp(aSystemTime); - } -#endif - - /** - * Return true if this is the "null" moment - */ - bool IsNull() const { return mValue == 0; } - - /** - * Return true if this is not the "null" moment, may be used in tests, e.g.: - * |if (timestamp) { ... }| - */ - explicit operator bool() const - { - return mValue != 0; - } - - /** - * Return a timestamp reflecting the current elapsed system time. This - * is monotonically increasing (i.e., does not decrease) over the - * lifetime of this process' XPCOM session. - * - * Now() is trying to ensure the best possible precision on each platform, - * at least one millisecond. - * - * NowLoRes() has been introduced to workaround performance problems of - * QueryPerformanceCounter on the Windows platform. NowLoRes() is giving - * lower precision, usually 15.6 ms, but with very good performance benefit. - * Use it for measurements of longer times, like >200ms timeouts. - */ - static TimeStamp Now() { return Now(true); } - static TimeStamp NowLoRes() { return Now(false); } - - /** - * Return a timestamp representing the time when the current process was - * created which will be comparable with other timestamps taken with this - * class. If the actual process creation time is detected to be inconsistent - * the @a aIsInconsistent parameter will be set to true, the returned - * timestamp however will still be valid though inaccurate. - * - * @param aIsInconsistent Set to true if an inconsistency was detected in the - * process creation time - * @returns A timestamp representing the time when the process was created, - * this timestamp is always valid even when errors are reported - */ - static MFBT_API TimeStamp ProcessCreation(bool& aIsInconsistent); - - /** - * Records a process restart. After this call ProcessCreation() will return - * the time when the browser was restarted instead of the actual time when - * the process was created. - */ - static MFBT_API void RecordProcessRestart(); - - /** - * Compute the difference between two timestamps. Both must be non-null. - */ - TimeDuration operator-(const TimeStamp& aOther) const - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value"); - static_assert(-INT64_MAX > INT64_MIN, "int64_t sanity check"); - int64_t ticks = int64_t(mValue - aOther.mValue); - // Check for overflow. - if (mValue > aOther.mValue) { - if (ticks < 0) { - ticks = INT64_MAX; - } - } else { - if (ticks > 0) { - ticks = INT64_MIN; - } - } - return TimeDuration::FromTicks(ticks); - } - - TimeStamp operator+(const TimeDuration& aOther) const - { - TimeStamp result = *this; - result += aOther; - return result; - } - TimeStamp operator-(const TimeDuration& aOther) const - { - TimeStamp result = *this; - result -= aOther; - return result; - } - TimeStamp& operator+=(const TimeDuration& aOther) - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - TimeStampValue value = mValue + aOther.mValue; - // Check for underflow. - // (We don't check for overflow because it's not obvious what the error - // behavior should be in that case.) - if (aOther.mValue < 0 && value > mValue) { - value = 0; - } - mValue = value; - return *this; - } - TimeStamp& operator-=(const TimeDuration& aOther) - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - TimeStampValue value = mValue - aOther.mValue; - // Check for underflow. - // (We don't check for overflow because it's not obvious what the error - // behavior should be in that case.) - if (aOther.mValue > 0 && value > mValue) { - value = 0; - } - mValue = value; - return *this; - } - - bool operator<(const TimeStamp& aOther) const - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value"); - return mValue < aOther.mValue; - } - bool operator<=(const TimeStamp& aOther) const - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value"); - return mValue <= aOther.mValue; - } - bool operator>=(const TimeStamp& aOther) const - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value"); - return mValue >= aOther.mValue; - } - bool operator>(const TimeStamp& aOther) const - { - MOZ_ASSERT(!IsNull(), "Cannot compute with a null value"); - MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value"); - return mValue > aOther.mValue; - } - bool operator==(const TimeStamp& aOther) const - { - return IsNull() - ? aOther.IsNull() - : !aOther.IsNull() && mValue == aOther.mValue; - } - bool operator!=(const TimeStamp& aOther) const - { - return !(*this == aOther); - } - - // Comparing TimeStamps for equality should be discouraged. Adding - // two TimeStamps, or scaling TimeStamps, is nonsense and must never - // be allowed. - - static MFBT_API void Startup(); - static MFBT_API void Shutdown(); - -private: - friend struct IPC::ParamTraits; - friend void StartupTimelineRecordExternal(int, uint64_t); - - MOZ_IMPLICIT TimeStamp(TimeStampValue aValue) : mValue(aValue) {} - - static MFBT_API TimeStamp Now(bool aHighResolution); - - /** - * Computes the uptime of the current process in microseconds. The result - * is platform-dependent and needs to be checked against existing timestamps - * for consistency. - * - * @returns The number of microseconds since the calling process was started - * or 0 if an error was encountered while computing the uptime - */ - static MFBT_API uint64_t ComputeProcessUptime(); - - /** - * When built with PRIntervalTime, a value of 0 means this instance - * is "null". Otherwise, the low 32 bits represent a PRIntervalTime, - * and the high 32 bits represent a counter of the number of - * rollovers of PRIntervalTime that we've seen. This counter starts - * at 1 to avoid a real time colliding with the "null" value. - * - * PR_INTERVAL_MAX is set at 100,000 ticks per second. So the minimum - * time to wrap around is about 2^64/100000 seconds, i.e. about - * 5,849,424 years. - * - * When using a system clock, a value is system dependent. - */ - TimeStampValue mValue; -}; - -} // namespace mozilla - -#endif /* mozilla_TimeStamp_h */ diff --git a/android/x86/include/spidermonkey/mozilla/ToString.h b/android/x86/include/spidermonkey/mozilla/ToString.h deleted file mode 100644 index f11cad5c..00000000 --- a/android/x86/include/spidermonkey/mozilla/ToString.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Utilities for converting an object to a string representation. */ - -#ifndef mozilla_ToString_h -#define mozilla_ToString_h - -#include -#include - -namespace mozilla { - -/** - * A convenience function for converting an object to a string representation. - * Supports any object which can be streamed to an std::ostream. - */ -template -std::string -ToString(const T& aValue) -{ - std::ostringstream stream; - stream << aValue; - return stream.str(); -} - -} // namespace mozilla - -#endif /* mozilla_ToString_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Tuple.h b/android/x86/include/spidermonkey/mozilla/Tuple.h deleted file mode 100644 index a7f9bee6..00000000 --- a/android/x86/include/spidermonkey/mozilla/Tuple.h +++ /dev/null @@ -1,461 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A variadic tuple class. */ - -#ifndef mozilla_Tuple_h -#define mozilla_Tuple_h - -#include "mozilla/Move.h" -#include "mozilla/Pair.h" -#include "mozilla/TemplateLib.h" -#include "mozilla/TypeTraits.h" - -#include -#include - -namespace mozilla { - -namespace detail { - -/* - * A helper class that allows passing around multiple variadic argument lists - * by grouping them. - */ -template -struct Group; - -/* - * CheckConvertibility checks whether each type in a source pack of types - * is convertible to the corresponding type in a target pack of types. - * - * It is intended to be invoked like this: - * CheckConvertibility, Group> - * 'Group' is used to separate types in the two packs (otherwise if we just - * wrote 'CheckConvertibility -struct CheckConvertibilityImpl; - -template -struct CheckConvertibilityImpl - : FalseType {}; - -template -struct CheckConvertibilityImpl, Group, true> - : IntegralConstant::value...>::value> { }; - -template -struct CheckConvertibility; - -template -struct CheckConvertibility, Group> - : CheckConvertibilityImpl, Group, - sizeof...(SourceTypes) == sizeof...(TargetTypes)> { }; - -/* - * TupleImpl is a helper class used to implement mozilla::Tuple. - * It represents one node in a recursive inheritance hierarchy. - * 'Index' is the 0-based index of the tuple element stored in this node; - * 'Elements...' are the types of the elements stored in this node and its - * base classes. - * - * Example: - * Tuple inherits from - * TupleImpl<0, int, float, char>, which stores the 'int' and inherits from - * TupleImpl<1, float, char>, which stores the 'float' and inherits from - * TupleImpl<2, char>, which stores the 'char' and inherits from - * TupleImpl<3>, which stores nothing and terminates the recursion. - * - * The purpose of the 'Index' parameter is to allow efficient index-based - * access to a tuple element: given a tuple, and an index 'I' that we wish to - * access, we can cast the tuple to the base which stores the I'th element - * by performing template argument deduction against 'TupleImpl', - * where 'I' is specified explicitly and 'E...' is deduced (this is what the - * non-member 'Get(t)' function does). - * - * This implementation strategy is borrowed from libstdc++'s std::tuple - * implementation. - */ -template -struct TupleImpl; - -/* - * The base case of the inheritance recursion (and also the implementation - * of an empty tuple). - */ -template -struct TupleImpl { - bool operator==(const TupleImpl& aOther) const - { - return true; - } -}; - -/* - * One node of the recursive inheritance hierarchy. It stores the element at - * index 'Index' of a tuple, of type 'HeadT', and inherits from the nodes - * that store the remaining elements, of types 'TailT...'. - */ -template -struct TupleImpl - : public TupleImpl -{ - typedef TupleImpl Base; - - // Accessors for the head and the tail. - // These are static, because the intended usage is for the caller to, - // given a tuple, obtain the type B of the base class which stores the - // element of interest, and then call B::Head(tuple) to access it. - // (Tail() is mostly for internal use, but is exposed for consistency.) - static HeadT& Head(TupleImpl& aTuple) { return aTuple.mHead; } - static const HeadT& Head(const TupleImpl& aTuple) { return aTuple.mHead; } - static Base& Tail(TupleImpl& aTuple) { return aTuple; } - static const Base& Tail(const TupleImpl& aTuple) { return aTuple; } - - TupleImpl() : Base(), mHead() { } - - // Construct from const references to the elements. - explicit TupleImpl(const HeadT& aHead, const TailT&... aTail) - : Base(aTail...), mHead(aHead) { } - - // Construct from objects that are convertible to the elements. - // This constructor is enabled only when the argument types are actually - // convertible to the element types, otherwise it could become a better - // match for certain invocations than the copy constructor. - template , - Group>::value>::Type> - explicit TupleImpl(OtherHeadT&& aHead, OtherTailT&&... aTail) - : Base(Forward(aTail)...), mHead(Forward(aHead)) { } - - // Copy and move constructors. - // We'd like to use '= default' to implement these, but MSVC 2013's support - // for '= default' is incomplete and this doesn't work. - TupleImpl(const TupleImpl& aOther) - : Base(Tail(aOther)) - , mHead(Head(aOther)) {} - TupleImpl(TupleImpl&& aOther) - : Base(Move(Tail(aOther))) - , mHead(Forward(Head(aOther))) {} - - // Assign from a tuple whose elements are convertible to the elements - // of this tuple. - template ::Type> - TupleImpl& operator=(const TupleImpl& aOther) - { - typedef TupleImpl OtherT; - Head(*this) = OtherT::Head(aOther); - Tail(*this) = OtherT::Tail(aOther); - return *this; - } - template ::Type> - TupleImpl& operator=(TupleImpl&& aOther) - { - typedef TupleImpl OtherT; - Head(*this) = Move(OtherT::Head(aOther)); - Tail(*this) = Move(OtherT::Tail(aOther)); - return *this; - } - - // Copy and move assignment operators. - TupleImpl& operator=(const TupleImpl& aOther) - { - Head(*this) = Head(aOther); - Tail(*this) = Tail(aOther); - return *this; - } - TupleImpl& operator=(TupleImpl&& aOther) - { - Head(*this) = Move(Head(aOther)); - Tail(*this) = Move(Tail(aOther)); - return *this; - } - bool operator==(const TupleImpl& aOther) const - { - return Head(*this) == Head(aOther) && Tail(*this) == Tail(aOther); - } -private: - HeadT mHead; // The element stored at this index in the tuple. -}; - -} // namespace detail - -/** - * Tuple is a class that stores zero or more objects, whose types are specified - * as template parameters. It can be thought of as a generalization of Pair, - * (which can be thought of as a 2-tuple). - * - * Tuple allows index-based access to its elements (with the index having to be - * known at compile time) via the non-member function 'Get(tuple)'. - */ -template -class Tuple : public detail::TupleImpl<0, Elements...> -{ - typedef detail::TupleImpl<0, Elements...> Impl; -public: - // The constructors and assignment operators here are simple wrappers - // around those in TupleImpl. - - Tuple() : Impl() { } - explicit Tuple(const Elements&... aElements) : Impl(aElements...) { } - // Here, we can't just use 'typename... OtherElements' because MSVC will give - // a warning "C4520: multiple default constructors specified" (even if no one - // actually instantiates the constructor with an empty parameter pack - - // that's probably a bug) and we compile with warnings-as-errors. - template , - detail::Group>::value>::Type> - explicit Tuple(OtherHead&& aHead, OtherTail&&... aTail) - : Impl(Forward(aHead), Forward(aTail)...) { } - Tuple(const Tuple& aOther) : Impl(aOther) { } - Tuple(Tuple&& aOther) : Impl(Move(aOther)) { } - - template ::Type> - Tuple& operator=(const Tuple& aOther) - { - static_cast(*this) = aOther; - return *this; - } - template ::Type> - Tuple& operator=(Tuple&& aOther) - { - static_cast(*this) = Move(aOther); - return *this; - } - Tuple& operator=(const Tuple& aOther) - { - static_cast(*this) = aOther; - return *this; - } - Tuple& operator=(Tuple&& aOther) - { - static_cast(*this) = Move(aOther); - return *this; - } - bool operator==(const Tuple& aOther) const - { - return static_cast(*this) == static_cast(aOther); - } -}; - -/** - * Specialization of Tuple for two elements. - * This is created to support construction and assignment from a Pair or std::pair. - */ -template -class Tuple : public detail::TupleImpl<0, A, B> -{ - typedef detail::TupleImpl<0, A, B> Impl; - -public: - // The constructors and assignment operators here are simple wrappers - // around those in TupleImpl. - - Tuple() : Impl() { } - explicit Tuple(const A& aA, const B& aB) : Impl(aA, aB) { } - template , - detail::Group>::value>::Type> - explicit Tuple(AArg&& aA, BArg&& aB) - : Impl(Forward(aA), Forward(aB)) { } - Tuple(const Tuple& aOther) : Impl(aOther) { } - Tuple(Tuple&& aOther) : Impl(Move(aOther)) { } - explicit Tuple(const Pair& aOther) - : Impl(aOther.first(), aOther.second()) { } - explicit Tuple(Pair&& aOther) : Impl(Forward(aOther.first()), - Forward(aOther.second())) { } - explicit Tuple(const std::pair& aOther) - : Impl(aOther.first, aOther.second) { } - explicit Tuple(std::pair&& aOther) : Impl(Forward(aOther.first), - Forward(aOther.second)) { } - - template - Tuple& operator=(const Tuple& aOther) - { - static_cast(*this) = aOther; - return *this; - } - template - Tuple& operator=(Tuple&& aOther) - { - static_cast(*this) = Move(aOther); - return *this; - } - Tuple& operator=(const Tuple& aOther) - { - static_cast(*this) = aOther; - return *this; - } - Tuple& operator=(Tuple&& aOther) - { - static_cast(*this) = Move(aOther); - return *this; - } - template - Tuple& operator=(const Pair& aOther) - { - Impl::Head(*this) = aOther.first(); - Impl::Tail(*this).Head(*this) = aOther.second(); - return *this; - } - template - Tuple& operator=(Pair&& aOther) - { - Impl::Head(*this) = Forward(aOther.first()); - Impl::Tail(*this).Head(*this) = Forward(aOther.second()); - return *this; - } - template - Tuple& operator=(const std::pair& aOther) - { - Impl::Head(*this) = aOther.first; - Impl::Tail(*this).Head(*this) = aOther.second; - return *this; - } - template - Tuple& operator=(std::pair&& aOther) - { - Impl::Head(*this) = Forward(aOther.first); - Impl::Tail(*this).Head(*this) = Forward(aOther.second); - return *this; - } -}; - -/** - * Specialization of Tuple for zero arguments. - * This is necessary because if the primary template were instantiated with - * an empty parameter pack, the 'Tuple(Elements...)' constructors would - * become illegal overloads of the default constructor. - */ -template <> -class Tuple<> {}; - -namespace detail { - -/* - * Helper functions for implementing Get(tuple). - * These functions take a TupleImpl, with Index being - * explicitly specified, and Elements being deduced. By passing a Tuple - * object as argument, template argument deduction will do its magic and - * cast the tuple to the base class which stores the element at Index. - */ - -// Const reference version. -template -auto TupleGetHelper(TupleImpl& aTuple) - -> decltype(TupleImpl::Head(aTuple)) -{ - return TupleImpl::Head(aTuple); -} - -// Non-const reference version. -template -auto TupleGetHelper(const TupleImpl& aTuple) - -> decltype(TupleImpl::Head(aTuple)) -{ - return TupleImpl::Head(aTuple); -} - -} // namespace detail - -/** - * Index-based access to an element of a tuple. - * The syntax is Get(tuple). The index is zero-based. - * - * Example: - * - * Tuple t; - * ... - * float f = Get<1>(t); - */ - -// Non-const reference version. -template -auto Get(Tuple& aTuple) - -> decltype(detail::TupleGetHelper(aTuple)) -{ - return detail::TupleGetHelper(aTuple); -} - -// Const reference version. -template -auto Get(const Tuple& aTuple) - -> decltype(detail::TupleGetHelper(aTuple)) -{ - return detail::TupleGetHelper(aTuple); -} - -// Rvalue reference version. -template -auto Get(Tuple&& aTuple) - -> decltype(Move(mozilla::Get(aTuple))) -{ - // We need a 'mozilla::' qualification here to avoid - // name lookup only finding the current function. - return Move(mozilla::Get(aTuple)); -} - -/** - * A convenience function for constructing a tuple out of a sequence of - * values without specifying the type of the tuple. - * The type of the tuple is deduced from the types of its elements. - * - * Example: - * - * auto tuple = MakeTuple(42, 0.5f, 'c'); // has type Tuple - */ -template -inline Tuple::Type...> -MakeTuple(Elements&&... aElements) -{ - return Tuple::Type...>(Forward(aElements)...); -} - -/** - * A convenience function for constructing a tuple of references to a - * sequence of variables. Since assignments to the elements of the tuple - * "go through" to the referenced variables, this can be used to "unpack" - * a tuple into individual variables. - * - * Example: - * - * int i; - * float f; - * char c; - * Tie(i, f, c) = FunctionThatReturnsATuple(); - */ -template -inline Tuple -Tie(Elements&... aVariables) -{ - return Tuple(aVariables...); -} - -} // namespace mozilla - -#endif /* mozilla_Tuple_h */ diff --git a/android/x86/include/spidermonkey/mozilla/TypeTraits.h b/android/x86/include/spidermonkey/mozilla/TypeTraits.h deleted file mode 100644 index 084f608c..00000000 --- a/android/x86/include/spidermonkey/mozilla/TypeTraits.h +++ /dev/null @@ -1,1262 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Template-based metaprogramming and type-testing facilities. */ - -#ifndef mozilla_TypeTraits_h -#define mozilla_TypeTraits_h - -#include "mozilla/Types.h" - -/* - * These traits are approximate copies of the traits and semantics from C++11's - * header. Don't add traits not in that header! When all - * platforms provide that header, we can convert all users and remove this one. - */ - -#include - -namespace mozilla { - -/* Forward declarations. */ - -template struct RemoveCV; -template struct AddRvalueReference; - -/* 20.2.4 Function template declval [declval] */ - -/** - * DeclVal simplifies the definition of expressions which occur as unevaluated - * operands. It converts T to a reference type, making it possible to use in - * decltype expressions even if T does not have a default constructor, e.g.: - * decltype(DeclVal().foo()) - */ -template -typename AddRvalueReference::Type DeclVal(); - -/* 20.9.3 Helper classes [meta.help] */ - -/** - * Helper class used as a base for various type traits, exposed publicly - * because exposes it as well. - */ -template -struct IntegralConstant -{ - static const T value = Value; - typedef T ValueType; - typedef IntegralConstant Type; -}; - -/** Convenient aliases. */ -typedef IntegralConstant TrueType; -typedef IntegralConstant FalseType; - -/* 20.9.4 Unary type traits [meta.unary] */ - -/* 20.9.4.1 Primary type categories [meta.unary.cat] */ - -namespace detail { - -template -struct IsVoidHelper : FalseType {}; - -template<> -struct IsVoidHelper : TrueType {}; - -} // namespace detail - -/** - * IsVoid determines whether a type is void. - * - * mozilla::IsVoid::value is false; - * mozilla::IsVoid::value is true; - * mozilla::IsVoid::value is false; - * mozilla::IsVoid::value is true. - */ -template -struct IsVoid : detail::IsVoidHelper::Type> {}; - -namespace detail { - -template -struct IsIntegralHelper : FalseType {}; - -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; -template<> struct IsIntegralHelper : TrueType {}; - -} /* namespace detail */ - -/** - * IsIntegral determines whether a type is an integral type. - * - * mozilla::IsIntegral::value is true; - * mozilla::IsIntegral::value is true; - * mozilla::IsIntegral::value is true; - * mozilla::IsIntegral::value is false; - * mozilla::IsIntegral::value is false; - */ -template -struct IsIntegral : detail::IsIntegralHelper::Type> -{}; - -template -struct IsSame; - -namespace detail { - -template -struct IsFloatingPointHelper - : IntegralConstant::value || - IsSame::value || - IsSame::value> -{}; - -} // namespace detail - -/** - * IsFloatingPoint determines whether a type is a floating point type (float, - * double, long double). - * - * mozilla::IsFloatingPoint::value is false; - * mozilla::IsFloatingPoint::value is true; - * mozilla::IsFloatingPoint::value is true; - * mozilla::IsFloatingPoint::value is false. - */ -template -struct IsFloatingPoint - : detail::IsFloatingPointHelper::Type> -{}; - -namespace detail { - -template -struct IsArrayHelper : FalseType {}; - -template -struct IsArrayHelper : TrueType {}; - -template -struct IsArrayHelper : TrueType {}; - -} // namespace detail - -/** - * IsArray determines whether a type is an array type, of known or unknown - * length. - * - * mozilla::IsArray::value is false; - * mozilla::IsArray::value is true; - * mozilla::IsArray::value is true. - */ -template -struct IsArray : detail::IsArrayHelper::Type> -{}; - -namespace detail { - -template -struct IsFunPtr; - -template -struct IsFunPtr - : public FalseType -{}; - -template -struct IsFunPtr - : public TrueType -{}; - -}; // namespace detail - -/** - * IsFunction determines whether a type is a function type. Function pointers - * don't qualify here--only the type of an actual function symbol. We do not - * correctly handle varags function types because of a bug in MSVC. - * - * Given the function: - * void f(int) {} - * - * mozilla::IsFunction is true; - * mozilla::IsFunction is false; - * mozilla::IsFunction is true. - */ -template -struct IsFunction - : public detail::IsFunPtr::Type *> -{}; - -namespace detail { - -template -struct IsPointerHelper : FalseType {}; - -template -struct IsPointerHelper : TrueType {}; - -} // namespace detail - -/** - * IsPointer determines whether a type is a possibly-CV-qualified pointer type - * (but not a pointer-to-member type). - * - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is true; - * mozilla::IsPointer::value is false; - * mozilla::IsPointer::value is false. - * mozilla::IsPointer::value is false - */ -template -struct IsPointer : detail::IsPointerHelper::Type> -{}; - -/** - * IsLvalueReference determines whether a type is an lvalue reference. - * - * mozilla::IsLvalueReference::value is false; - * mozilla::IsLvalueReference::value is false; - * mozilla::IsLvalueReference::value is false; - * mozilla::IsLvalueReference::value is false; - * mozilla::IsLvalueReference::value is false; - * mozilla::IsLvalueReference::value is true; - * mozilla::IsLvalueReference::value is false. - */ -template -struct IsLvalueReference : FalseType {}; - -template -struct IsLvalueReference : TrueType {}; - -/** - * IsRvalueReference determines whether a type is an rvalue reference. - * - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is false; - * mozilla::IsRvalueReference::value is true. - */ -template -struct IsRvalueReference : FalseType {}; - -template -struct IsRvalueReference : TrueType {}; - -namespace detail { - -// __is_enum is a supported extension across all of our supported compilers. -template -struct IsEnumHelper - : IntegralConstant -{}; - -} // namespace detail - -/** - * IsEnum determines whether a type is an enum type. - * - * mozilla::IsEnum::value is true; - * mozilla::IsEnum::value is false; - * mozilla::IsEnum::value is false; - */ -template -struct IsEnum - : detail::IsEnumHelper::Type> -{}; - -namespace detail { - -// __is_class is a supported extension across all of our supported compilers: -// http://llvm.org/releases/3.0/docs/ClangReleaseNotes.html -// http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Type-Traits.html#Type-Traits -// http://msdn.microsoft.com/en-us/library/ms177194%28v=vs.100%29.aspx -template -struct IsClassHelper - : IntegralConstant -{}; - -} // namespace detail - -/** - * IsClass determines whether a type is a class type (but not a union). - * - * struct S {}; - * union U {}; - * mozilla::IsClass::value is false; - * mozilla::IsClass::value is true; - * mozilla::IsClass::value is false; - */ -template -struct IsClass - : detail::IsClassHelper::Type> -{}; - -/* 20.9.4.2 Composite type traits [meta.unary.comp] */ - -/** - * IsReference determines whether a type is an lvalue or rvalue reference. - * - * mozilla::IsReference::value is false; - * mozilla::IsReference::value is false; - * mozilla::IsReference::value is true; - * mozilla::IsReference::value is false; - * mozilla::IsReference::value is true; - * mozilla::IsReference::value is false; - * mozilla::IsReference::value is false; - * mozilla::IsReference::value is true; - * mozilla::IsReference::value is true; - * mozilla::IsReference::value is true. - */ -template -struct IsReference - : IntegralConstant::value || IsRvalueReference::value> -{}; - -/** - * IsArithmetic determines whether a type is arithmetic. A type is arithmetic - * iff it is an integral type or a floating point type. - * - * mozilla::IsArithmetic::value is true; - * mozilla::IsArithmetic::value is true; - * mozilla::IsArithmetic::value is false. - */ -template -struct IsArithmetic - : IntegralConstant::value || IsFloatingPoint::value> -{}; - -namespace detail { - -template -struct IsMemberPointerHelper : FalseType {}; - -template -struct IsMemberPointerHelper : TrueType {}; - -} // namespace detail - -/** - * IsMemberPointer determines whether a type is pointer to non-static member - * object or a pointer to non-static member function. - * - * mozilla::IsMemberPointer::value is true - * mozilla::IsMemberPointer::value is false - */ -template -struct IsMemberPointer - : detail::IsMemberPointerHelper::Type> -{}; - -/** - * IsScalar determines whether a type is a scalar type. - * - * mozilla::IsScalar::value is true - * mozilla::IsScalar::value is true - * mozilla::IsScalar::value is false - */ -template -struct IsScalar - : IntegralConstant::value || IsEnum::value || - IsPointer::value || IsMemberPointer::value> -{}; - -/* 20.9.4.3 Type properties [meta.unary.prop] */ - -/** - * IsConst determines whether a type is const or not. - * - * mozilla::IsConst::value is false; - * mozilla::IsConst::value is true; - * mozilla::IsConst::value is false. - */ -template -struct IsConst : FalseType {}; - -template -struct IsConst : TrueType {}; - -/** - * IsVolatile determines whether a type is volatile or not. - * - * mozilla::IsVolatile::value is false; - * mozilla::IsVolatile::value is true; - * mozilla::IsVolatile::value is false. - */ -template -struct IsVolatile : FalseType {}; - -template -struct IsVolatile : TrueType {}; - -/** - * Traits class for identifying POD types. Until C++11 there's no automatic - * way to detect PODs, so for the moment this is done manually. Users may - * define specializations of this class that inherit from mozilla::TrueType and - * mozilla::FalseType (or equivalently mozilla::IntegralConstant, or conveniently from mozilla::IsPod for composite types) as needed to - * ensure correct IsPod behavior. - */ -template -struct IsPod : public FalseType {}; - -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template<> struct IsPod : TrueType {}; -template struct IsPod : TrueType {}; - -namespace detail { - -// __is_empty is a supported extension across all of our supported compilers: -// http://llvm.org/releases/3.0/docs/ClangReleaseNotes.html -// http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Type-Traits.html#Type-Traits -// http://msdn.microsoft.com/en-us/library/ms177194%28v=vs.100%29.aspx -template -struct IsEmptyHelper - : IntegralConstant::value && __is_empty(T)> -{}; - -} // namespace detail - -/** - * IsEmpty determines whether a type is a class (but not a union) that is empty. - * - * A class is empty iff it and all its base classes have no non-static data - * members (except bit-fields of length 0) and no virtual member functions, and - * no base class is empty or a virtual base class. - * - * Intuitively, empty classes don't have any data that has to be stored in - * instances of those classes. (The size of the class must still be non-zero, - * because distinct array elements of any type must have different addresses. - * However, if the Empty Base Optimization is implemented by the compiler [most - * compilers implement it, and in certain cases C++11 requires it], the size of - * a class inheriting from an empty |Base| class need not be inflated by - * |sizeof(Base)|.) And intuitively, non-empty classes have data members and/or - * vtable pointers that must be stored in each instance for proper behavior. - * - * static_assert(!mozilla::IsEmpty::value, "not a class => not empty"); - * union U1 { int x; }; - * static_assert(!mozilla::IsEmpty::value, "not a class => not empty"); - * struct E1 {}; - * struct E2 { int : 0 }; - * struct E3 : E1 {}; - * struct E4 : E2 {}; - * static_assert(mozilla::IsEmpty::value && - * mozilla::IsEmpty::value && - * mozilla::IsEmpty::value && - * mozilla::IsEmpty::value, - * "all empty"); - * union U2 { E1 e1; }; - * static_assert(!mozilla::IsEmpty::value, "not a class => not empty"); - * struct NE1 { int x; }; - * struct NE2 : virtual E1 {}; - * struct NE3 : E2 { virtual ~NE3() {} }; - * struct NE4 { virtual void f() {} }; - * static_assert(!mozilla::IsEmpty::value && - * !mozilla::IsEmpty::value && - * !mozilla::IsEmpty::value && - * !mozilla::IsEmpty::value, - * "all empty"); - */ -template -struct IsEmpty : detail::IsEmptyHelper::Type> -{}; - - -namespace detail { - -template::value, - bool = IsIntegral::value, - typename NoCV = typename RemoveCV::Type> -struct IsSignedHelper; - -// Floating point is signed. -template -struct IsSignedHelper : TrueType {}; - -// Integral is conditionally signed. -template -struct IsSignedHelper - : IntegralConstant -{}; - -// Non-floating point, non-integral is not signed. -template -struct IsSignedHelper : FalseType {}; - -} // namespace detail - -/** - * IsSigned determines whether a type is a signed arithmetic type. |char| is - * considered a signed type if it has the same representation as |signed char|. - * - * mozilla::IsSigned::value is true; - * mozilla::IsSigned::value is false; - * mozilla::IsSigned::value is false; - * mozilla::IsSigned::value is true. - */ -template -struct IsSigned : detail::IsSignedHelper {}; - -namespace detail { - -template::value, - bool = IsIntegral::value, - typename NoCV = typename RemoveCV::Type> -struct IsUnsignedHelper; - -// Floating point is not unsigned. -template -struct IsUnsignedHelper : FalseType {}; - -// Integral is conditionally unsigned. -template -struct IsUnsignedHelper - : IntegralConstant::value || bool(NoCV(1) < NoCV(-1)))> -{}; - -// Non-floating point, non-integral is not unsigned. -template -struct IsUnsignedHelper : FalseType {}; - -} // namespace detail - -/** - * IsUnsigned determines whether a type is an unsigned arithmetic type. - * - * mozilla::IsUnsigned::value is false; - * mozilla::IsUnsigned::value is true; - * mozilla::IsUnsigned::value is true; - * mozilla::IsUnsigned::value is false. - */ -template -struct IsUnsigned : detail::IsUnsignedHelper {}; - -namespace detail { - -struct DoIsDestructibleImpl -{ - template().~T())> - static TrueType test(int); - template - static FalseType test(...); -}; - -template -struct IsDestructibleImpl : public DoIsDestructibleImpl -{ - typedef decltype(test(0)) Type; -}; - -} // namespace detail - -template -struct IsDestructible : public detail::IsDestructibleImpl::Type {}; - -/* 20.9.5 Type property queries [meta.unary.prop.query] */ - -/* 20.9.6 Relationships between types [meta.rel] */ - -/** - * IsSame tests whether two types are the same type. - * - * mozilla::IsSame::value is true; - * mozilla::IsSame::value is true; - * mozilla::IsSame::value is false; - * mozilla::IsSame::value is true; - * mozilla::IsSame::value is false; - * mozilla::IsSame::value is true. - */ -template -struct IsSame : FalseType {}; - -template -struct IsSame : TrueType {}; - -namespace detail { - -#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) - -template -struct BaseOfTester : IntegralConstant {}; - -#else - -// The trickery used to implement IsBaseOf here makes it possible to use it for -// the cases of private and multiple inheritance. This code was inspired by the -// sample code here: -// -// http://stackoverflow.com/questions/2910979/how-is-base-of-works -template -struct BaseOfHelper -{ -public: - operator Base*() const; - operator Derived*(); -}; - -template -struct BaseOfTester -{ -private: - template - static char test(Derived*, T); - static int test(Base*, int); - -public: - static const bool value = - sizeof(test(BaseOfHelper(), int())) == sizeof(char); -}; - -template -struct BaseOfTester -{ -private: - template - static char test(Derived*, T); - static int test(Base*, int); - -public: - static const bool value = - sizeof(test(BaseOfHelper(), int())) == sizeof(char); -}; - -template -struct BaseOfTester : FalseType {}; - -template -struct BaseOfTester : TrueType {}; - -template -struct BaseOfTester : TrueType {}; - -#endif - -} /* namespace detail */ - -/* - * IsBaseOf allows to know whether a given class is derived from another. - * - * Consider the following class definitions: - * - * class A {}; - * class B : public A {}; - * class C {}; - * - * mozilla::IsBaseOf::value is true; - * mozilla::IsBaseOf::value is false; - */ -template -struct IsBaseOf - : IntegralConstant::value> -{}; - -namespace detail { - -template -struct ConvertibleTester -{ -private: - template - static char test_helper(To1); - - template - static decltype(test_helper(DeclVal())) test(int); - - template - static int test(...); - -public: - static const bool value = - sizeof(test(0)) == sizeof(char); -}; - -} // namespace detail - -/** - * IsConvertible determines whether a value of type From will implicitly convert - * to a value of type To. For example: - * - * struct A {}; - * struct B : public A {}; - * struct C {}; - * - * mozilla::IsConvertible::value is true; - * mozilla::IsConvertible::value is true; - * mozilla::IsConvertible::value is true; - * mozilla::IsConvertible::value is true; - * mozilla::IsConvertible::value is false; - * mozilla::IsConvertible::value is false; - * mozilla::IsConvertible::value is false; - * mozilla::IsConvertible::value is false. - * - * For obscure reasons, you can't use IsConvertible when the types being tested - * are related through private inheritance, and you'll get a compile error if - * you try. Just don't do it! - * - * Note - we need special handling for void, which ConvertibleTester doesn't - * handle. The void handling here doesn't handle const/volatile void correctly, - * which could be easily fixed if the need arises. - */ -template -struct IsConvertible - : IntegralConstant::value> -{}; - -template -struct IsConvertible - : IntegralConstant::value> -{}; - -template -struct IsConvertible - : IntegralConstant::value> -{}; - -template<> -struct IsConvertible - : TrueType -{}; - -/* 20.9.7 Transformations between types [meta.trans] */ - -/* 20.9.7.1 Const-volatile modifications [meta.trans.cv] */ - -/** - * RemoveConst removes top-level const qualifications on a type. - * - * mozilla::RemoveConst::Type is int; - * mozilla::RemoveConst::Type is int; - * mozilla::RemoveConst::Type is const int*; - * mozilla::RemoveConst::Type is int*. - */ -template -struct RemoveConst -{ - typedef T Type; -}; - -template -struct RemoveConst -{ - typedef T Type; -}; - -/** - * RemoveVolatile removes top-level volatile qualifications on a type. - * - * mozilla::RemoveVolatile::Type is int; - * mozilla::RemoveVolatile::Type is int; - * mozilla::RemoveVolatile::Type is volatile int*; - * mozilla::RemoveVolatile::Type is int*. - */ -template -struct RemoveVolatile -{ - typedef T Type; -}; - -template -struct RemoveVolatile -{ - typedef T Type; -}; - -/** - * RemoveCV removes top-level const and volatile qualifications on a type. - * - * mozilla::RemoveCV::Type is int; - * mozilla::RemoveCV::Type is int; - * mozilla::RemoveCV::Type is int; - * mozilla::RemoveCV::Type is int*. - */ -template -struct RemoveCV -{ - typedef typename RemoveConst::Type>::Type Type; -}; - -/* 20.9.7.2 Reference modifications [meta.trans.ref] */ - -/** - * Converts reference types to the underlying types. - * - * mozilla::RemoveReference::Type is T; - * mozilla::RemoveReference::Type is T; - * mozilla::RemoveReference::Type is T; - */ - -template -struct RemoveReference -{ - typedef T Type; -}; - -template -struct RemoveReference -{ - typedef T Type; -}; - -template -struct RemoveReference -{ - typedef T Type; -}; - -template -struct Conditional; - -namespace detail { - -enum Voidness { TIsVoid, TIsNotVoid }; - -template::value ? TIsVoid : TIsNotVoid> -struct AddLvalueReferenceHelper; - -template -struct AddLvalueReferenceHelper -{ - typedef void Type; -}; - -template -struct AddLvalueReferenceHelper -{ - typedef T& Type; -}; - -} // namespace detail - -/** - * AddLvalueReference adds an lvalue & reference to T if one isn't already - * present. (Note: adding an lvalue reference to an rvalue && reference in - * essence replaces the && with a &&, per C+11 reference collapsing rules. For - * example, int&& would become int&.) - * - * The final computed type will only *not* be an lvalue reference if T is void. - * - * mozilla::AddLvalueReference::Type is int&; - * mozilla::AddLvalueRference::Type is volatile int&; - * mozilla::AddLvalueReference::Type is void*&; - * mozilla::AddLvalueReference::Type is void; - * mozilla::AddLvalueReference::Type is struct S&. - */ -template -struct AddLvalueReference - : detail::AddLvalueReferenceHelper -{}; - -namespace detail { - -template::value ? TIsVoid : TIsNotVoid> -struct AddRvalueReferenceHelper; - -template -struct AddRvalueReferenceHelper -{ - typedef void Type; -}; - -template -struct AddRvalueReferenceHelper -{ - typedef T&& Type; -}; - -} // namespace detail - -/** - * AddRvalueReference adds an rvalue && reference to T if one isn't already - * present. (Note: adding an rvalue reference to an lvalue & reference in - * essence keeps the &, per C+11 reference collapsing rules. For example, - * int& would remain int&.) - * - * The final computed type will only *not* be a reference if T is void. - * - * mozilla::AddRvalueReference::Type is int&&; - * mozilla::AddRvalueRference::Type is volatile int&; - * mozilla::AddRvalueRference::Type is const int&&; - * mozilla::AddRvalueReference::Type is void*&&; - * mozilla::AddRvalueReference::Type is void; - * mozilla::AddRvalueReference::Type is struct S&. - */ -template -struct AddRvalueReference - : detail::AddRvalueReferenceHelper -{}; - -/* 20.9.7.3 Sign modifications [meta.trans.sign] */ - -template -struct EnableIf; - -namespace detail { - -template -struct WithC : Conditional -{}; - -template -struct WithV : Conditional -{}; - - -template -struct WithCV : WithC::Type> -{}; - -template -struct CorrespondingSigned; - -template<> -struct CorrespondingSigned { typedef signed char Type; }; -template<> -struct CorrespondingSigned { typedef signed char Type; }; -template<> -struct CorrespondingSigned { typedef short Type; }; -template<> -struct CorrespondingSigned { typedef int Type; }; -template<> -struct CorrespondingSigned { typedef long Type; }; -template<> -struct CorrespondingSigned { typedef long long Type; }; - -template::Type, - bool IsSignedIntegerType = IsSigned::value && - !IsSame::value> -struct MakeSigned; - -template -struct MakeSigned -{ - typedef T Type; -}; - -template -struct MakeSigned - : WithCV::value, IsVolatile::value, - typename CorrespondingSigned::Type> -{}; - -} // namespace detail - -/** - * MakeSigned produces the corresponding signed integer type for a given - * integral type T, with the const/volatile qualifiers of T. T must be a - * possibly-const/volatile-qualified integral type that isn't bool. - * - * If T is already a signed integer type (not including char!), then T is - * produced. - * - * Otherwise, if T is an unsigned integer type, the signed variety of T, with - * T's const/volatile qualifiers, is produced. - * - * Otherwise, the integral type of the same size as T, with the lowest rank, - * with T's const/volatile qualifiers, is produced. (This basically only acts - * to produce signed char when T = char.) - * - * mozilla::MakeSigned::Type is signed long; - * mozilla::MakeSigned::Type is volatile int; - * mozilla::MakeSigned::Type is const signed short; - * mozilla::MakeSigned::Type is const signed char; - * mozilla::MakeSigned is an error; - * mozilla::MakeSigned is an error. - */ -template -struct MakeSigned - : EnableIf::value && - !IsSame::Type>::value, - typename detail::MakeSigned - >::Type -{}; - -namespace detail { - -template -struct CorrespondingUnsigned; - -template<> -struct CorrespondingUnsigned { typedef unsigned char Type; }; -template<> -struct CorrespondingUnsigned { typedef unsigned char Type; }; -template<> -struct CorrespondingUnsigned { typedef unsigned short Type; }; -template<> -struct CorrespondingUnsigned { typedef unsigned int Type; }; -template<> -struct CorrespondingUnsigned { typedef unsigned long Type; }; -template<> -struct CorrespondingUnsigned { typedef unsigned long long Type; }; - - -template::Type, - bool IsUnsignedIntegerType = IsUnsigned::value && - !IsSame::value> -struct MakeUnsigned; - -template -struct MakeUnsigned -{ - typedef T Type; -}; - -template -struct MakeUnsigned - : WithCV::value, IsVolatile::value, - typename CorrespondingUnsigned::Type> -{}; - -} // namespace detail - -/** - * MakeUnsigned produces the corresponding unsigned integer type for a given - * integral type T, with the const/volatile qualifiers of T. T must be a - * possibly-const/volatile-qualified integral type that isn't bool. - * - * If T is already an unsigned integer type (not including char!), then T is - * produced. - * - * Otherwise, if T is an signed integer type, the unsigned variety of T, with - * T's const/volatile qualifiers, is produced. - * - * Otherwise, the unsigned integral type of the same size as T, with the lowest - * rank, with T's const/volatile qualifiers, is produced. (This basically only - * acts to produce unsigned char when T = char.) - * - * mozilla::MakeUnsigned::Type is unsigned long; - * mozilla::MakeUnsigned::Type is volatile unsigned int; - * mozilla::MakeUnsigned::Type is const unsigned short; - * mozilla::MakeUnsigned::Type is const unsigned char; - * mozilla::MakeUnsigned is an error; - * mozilla::MakeUnsigned is an error. - */ -template -struct MakeUnsigned - : EnableIf::value && - !IsSame::Type>::value, - typename detail::MakeUnsigned - >::Type -{}; - -/* 20.9.7.4 Array modifications [meta.trans.arr] */ - -/** - * RemoveExtent produces either the type of the elements of the array T, or T - * itself. - * - * mozilla::RemoveExtent::Type is int; - * mozilla::RemoveExtent::Type is const int; - * mozilla::RemoveExtent::Type is volatile int; - * mozilla::RemoveExtent::Type is long[17]. - */ -template -struct RemoveExtent -{ - typedef T Type; -}; - -template -struct RemoveExtent -{ - typedef T Type; -}; - -template -struct RemoveExtent -{ - typedef T Type; -}; - -/* 20.9.7.5 Pointer modifications [meta.trans.ptr] */ - -namespace detail { - -template -struct RemovePointerHelper -{ - typedef T Type; -}; - -template -struct RemovePointerHelper -{ - typedef Pointee Type; -}; - -} // namespace detail - -/** - * Produces the pointed-to type if a pointer is provided, else returns the input - * type. Note that this does not dereference pointer-to-member pointers. - * - * struct S { bool m; void f(); }; - * mozilla::RemovePointer::Type is int; - * mozilla::RemovePointer::Type is int; - * mozilla::RemovePointer::Type is int; - * mozilla::RemovePointer::Type is int; - * mozilla::RemovePointer::Type is const long; - * mozilla::RemovePointer::Type is void; - * mozilla::RemovePointer::Type is void (S::*)(); - * mozilla::RemovePointer::Type is void(); - * mozilla::RemovePointer::Type is bool S::*. - */ -template -struct RemovePointer - : detail::RemovePointerHelper::Type> -{}; - -/** - * Converts T& to T*. Otherwise returns T* given T. Note that C++17 wants - * std::add_pointer to work differently for function types. We don't implement - * that behavior here. - * - * mozilla::AddPointer is int*; - * mozilla::AddPointer is int**; - * mozilla::AddPointer is int*; - * mozilla::AddPointer is int** const. - */ -template -struct AddPointer -{ - typedef typename RemoveReference::Type* Type; -}; - -/* 20.9.7.6 Other transformations [meta.trans.other] */ - -/** - * EnableIf is a struct containing a typedef of T if and only if B is true. - * - * mozilla::EnableIf::Type is int; - * mozilla::EnableIf::Type is a compile-time error. - * - * Use this template to implement SFINAE-style (Substitution Failure Is not An - * Error) requirements. For example, you might use it to impose a restriction - * on a template parameter: - * - * template - * class PodVector // vector optimized to store POD (memcpy-able) types - * { - * EnableIf::value, T>::Type* vector; - * size_t length; - * ... - * }; - */ -template -struct EnableIf -{}; - -template -struct EnableIf -{ - typedef T Type; -}; - -/** - * Conditional selects a class between two, depending on a given boolean value. - * - * mozilla::Conditional::Type is A; - * mozilla::Conditional::Type is B; - */ -template -struct Conditional -{ - typedef A Type; -}; - -template -struct Conditional -{ - typedef B Type; -}; - -namespace detail { - -template::value, - bool IsFunction = IsFunction::value> -struct DecaySelector; - -template -struct DecaySelector -{ - typedef typename RemoveCV::Type Type; -}; - -template -struct DecaySelector -{ - typedef typename RemoveExtent::Type* Type; -}; - -template -struct DecaySelector -{ - typedef typename AddPointer::Type Type; -}; - -}; // namespace detail - -/** - * Strips const/volatile off a type and decays it from an lvalue to an - * rvalue. So function types are converted to function pointers, arrays to - * pointers, and references are removed. - * - * mozilla::Decay::Type is int - * mozilla::Decay::Type is int - * mozilla::Decay::Type is int - * mozilla::Decay::Type is int - * mozilla::Decay::Type is int* - * mozilla::Decay::Type is int(*)(int) - */ -template -class Decay - : public detail::DecaySelector::Type> -{ -}; - -} /* namespace mozilla */ - -#endif /* mozilla_TypeTraits_h */ diff --git a/android/x86/include/spidermonkey/mozilla/TypedEnumBits.h b/android/x86/include/spidermonkey/mozilla/TypedEnumBits.h deleted file mode 100644 index 5ee6315c..00000000 --- a/android/x86/include/spidermonkey/mozilla/TypedEnumBits.h +++ /dev/null @@ -1,156 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* - * MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS allows using a typed enum as bit flags. - */ - -#ifndef mozilla_TypedEnumBits_h -#define mozilla_TypedEnumBits_h - -#include "mozilla/Attributes.h" -#include "mozilla/IntegerTypeTraits.h" - -namespace mozilla { - -/* - * The problem that CastableTypedEnumResult aims to solve is that - * typed enums are not convertible to bool, and there is no way to make them - * be, yet user code wants to be able to write - * - * if (myFlags & Flags::SOME_PARTICULAR_FLAG) (1) - * - * There are different approaches to solving this. Most of them require - * adapting user code. For example, we could implement operator! and have - * the user write - * - * if (!!(myFlags & Flags::SOME_PARTICULAR_FLAG)) (2) - * - * Or we could supply a IsNonZero() or Any() function returning whether - * an enum value is nonzero, and have the user write - * - * if (Any(Flags & Flags::SOME_PARTICULAR_FLAG)) (3) - * - * But instead, we choose to preserve the original user syntax (1) as it - * is inherently more readable, and to ease porting existing code to typed - * enums. We achieve this by having operator& and other binary bitwise - * operators have as return type a class, CastableTypedEnumResult, - * that wraps a typed enum but adds bool convertibility. - */ -template -class CastableTypedEnumResult -{ -private: - const E mValue; - -public: - explicit constexpr CastableTypedEnumResult(E aValue) - : mValue(aValue) - {} - - constexpr operator E() const { return mValue; } - - template - explicit constexpr - operator DestinationType() const { return DestinationType(mValue); } - - constexpr bool operator !() const { return !bool(mValue); } -}; - -#define MOZ_CASTABLETYPEDENUMRESULT_BINOP(Op, OtherType, ReturnType) \ -template \ -constexpr ReturnType \ -operator Op(const OtherType& aE, const CastableTypedEnumResult& aR) \ -{ \ - return ReturnType(aE Op OtherType(aR)); \ -} \ -template \ -constexpr ReturnType \ -operator Op(const CastableTypedEnumResult& aR, const OtherType& aE) \ -{ \ - return ReturnType(OtherType(aR) Op aE); \ -} \ -template \ -constexpr ReturnType \ -operator Op(const CastableTypedEnumResult& aR1, \ - const CastableTypedEnumResult& aR2) \ -{ \ - return ReturnType(OtherType(aR1) Op OtherType(aR2)); \ -} - -MOZ_CASTABLETYPEDENUMRESULT_BINOP(|, E, CastableTypedEnumResult) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(&, E, CastableTypedEnumResult) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(^, E, CastableTypedEnumResult) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(==, E, bool) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(!=, E, bool) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(||, bool, bool) -MOZ_CASTABLETYPEDENUMRESULT_BINOP(&&, bool, bool) - -template -constexpr CastableTypedEnumResult -operator ~(const CastableTypedEnumResult& aR) -{ - return CastableTypedEnumResult(~(E(aR))); -} - -#define MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(Op) \ -template \ -E& \ -operator Op(E& aR1, \ - const CastableTypedEnumResult& aR2) \ -{ \ - return aR1 Op E(aR2); \ -} - -MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(&=) -MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(|=) -MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(^=) - -#undef MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP - -#undef MOZ_CASTABLETYPEDENUMRESULT_BINOP - -namespace detail { -template -struct UnsignedIntegerTypeForEnum - : UnsignedStdintTypeForSize -{}; -} // namespace detail - -} // namespace mozilla - -#define MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, Op) \ - inline constexpr mozilla::CastableTypedEnumResult \ - operator Op(Name a, Name b) \ - { \ - typedef mozilla::CastableTypedEnumResult Result; \ - typedef mozilla::detail::UnsignedIntegerTypeForEnum::Type U; \ - return Result(Name(U(a) Op U(b))); \ - } \ - \ - inline Name& \ - operator Op##=(Name& a, Name b) \ - { \ - return a = a Op b; \ - } - -/** - * MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS generates standard bitwise operators - * for the given enum type. Use this to enable using an enum type as bit-field. - */ -#define MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Name) \ - MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, |) \ - MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, &) \ - MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, ^) \ - inline constexpr mozilla::CastableTypedEnumResult \ - operator~(Name a) \ - { \ - typedef mozilla::CastableTypedEnumResult Result; \ - typedef mozilla::detail::UnsignedIntegerTypeForEnum::Type U; \ - return Result(Name(~(U(a)))); \ - } - -#endif // mozilla_TypedEnumBits_h diff --git a/android/x86/include/spidermonkey/mozilla/Types.h b/android/x86/include/spidermonkey/mozilla/Types.h deleted file mode 100644 index e7e18abb..00000000 --- a/android/x86/include/spidermonkey/mozilla/Types.h +++ /dev/null @@ -1,134 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* mfbt foundational types and macros. */ - -#ifndef mozilla_Types_h -#define mozilla_Types_h - -/* - * This header must be valid C and C++, includable by code embedding either - * SpiderMonkey or Gecko. - */ - -/* Expose all types and size_t. */ -#include -#include - -/* Implement compiler and linker macros needed for APIs. */ - -/* - * MOZ_EXPORT is used to declare and define a symbol or type which is externally - * visible to users of the current library. It encapsulates various decorations - * needed to properly export the method's symbol. - * - * api.h: - * extern MOZ_EXPORT int MeaningOfLife(void); - * extern MOZ_EXPORT int LuggageCombination; - * - * api.c: - * int MeaningOfLife(void) { return 42; } - * int LuggageCombination = 12345; - * - * If you are merely sharing a method across files, just use plain |extern|. - * These macros are designed for use by library interfaces -- not for normal - * methods or data used cross-file. - */ -#if defined(WIN32) -# define MOZ_EXPORT __declspec(dllexport) -#else /* Unix */ -# ifdef HAVE_VISIBILITY_ATTRIBUTE -# define MOZ_EXPORT __attribute__((visibility("default"))) -# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) -# define MOZ_EXPORT __global -# else -# define MOZ_EXPORT /* nothing */ -# endif -#endif - - -/* - * Whereas implementers use MOZ_EXPORT to declare and define library symbols, - * users use MOZ_IMPORT_API and MOZ_IMPORT_DATA to access them. Most often the - * implementer of the library will expose an API macro which expands to either - * the export or import version of the macro, depending upon the compilation - * mode. - */ -#ifdef _WIN32 -# if defined(__MWERKS__) -# define MOZ_IMPORT_API /* nothing */ -# else -# define MOZ_IMPORT_API __declspec(dllimport) -# endif -#else -# define MOZ_IMPORT_API MOZ_EXPORT -#endif - -#if defined(_WIN32) && !defined(__MWERKS__) -# define MOZ_IMPORT_DATA __declspec(dllimport) -#else -# define MOZ_IMPORT_DATA MOZ_EXPORT -#endif - -/* - * Consistent with the above comment, the MFBT_API and MFBT_DATA macros expose - * export mfbt declarations when building mfbt, and they expose import mfbt - * declarations when using mfbt. - */ -#if defined(IMPL_MFBT) -# define MFBT_API MOZ_EXPORT -# define MFBT_DATA MOZ_EXPORT -#else - /* - * On linux mozglue is linked in the program and we link libxul.so with - * -z,defs. Normally that causes the linker to reject undefined references in - * libxul.so, but as a loophole it allows undefined references to weak - * symbols. We add the weak attribute to the import version of the MFBT API - * macros to exploit this. - */ -# if defined(MOZ_GLUE_IN_PROGRAM) -# define MFBT_API __attribute__((weak)) MOZ_IMPORT_API -# define MFBT_DATA __attribute__((weak)) MOZ_IMPORT_DATA -# else -# define MFBT_API MOZ_IMPORT_API -# define MFBT_DATA MOZ_IMPORT_DATA -# endif -#endif - -/* - * C symbols in C++ code must be declared immediately within |extern "C"| - * blocks. However, in C code, they need not be declared specially. This - * difference is abstracted behind the MOZ_BEGIN_EXTERN_C and MOZ_END_EXTERN_C - * macros, so that the user need not know whether he is being used in C or C++ - * code. - * - * MOZ_BEGIN_EXTERN_C - * - * extern MOZ_EXPORT int MostRandomNumber(void); - * ...other declarations... - * - * MOZ_END_EXTERN_C - * - * This said, it is preferable to just use |extern "C"| in C++ header files for - * its greater clarity. - */ -#ifdef __cplusplus -# define MOZ_BEGIN_EXTERN_C extern "C" { -# define MOZ_END_EXTERN_C } -#else -# define MOZ_BEGIN_EXTERN_C -# define MOZ_END_EXTERN_C -#endif - -/* - * GCC's typeof is available when decltype is not. - */ -#if defined(__GNUC__) && defined(__cplusplus) && \ - !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L -# define decltype __typeof__ -#endif - -#endif /* mozilla_Types_h */ diff --git a/android/x86/include/spidermonkey/mozilla/UniquePtr.h b/android/x86/include/spidermonkey/mozilla/UniquePtr.h deleted file mode 100644 index 7e1035bc..00000000 --- a/android/x86/include/spidermonkey/mozilla/UniquePtr.h +++ /dev/null @@ -1,697 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Smart pointer managing sole ownership of a resource. */ - -#ifndef mozilla_UniquePtr_h -#define mozilla_UniquePtr_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/Compiler.h" -#include "mozilla/Move.h" -#include "mozilla/Pair.h" -#include "mozilla/TypeTraits.h" - -namespace mozilla { - -template class DefaultDelete; -template> class UniquePtr; - -} // namespace mozilla - -namespace mozilla { - -namespace detail { - -struct HasPointerTypeHelper -{ - template static double Test(...); - template static char Test(typename U::pointer* = 0); -}; - -template -class HasPointerType : public IntegralConstant(0)) == 1> -{ -}; - -template ::value> -struct PointerTypeImpl -{ - typedef typename D::pointer Type; -}; - -template -struct PointerTypeImpl -{ - typedef T* Type; -}; - -template -struct PointerType -{ - typedef typename PointerTypeImpl::Type>::Type Type; -}; - -} // namespace detail - -/** - * UniquePtr is a smart pointer that wholly owns a resource. Ownership may be - * transferred out of a UniquePtr through explicit action, but otherwise the - * resource is destroyed when the UniquePtr is destroyed. - * - * UniquePtr is similar to C++98's std::auto_ptr, but it improves upon auto_ptr - * in one crucial way: it's impossible to copy a UniquePtr. Copying an auto_ptr - * obviously *can't* copy ownership of its singly-owned resource. So what - * happens if you try to copy one? Bizarrely, ownership is implicitly - * *transferred*, preserving single ownership but breaking code that assumes a - * copy of an object is identical to the original. (This is why auto_ptr is - * prohibited in STL containers.) - * - * UniquePtr solves this problem by being *movable* rather than copyable. - * Instead of passing a |UniquePtr u| directly to the constructor or assignment - * operator, you pass |Move(u)|. In doing so you indicate that you're *moving* - * ownership out of |u|, into the target of the construction/assignment. After - * the transfer completes, |u| contains |nullptr| and may be safely destroyed. - * This preserves single ownership but also allows UniquePtr to be moved by - * algorithms that have been made move-safe. (Note: if |u| is instead a - * temporary expression, don't use |Move()|: just pass the expression, because - * it's already move-ready. For more information see Move.h.) - * - * UniquePtr is also better than std::auto_ptr in that the deletion operation is - * customizable. An optional second template parameter specifies a class that - * (through its operator()(T*)) implements the desired deletion policy. If no - * policy is specified, mozilla::DefaultDelete is used -- which will either - * |delete| or |delete[]| the resource, depending whether the resource is an - * array. Custom deletion policies ideally should be empty classes (no member - * fields, no member fields in base classes, no virtual methods/inheritance), - * because then UniquePtr can be just as efficient as a raw pointer. - * - * Use of UniquePtr proceeds like so: - * - * UniquePtr g1; // initializes to nullptr - * g1.reset(new int); // switch resources using reset() - * g1 = nullptr; // clears g1, deletes the int - * - * UniquePtr g2(new int); // owns that int - * int* p = g2.release(); // g2 leaks its int -- still requires deletion - * delete p; // now freed - * - * struct S { int x; S(int x) : x(x) {} }; - * UniquePtr g3, g4(new S(5)); - * g3 = Move(g4); // g3 owns the S, g4 cleared - * S* p = g3.get(); // g3 still owns |p| - * assert(g3->x == 5); // operator-> works (if .get() != nullptr) - * assert((*g3).x == 5); // also operator* (again, if not cleared) - * Swap(g3, g4); // g4 now owns the S, g3 cleared - * g3.swap(g4); // g3 now owns the S, g4 cleared - * UniquePtr g5(Move(g3)); // g5 owns the S, g3 cleared - * g5.reset(); // deletes the S, g5 cleared - * - * struct FreePolicy { void operator()(void* p) { free(p); } }; - * UniquePtr g6(static_cast(malloc(sizeof(int)))); - * int* ptr = g6.get(); - * g6 = nullptr; // calls free(ptr) - * - * Now, carefully note a few things you *can't* do: - * - * UniquePtr b1; - * b1 = new int; // BAD: can only assign another UniquePtr - * int* ptr = b1; // BAD: no auto-conversion to pointer, use get() - * - * UniquePtr b2(b1); // BAD: can't copy a UniquePtr - * UniquePtr b3 = b1; // BAD: can't copy-assign a UniquePtr - * - * (Note that changing a UniquePtr to store a direct |new| expression is - * permitted, but usually you should use MakeUnique, defined at the end of this - * header.) - * - * A few miscellaneous notes: - * - * UniquePtr, when not instantiated for an array type, can be move-constructed - * and move-assigned, not only from itself but from "derived" UniquePtr - * instantiations where U converts to T and E converts to D. If you want to use - * this, you're going to have to specify a deletion policy for both UniquePtr - * instantations, and T pretty much has to have a virtual destructor. In other - * words, this doesn't work: - * - * struct Base { virtual ~Base() {} }; - * struct Derived : Base {}; - * - * UniquePtr b1; - * // BAD: DefaultDelete and DefaultDelete don't interconvert - * UniquePtr d1(Move(b)); - * - * UniquePtr b2; - * UniquePtr> d2(Move(b2)); // okay - * - * UniquePtr is specialized for array types. Specializing with an array type - * creates a smart-pointer version of that array -- not a pointer to such an - * array. - * - * UniquePtr arr(new int[5]); - * arr[0] = 4; - * - * What else is different? Deletion of course uses |delete[]|. An operator[] - * is provided. Functionality that doesn't make sense for arrays is removed. - * The constructors and mutating methods only accept array pointers (not T*, U* - * that converts to T*, or UniquePtr or UniquePtr) or |nullptr|. - * - * It's perfectly okay for a function to return a UniquePtr. This transfers - * the UniquePtr's sole ownership of the data, to the fresh UniquePtr created - * in the calling function, that will then solely own that data. Such functions - * can return a local variable UniquePtr, |nullptr|, |UniquePtr(ptr)| where - * |ptr| is a |T*|, or a UniquePtr |Move()|'d from elsewhere. - * - * UniquePtr will commonly be a member of a class, with lifetime equivalent to - * that of that class. If you want to expose the related resource, you could - * expose a raw pointer via |get()|, but ownership of a raw pointer is - * inherently unclear. So it's better to expose a |const UniquePtr&| instead. - * This prohibits mutation but still allows use of |get()| when needed (but - * operator-> is preferred). Of course, you can only use this smart pointer as - * long as the enclosing class instance remains live -- no different than if you - * exposed the |get()| raw pointer. - * - * To pass a UniquePtr-managed resource as a pointer, use a |const UniquePtr&| - * argument. To specify an inout parameter (where the method may or may not - * take ownership of the resource, or reset it), or to specify an out parameter - * (where simply returning a |UniquePtr| isn't possible), use a |UniquePtr&| - * argument. To unconditionally transfer ownership of a UniquePtr - * into a method, use a |UniquePtr| argument. To conditionally transfer - * ownership of a resource into a method, should the method want it, use a - * |UniquePtr&&| argument. - */ -template -class UniquePtr -{ -public: - typedef T ElementType; - typedef D DeleterType; - typedef typename detail::PointerType::Type Pointer; - -private: - Pair mTuple; - - Pointer& ptr() { return mTuple.first(); } - const Pointer& ptr() const { return mTuple.first(); } - - DeleterType& del() { return mTuple.second(); } - const DeleterType& del() const { return mTuple.second(); } - -public: - /** - * Construct a UniquePtr containing |nullptr|. - */ - constexpr UniquePtr() - : mTuple(static_cast(nullptr), DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - /** - * Construct a UniquePtr containing |aPtr|. - */ - explicit UniquePtr(Pointer aPtr) - : mTuple(aPtr, DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - UniquePtr(Pointer aPtr, - typename Conditional::value, - D, - const D&>::Type aD1) - : mTuple(aPtr, aD1) - {} - - // If you encounter an error with MSVC10 about RemoveReference below, along - // the lines that "more than one partial specialization matches the template - // argument list": don't use UniquePtr! Ideally - // you should make deletion use the same function every time, using a - // deleter policy: - // - // // BAD, won't compile with MSVC10, deleter doesn't need to be a - // // variable at all - // typedef void (&FreeSignature)(void*); - // UniquePtr ptr((int*) malloc(sizeof(int)), free); - // - // // GOOD, compiles with MSVC10, deletion behavior statically known and - // // optimizable - // struct DeleteByFreeing - // { - // void operator()(void* aPtr) { free(aPtr); } - // }; - // - // If deletion really, truly, must be a variable: you might be able to work - // around this with a deleter class that contains the function reference. - // But this workaround is untried and untested, because variable deletion - // behavior really isn't something you should use. - UniquePtr(Pointer aPtr, - typename RemoveReference::Type&& aD2) - : mTuple(aPtr, Move(aD2)) - { - static_assert(!IsReference::value, - "rvalue deleter can't be stored by reference"); - } - - UniquePtr(UniquePtr&& aOther) - : mTuple(aOther.release(), Forward(aOther.get_deleter())) - {} - - MOZ_IMPLICIT - UniquePtr(decltype(nullptr)) - : mTuple(nullptr, DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - template - MOZ_IMPLICIT - UniquePtr(UniquePtr&& aOther, - typename EnableIf::Pointer, - Pointer>::value && - !IsArray::value && - (IsReference::value - ? IsSame::value - : IsConvertible::value), - int>::Type aDummy = 0) - : mTuple(aOther.release(), Forward(aOther.get_deleter())) - { - } - - ~UniquePtr() { reset(nullptr); } - - UniquePtr& operator=(UniquePtr&& aOther) - { - reset(aOther.release()); - get_deleter() = Forward(aOther.get_deleter()); - return *this; - } - - template - UniquePtr& operator=(UniquePtr&& aOther) - { - static_assert(IsConvertible::Pointer, - Pointer>::value, - "incompatible UniquePtr pointees"); - static_assert(!IsArray::value, - "can't assign from UniquePtr holding an array"); - - reset(aOther.release()); - get_deleter() = Forward(aOther.get_deleter()); - return *this; - } - - UniquePtr& operator=(decltype(nullptr)) - { - reset(nullptr); - return *this; - } - - T& operator*() const { return *get(); } - Pointer operator->() const - { - MOZ_ASSERT(get(), "dereferencing a UniquePtr containing nullptr"); - return get(); - } - - explicit operator bool() const { return get() != nullptr; } - - Pointer get() const { return ptr(); } - - DeleterType& get_deleter() { return del(); } - const DeleterType& get_deleter() const { return del(); } - - MOZ_MUST_USE Pointer release() - { - Pointer p = ptr(); - ptr() = nullptr; - return p; - } - - void reset(Pointer aPtr = Pointer()) - { - Pointer old = ptr(); - ptr() = aPtr; - if (old != nullptr) { - get_deleter()(old); - } - } - - void swap(UniquePtr& aOther) - { - mTuple.swap(aOther.mTuple); - } - - UniquePtr(const UniquePtr& aOther) = delete; // construct using Move()! - void operator=(const UniquePtr& aOther) = delete; // assign using Move()! -}; - -// In case you didn't read the comment by the main definition (you should!): the -// UniquePtr specialization exists to manage array pointers. It deletes -// such pointers using delete[], it will reject construction and modification -// attempts using U* or U[]. Otherwise it works like the normal UniquePtr. -template -class UniquePtr -{ -public: - typedef T* Pointer; - typedef T ElementType; - typedef D DeleterType; - -private: - Pair mTuple; - -public: - /** - * Construct a UniquePtr containing nullptr. - */ - constexpr UniquePtr() - : mTuple(static_cast(nullptr), DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - /** - * Construct a UniquePtr containing |aPtr|. - */ - explicit UniquePtr(Pointer aPtr) - : mTuple(aPtr, DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - // delete[] knows how to handle *only* an array of a single class type. For - // delete[] to work correctly, it must know the size of each element, the - // fields and base classes of each element requiring destruction, and so on. - // So forbid all overloads which would end up invoking delete[] on a pointer - // of the wrong type. - template - UniquePtr(U&& aU, - typename EnableIf::value && - IsConvertible::value, - int>::Type aDummy = 0) - = delete; - - UniquePtr(Pointer aPtr, - typename Conditional::value, - D, - const D&>::Type aD1) - : mTuple(aPtr, aD1) - {} - - // If you encounter an error with MSVC10 about RemoveReference below, along - // the lines that "more than one partial specialization matches the template - // argument list": don't use UniquePtr! See the - // comment by this constructor in the non-T[] specialization above. - UniquePtr(Pointer aPtr, - typename RemoveReference::Type&& aD2) - : mTuple(aPtr, Move(aD2)) - { - static_assert(!IsReference::value, - "rvalue deleter can't be stored by reference"); - } - - // Forbidden for the same reasons as stated above. - template - UniquePtr(U&& aU, V&& aV, - typename EnableIf::value && - IsConvertible::value, - int>::Type aDummy = 0) - = delete; - - UniquePtr(UniquePtr&& aOther) - : mTuple(aOther.release(), Forward(aOther.get_deleter())) - {} - - MOZ_IMPLICIT - UniquePtr(decltype(nullptr)) - : mTuple(nullptr, DeleterType()) - { - static_assert(!IsPointer::value, "must provide a deleter instance"); - static_assert(!IsReference::value, "must provide a deleter instance"); - } - - ~UniquePtr() { reset(nullptr); } - - UniquePtr& operator=(UniquePtr&& aOther) - { - reset(aOther.release()); - get_deleter() = Forward(aOther.get_deleter()); - return *this; - } - - UniquePtr& operator=(decltype(nullptr)) - { - reset(); - return *this; - } - - explicit operator bool() const { return get() != nullptr; } - - T& operator[](decltype(sizeof(int)) aIndex) const { return get()[aIndex]; } - Pointer get() const { return mTuple.first(); } - - DeleterType& get_deleter() { return mTuple.second(); } - const DeleterType& get_deleter() const { return mTuple.second(); } - - MOZ_MUST_USE Pointer release() - { - Pointer p = mTuple.first(); - mTuple.first() = nullptr; - return p; - } - - void reset(Pointer aPtr = Pointer()) - { - Pointer old = mTuple.first(); - mTuple.first() = aPtr; - if (old != nullptr) { - mTuple.second()(old); - } - } - - void reset(decltype(nullptr)) - { - Pointer old = mTuple.first(); - mTuple.first() = nullptr; - if (old != nullptr) { - mTuple.second()(old); - } - } - - template - void reset(U) = delete; - - void swap(UniquePtr& aOther) { mTuple.swap(aOther.mTuple); } - - UniquePtr(const UniquePtr& aOther) = delete; // construct using Move()! - void operator=(const UniquePtr& aOther) = delete; // assign using Move()! -}; - -/** - * A default deletion policy using plain old operator delete. - * - * Note that this type can be specialized, but authors should beware of the risk - * that the specialization may at some point cease to match (either because it - * gets moved to a different compilation unit or the signature changes). If the - * non-specialized (|delete|-based) version compiles for that type but does the - * wrong thing, bad things could happen. - * - * This is a non-issue for types which are always incomplete (i.e. opaque handle - * types), since |delete|-ing such a type will always trigger a compilation - * error. - */ -template -class DefaultDelete -{ -public: - constexpr DefaultDelete() {} - - template - MOZ_IMPLICIT DefaultDelete(const DefaultDelete& aOther, - typename EnableIf::value, - int>::Type aDummy = 0) - {} - - void operator()(T* aPtr) const - { - static_assert(sizeof(T) > 0, "T must be complete"); - delete aPtr; - } -}; - -/** A default deletion policy using operator delete[]. */ -template -class DefaultDelete -{ -public: - constexpr DefaultDelete() {} - - void operator()(T* aPtr) const - { - static_assert(sizeof(T) > 0, "T must be complete"); - delete[] aPtr; - } - - template - void operator()(U* aPtr) const = delete; -}; - -template -void -Swap(UniquePtr& aX, UniquePtr& aY) -{ - aX.swap(aY); -} - -template -bool -operator==(const UniquePtr& aX, const UniquePtr& aY) -{ - return aX.get() == aY.get(); -} - -template -bool -operator!=(const UniquePtr& aX, const UniquePtr& aY) -{ - return aX.get() != aY.get(); -} - -template -bool -operator==(const UniquePtr& aX, decltype(nullptr)) -{ - return !aX; -} - -template -bool -operator==(decltype(nullptr), const UniquePtr& aX) -{ - return !aX; -} - -template -bool -operator!=(const UniquePtr& aX, decltype(nullptr)) -{ - return bool(aX); -} - -template -bool -operator!=(decltype(nullptr), const UniquePtr& aX) -{ - return bool(aX); -} - -// No operator<, operator>, operator<=, operator>= for now because simplicity. - -namespace detail { - -template -struct UniqueSelector -{ - typedef UniquePtr SingleObject; -}; - -template -struct UniqueSelector -{ - typedef UniquePtr UnknownBound; -}; - -template -struct UniqueSelector -{ - typedef UniquePtr KnownBound; -}; - -} // namespace detail - -/** - * MakeUnique is a helper function for allocating new'd objects and arrays, - * returning a UniquePtr containing the resulting pointer. The semantics of - * MakeUnique(...) are as follows. - * - * If Type is an array T[n]: - * Disallowed, deleted, no overload for you! - * If Type is an array T[]: - * MakeUnique(size_t) is the only valid overload. The pointer returned - * is as if by |new T[n]()|, which value-initializes each element. (If T - * isn't a class type, this will zero each element. If T is a class type, - * then roughly speaking, each element will be constructed using its default - * constructor. See C++11 [dcl.init]p7 for the full gory details.) - * If Type is non-array T: - * The arguments passed to MakeUnique(...) are forwarded into a - * |new T(...)| call, initializing the T as would happen if executing - * |T(...)|. - * - * There are various benefits to using MakeUnique instead of |new| expressions. - * - * First, MakeUnique eliminates use of |new| from code entirely. If objects are - * only created through UniquePtr, then (assuming all explicit release() calls - * are safe, including transitively, and no type-safety casting funniness) - * correctly maintained ownership of the UniquePtr guarantees no leaks are - * possible. (This pays off best if a class is only ever created through a - * factory method on the class, using a private constructor.) - * - * Second, initializing a UniquePtr using a |new| expression requires repeating - * the name of the new'd type, whereas MakeUnique in concert with the |auto| - * keyword names it only once: - * - * UniquePtr ptr1(new char()); // repetitive - * auto ptr2 = MakeUnique(); // shorter - * - * Of course this assumes the reader understands the operation MakeUnique - * performs. In the long run this is probably a reasonable assumption. In the - * short run you'll have to use your judgment about what readers can be expected - * to know, or to quickly look up. - * - * Third, a call to MakeUnique can be assigned directly to a UniquePtr. In - * contrast you can't assign a pointer into a UniquePtr without using the - * cumbersome reset(). - * - * UniquePtr p; - * p = new char; // ERROR - * p.reset(new char); // works, but fugly - * p = MakeUnique(); // preferred - * - * (And third, although not relevant to Mozilla: MakeUnique is exception-safe. - * An exception thrown after |new T| succeeds will leak that memory, unless the - * pointer is assigned to an object that will manage its ownership. UniquePtr - * ably serves this function.) - */ - -template -typename detail::UniqueSelector::SingleObject -MakeUnique(Args&&... aArgs) -{ - return UniquePtr(new T(Forward(aArgs)...)); -} - -template -typename detail::UniqueSelector::UnknownBound -MakeUnique(decltype(sizeof(int)) aN) -{ - typedef typename RemoveExtent::Type ArrayType; - return UniquePtr(new ArrayType[aN]()); -} - -template -typename detail::UniqueSelector::KnownBound -MakeUnique(Args&&... aArgs) = delete; - -} // namespace mozilla - -#endif /* mozilla_UniquePtr_h */ diff --git a/android/x86/include/spidermonkey/mozilla/UniquePtrExtensions.h b/android/x86/include/spidermonkey/mozilla/UniquePtrExtensions.h deleted file mode 100644 index d94f33ee..00000000 --- a/android/x86/include/spidermonkey/mozilla/UniquePtrExtensions.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Useful extensions to UniquePtr. */ - -#ifndef mozilla_UniquePtrExtensions_h -#define mozilla_UniquePtrExtensions_h - -#include "mozilla/fallible.h" -#include "mozilla/UniquePtr.h" - -namespace mozilla { - -/** - * MakeUniqueFallible works exactly like MakeUnique, except that the memory - * allocation performed is done fallibly, i.e. it can return nullptr. - */ -template -typename detail::UniqueSelector::SingleObject -MakeUniqueFallible(Args&&... aArgs) -{ - return UniquePtr(new (fallible) T(Forward(aArgs)...)); -} - -template -typename detail::UniqueSelector::UnknownBound -MakeUniqueFallible(decltype(sizeof(int)) aN) -{ - typedef typename RemoveExtent::Type ArrayType; - return UniquePtr(new (fallible) ArrayType[aN]()); -} - -template -typename detail::UniqueSelector::KnownBound -MakeUniqueFallible(Args&&... aArgs) = delete; - -namespace detail { - -template -struct FreePolicy -{ - void operator()(const void* ptr) { - free(const_cast(ptr)); - } -}; - -} // namespace detail - -template -using UniqueFreePtr = UniquePtr>; - -} // namespace mozilla - -#endif // mozilla_UniquePtrExtensions_h diff --git a/android/x86/include/spidermonkey/mozilla/Unused.h b/android/x86/include/spidermonkey/mozilla/Unused.h deleted file mode 100644 index e693e32a..00000000 --- a/android/x86/include/spidermonkey/mozilla/Unused.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_unused_h -#define mozilla_unused_h - -#include "mozilla/Types.h" - -#ifdef __cplusplus - -namespace mozilla { - -// -// Suppress GCC warnings about unused return values with -// Unused << SomeFuncDeclaredWarnUnusedReturnValue(); -// -struct unused_t -{ - template - inline void - operator<<(const T& /*unused*/) const {} -}; - -extern MFBT_DATA const unused_t Unused; - -} // namespace mozilla - -#endif // __cplusplus - -// An alternative to mozilla::Unused for use in (a) C code and (b) code where -// linking with unused.o is difficult. -#define MOZ_UNUSED(expr) \ - do { if (expr) { (void)0; } } while (0) - -#endif // mozilla_unused_h diff --git a/android/x86/include/spidermonkey/mozilla/Variant.h b/android/x86/include/spidermonkey/mozilla/Variant.h deleted file mode 100644 index 8a33286e..00000000 --- a/android/x86/include/spidermonkey/mozilla/Variant.h +++ /dev/null @@ -1,625 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A template class for tagged unions. */ - -#include -#include - -#include "mozilla/Alignment.h" -#include "mozilla/Assertions.h" -#include "mozilla/Move.h" -#include "mozilla/TypeTraits.h" - -#ifndef mozilla_Variant_h -#define mozilla_Variant_h - -namespace mozilla { - -template -class Variant; - -namespace detail { - -// MaxSizeOf computes the maximum sizeof(T) for each T in Ts. - -template -struct MaxSizeOf -{ - static const size_t size = sizeof(T) > MaxSizeOf::size - ? sizeof(T) - : MaxSizeOf::size; -}; - -template -struct MaxSizeOf -{ - static const size_t size = sizeof(T); -}; - -// The `IsVariant` helper is used in conjunction with static_assert and -// `mozilla::EnableIf` to catch passing non-variant types to `Variant::is()` -// and friends at compile time, rather than at runtime. It ensures that the -// given type `Needle` is one of the types in the set of types `Haystack`. - -template -struct IsVariant; - -template -struct IsVariant -{ - static const bool value = false; -}; - -template -struct IsVariant -{ - static const bool value = true; -}; - -template -struct IsVariant : public IsVariant { }; - -/// SelectVariantTypeHelper is used in the implementation of SelectVariantType. -template -struct SelectVariantTypeHelper; - -template -struct SelectVariantTypeHelper -{ }; - -template -struct SelectVariantTypeHelper -{ - typedef T Type; -}; - -template -struct SelectVariantTypeHelper -{ - typedef const T Type; -}; - -template -struct SelectVariantTypeHelper -{ - typedef const T& Type; -}; - -template -struct SelectVariantTypeHelper -{ - typedef T&& Type; -}; - -template -struct SelectVariantTypeHelper - : public SelectVariantTypeHelper -{ }; - -/** - * SelectVariantType takes a type T and a list of variant types Variants and - * yields a type Type, selected from Variants, that can store a value of type T - * or a reference to type T. If no such type was found, Type is not defined. - */ -template -struct SelectVariantType - : public SelectVariantTypeHelper::Type>::Type, - Variants...> -{ }; - -// Compute a fast, compact type that can be used to hold integral values that -// distinctly map to every type in Ts. -template -struct VariantTag -{ -private: - static const size_t TypeCount = sizeof...(Ts); - -public: - using Type = - typename Conditional::Type - >::Type; -}; - -// TagHelper gets the given sentinel tag value for the given type T. This has to -// be split out from VariantImplementation because you can't nest a partial -// template specialization within a template class. - -template -struct TagHelper; - -// In the case where T != U, we continue recursion. -template -struct TagHelper -{ - static Tag tag() { return Next::template tag(); } -}; - -// In the case where T == U, return the tag number. -template -struct TagHelper -{ - static Tag tag() { return Tag(N); } -}; - -// The VariantImplementation template provides the guts of mozilla::Variant. We -// create a VariantImplementation for each T in Ts... which handles -// construction, destruction, etc for when the Variant's type is T. If the -// Variant's type isn't T, it punts the request on to the next -// VariantImplementation. - -template -struct VariantImplementation; - -// The singly typed Variant / recursion base case. -template -struct VariantImplementation -{ - template - static Tag tag() { - static_assert(mozilla::IsSame::value, - "mozilla::Variant: tag: bad type!"); - return Tag(N); - } - - template - static void copyConstruct(void* aLhs, const Variant& aRhs) { - new (aLhs) T(aRhs.template as()); - } - - template - static void moveConstruct(void* aLhs, Variant&& aRhs) { - new (aLhs) T(aRhs.template extract()); - } - - template - static void destroy(Variant& aV) { - aV.template as().~T(); - } - - template - static bool - equal(const Variant& aLhs, const Variant& aRhs) { - return aLhs.template as() == aRhs.template as(); - } - - template - static auto - match(Matcher&& aMatcher, ConcreteVariant& aV) - -> decltype(aMatcher.match(aV.template as())) - { - return aMatcher.match(aV.template as()); - } -}; - -// VariantImplementation for some variant type T. -template -struct VariantImplementation -{ - // The next recursive VariantImplementation. - using Next = VariantImplementation; - - template - static Tag tag() { - return TagHelper::value>::tag(); - } - - template - static void copyConstruct(void* aLhs, const Variant& aRhs) { - if (aRhs.template is()) { - new (aLhs) T(aRhs.template as()); - } else { - Next::copyConstruct(aLhs, aRhs); - } - } - - template - static void moveConstruct(void* aLhs, Variant&& aRhs) { - if (aRhs.template is()) { - new (aLhs) T(aRhs.template extract()); - } else { - Next::moveConstruct(aLhs, aRhs); - } - } - - template - static void destroy(Variant& aV) { - if (aV.template is()) { - aV.template as().~T(); - } else { - Next::destroy(aV); - } - } - - template - static bool equal(const Variant& aLhs, const Variant& aRhs) { - if (aLhs.template is()) { - MOZ_ASSERT(aRhs.template is()); - return aLhs.template as() == aRhs.template as(); - } else { - return Next::equal(aLhs, aRhs); - } - } - - template - static auto - match(Matcher&& aMatcher, ConcreteVariant& aV) - -> decltype(aMatcher.match(aV.template as())) - { - if (aV.template is()) { - return aMatcher.match(aV.template as()); - } else { - // If you're seeing compilation errors here like "no matching - // function for call to 'match'" then that means that the - // Matcher doesn't exhaust all variant types. There must exist a - // Matcher::match(T&) for every variant type T. - // - // If you're seeing compilation errors here like "cannot - // initialize return object of type <...> with an rvalue of type - // <...>" then that means that the Matcher::match(T&) overloads - // are returning different types. They must all return the same - // Matcher::ReturnType type. - return Next::match(aMatcher, aV); - } - } -}; - -/** - * AsVariantTemporary stores a value of type T to allow construction of a - * Variant value via type inference. Because T is copied and there's no - * guarantee that the copy can be elided, AsVariantTemporary is best used with - * primitive or very small types. - */ -template -struct AsVariantTemporary -{ - explicit AsVariantTemporary(const T& aValue) - : mValue(aValue) - {} - - template - explicit AsVariantTemporary(U&& aValue) - : mValue(Forward(aValue)) - {} - - AsVariantTemporary(const AsVariantTemporary& aOther) - : mValue(aOther.mValue) - {} - - AsVariantTemporary(AsVariantTemporary&& aOther) - : mValue(Move(aOther.mValue)) - {} - - AsVariantTemporary() = delete; - void operator=(const AsVariantTemporary&) = delete; - void operator=(AsVariantTemporary&&) = delete; - - typename RemoveConst::Type>::Type mValue; -}; - -} // namespace detail - -/** - * # mozilla::Variant - * - * A variant / tagged union / heterogenous disjoint union / sum-type template - * class. Similar in concept to (but not derived from) `boost::variant`. - * - * Sometimes, you may wish to use a C union with non-POD types. However, this is - * forbidden in C++ because it is not clear which type in the union should have - * its constructor and destructor run on creation and deletion - * respectively. This is the problem that `mozilla::Variant` solves. - * - * ## Usage - * - * A `mozilla::Variant` instance is constructed (via move or copy) from one of - * its variant types (ignoring const and references). It does *not* support - * construction from subclasses of variant types or types that coerce to one of - * the variant types. - * - * Variant v1('a'); - * Variant, B, C> v2(MakeUnique()); - * - * Because specifying the full type of a Variant value is often verbose, - * AsVariant() can be used to construct a Variant value using type inference in - * contexts such as expressions or when returning values from functions. Because - * AsVariant() must copy or move the value into a temporary and this cannot - * necessarily be elided by the compiler, it's mostly appropriate only for use - * with primitive or very small types. - * - * - * Variant Foo() { return AsVariant('x'); } - * // ... - * Variant v1 = Foo(); // v1 holds char('x'). - * - * All access to the contained value goes through type-safe accessors. - * - * void - * Foo(Variant v) - * { - * if (v.is()) { - * A& ref = v.as(); - * ... - * } else { - * ... - * } - * } - * - * Attempting to use the contained value as type `T1` when the `Variant` - * instance contains a value of type `T2` causes an assertion failure. - * - * A a; - * Variant v(a); - * v.as(); // <--- Assertion failure! - * - * Trying to use a `Variant` instance as some type `U` that is not a - * member of the set of `Ts...` is a compiler error. - * - * A a; - * Variant v(a); - * v.as(); // <--- Compiler error! - * - * Additionally, you can turn a `Variant` that `is` into a `T` by moving it - * out of the containing `Variant` instance with the `extract` method: - * - * Variant, B, C> v(MakeUnique()); - * auto ptr = v.extract>(); - * - * Finally, you can exhaustively match on the contained variant and branch into - * different code paths depending which type is contained. This is preferred to - * manually checking every variant type T with is() because it provides - * compile-time checking that you handled every type, rather than runtime - * assertion failures. - * - * // Bad! - * char* foo(Variant& v) { - * if (v.is()) { - * return ...; - * } else if (v.is()) { - * return ...; - * } else { - * return doSomething(v.as()); // Forgot about case D! - * } - * } - * - * // Good! - * struct FooMatcher - * { - * // The return type of all matchers must be identical. - * char* match(A& a) { ... } - * char* match(B& b) { ... } - * char* match(C& c) { ... } - * char* match(D& d) { ... } // Compile-time error to forget D! - * } - * char* foo(Variant& v) { - * return v.match(FooMatcher()); - * } - * - * ## Examples - * - * A tree is either an empty leaf, or a node with a value and two children: - * - * struct Leaf { }; - * - * template - * struct Node - * { - * T value; - * Tree* left; - * Tree* right; - * }; - * - * template - * using Tree = Variant>; - * - * A copy-on-write string is either a non-owning reference to some existing - * string, or an owning reference to our copy: - * - * class CopyOnWriteString - * { - * Variant> string; - * - * ... - * }; - */ -template -class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS Variant -{ - using Tag = typename detail::VariantTag::Type; - using Impl = detail::VariantImplementation; - using RawData = AlignedStorage::size>; - - // Raw storage for the contained variant value. - RawData raw; - - // Each type is given a unique tag value that lets us keep track of the - // contained variant value's type. - Tag tag; - - void* ptr() { - return reinterpret_cast(&raw); - } - -public: - /** Perfect forwarding construction for some variant type T. */ - template::Type> - explicit Variant(RefT&& aT) - : tag(Impl::template tag()) - { - new (ptr()) T(Forward(aT)); - } - - /** - * Constructs this Variant from an AsVariantTemporary such that T can be - * stored in one of the types allowable in this Variant. This is used in the - * implementation of AsVariant(). - */ - template::Type> - MOZ_IMPLICIT Variant(detail::AsVariantTemporary&& aValue) - : tag(Impl::template tag()) - { - new (ptr()) T(Move(aValue.mValue)); - } - - /** Copy construction. */ - Variant(const Variant& aRhs) - : tag(aRhs.tag) - { - Impl::copyConstruct(ptr(), aRhs); - } - - /** Move construction. */ - Variant(Variant&& aRhs) - : tag(aRhs.tag) - { - Impl::moveConstruct(ptr(), Move(aRhs)); - } - - /** Copy assignment. */ - Variant& operator=(const Variant& aRhs) { - MOZ_ASSERT(&aRhs != this, "self-assign disallowed"); - this->~Variant(); - new (this) Variant(aRhs); - return *this; - } - - /** Move assignment. */ - Variant& operator=(Variant&& aRhs) { - MOZ_ASSERT(&aRhs != this, "self-assign disallowed"); - this->~Variant(); - new (this) Variant(Move(aRhs)); - return *this; - } - - /** Move assignment from AsVariant(). */ - template - Variant& operator=(detail::AsVariantTemporary&& aValue) - { - this->~Variant(); - new (this) Variant(Move(aValue)); - return *this; - } - - ~Variant() - { - Impl::destroy(*this); - } - - /** Check which variant type is currently contained. */ - template - bool is() const { - static_assert(detail::IsVariant::value, - "provided a type not found in this Variant's type list"); - return Impl::template tag() == tag; - } - - /** - * Operator == overload that defers to the variant type's operator== - * implementation if the rhs is tagged as the same type as this one. - */ - bool operator==(const Variant& aRhs) const { - return tag == aRhs.tag && Impl::equal(*this, aRhs); - } - - /** - * Operator != overload that defers to the negation of the variant type's - * operator== implementation if the rhs is tagged as the same type as this - * one. - */ - bool operator!=(const Variant& aRhs) const { - return !(*this == aRhs); - } - - // Accessors for working with the contained variant value. - - /** Mutable reference. */ - template - T& as() { - static_assert(detail::IsVariant::value, - "provided a type not found in this Variant's type list"); - MOZ_ASSERT(is()); - return *reinterpret_cast(&raw); - } - - /** Immutable const reference. */ - template - const T& as() const { - static_assert(detail::IsVariant::value, - "provided a type not found in this Variant's type list"); - MOZ_ASSERT(is()); - return *reinterpret_cast(&raw); - } - - /** - * Extract the contained variant value from this container into a temporary - * value. On completion, the value in the variant will be in a - * safely-destructible state, as determined by the behavior of T's move - * constructor when provided the variant's internal value. - */ - template - T extract() { - static_assert(detail::IsVariant::value, - "provided a type not found in this Variant's type list"); - MOZ_ASSERT(is()); - return T(Move(as())); - } - - // Exhaustive matching of all variant types on the contained value. - - /** Match on an immutable const reference. */ - template - auto - match(Matcher&& aMatcher) const - -> decltype(Impl::match(aMatcher, *this)) - { - return Impl::match(aMatcher, *this); - } - - /** Match on a mutable non-const reference. */ - template - auto - match(Matcher&& aMatcher) - -> decltype(Impl::match(aMatcher, *this)) - { - return Impl::match(aMatcher, *this); - } -}; - -/* - * AsVariant() is used to construct a Variant value containing the - * provided T value using type inference. It can be used to construct Variant - * values in expressions or return them from functions without specifying the - * entire Variant type. - * - * Because AsVariant() must copy or move the value into a temporary and this - * cannot necessarily be elided by the compiler, it's mostly appropriate only - * for use with primitive or very small types. - * - * AsVariant() returns a AsVariantTemporary value which is implicitly - * convertible to any Variant that can hold a value of type T. - */ -template -detail::AsVariantTemporary -AsVariant(T&& aValue) -{ - return detail::AsVariantTemporary(Forward(aValue)); -} - -} // namespace mozilla - -#endif /* mozilla_Variant_h */ diff --git a/android/x86/include/spidermonkey/mozilla/Vector.h b/android/x86/include/spidermonkey/mozilla/Vector.h deleted file mode 100644 index fc43afcf..00000000 --- a/android/x86/include/spidermonkey/mozilla/Vector.h +++ /dev/null @@ -1,1491 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* A type/length-parametrized vector class. */ - -#ifndef mozilla_Vector_h -#define mozilla_Vector_h - -#include "mozilla/Alignment.h" -#include "mozilla/AllocPolicy.h" -#include "mozilla/ArrayUtils.h" // for PointerRangeSize -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/MathAlgorithms.h" -#include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" -#include "mozilla/OperatorNewExtensions.h" -#include "mozilla/ReentrancyGuard.h" -#include "mozilla/TemplateLib.h" -#include "mozilla/TypeTraits.h" - -#include // for placement new - -/* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */ -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4345) -#endif - -namespace mozilla { - -template -class Vector; - -namespace detail { - -/* - * Check that the given capacity wastes the minimal amount of space if - * allocated on the heap. This means that aCapacity*sizeof(T) is as close to a - * power-of-two as possible. growStorageBy() is responsible for ensuring this. - */ -template -static bool CapacityHasExcessSpace(size_t aCapacity) -{ - size_t size = aCapacity * sizeof(T); - return RoundUpPow2(size) - size >= sizeof(T); -} - -/* - * This template class provides a default implementation for vector operations - * when the element type is not known to be a POD, as judged by IsPod. - */ -template -struct VectorImpl -{ - /* - * Constructs an object in the uninitialized memory at *aDst with aArgs. - */ - template - MOZ_NONNULL(1) - static inline void new_(T* aDst, Args&&... aArgs) - { - new(KnownNotNull, aDst) T(Forward(aArgs)...); - } - - /* Destroys constructed objects in the range [aBegin, aEnd). */ - static inline void destroy(T* aBegin, T* aEnd) - { - MOZ_ASSERT(aBegin <= aEnd); - for (T* p = aBegin; p < aEnd; ++p) { - p->~T(); - } - } - - /* Constructs objects in the uninitialized range [aBegin, aEnd). */ - static inline void initialize(T* aBegin, T* aEnd) - { - MOZ_ASSERT(aBegin <= aEnd); - for (T* p = aBegin; p < aEnd; ++p) { - new_(p); - } - } - - /* - * Copy-constructs objects in the uninitialized range - * [aDst, aDst+(aSrcEnd-aSrcStart)) from the range [aSrcStart, aSrcEnd). - */ - template - static inline void copyConstruct(T* aDst, - const U* aSrcStart, const U* aSrcEnd) - { - MOZ_ASSERT(aSrcStart <= aSrcEnd); - for (const U* p = aSrcStart; p < aSrcEnd; ++p, ++aDst) { - new_(aDst, *p); - } - } - - /* - * Move-constructs objects in the uninitialized range - * [aDst, aDst+(aSrcEnd-aSrcStart)) from the range [aSrcStart, aSrcEnd). - */ - template - static inline void moveConstruct(T* aDst, U* aSrcStart, U* aSrcEnd) - { - MOZ_ASSERT(aSrcStart <= aSrcEnd); - for (U* p = aSrcStart; p < aSrcEnd; ++p, ++aDst) { - new_(aDst, Move(*p)); - } - } - - /* - * Copy-constructs objects in the uninitialized range [aDst, aDst+aN) from - * the same object aU. - */ - template - static inline void copyConstructN(T* aDst, size_t aN, const U& aU) - { - for (T* end = aDst + aN; aDst < end; ++aDst) { - new_(aDst, aU); - } - } - - /* - * Grows the given buffer to have capacity aNewCap, preserving the objects - * constructed in the range [begin, end) and updating aV. Assumes that (1) - * aNewCap has not overflowed, and (2) multiplying aNewCap by sizeof(T) will - * not overflow. - */ - static inline MOZ_MUST_USE bool - growTo(Vector& aV, size_t aNewCap) - { - MOZ_ASSERT(!aV.usingInlineStorage()); - MOZ_ASSERT(!CapacityHasExcessSpace(aNewCap)); - T* newbuf = aV.template pod_malloc(aNewCap); - if (MOZ_UNLIKELY(!newbuf)) { - return false; - } - T* dst = newbuf; - T* src = aV.beginNoCheck(); - for (; src < aV.endNoCheck(); ++dst, ++src) { - new_(dst, Move(*src)); - } - VectorImpl::destroy(aV.beginNoCheck(), aV.endNoCheck()); - aV.free_(aV.mBegin); - aV.mBegin = newbuf; - /* aV.mLength is unchanged. */ - aV.mCapacity = aNewCap; - return true; - } -}; - -/* - * This partial template specialization provides a default implementation for - * vector operations when the element type is known to be a POD, as judged by - * IsPod. - */ -template -struct VectorImpl -{ - template - MOZ_NONNULL(1) - static inline void new_(T* aDst, Args&&... aArgs) - { - // Explicitly construct a local object instead of using a temporary since - // T(args...) will be treated like a C-style cast in the unary case and - // allow unsafe conversions. Both forms should be equivalent to an - // optimizing compiler. - T temp(Forward(aArgs)...); - *aDst = temp; - } - - static inline void destroy(T*, T*) {} - - static inline void initialize(T* aBegin, T* aEnd) - { - /* - * You would think that memset would be a big win (or even break even) - * when we know T is a POD. But currently it's not. This is probably - * because |append| tends to be given small ranges and memset requires - * a function call that doesn't get inlined. - * - * memset(aBegin, 0, sizeof(T) * (aEnd - aBegin)); - */ - MOZ_ASSERT(aBegin <= aEnd); - for (T* p = aBegin; p < aEnd; ++p) { - new_(p); - } - } - - template - static inline void copyConstruct(T* aDst, - const U* aSrcStart, const U* aSrcEnd) - { - /* - * See above memset comment. Also, notice that copyConstruct is - * currently templated (T != U), so memcpy won't work without - * requiring T == U. - * - * memcpy(aDst, aSrcStart, sizeof(T) * (aSrcEnd - aSrcStart)); - */ - MOZ_ASSERT(aSrcStart <= aSrcEnd); - for (const U* p = aSrcStart; p < aSrcEnd; ++p, ++aDst) { - new_(aDst, *p); - } - } - - template - static inline void moveConstruct(T* aDst, - const U* aSrcStart, const U* aSrcEnd) - { - copyConstruct(aDst, aSrcStart, aSrcEnd); - } - - static inline void copyConstructN(T* aDst, size_t aN, const T& aT) - { - for (T* end = aDst + aN; aDst < end; ++aDst) { - new_(aDst, aT); - } - } - - static inline MOZ_MUST_USE bool - growTo(Vector& aV, size_t aNewCap) - { - MOZ_ASSERT(!aV.usingInlineStorage()); - MOZ_ASSERT(!CapacityHasExcessSpace(aNewCap)); - T* newbuf = aV.template pod_realloc(aV.mBegin, aV.mCapacity, aNewCap); - if (MOZ_UNLIKELY(!newbuf)) { - return false; - } - aV.mBegin = newbuf; - /* aV.mLength is unchanged. */ - aV.mCapacity = aNewCap; - return true; - } - - static inline void - podResizeToFit(Vector& aV) - { - if (aV.usingInlineStorage() || aV.mLength == aV.mCapacity) { - return; - } - T* newbuf = aV.template pod_realloc(aV.mBegin, aV.mCapacity, aV.mLength); - if (MOZ_UNLIKELY(!newbuf)) { - return; - } - aV.mBegin = newbuf; - aV.mCapacity = aV.mLength; - } -}; - -// A struct for TestVector.cpp to access private internal fields. -// DO NOT DEFINE IN YOUR OWN CODE. -struct VectorTesting; - -} // namespace detail - -/* - * STL-like container providing a short-lived, dynamic buffer. Vector calls the - * constructors/destructors of all elements stored in its internal buffer, so - * non-PODs may be safely used. Additionally, Vector will store the first N - * elements in-place before resorting to dynamic allocation. - * - * T requirements: - * - default and copy constructible, assignable, destructible - * - operations do not throw - * MinInlineCapacity requirements: - * - any value, however, MinInlineCapacity is clamped to min/max values - * AllocPolicy: - * - see "Allocation policies" in AllocPolicy.h (defaults to - * mozilla::MallocAllocPolicy) - * - * Vector is not reentrant: T member functions called during Vector member - * functions must not call back into the same object! - */ -template -class Vector final : private AllocPolicy -{ - /* utilities */ - - static const bool kElemIsPod = IsPod::value; - typedef detail::VectorImpl Impl; - friend struct detail::VectorImpl; - - friend struct detail::VectorTesting; - - MOZ_MUST_USE bool growStorageBy(size_t aIncr); - MOZ_MUST_USE bool convertToHeapStorage(size_t aNewCap); - MOZ_MUST_USE bool maybeCheckSimulatedOOM(size_t aRequestedSize); - - /* magic constants */ - - static const int kMaxInlineBytes = 1024; - - /* compute constants */ - - /* - * Consider element size to be 1 for buffer sizing if there are 0 inline - * elements. This allows us to compile when the definition of the element - * type is not visible here. - * - * Explicit specialization is only allowed at namespace scope, so in order - * to keep everything here, we use a dummy template parameter with partial - * specialization. - */ - template - struct ElemSize - { - static const size_t value = sizeof(T); - }; - template - struct ElemSize<0, Dummy> - { - static const size_t value = 1; - }; - - static const size_t kInlineCapacity = - tl::Min::value>::value; - - /* Calculate inline buffer size; avoid 0-sized array. */ - static const size_t kInlineBytes = - tl::Max<1, kInlineCapacity * ElemSize::value>::value; - - /* member data */ - - /* - * Pointer to the buffer, be it inline or heap-allocated. Only [mBegin, - * mBegin + mLength) hold valid constructed T objects. The range [mBegin + - * mLength, mBegin + mCapacity) holds uninitialized memory. The range - * [mBegin + mLength, mBegin + mReserved) also holds uninitialized memory - * previously allocated by a call to reserve(). - */ - T* mBegin; - - /* Number of elements in the vector. */ - size_t mLength; - - /* Max number of elements storable in the vector without resizing. */ - size_t mCapacity; - -#ifdef DEBUG - /* Max elements of reserved or used space in this vector. */ - size_t mReserved; -#endif - - /* Memory used for inline storage. */ - AlignedStorage mStorage; - -#ifdef DEBUG - friend class ReentrancyGuard; - bool mEntered; -#endif - - /* private accessors */ - - bool usingInlineStorage() const - { - return mBegin == const_cast(this)->inlineStorage(); - } - - T* inlineStorage() - { - return static_cast(mStorage.addr()); - } - - T* beginNoCheck() const - { - return mBegin; - } - - T* endNoCheck() - { - return mBegin + mLength; - } - - const T* endNoCheck() const - { - return mBegin + mLength; - } - -#ifdef DEBUG - /** - * The amount of explicitly allocated space in this vector that is immediately - * available to be filled by appending additional elements. This value is - * always greater than or equal to |length()| -- the vector's actual elements - * are implicitly reserved. This value is always less than or equal to - * |capacity()|. It may be explicitly increased using the |reserve()| method. - */ - size_t reserved() const - { - MOZ_ASSERT(mLength <= mReserved); - MOZ_ASSERT(mReserved <= mCapacity); - return mReserved; - } -#endif - - /* Append operations guaranteed to succeed due to pre-reserved space. */ - template void internalAppend(U&& aU); - template - void internalAppendAll(const Vector& aU); - void internalAppendN(const T& aT, size_t aN); - template void internalAppend(const U* aBegin, size_t aLength); - -public: - static const size_t sMaxInlineStorage = MinInlineCapacity; - - typedef T ElementType; - - explicit Vector(AllocPolicy = AllocPolicy()); - Vector(Vector&&); /* Move constructor. */ - Vector& operator=(Vector&&); /* Move assignment. */ - ~Vector(); - - /* accessors */ - - const AllocPolicy& allocPolicy() const { return *this; } - - AllocPolicy& allocPolicy() { return *this; } - - enum { InlineLength = MinInlineCapacity }; - - size_t length() const { return mLength; } - - bool empty() const { return mLength == 0; } - - size_t capacity() const { return mCapacity; } - - T* begin() - { - MOZ_ASSERT(!mEntered); - return mBegin; - } - - const T* begin() const - { - MOZ_ASSERT(!mEntered); - return mBegin; - } - - T* end() - { - MOZ_ASSERT(!mEntered); - return mBegin + mLength; - } - - const T* end() const - { - MOZ_ASSERT(!mEntered); - return mBegin + mLength; - } - - T& operator[](size_t aIndex) - { - MOZ_ASSERT(!mEntered); - MOZ_ASSERT(aIndex < mLength); - return begin()[aIndex]; - } - - const T& operator[](size_t aIndex) const - { - MOZ_ASSERT(!mEntered); - MOZ_ASSERT(aIndex < mLength); - return begin()[aIndex]; - } - - T& back() - { - MOZ_ASSERT(!mEntered); - MOZ_ASSERT(!empty()); - return *(end() - 1); - } - - const T& back() const - { - MOZ_ASSERT(!mEntered); - MOZ_ASSERT(!empty()); - return *(end() - 1); - } - - class Range - { - friend class Vector; - T* mCur; - T* mEnd; - Range(T* aCur, T* aEnd) - : mCur(aCur) - , mEnd(aEnd) - { - MOZ_ASSERT(aCur <= aEnd); - } - - public: - bool empty() const { return mCur == mEnd; } - size_t remain() const { return PointerRangeSize(mCur, mEnd); } - T& front() const { MOZ_ASSERT(!empty()); return *mCur; } - void popFront() { MOZ_ASSERT(!empty()); ++mCur; } - T popCopyFront() { MOZ_ASSERT(!empty()); return *mCur++; } - }; - - class ConstRange - { - friend class Vector; - const T* mCur; - const T* mEnd; - ConstRange(const T* aCur, const T* aEnd) - : mCur(aCur) - , mEnd(aEnd) - { - MOZ_ASSERT(aCur <= aEnd); - } - - public: - bool empty() const { return mCur == mEnd; } - size_t remain() const { return PointerRangeSize(mCur, mEnd); } - const T& front() const { MOZ_ASSERT(!empty()); return *mCur; } - void popFront() { MOZ_ASSERT(!empty()); ++mCur; } - T popCopyFront() { MOZ_ASSERT(!empty()); return *mCur++; } - }; - - Range all() { return Range(begin(), end()); } - ConstRange all() const { return ConstRange(begin(), end()); } - - /* mutators */ - - /** - * Reverse the order of the elements in the vector in place. - */ - void reverse(); - - /** - * Given that the vector is empty, grow the internal capacity to |aRequest|, - * keeping the length 0. - */ - MOZ_MUST_USE bool initCapacity(size_t aRequest); - - /** - * Given that the vector is empty, grow the internal capacity and length to - * |aRequest| leaving the elements' memory completely uninitialized (with all - * the associated hazards and caveats). This avoids the usual allocation-size - * rounding that happens in resize and overhead of initialization for elements - * that are about to be overwritten. - */ - MOZ_MUST_USE bool initLengthUninitialized(size_t aRequest); - - /** - * If reserve(aRequest) succeeds and |aRequest >= length()|, then appending - * |aRequest - length()| elements, in any sequence of append/appendAll calls, - * is guaranteed to succeed. - * - * A request to reserve an amount less than the current length does not affect - * reserved space. - */ - MOZ_MUST_USE bool reserve(size_t aRequest); - - /** - * Destroy elements in the range [end() - aIncr, end()). Does not deallocate - * or unreserve storage for those elements. - */ - void shrinkBy(size_t aIncr); - - /** - * Destroy elements in the range [aNewLength, end()). Does not deallocate - * or unreserve storage for those elements. - */ - void shrinkTo(size_t aNewLength); - - /** Grow the vector by aIncr elements. */ - MOZ_MUST_USE bool growBy(size_t aIncr); - - /** Call shrinkBy or growBy based on whether newSize > length(). */ - MOZ_MUST_USE bool resize(size_t aNewLength); - - /** - * Increase the length of the vector, but don't initialize the new elements - * -- leave them as uninitialized memory. - */ - MOZ_MUST_USE bool growByUninitialized(size_t aIncr); - void infallibleGrowByUninitialized(size_t aIncr); - MOZ_MUST_USE bool resizeUninitialized(size_t aNewLength); - - /** Shorthand for shrinkBy(length()). */ - void clear(); - - /** Clears and releases any heap-allocated storage. */ - void clearAndFree(); - - /** - * Calls the AllocPolicy's pod_realloc to release excess capacity. Since - * realloc is only safe on PODs, this method fails to compile if IsPod - * is false. - */ - void podResizeToFit(); - - /** - * If true, appending |aNeeded| elements won't reallocate elements storage. - * This *doesn't* mean that infallibleAppend may be used! You still must - * reserve the extra space, even if this method indicates that appends won't - * need to reallocate elements storage. - */ - bool canAppendWithoutRealloc(size_t aNeeded) const; - - /** Potentially fallible append operations. */ - - /** - * This can take either a T& or a T&&. Given a T&&, it moves |aU| into the - * vector, instead of copying it. If it fails, |aU| is left unmoved. ("We are - * not amused.") - */ - template MOZ_MUST_USE bool append(U&& aU); - - /** - * Construct a T in-place as a new entry at the end of this vector. - */ - template - MOZ_MUST_USE bool emplaceBack(Args&&... aArgs) - { - if (!growByUninitialized(1)) - return false; - Impl::new_(&back(), Forward(aArgs)...); - return true; - } - - template - MOZ_MUST_USE bool appendAll(const Vector& aU); - MOZ_MUST_USE bool appendN(const T& aT, size_t aN); - template MOZ_MUST_USE bool append(const U* aBegin, const U* aEnd); - template MOZ_MUST_USE bool append(const U* aBegin, size_t aLength); - - /* - * Guaranteed-infallible append operations for use upon vectors whose - * memory has been pre-reserved. Don't use this if you haven't reserved the - * memory! - */ - template void infallibleAppend(U&& aU) - { - internalAppend(Forward(aU)); - } - void infallibleAppendN(const T& aT, size_t aN) - { - internalAppendN(aT, aN); - } - template void infallibleAppend(const U* aBegin, const U* aEnd) - { - internalAppend(aBegin, PointerRangeSize(aBegin, aEnd)); - } - template void infallibleAppend(const U* aBegin, size_t aLength) - { - internalAppend(aBegin, aLength); - } - template - void infallibleEmplaceBack(Args&&... aArgs) - { - infallibleGrowByUninitialized(1); - Impl::new_(&back(), Forward(aArgs)...); - } - - void popBack(); - - T popCopy(); - - /** - * If elements are stored in-place, return nullptr and leave this vector - * unmodified. - * - * Otherwise return this vector's elements buffer, and clear this vector as if - * by clearAndFree(). The caller now owns the buffer and is responsible for - * deallocating it consistent with this vector's AllocPolicy. - * - * N.B. Although a T*, only the range [0, length()) is constructed. - */ - MOZ_MUST_USE T* extractRawBuffer(); - - /** - * If elements are stored in-place, allocate a new buffer, move this vector's - * elements into it, and return that buffer. - * - * Otherwise return this vector's elements buffer. The caller now owns the - * buffer and is responsible for deallocating it consistent with this vector's - * AllocPolicy. - * - * This vector is cleared, as if by clearAndFree(), when this method - * succeeds. This method fails and returns nullptr only if new elements buffer - * allocation fails. - * - * N.B. Only the range [0, length()) of the returned buffer is constructed. - * If any of these elements are uninitialized (as growByUninitialized - * enables), behavior is undefined. - */ - MOZ_MUST_USE T* extractOrCopyRawBuffer(); - - /** - * Transfer ownership of an array of objects into the vector. The caller - * must have allocated the array in accordance with this vector's - * AllocPolicy. - * - * N.B. This call assumes that there are no uninitialized elements in the - * passed array. - */ - void replaceRawBuffer(T* aP, size_t aLength); - - /** - * Places |aVal| at position |aP|, shifting existing elements from |aP| onward - * one position higher. On success, |aP| should not be reused because it'll - * be a dangling pointer if reallocation of the vector storage occurred; the - * return value should be used instead. On failure, nullptr is returned. - * - * Example usage: - * - * if (!(p = vec.insert(p, val))) { - * - * } - * - * - * This is inherently a linear-time operation. Be careful! - */ - template - MOZ_MUST_USE T* insert(T* aP, U&& aVal); - - /** - * Removes the element |aT|, which must fall in the bounds [begin, end), - * shifting existing elements from |aT + 1| onward one position lower. - */ - void erase(T* aT); - - /** - * Removes the elements [|aBegin|, |aEnd|), which must fall in the bounds - * [begin, end), shifting existing elements from |aEnd + 1| onward to aBegin's - * old position. - */ - void erase(T* aBegin, T* aEnd); - - /** - * Measure the size of the vector's heap-allocated storage. - */ - size_t sizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const; - - /** - * Like sizeOfExcludingThis, but also measures the size of the vector - * object (which must be heap-allocated) itself. - */ - size_t sizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const; - - void swap(Vector& aOther); - -private: - Vector(const Vector&) = delete; - void operator=(const Vector&) = delete; -}; - -/* This does the re-entrancy check plus several other sanity checks. */ -#define MOZ_REENTRANCY_GUARD_ET_AL \ - ReentrancyGuard g(*this); \ - MOZ_ASSERT_IF(usingInlineStorage(), mCapacity == kInlineCapacity); \ - MOZ_ASSERT(reserved() <= mCapacity); \ - MOZ_ASSERT(mLength <= reserved()); \ - MOZ_ASSERT(mLength <= mCapacity) - -/* Vector Implementation */ - -template -MOZ_ALWAYS_INLINE -Vector::Vector(AP aAP) - : AP(aAP) - , mLength(0) - , mCapacity(kInlineCapacity) -#ifdef DEBUG - , mReserved(0) - , mEntered(false) -#endif -{ - mBegin = static_cast(mStorage.addr()); -} - -/* Move constructor. */ -template -MOZ_ALWAYS_INLINE -Vector::Vector(Vector&& aRhs) - : AllocPolicy(Move(aRhs)) -#ifdef DEBUG - , mEntered(false) -#endif -{ - mLength = aRhs.mLength; - mCapacity = aRhs.mCapacity; -#ifdef DEBUG - mReserved = aRhs.mReserved; -#endif - - if (aRhs.usingInlineStorage()) { - /* We can't move the buffer over in this case, so copy elements. */ - mBegin = static_cast(mStorage.addr()); - Impl::moveConstruct(mBegin, aRhs.beginNoCheck(), aRhs.endNoCheck()); - /* - * Leave aRhs's mLength, mBegin, mCapacity, and mReserved as they are. - * The elements in its in-line storage still need to be destroyed. - */ - } else { - /* - * Take src's buffer, and turn src into an empty vector using - * in-line storage. - */ - mBegin = aRhs.mBegin; - aRhs.mBegin = static_cast(aRhs.mStorage.addr()); - aRhs.mCapacity = kInlineCapacity; - aRhs.mLength = 0; -#ifdef DEBUG - aRhs.mReserved = 0; -#endif - } -} - -/* Move assignment. */ -template -MOZ_ALWAYS_INLINE Vector& -Vector::operator=(Vector&& aRhs) -{ - MOZ_ASSERT(this != &aRhs, "self-move assignment is prohibited"); - this->~Vector(); - new(KnownNotNull, this) Vector(Move(aRhs)); - return *this; -} - -template -MOZ_ALWAYS_INLINE -Vector::~Vector() -{ - MOZ_REENTRANCY_GUARD_ET_AL; - Impl::destroy(beginNoCheck(), endNoCheck()); - if (!usingInlineStorage()) { - this->free_(beginNoCheck()); - } -} - -template -MOZ_ALWAYS_INLINE void -Vector::reverse() { - MOZ_REENTRANCY_GUARD_ET_AL; - T* elems = mBegin; - size_t len = mLength; - size_t mid = len / 2; - for (size_t i = 0; i < mid; i++) { - Swap(elems[i], elems[len - i - 1]); - } -} - -/* - * This function will create a new heap buffer with capacity aNewCap, - * move all elements in the inline buffer to this new buffer, - * and fail on OOM. - */ -template -inline bool -Vector::convertToHeapStorage(size_t aNewCap) -{ - MOZ_ASSERT(usingInlineStorage()); - - /* Allocate buffer. */ - MOZ_ASSERT(!detail::CapacityHasExcessSpace(aNewCap)); - T* newBuf = this->template pod_malloc(aNewCap); - if (MOZ_UNLIKELY(!newBuf)) { - return false; - } - - /* Copy inline elements into heap buffer. */ - Impl::moveConstruct(newBuf, beginNoCheck(), endNoCheck()); - Impl::destroy(beginNoCheck(), endNoCheck()); - - /* Switch in heap buffer. */ - mBegin = newBuf; - /* mLength is unchanged. */ - mCapacity = aNewCap; - return true; -} - -template -MOZ_NEVER_INLINE bool -Vector::growStorageBy(size_t aIncr) -{ - MOZ_ASSERT(mLength + aIncr > mCapacity); - - /* - * When choosing a new capacity, its size should is as close to 2**N bytes - * as possible. 2**N-sized requests are best because they are unlikely to - * be rounded up by the allocator. Asking for a 2**N number of elements - * isn't as good, because if sizeof(T) is not a power-of-two that would - * result in a non-2**N request size. - */ - - size_t newCap; - - if (aIncr == 1) { - if (usingInlineStorage()) { - /* This case occurs in ~70--80% of the calls to this function. */ - size_t newSize = - tl::RoundUpPow2<(kInlineCapacity + 1) * sizeof(T)>::value; - newCap = newSize / sizeof(T); - goto convert; - } - - if (mLength == 0) { - /* This case occurs in ~0--10% of the calls to this function. */ - newCap = 1; - goto grow; - } - - /* This case occurs in ~15--20% of the calls to this function. */ - - /* - * Will mLength * 4 *sizeof(T) overflow? This condition limits a vector - * to 1GB of memory on a 32-bit system, which is a reasonable limit. It - * also ensures that - * - * static_cast(end()) - static_cast(begin()) - * - * doesn't overflow ptrdiff_t (see bug 510319). - */ - if (MOZ_UNLIKELY(mLength & tl::MulOverflowMask<4 * sizeof(T)>::value)) { - this->reportAllocOverflow(); - return false; - } - - /* - * If we reach here, the existing capacity will have a size that is already - * as close to 2^N as sizeof(T) will allow. Just double the capacity, and - * then there might be space for one more element. - */ - newCap = mLength * 2; - if (detail::CapacityHasExcessSpace(newCap)) { - newCap += 1; - } - } else { - /* This case occurs in ~2% of the calls to this function. */ - size_t newMinCap = mLength + aIncr; - - /* Did mLength + aIncr overflow? Will newCap * sizeof(T) overflow? */ - if (MOZ_UNLIKELY(newMinCap < mLength || - newMinCap & tl::MulOverflowMask<2 * sizeof(T)>::value)) - { - this->reportAllocOverflow(); - return false; - } - - size_t newMinSize = newMinCap * sizeof(T); - size_t newSize = RoundUpPow2(newMinSize); - newCap = newSize / sizeof(T); - } - - if (usingInlineStorage()) { -convert: - return convertToHeapStorage(newCap); - } - -grow: - return Impl::growTo(*this, newCap); -} - -template -inline bool -Vector::initCapacity(size_t aRequest) -{ - MOZ_ASSERT(empty()); - MOZ_ASSERT(usingInlineStorage()); - if (aRequest == 0) { - return true; - } - T* newbuf = this->template pod_malloc(aRequest); - if (MOZ_UNLIKELY(!newbuf)) { - return false; - } - mBegin = newbuf; - mCapacity = aRequest; -#ifdef DEBUG - mReserved = aRequest; -#endif - return true; -} - -template -inline bool -Vector::initLengthUninitialized(size_t aRequest) -{ - if (!initCapacity(aRequest)) { - return false; - } - infallibleGrowByUninitialized(aRequest); - return true; -} - -template -inline bool -Vector::maybeCheckSimulatedOOM(size_t aRequestedSize) -{ - if (aRequestedSize <= N) { - return true; - } - -#ifdef DEBUG - if (aRequestedSize <= mReserved) { - return true; - } -#endif - - return allocPolicy().checkSimulatedOOM(); -} - -template -inline bool -Vector::reserve(size_t aRequest) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - if (aRequest > mCapacity) { - if (MOZ_UNLIKELY(!growStorageBy(aRequest - mLength))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(aRequest)) { - return false; - } -#ifdef DEBUG - if (aRequest > mReserved) { - mReserved = aRequest; - } - MOZ_ASSERT(mLength <= mReserved); - MOZ_ASSERT(mReserved <= mCapacity); -#endif - return true; -} - -template -inline void -Vector::shrinkBy(size_t aIncr) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - MOZ_ASSERT(aIncr <= mLength); - Impl::destroy(endNoCheck() - aIncr, endNoCheck()); - mLength -= aIncr; -} - -template -MOZ_ALWAYS_INLINE void -Vector::shrinkTo(size_t aNewLength) -{ - MOZ_ASSERT(aNewLength <= mLength); - shrinkBy(mLength - aNewLength); -} - -template -MOZ_ALWAYS_INLINE bool -Vector::growBy(size_t aIncr) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - if (aIncr > mCapacity - mLength) { - if (MOZ_UNLIKELY(!growStorageBy(aIncr))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(mLength + aIncr)) { - return false; - } - MOZ_ASSERT(mLength + aIncr <= mCapacity); - T* newend = endNoCheck() + aIncr; - Impl::initialize(endNoCheck(), newend); - mLength += aIncr; -#ifdef DEBUG - if (mLength > mReserved) { - mReserved = mLength; - } -#endif - return true; -} - -template -MOZ_ALWAYS_INLINE bool -Vector::growByUninitialized(size_t aIncr) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - if (aIncr > mCapacity - mLength) { - if (MOZ_UNLIKELY(!growStorageBy(aIncr))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(mLength + aIncr)) { - return false; - } -#ifdef DEBUG - if (mLength + aIncr > mReserved) { - mReserved = mLength + aIncr; - } -#endif - infallibleGrowByUninitialized(aIncr); - return true; -} - -template -MOZ_ALWAYS_INLINE void -Vector::infallibleGrowByUninitialized(size_t aIncr) -{ - MOZ_ASSERT(mLength + aIncr <= reserved()); - mLength += aIncr; -} - -template -inline bool -Vector::resize(size_t aNewLength) -{ - size_t curLength = mLength; - if (aNewLength > curLength) { - return growBy(aNewLength - curLength); - } - shrinkBy(curLength - aNewLength); - return true; -} - -template -MOZ_ALWAYS_INLINE bool -Vector::resizeUninitialized(size_t aNewLength) -{ - size_t curLength = mLength; - if (aNewLength > curLength) { - return growByUninitialized(aNewLength - curLength); - } - shrinkBy(curLength - aNewLength); - return true; -} - -template -inline void -Vector::clear() -{ - MOZ_REENTRANCY_GUARD_ET_AL; - Impl::destroy(beginNoCheck(), endNoCheck()); - mLength = 0; -} - -template -inline void -Vector::clearAndFree() -{ - clear(); - - if (usingInlineStorage()) { - return; - } - this->free_(beginNoCheck()); - mBegin = static_cast(mStorage.addr()); - mCapacity = kInlineCapacity; -#ifdef DEBUG - mReserved = 0; -#endif -} - -template -inline void -Vector::podResizeToFit() -{ - // This function is only defined if IsPod is true and will fail to compile - // otherwise. - Impl::podResizeToFit(*this); -} - -template -inline bool -Vector::canAppendWithoutRealloc(size_t aNeeded) const -{ - return mLength + aNeeded <= mCapacity; -} - -template -template -MOZ_ALWAYS_INLINE void -Vector::internalAppendAll(const Vector& aOther) -{ - internalAppend(aOther.begin(), aOther.length()); -} - -template -template -MOZ_ALWAYS_INLINE void -Vector::internalAppend(U&& aU) -{ - MOZ_ASSERT(mLength + 1 <= mReserved); - MOZ_ASSERT(mReserved <= mCapacity); - Impl::new_(endNoCheck(), Forward(aU)); - ++mLength; -} - -template -MOZ_ALWAYS_INLINE bool -Vector::appendN(const T& aT, size_t aNeeded) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - if (mLength + aNeeded > mCapacity) { - if (MOZ_UNLIKELY(!growStorageBy(aNeeded))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(mLength + aNeeded)) { - return false; - } -#ifdef DEBUG - if (mLength + aNeeded > mReserved) { - mReserved = mLength + aNeeded; - } -#endif - internalAppendN(aT, aNeeded); - return true; -} - -template -MOZ_ALWAYS_INLINE void -Vector::internalAppendN(const T& aT, size_t aNeeded) -{ - MOZ_ASSERT(mLength + aNeeded <= mReserved); - MOZ_ASSERT(mReserved <= mCapacity); - Impl::copyConstructN(endNoCheck(), aNeeded, aT); - mLength += aNeeded; -} - -template -template -inline T* -Vector::insert(T* aP, U&& aVal) -{ - MOZ_ASSERT(begin() <= aP); - MOZ_ASSERT(aP <= end()); - size_t pos = aP - begin(); - MOZ_ASSERT(pos <= mLength); - size_t oldLength = mLength; - if (pos == oldLength) { - if (!append(Forward(aVal))) { - return nullptr; - } - } else { - T oldBack = Move(back()); - if (!append(Move(oldBack))) { /* Dup the last element. */ - return nullptr; - } - for (size_t i = oldLength; i > pos; --i) { - (*this)[i] = Move((*this)[i - 1]); - } - (*this)[pos] = Forward(aVal); - } - return begin() + pos; -} - -template -inline void -Vector::erase(T* aIt) -{ - MOZ_ASSERT(begin() <= aIt); - MOZ_ASSERT(aIt < end()); - while (aIt + 1 < end()) { - *aIt = Move(*(aIt + 1)); - ++aIt; - } - popBack(); -} - -template -inline void -Vector::erase(T* aBegin, T* aEnd) -{ - MOZ_ASSERT(begin() <= aBegin); - MOZ_ASSERT(aBegin <= aEnd); - MOZ_ASSERT(aEnd <= end()); - while (aEnd < end()) { - *aBegin++ = Move(*aEnd++); - } - shrinkBy(aEnd - aBegin); -} - -template -template -MOZ_ALWAYS_INLINE bool -Vector::append(const U* aInsBegin, const U* aInsEnd) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - size_t aNeeded = PointerRangeSize(aInsBegin, aInsEnd); - if (mLength + aNeeded > mCapacity) { - if (MOZ_UNLIKELY(!growStorageBy(aNeeded))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(mLength + aNeeded)) { - return false; - } -#ifdef DEBUG - if (mLength + aNeeded > mReserved) { - mReserved = mLength + aNeeded; - } -#endif - internalAppend(aInsBegin, aNeeded); - return true; -} - -template -template -MOZ_ALWAYS_INLINE void -Vector::internalAppend(const U* aInsBegin, size_t aInsLength) -{ - MOZ_ASSERT(mLength + aInsLength <= mReserved); - MOZ_ASSERT(mReserved <= mCapacity); - Impl::copyConstruct(endNoCheck(), aInsBegin, aInsBegin + aInsLength); - mLength += aInsLength; -} - -template -template -MOZ_ALWAYS_INLINE bool -Vector::append(U&& aU) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - if (mLength == mCapacity) { - if (MOZ_UNLIKELY(!growStorageBy(1))) { - return false; - } - } else if (!maybeCheckSimulatedOOM(mLength + 1)) { - return false; - } -#ifdef DEBUG - if (mLength + 1 > mReserved) { - mReserved = mLength + 1; - } -#endif - internalAppend(Forward(aU)); - return true; -} - -template -template -MOZ_ALWAYS_INLINE bool -Vector::appendAll(const Vector& aOther) -{ - return append(aOther.begin(), aOther.length()); -} - -template -template -MOZ_ALWAYS_INLINE bool -Vector::append(const U* aInsBegin, size_t aInsLength) -{ - return append(aInsBegin, aInsBegin + aInsLength); -} - -template -MOZ_ALWAYS_INLINE void -Vector::popBack() -{ - MOZ_REENTRANCY_GUARD_ET_AL; - MOZ_ASSERT(!empty()); - --mLength; - endNoCheck()->~T(); -} - -template -MOZ_ALWAYS_INLINE T -Vector::popCopy() -{ - T ret = back(); - popBack(); - return ret; -} - -template -inline T* -Vector::extractRawBuffer() -{ - MOZ_REENTRANCY_GUARD_ET_AL; - - if (usingInlineStorage()) { - return nullptr; - } - - T* ret = mBegin; - mBegin = static_cast(mStorage.addr()); - mLength = 0; - mCapacity = kInlineCapacity; -#ifdef DEBUG - mReserved = 0; -#endif - return ret; -} - -template -inline T* -Vector::extractOrCopyRawBuffer() -{ - if (T* ret = extractRawBuffer()) { - return ret; - } - - MOZ_REENTRANCY_GUARD_ET_AL; - - T* copy = this->template pod_malloc(mLength); - if (!copy) { - return nullptr; - } - - Impl::moveConstruct(copy, beginNoCheck(), endNoCheck()); - Impl::destroy(beginNoCheck(), endNoCheck()); - mBegin = static_cast(mStorage.addr()); - mLength = 0; - mCapacity = kInlineCapacity; -#ifdef DEBUG - mReserved = 0; -#endif - return copy; -} - -template -inline void -Vector::replaceRawBuffer(T* aP, size_t aLength) -{ - MOZ_REENTRANCY_GUARD_ET_AL; - - /* Destroy what we have. */ - Impl::destroy(beginNoCheck(), endNoCheck()); - if (!usingInlineStorage()) { - this->free_(beginNoCheck()); - } - - /* Take in the new buffer. */ - if (aLength <= kInlineCapacity) { - /* - * We convert to inline storage if possible, even though aP might - * otherwise be acceptable. Maybe this behaviour should be - * specifiable with an argument to this function. - */ - mBegin = static_cast(mStorage.addr()); - mLength = aLength; - mCapacity = kInlineCapacity; - Impl::moveConstruct(mBegin, aP, aP + aLength); - Impl::destroy(aP, aP + aLength); - this->free_(aP); - } else { - mBegin = aP; - mLength = aLength; - mCapacity = aLength; - } -#ifdef DEBUG - mReserved = aLength; -#endif -} - -template -inline size_t -Vector::sizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const -{ - return usingInlineStorage() ? 0 : aMallocSizeOf(beginNoCheck()); -} - -template -inline size_t -Vector::sizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const -{ - return aMallocSizeOf(this) + sizeOfExcludingThis(aMallocSizeOf); -} - -template -inline void -Vector::swap(Vector& aOther) -{ - static_assert(N == 0, - "still need to implement this for N != 0"); - - // This only works when inline storage is always empty. - if (!usingInlineStorage() && aOther.usingInlineStorage()) { - aOther.mBegin = mBegin; - mBegin = inlineStorage(); - } else if (usingInlineStorage() && !aOther.usingInlineStorage()) { - mBegin = aOther.mBegin; - aOther.mBegin = aOther.inlineStorage(); - } else if (!usingInlineStorage() && !aOther.usingInlineStorage()) { - Swap(mBegin, aOther.mBegin); - } else { - // This case is a no-op, since we'd set both to use their inline storage. - } - - Swap(mLength, aOther.mLength); - Swap(mCapacity, aOther.mCapacity); -#ifdef DEBUG - Swap(mReserved, aOther.mReserved); -#endif -} - -} // namespace mozilla - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#endif /* mozilla_Vector_h */ diff --git a/android/x86/include/spidermonkey/mozilla/WeakPtr.h b/android/x86/include/spidermonkey/mozilla/WeakPtr.h deleted file mode 100644 index ef0c19f4..00000000 --- a/android/x86/include/spidermonkey/mozilla/WeakPtr.h +++ /dev/null @@ -1,283 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* Weak pointer functionality, implemented as a mixin for use with any class. */ - -/** - * SupportsWeakPtr lets you have a pointer to an object 'Foo' without affecting - * its lifetime. It works by creating a single shared reference counted object - * (WeakReference) that each WeakPtr will access 'Foo' through. This lets 'Foo' - * clear the pointer in the WeakReference without having to know about all of - * the WeakPtrs to it and allows the WeakReference to live beyond the lifetime - * of 'Foo'. - * - * PLEASE NOTE: This weak pointer implementation is not thread-safe. - * - * Note that when deriving from SupportsWeakPtr you should add - * MOZ_DECLARE_WEAKREFERENCE_TYPENAME(ClassName) to the public section of your - * class, where ClassName is the name of your class. - * - * The overhead of WeakPtr is that accesses to 'Foo' becomes an additional - * dereference, and an additional heap allocated pointer sized object shared - * between all of the WeakPtrs. - * - * Example of usage: - * - * // To have a class C support weak pointers, inherit from - * // SupportsWeakPtr. - * class C : public SupportsWeakPtr - * { - * public: - * MOZ_DECLARE_WEAKREFERENCE_TYPENAME(C) - * int mNum; - * void act(); - * }; - * - * C* ptr = new C(); - * - * // Get weak pointers to ptr. The first time a weak pointer - * // is obtained, a reference counted WeakReference object is created that - * // can live beyond the lifetime of 'ptr'. The WeakReference - * // object will be notified of 'ptr's destruction. - * WeakPtr weak = ptr; - * WeakPtr other = ptr; - * - * // Test a weak pointer for validity before using it. - * if (weak) { - * weak->mNum = 17; - * weak->act(); - * } - * - * // Destroying the underlying object clears weak pointers to it. - * delete ptr; - * - * MOZ_ASSERT(!weak, "Deleting |ptr| clears weak pointers to it."); - * MOZ_ASSERT(!other, "Deleting |ptr| clears all weak pointers to it."); - * - * WeakPtr is typesafe and may be used with any class. It is not required that - * the class be reference-counted or allocated in any particular way. - * - * The API was loosely inspired by Chromium's weak_ptr.h: - * http://src.chromium.org/svn/trunk/src/base/memory/weak_ptr.h - */ - -#ifndef mozilla_WeakPtr_h -#define mozilla_WeakPtr_h - -#include "mozilla/ArrayUtils.h" -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/RefCounted.h" -#include "mozilla/RefPtr.h" -#include "mozilla/TypeTraits.h" - -#include - -// Weak referencing is not implemeted as thread safe. When a WeakPtr -// is created or dereferenced on thread A but the real object is just -// being Released() on thread B, there is a possibility of a race -// when the proxy object (detail::WeakReference) is notified about -// the real object destruction just between when thread A is storing -// the object pointer locally and is about to add a reference to it. -// -// Hence, a non-null weak proxy object is considered to have a single -// "owning thread". It means that each query for a weak reference, -// its dereference, and destruction of the real object must all happen -// on a single thread. The following macros implement assertions for -// checking these conditions. -// -// We disable this on MinGW. MinGW has two threading models: win32 -// API based, which disables std::thread; and POSIX based which -// enables it but requires an emulation library (winpthreads). -// Rather than attempting to switch to pthread emulation at this point, -// we are disabling the std::thread based assertion checking. -// -// In the future, to enable it we could -// a. have libgcc/stdc++ support win32 threads natively -// b. switch to POSIX-based threading in MinGW with pthread emulation -// c. refactor it to not use std::thread - -#if !defined(__MINGW32__) && (defined(DEBUG) || (defined(NIGHTLY_BUILD) && !defined(MOZ_PROFILING))) - -#include -#define MOZ_WEAKPTR_DECLARE_THREAD_SAFETY_CHECK \ - std::thread::id _owningThread; \ - bool _empty; // If it was initialized as a placeholder with mPtr = nullptr. -#define MOZ_WEAKPTR_INIT_THREAD_SAFETY_CHECK() \ - do { \ - _owningThread = std::this_thread::get_id(); \ - _empty = !p; \ - } while (false) -#define MOZ_WEAKPTR_ASSERT_THREAD_SAFETY() \ - MOZ_DIAGNOSTIC_ASSERT(_empty || _owningThread == std::this_thread::get_id(), \ - "WeakPtr used on multiple threads") -#define MOZ_WEAKPTR_ASSERT_THREAD_SAFETY_DELEGATED(that) \ - (that)->AssertThreadSafety(); - -#define MOZ_WEAKPTR_THREAD_SAFETY_CHECKING 1 - -#else - -#define MOZ_WEAKPTR_DECLARE_THREAD_SAFETY_CHECK -#define MOZ_WEAKPTR_INIT_THREAD_SAFETY_CHECK() do { } while (false) -#define MOZ_WEAKPTR_ASSERT_THREAD_SAFETY() do { } while (false) -#define MOZ_WEAKPTR_ASSERT_THREAD_SAFETY_DELEGATED(that) do { } while (false) - -#endif - -namespace mozilla { - -template class WeakPtr; -template class SupportsWeakPtr; - -#ifdef MOZ_REFCOUNTED_LEAK_CHECKING -#define MOZ_DECLARE_WEAKREFERENCE_TYPENAME(T) \ - static const char* weakReferenceTypeName() { return "WeakReference<" #T ">"; } -#else -#define MOZ_DECLARE_WEAKREFERENCE_TYPENAME(T) -#endif - -namespace detail { - -// This can live beyond the lifetime of the class derived from -// SupportsWeakPtr. -template -class WeakReference : public ::mozilla::RefCounted > -{ -public: - explicit WeakReference(T* p) : mPtr(p) - { - MOZ_WEAKPTR_INIT_THREAD_SAFETY_CHECK(); - } - - T* get() const { - MOZ_WEAKPTR_ASSERT_THREAD_SAFETY(); - return mPtr; - } - -#ifdef MOZ_REFCOUNTED_LEAK_CHECKING - const char* typeName() const - { - // The first time this is called mPtr is null, so don't - // invoke any methods on mPtr. - return T::weakReferenceTypeName(); - } - size_t typeSize() const { return sizeof(*this); } -#endif - -#ifdef MOZ_WEAKPTR_THREAD_SAFETY_CHECKING - void AssertThreadSafety() { MOZ_WEAKPTR_ASSERT_THREAD_SAFETY(); } -#endif - -private: - friend class mozilla::SupportsWeakPtr; - - void detach() { - MOZ_WEAKPTR_ASSERT_THREAD_SAFETY(); - mPtr = nullptr; - } - - T* MOZ_NON_OWNING_REF mPtr; - MOZ_WEAKPTR_DECLARE_THREAD_SAFETY_CHECK -}; - -} // namespace detail - -template -class SupportsWeakPtr -{ -protected: - ~SupportsWeakPtr() - { - static_assert(IsBaseOf, T>::value, - "T must derive from SupportsWeakPtr"); - if (mSelfReferencingWeakPtr) { - mSelfReferencingWeakPtr.mRef->detach(); - } - } - -private: - const WeakPtr& SelfReferencingWeakPtr() - { - if (!mSelfReferencingWeakPtr) { - mSelfReferencingWeakPtr.mRef = new detail::WeakReference(static_cast(this)); - } else { - MOZ_WEAKPTR_ASSERT_THREAD_SAFETY_DELEGATED(mSelfReferencingWeakPtr.mRef); - } - return mSelfReferencingWeakPtr; - } - - const WeakPtr& SelfReferencingWeakPtr() const - { - const WeakPtr& p = const_cast(this)->SelfReferencingWeakPtr(); - return reinterpret_cast&>(p); - } - - friend class WeakPtr; - friend class WeakPtr; - - WeakPtr mSelfReferencingWeakPtr; -}; - -template -class WeakPtr -{ - typedef detail::WeakReference WeakReference; - -public: - WeakPtr& operator=(const WeakPtr& aOther) - { - mRef = aOther.mRef; - MOZ_WEAKPTR_ASSERT_THREAD_SAFETY_DELEGATED(mRef); - return *this; - } - - WeakPtr(const WeakPtr& aOther) - { - // The thread safety check is performed inside of the operator= method. - *this = aOther; - } - - WeakPtr& operator=(T* aOther) - { - if (aOther) { - *this = aOther->SelfReferencingWeakPtr(); - } else if (!mRef || mRef->get()) { - // Ensure that mRef is dereferenceable in the uninitialized state. - mRef = new WeakReference(nullptr); - } - // The thread safety check happens inside SelfReferencingWeakPtr - // or is initialized in the WeakReference constructor. - return *this; - } - - MOZ_IMPLICIT WeakPtr(T* aOther) - { - *this = aOther; - MOZ_WEAKPTR_ASSERT_THREAD_SAFETY_DELEGATED(mRef); - } - - // Ensure that mRef is dereferenceable in the uninitialized state. - WeakPtr() : mRef(new WeakReference(nullptr)) {} - - operator T*() const { return mRef->get(); } - T& operator*() const { return *mRef->get(); } - - T* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN { return mRef->get(); } - - T* get() const { return mRef->get(); } - -private: - friend class SupportsWeakPtr; - - explicit WeakPtr(const RefPtr& aOther) : mRef(aOther) {} - - RefPtr mRef; -}; - -} // namespace mozilla - -#endif /* mozilla_WeakPtr_h */ diff --git a/android/x86/include/spidermonkey/mozilla/XorShift128PlusRNG.h b/android/x86/include/spidermonkey/mozilla/XorShift128PlusRNG.h deleted file mode 100644 index 2f182f0f..00000000 --- a/android/x86/include/spidermonkey/mozilla/XorShift128PlusRNG.h +++ /dev/null @@ -1,121 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/* The xorshift128+ pseudo-random number generator. */ - -#ifndef mozilla_XorShift128Plus_h -#define mozilla_XorShift128Plus_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/FloatingPoint.h" - -#include - -namespace mozilla { -namespace non_crypto { - -/* - * A stream of pseudo-random numbers generated using the xorshift+ technique - * described here: - * - * Vigna, Sebastiano (2014). "Further scramblings of Marsaglia's xorshift - * generators". arXiv:1404.0390 (http://arxiv.org/abs/1404.0390) - * - * That paper says: - * - * In particular, we propose a tightly coded xorshift128+ generator that - * does not fail systematically any test from the BigCrush suite of TestU01 - * (even reversed) and generates 64 pseudorandom bits in 1.10 ns on an - * Intel(R) Core(TM) i7-4770 CPU @3.40GHz (Haswell). It is the fastest - * generator we are aware of with such empirical statistical properties. - * - * The stream of numbers produced by this method repeats every 2**128 - 1 calls - * (i.e. never, for all practical purposes). Zero appears 2**64 - 1 times in - * this period; all other numbers appear 2**64 times. Additionally, each *bit* - * in the produced numbers repeats every 2**128 - 1 calls. - * - * This generator is not suitable as a cryptographically secure random number - * generator. - */ -class XorShift128PlusRNG { - uint64_t mState[2]; - - public: - /* - * Construct a xorshift128+ pseudo-random number stream using |aInitial0| and - * |aInitial1| as the initial state. These MUST NOT both be zero. - * - * If the initial states contain many zeros, for a few iterations you'll see - * many zeroes in the generated numbers. It's suggested to seed a SplitMix64 - * generator and use its first two - * outputs to seed xorshift128+. - */ - XorShift128PlusRNG(uint64_t aInitial0, uint64_t aInitial1) { - setState(aInitial0, aInitial1); - } - - /** - * Return a pseudo-random 64-bit number. - */ - uint64_t next() { - /* - * The offsetOfState*() methods below are provided so that exceedingly-rare - * callers that want to observe or poke at RNG state in C++ type-system- - * ignoring means can do so. Don't change the next() or nextDouble() - * algorithms without altering code that uses offsetOfState*()! - */ - uint64_t s1 = mState[0]; - const uint64_t s0 = mState[1]; - mState[0] = s0; - s1 ^= s1 << 23; - mState[1] = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26); - return mState[1] + s0; - } - - /* - * Return a pseudo-random floating-point value in the range [0, 1). More - * precisely, choose an integer in the range [0, 2**53) and divide it by - * 2**53. Given the 2**128 - 1 period noted above, the produced doubles are - * all but uniformly distributed in this range. - */ - double nextDouble() { - /* - * Because the IEEE 64-bit floating point format stores the leading '1' bit - * of the mantissa implicitly, it effectively represents a mantissa in the - * range [0, 2**53) in only 52 bits. FloatingPoint::kExponentShift - * is the width of the bitfield in the in-memory format, so we must add one - * to get the mantissa's range. - */ - static constexpr int kMantissaBits = - mozilla::FloatingPoint::kExponentShift + 1; - uint64_t mantissa = next() & ((UINT64_C(1) << kMantissaBits) - 1); - return double(mantissa) / (UINT64_C(1) << kMantissaBits); - } - - /* - * Set the stream's current state to |aState0| and |aState1|. These must not - * both be zero; ideally, they should have an almost even mix of zero and one - * bits. - */ - void setState(uint64_t aState0, uint64_t aState1) { - MOZ_ASSERT(aState0 || aState1); - mState[0] = aState0; - mState[1] = aState1; - } - - static size_t offsetOfState0() { - return offsetof(XorShift128PlusRNG, mState[0]); - } - static size_t offsetOfState1() { - return offsetof(XorShift128PlusRNG, mState[1]); - } -}; - -} // namespace non_crypto -} // namespace mozilla - -#endif // mozilla_XorShift128Plus_h diff --git a/android/x86/include/spidermonkey/mozilla/double-conversion.h b/android/x86/include/spidermonkey/mozilla/double-conversion.h deleted file mode 100644 index 957575cf..00000000 --- a/android/x86/include/spidermonkey/mozilla/double-conversion.h +++ /dev/null @@ -1,538 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ -#define DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ - -#include "mozilla/Types.h" -#include "utils.h" - -namespace double_conversion { - -class DoubleToStringConverter { - public: - // When calling ToFixed with a double > 10^kMaxFixedDigitsBeforePoint - // or a requested_digits parameter > kMaxFixedDigitsAfterPoint then the - // function returns false. - static const int kMaxFixedDigitsBeforePoint = 60; - static const int kMaxFixedDigitsAfterPoint = 60; - - // When calling ToExponential with a requested_digits - // parameter > kMaxExponentialDigits then the function returns false. - static const int kMaxExponentialDigits = 120; - - // When calling ToPrecision with a requested_digits - // parameter < kMinPrecisionDigits or requested_digits > kMaxPrecisionDigits - // then the function returns false. - static const int kMinPrecisionDigits = 1; - static const int kMaxPrecisionDigits = 120; - - enum Flags { - NO_FLAGS = 0, - EMIT_POSITIVE_EXPONENT_SIGN = 1, - EMIT_TRAILING_DECIMAL_POINT = 2, - EMIT_TRAILING_ZERO_AFTER_POINT = 4, - UNIQUE_ZERO = 8 - }; - - // Flags should be a bit-or combination of the possible Flags-enum. - // - NO_FLAGS: no special flags. - // - EMIT_POSITIVE_EXPONENT_SIGN: when the number is converted into exponent - // form, emits a '+' for positive exponents. Example: 1.2e+2. - // - EMIT_TRAILING_DECIMAL_POINT: when the input number is an integer and is - // converted into decimal format then a trailing decimal point is appended. - // Example: 2345.0 is converted to "2345.". - // - EMIT_TRAILING_ZERO_AFTER_POINT: in addition to a trailing decimal point - // emits a trailing '0'-character. This flag requires the - // EXMIT_TRAILING_DECIMAL_POINT flag. - // Example: 2345.0 is converted to "2345.0". - // - UNIQUE_ZERO: "-0.0" is converted to "0.0". - // - // Infinity symbol and nan_symbol provide the string representation for these - // special values. If the string is NULL and the special value is encountered - // then the conversion functions return false. - // - // The exponent_character is used in exponential representations. It is - // usually 'e' or 'E'. - // - // When converting to the shortest representation the converter will - // represent input numbers in decimal format if they are in the interval - // [10^decimal_in_shortest_low; 10^decimal_in_shortest_high[ - // (lower boundary included, greater boundary excluded). - // Example: with decimal_in_shortest_low = -6 and - // decimal_in_shortest_high = 21: - // ToShortest(0.000001) -> "0.000001" - // ToShortest(0.0000001) -> "1e-7" - // ToShortest(111111111111111111111.0) -> "111111111111111110000" - // ToShortest(100000000000000000000.0) -> "100000000000000000000" - // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21" - // - // When converting to precision mode the converter may add - // max_leading_padding_zeroes before returning the number in exponential - // format. - // Example with max_leading_padding_zeroes_in_precision_mode = 6. - // ToPrecision(0.0000012345, 2) -> "0.0000012" - // ToPrecision(0.00000012345, 2) -> "1.2e-7" - // Similarily the converter may add up to - // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid - // returning an exponential representation. A zero added by the - // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit. - // Examples for max_trailing_padding_zeroes_in_precision_mode = 1: - // ToPrecision(230.0, 2) -> "230" - // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT. - // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT. - DoubleToStringConverter(int flags, - const char* infinity_symbol, - const char* nan_symbol, - char exponent_character, - int decimal_in_shortest_low, - int decimal_in_shortest_high, - int max_leading_padding_zeroes_in_precision_mode, - int max_trailing_padding_zeroes_in_precision_mode) - : flags_(flags), - infinity_symbol_(infinity_symbol), - nan_symbol_(nan_symbol), - exponent_character_(exponent_character), - decimal_in_shortest_low_(decimal_in_shortest_low), - decimal_in_shortest_high_(decimal_in_shortest_high), - max_leading_padding_zeroes_in_precision_mode_( - max_leading_padding_zeroes_in_precision_mode), - max_trailing_padding_zeroes_in_precision_mode_( - max_trailing_padding_zeroes_in_precision_mode) { - // When 'trailing zero after the point' is set, then 'trailing point' - // must be set too. - ASSERT(((flags & EMIT_TRAILING_DECIMAL_POINT) != 0) || - !((flags & EMIT_TRAILING_ZERO_AFTER_POINT) != 0)); - } - - // Returns a converter following the EcmaScript specification. - static MFBT_API const DoubleToStringConverter& EcmaScriptConverter(); - - // Computes the shortest string of digits that correctly represent the input - // number. Depending on decimal_in_shortest_low and decimal_in_shortest_high - // (see constructor) it then either returns a decimal representation, or an - // exponential representation. - // Example with decimal_in_shortest_low = -6, - // decimal_in_shortest_high = 21, - // EMIT_POSITIVE_EXPONENT_SIGN activated, and - // EMIT_TRAILING_DECIMAL_POINT deactived: - // ToShortest(0.000001) -> "0.000001" - // ToShortest(0.0000001) -> "1e-7" - // ToShortest(111111111111111111111.0) -> "111111111111111110000" - // ToShortest(100000000000000000000.0) -> "100000000000000000000" - // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21" - // - // Note: the conversion may round the output if the returned string - // is accurate enough to uniquely identify the input-number. - // For example the most precise representation of the double 9e59 equals - // "899999999999999918767229449717619953810131273674690656206848", but - // the converter will return the shorter (but still correct) "9e59". - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except when the input value is special and no infinity_symbol or - // nan_symbol has been given to the constructor. - bool ToShortest(double value, StringBuilder* result_builder) const { - return ToShortestIeeeNumber(value, result_builder, SHORTEST); - } - - // Same as ToShortest, but for single-precision floats. - bool ToShortestSingle(float value, StringBuilder* result_builder) const { - return ToShortestIeeeNumber(value, result_builder, SHORTEST_SINGLE); - } - - - // Computes a decimal representation with a fixed number of digits after the - // decimal point. The last emitted digit is rounded. - // - // Examples: - // ToFixed(3.12, 1) -> "3.1" - // ToFixed(3.1415, 3) -> "3.142" - // ToFixed(1234.56789, 4) -> "1234.5679" - // ToFixed(1.23, 5) -> "1.23000" - // ToFixed(0.1, 4) -> "0.1000" - // ToFixed(1e30, 2) -> "1000000000000000019884624838656.00" - // ToFixed(0.1, 30) -> "0.100000000000000005551115123126" - // ToFixed(0.1, 17) -> "0.10000000000000001" - // - // If requested_digits equals 0, then the tail of the result depends on - // the EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT. - // Examples, for requested_digits == 0, - // let EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT be - // - false and false: then 123.45 -> 123 - // 0.678 -> 1 - // - true and false: then 123.45 -> 123. - // 0.678 -> 1. - // - true and true: then 123.45 -> 123.0 - // 0.678 -> 1.0 - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except for the following cases: - // - the input value is special and no infinity_symbol or nan_symbol has - // been provided to the constructor, - // - 'value' > 10^kMaxFixedDigitsBeforePoint, or - // - 'requested_digits' > kMaxFixedDigitsAfterPoint. - // The last two conditions imply that the result will never contain more than - // 1 + kMaxFixedDigitsBeforePoint + 1 + kMaxFixedDigitsAfterPoint characters - // (one additional character for the sign, and one for the decimal point). - MFBT_API bool ToFixed(double value, - int requested_digits, - StringBuilder* result_builder) const; - - // Computes a representation in exponential format with requested_digits - // after the decimal point. The last emitted digit is rounded. - // If requested_digits equals -1, then the shortest exponential representation - // is computed. - // - // Examples with EMIT_POSITIVE_EXPONENT_SIGN deactivated, and - // exponent_character set to 'e'. - // ToExponential(3.12, 1) -> "3.1e0" - // ToExponential(5.0, 3) -> "5.000e0" - // ToExponential(0.001, 2) -> "1.00e-3" - // ToExponential(3.1415, -1) -> "3.1415e0" - // ToExponential(3.1415, 4) -> "3.1415e0" - // ToExponential(3.1415, 3) -> "3.142e0" - // ToExponential(123456789000000, 3) -> "1.235e14" - // ToExponential(1000000000000000019884624838656.0, -1) -> "1e30" - // ToExponential(1000000000000000019884624838656.0, 32) -> - // "1.00000000000000001988462483865600e30" - // ToExponential(1234, 0) -> "1e3" - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except for the following cases: - // - the input value is special and no infinity_symbol or nan_symbol has - // been provided to the constructor, - // - 'requested_digits' > kMaxExponentialDigits. - // The last condition implies that the result will never contain more than - // kMaxExponentialDigits + 8 characters (the sign, the digit before the - // decimal point, the decimal point, the exponent character, the - // exponent's sign, and at most 3 exponent digits). - MFBT_API bool ToExponential(double value, - int requested_digits, - StringBuilder* result_builder) const; - - // Computes 'precision' leading digits of the given 'value' and returns them - // either in exponential or decimal format, depending on - // max_{leading|trailing}_padding_zeroes_in_precision_mode (given to the - // constructor). - // The last computed digit is rounded. - // - // Example with max_leading_padding_zeroes_in_precision_mode = 6. - // ToPrecision(0.0000012345, 2) -> "0.0000012" - // ToPrecision(0.00000012345, 2) -> "1.2e-7" - // Similarily the converter may add up to - // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid - // returning an exponential representation. A zero added by the - // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit. - // Examples for max_trailing_padding_zeroes_in_precision_mode = 1: - // ToPrecision(230.0, 2) -> "230" - // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT. - // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT. - // Examples for max_trailing_padding_zeroes_in_precision_mode = 3, and no - // EMIT_TRAILING_ZERO_AFTER_POINT: - // ToPrecision(123450.0, 6) -> "123450" - // ToPrecision(123450.0, 5) -> "123450" - // ToPrecision(123450.0, 4) -> "123500" - // ToPrecision(123450.0, 3) -> "123000" - // ToPrecision(123450.0, 2) -> "1.2e5" - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except for the following cases: - // - the input value is special and no infinity_symbol or nan_symbol has - // been provided to the constructor, - // - precision < kMinPericisionDigits - // - precision > kMaxPrecisionDigits - // The last condition implies that the result will never contain more than - // kMaxPrecisionDigits + 7 characters (the sign, the decimal point, the - // exponent character, the exponent's sign, and at most 3 exponent digits). - MFBT_API bool ToPrecision(double value, - int precision, - bool* used_exponential_notation, - StringBuilder* result_builder) const; - - enum DtoaMode { - // Produce the shortest correct representation. - // For example the output of 0.299999999999999988897 is (the less accurate - // but correct) 0.3. - SHORTEST, - // Same as SHORTEST, but for single-precision floats. - SHORTEST_SINGLE, - // Produce a fixed number of digits after the decimal point. - // For instance fixed(0.1, 4) becomes 0.1000 - // If the input number is big, the output will be big. - FIXED, - // Fixed number of digits (independent of the decimal point). - PRECISION - }; - - // The maximal number of digits that are needed to emit a double in base 10. - // A higher precision can be achieved by using more digits, but the shortest - // accurate representation of any double will never use more digits than - // kBase10MaximalLength. - // Note that DoubleToAscii null-terminates its input. So the given buffer - // should be at least kBase10MaximalLength + 1 characters long. - static const MFBT_DATA int kBase10MaximalLength = 17; - - // Converts the given double 'v' to ascii. 'v' must not be NaN, +Infinity, or - // -Infinity. In SHORTEST_SINGLE-mode this restriction also applies to 'v' - // after it has been casted to a single-precision float. That is, in this - // mode static_cast(v) must not be NaN, +Infinity or -Infinity. - // - // The result should be interpreted as buffer * 10^(point-length). - // - // The output depends on the given mode: - // - SHORTEST: produce the least amount of digits for which the internal - // identity requirement is still satisfied. If the digits are printed - // (together with the correct exponent) then reading this number will give - // 'v' again. The buffer will choose the representation that is closest to - // 'v'. If there are two at the same distance, than the one farther away - // from 0 is chosen (halfway cases - ending with 5 - are rounded up). - // In this mode the 'requested_digits' parameter is ignored. - // - SHORTEST_SINGLE: same as SHORTEST but with single-precision. - // - FIXED: produces digits necessary to print a given number with - // 'requested_digits' digits after the decimal point. The produced digits - // might be too short in which case the caller has to fill the remainder - // with '0's. - // Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2. - // Halfway cases are rounded towards +/-Infinity (away from 0). The call - // toFixed(0.15, 2) thus returns buffer="2", point=0. - // The returned buffer may contain digits that would be truncated from the - // shortest representation of the input. - // - PRECISION: produces 'requested_digits' where the first digit is not '0'. - // Even though the length of produced digits usually equals - // 'requested_digits', the function is allowed to return fewer digits, in - // which case the caller has to fill the missing digits with '0's. - // Halfway cases are again rounded away from 0. - // DoubleToAscii expects the given buffer to be big enough to hold all - // digits and a terminating null-character. In SHORTEST-mode it expects a - // buffer of at least kBase10MaximalLength + 1. In all other modes the - // requested_digits parameter and the padding-zeroes limit the size of the - // output. Don't forget the decimal point, the exponent character and the - // terminating null-character when computing the maximal output size. - // The given length is only used in debug mode to ensure the buffer is big - // enough. - static MFBT_API void DoubleToAscii(double v, - DtoaMode mode, - int requested_digits, - char* buffer, - int buffer_length, - bool* sign, - int* length, - int* point); - - private: - // Implementation for ToShortest and ToShortestSingle. - MFBT_API bool ToShortestIeeeNumber(double value, - StringBuilder* result_builder, - DtoaMode mode) const; - - // If the value is a special value (NaN or Infinity) constructs the - // corresponding string using the configured infinity/nan-symbol. - // If either of them is NULL or the value is not special then the - // function returns false. - MFBT_API bool HandleSpecialValues(double value, StringBuilder* result_builder) const; - // Constructs an exponential representation (i.e. 1.234e56). - // The given exponent assumes a decimal point after the first decimal digit. - MFBT_API void CreateExponentialRepresentation(const char* decimal_digits, - int length, - int exponent, - StringBuilder* result_builder) const; - // Creates a decimal representation (i.e 1234.5678). - MFBT_API void CreateDecimalRepresentation(const char* decimal_digits, - int length, - int decimal_point, - int digits_after_point, - StringBuilder* result_builder) const; - - const int flags_; - const char* const infinity_symbol_; - const char* const nan_symbol_; - const char exponent_character_; - const int decimal_in_shortest_low_; - const int decimal_in_shortest_high_; - const int max_leading_padding_zeroes_in_precision_mode_; - const int max_trailing_padding_zeroes_in_precision_mode_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter); -}; - - -class StringToDoubleConverter { - public: - // Enumeration for allowing octals and ignoring junk when converting - // strings to numbers. - enum Flags { - NO_FLAGS = 0, - ALLOW_HEX = 1, - ALLOW_OCTALS = 2, - ALLOW_TRAILING_JUNK = 4, - ALLOW_LEADING_SPACES = 8, - ALLOW_TRAILING_SPACES = 16, - ALLOW_SPACES_AFTER_SIGN = 32 - }; - - // Flags should be a bit-or combination of the possible Flags-enum. - // - NO_FLAGS: no special flags. - // - ALLOW_HEX: recognizes the prefix "0x". Hex numbers may only be integers. - // Ex: StringToDouble("0x1234") -> 4660.0 - // In StringToDouble("0x1234.56") the characters ".56" are trailing - // junk. The result of the call is hence dependent on - // the ALLOW_TRAILING_JUNK flag and/or the junk value. - // With this flag "0x" is a junk-string. Even with ALLOW_TRAILING_JUNK, - // the string will not be parsed as "0" followed by junk. - // - // - ALLOW_OCTALS: recognizes the prefix "0" for octals: - // If a sequence of octal digits starts with '0', then the number is - // read as octal integer. Octal numbers may only be integers. - // Ex: StringToDouble("01234") -> 668.0 - // StringToDouble("012349") -> 12349.0 // Not a sequence of octal - // // digits. - // In StringToDouble("01234.56") the characters ".56" are trailing - // junk. The result of the call is hence dependent on - // the ALLOW_TRAILING_JUNK flag and/or the junk value. - // In StringToDouble("01234e56") the characters "e56" are trailing - // junk, too. - // - ALLOW_TRAILING_JUNK: ignore trailing characters that are not part of - // a double literal. - // - ALLOW_LEADING_SPACES: skip over leading spaces. - // - ALLOW_TRAILING_SPACES: ignore trailing spaces. - // - ALLOW_SPACES_AFTER_SIGN: ignore spaces after the sign. - // Ex: StringToDouble("- 123.2") -> -123.2. - // StringToDouble("+ 123.2") -> 123.2 - // - // empty_string_value is returned when an empty string is given as input. - // If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a string - // containing only spaces is converted to the 'empty_string_value', too. - // - // junk_string_value is returned when - // a) ALLOW_TRAILING_JUNK is not set, and a junk character (a character not - // part of a double-literal) is found. - // b) ALLOW_TRAILING_JUNK is set, but the string does not start with a - // double literal. - // - // infinity_symbol and nan_symbol are strings that are used to detect - // inputs that represent infinity and NaN. They can be null, in which case - // they are ignored. - // The conversion routine first reads any possible signs. Then it compares the - // following character of the input-string with the first character of - // the infinity, and nan-symbol. If either matches, the function assumes, that - // a match has been found, and expects the following input characters to match - // the remaining characters of the special-value symbol. - // This means that the following restrictions apply to special-value symbols: - // - they must not start with signs ('+', or '-'), - // - they must not have the same first character. - // - they must not start with digits. - // - // Examples: - // flags = ALLOW_HEX | ALLOW_TRAILING_JUNK, - // empty_string_value = 0.0, - // junk_string_value = NaN, - // infinity_symbol = "infinity", - // nan_symbol = "nan": - // StringToDouble("0x1234") -> 4660.0. - // StringToDouble("0x1234K") -> 4660.0. - // StringToDouble("") -> 0.0 // empty_string_value. - // StringToDouble(" ") -> NaN // junk_string_value. - // StringToDouble(" 1") -> NaN // junk_string_value. - // StringToDouble("0x") -> NaN // junk_string_value. - // StringToDouble("-123.45") -> -123.45. - // StringToDouble("--123.45") -> NaN // junk_string_value. - // StringToDouble("123e45") -> 123e45. - // StringToDouble("123E45") -> 123e45. - // StringToDouble("123e+45") -> 123e45. - // StringToDouble("123E-45") -> 123e-45. - // StringToDouble("123e") -> 123.0 // trailing junk ignored. - // StringToDouble("123e-") -> 123.0 // trailing junk ignored. - // StringToDouble("+NaN") -> NaN // NaN string literal. - // StringToDouble("-infinity") -> -inf. // infinity literal. - // StringToDouble("Infinity") -> NaN // junk_string_value. - // - // flags = ALLOW_OCTAL | ALLOW_LEADING_SPACES, - // empty_string_value = 0.0, - // junk_string_value = NaN, - // infinity_symbol = NULL, - // nan_symbol = NULL: - // StringToDouble("0x1234") -> NaN // junk_string_value. - // StringToDouble("01234") -> 668.0. - // StringToDouble("") -> 0.0 // empty_string_value. - // StringToDouble(" ") -> 0.0 // empty_string_value. - // StringToDouble(" 1") -> 1.0 - // StringToDouble("0x") -> NaN // junk_string_value. - // StringToDouble("0123e45") -> NaN // junk_string_value. - // StringToDouble("01239E45") -> 1239e45. - // StringToDouble("-infinity") -> NaN // junk_string_value. - // StringToDouble("NaN") -> NaN // junk_string_value. - StringToDoubleConverter(int flags, - double empty_string_value, - double junk_string_value, - const char* infinity_symbol, - const char* nan_symbol) - : flags_(flags), - empty_string_value_(empty_string_value), - junk_string_value_(junk_string_value), - infinity_symbol_(infinity_symbol), - nan_symbol_(nan_symbol) { - } - - // Performs the conversion. - // The output parameter 'processed_characters_count' is set to the number - // of characters that have been processed to read the number. - // Spaces than are processed with ALLOW_{LEADING|TRAILING}_SPACES are included - // in the 'processed_characters_count'. Trailing junk is never included. - double StringToDouble(const char* buffer, - int length, - int* processed_characters_count) const { - return StringToIeee(buffer, length, processed_characters_count, true); - } - - // Same as StringToDouble but reads a float. - // Note that this is not equivalent to static_cast(StringToDouble(...)) - // due to potential double-rounding. - float StringToFloat(const char* buffer, - int length, - int* processed_characters_count) const { - return static_cast(StringToIeee(buffer, length, - processed_characters_count, false)); - } - - private: - const int flags_; - const double empty_string_value_; - const double junk_string_value_; - const char* const infinity_symbol_; - const char* const nan_symbol_; - - double StringToIeee(const char* buffer, - int length, - int* processed_characters_count, - bool read_as_double) const; - - DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter); -}; - -} // namespace double_conversion - -#endif // DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ diff --git a/android/x86/include/spidermonkey/mozilla/fallible.h b/android/x86/include/spidermonkey/mozilla/fallible.h deleted file mode 100644 index c028360b..00000000 --- a/android/x86/include/spidermonkey/mozilla/fallible.h +++ /dev/null @@ -1,68 +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/. */ - -#ifndef mozilla_fallible_h -#define mozilla_fallible_h - -#if defined(__cplusplus) - -/* Explicit fallible allocation - * - * Memory allocation (normally) defaults to abort in case of failed - * allocation. That is, it never returns NULL, and crashes instead. - * - * Code can explicitely request for fallible memory allocation thanks - * to the declarations below. - * - * The typical use of the mozilla::fallible const is with placement new, - * like the following: - * - * foo = new (mozilla::fallible) Foo(); - * - * The following forms, or derivatives, are also possible but deprecated: - * - * foo = new ((mozilla::fallible_t())) Foo(); - * - * const mozilla::fallible_t fallible = mozilla::fallible_t(); - * bar = new (f) Bar(); - * - * It is also possible to declare method overloads with fallible allocation - * alternatives, like so: - * - * class Foo { - * public: - * void Method(void *); - * void Method(void *, const mozilla::fallible_t&); - * }; - * - * Foo foo; - * foo.Method(nullptr, mozilla::fallible); - * - * If that last method call is in a method that itself takes a const - * fallible_t& argument, it is recommended to propagate that argument - * instead of using mozilla::fallible: - * - * void Func(Foo &foo, const mozilla::fallible_t& aFallible) { - * foo.Method(nullptr, aFallible); - * } - * - */ -namespace mozilla { - -struct fallible_t { }; - -/* This symbol is kept unexported, such that in corner cases where the - * compiler can't remove its use (essentially, cross compilation-unit - * calls), the smallest machine code is used. - * Depending how the linker packs symbols, it will consume between 1 and - * 8 bytes of read-only data in each executable or shared library, but - * only in those where it's actually not optimized out by the compiler. - */ -extern const fallible_t fallible; - -} // namespace mozilla - -#endif - -#endif // mozilla_fallible_h diff --git a/android/x86/include/spidermonkey/mozilla/mozalloc.h b/android/x86/include/spidermonkey/mozilla/mozalloc.h deleted file mode 100644 index f7ddb7e6..00000000 --- a/android/x86/include/spidermonkey/mozilla/mozalloc.h +++ /dev/null @@ -1,361 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: sw=4 ts=4 et : - */ -/* 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 mozilla_mozalloc_h -#define mozilla_mozalloc_h - -/* - * https://bugzilla.mozilla.org/show_bug.cgi?id=427099 - */ - -#if defined(__cplusplus) -# include -// Since libstdc++ 6, including the C headers (e.g. stdlib.h) instead of the -// corresponding C++ header (e.g. cstdlib) can cause confusion in C++ code -// using things defined there. Specifically, with stdlib.h, the use of abs() -// in gfx/graphite2/src/inc/UtfCodec.h somehow ends up picking the wrong abs() -# include -# include -#else -# include -# include -#endif - -#if defined(__cplusplus) -#include "mozilla/fallible.h" -#include "mozilla/mozalloc_abort.h" -#include "mozilla/TemplateLib.h" -#endif -#include "mozilla/Attributes.h" -#include "mozilla/Types.h" - -#define MOZALLOC_HAVE_XMALLOC - -#if defined(MOZ_ALWAYS_INLINE_EVEN_DEBUG) -# define MOZALLOC_INLINE MOZ_ALWAYS_INLINE_EVEN_DEBUG -#elif defined(HAVE_FORCEINLINE) -# define MOZALLOC_INLINE __forceinline -#else -# define MOZALLOC_INLINE inline -#endif - -/* Workaround build problem with Sun Studio 12 */ -#if defined(__SUNPRO_C) || defined(__SUNPRO_CC) -# undef MOZ_MUST_USE -# define MOZ_MUST_USE -# undef MOZ_ALLOCATOR -# define MOZ_ALLOCATOR -#endif - -#if defined(__cplusplus) -extern "C" { -#endif /* ifdef __cplusplus */ - -/* - * We need to use malloc_impl and free_impl in this file when they are - * defined, because of how mozglue.dll is linked on Windows, where using - * malloc/free would end up using the symbols from the MSVCRT instead of - * ours. - */ -#ifndef free_impl -#define free_impl free -#define free_impl_ -#endif -#ifndef malloc_impl -#define malloc_impl malloc -#define malloc_impl_ -#endif - -/* - * Each declaration below is analogous to a "standard" allocation - * function, except that the out-of-memory handling is made explicit. - * The |moz_x| versions will never return a NULL pointer; if memory - * is exhausted, they abort. The |moz_| versions may return NULL - * pointers if memory is exhausted: their return value must be checked. - * - * All these allocation functions are *guaranteed* to return a pointer - * to memory allocated in such a way that that memory can be freed by - * passing that pointer to |free()|. - */ - -MFBT_API void* moz_xmalloc(size_t size) - MOZ_ALLOCATOR; - -MFBT_API void* moz_xcalloc(size_t nmemb, size_t size) - MOZ_ALLOCATOR; - -MFBT_API void* moz_xrealloc(void* ptr, size_t size) - MOZ_ALLOCATOR; - -MFBT_API char* moz_xstrdup(const char* str) - MOZ_ALLOCATOR; - -MFBT_API size_t moz_malloc_usable_size(void *ptr); - -MFBT_API size_t moz_malloc_size_of(const void *ptr); - -#if defined(HAVE_STRNDUP) -MFBT_API char* moz_xstrndup(const char* str, size_t strsize) - MOZ_ALLOCATOR; -#endif /* if defined(HAVE_STRNDUP) */ - - -#if defined(HAVE_POSIX_MEMALIGN) -MFBT_API MOZ_MUST_USE -int moz_xposix_memalign(void **ptr, size_t alignment, size_t size); - -MFBT_API MOZ_MUST_USE -int moz_posix_memalign(void **ptr, size_t alignment, size_t size); -#endif /* if defined(HAVE_POSIX_MEMALIGN) */ - - -#if defined(HAVE_MEMALIGN) -MFBT_API void* moz_xmemalign(size_t boundary, size_t size) - MOZ_ALLOCATOR; -#endif /* if defined(HAVE_MEMALIGN) */ - - -#if defined(HAVE_VALLOC) -MFBT_API void* moz_xvalloc(size_t size) - MOZ_ALLOCATOR; -#endif /* if defined(HAVE_VALLOC) */ - - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* ifdef __cplusplus */ - - -#ifdef __cplusplus - -/* - * We implement the default operators new/delete as part of - * libmozalloc, replacing their definitions in libstdc++. The - * operator new* definitions in libmozalloc will never return a NULL - * pointer. - * - * Each operator new immediately below returns a pointer to memory - * that can be delete'd by any of - * - * (1) the matching infallible operator delete immediately below - * (2) the matching "fallible" operator delete further below - * (3) the matching system |operator delete(void*, std::nothrow)| - * (4) the matching system |operator delete(void*) throw(std::bad_alloc)| - * - * NB: these are declared |throw(std::bad_alloc)|, though they will never - * throw that exception. This declaration is consistent with the rule - * that |::operator new() throw(std::bad_alloc)| will never return NULL. - */ - -/* NB: This is defined just to silence vacuous warnings about symbol - * visibility on OS X/gcc. These symbols are force-inline and not - * exported. */ -#if defined(XP_MACOSX) -# define MOZALLOC_EXPORT_NEW MFBT_API -#else -# define MOZALLOC_EXPORT_NEW -#endif - -#if defined(ANDROID) -/* - * It's important to always specify 'throw()' in GCC because it's used to tell - * GCC that 'new' may return null. That makes GCC null-check the result before - * potentially initializing the memory to zero. - * Also, the Android minimalistic headers don't include std::bad_alloc. - */ -#define MOZALLOC_THROW_IF_HAS_EXCEPTIONS throw() -#define MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS -#elif defined(_MSC_VER) -/* - * Suppress build warning spam (bug 578546). - */ -#define MOZALLOC_THROW_IF_HAS_EXCEPTIONS -#define MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS -#else -#define MOZALLOC_THROW_IF_HAS_EXCEPTIONS throw() -#define MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS throw(std::bad_alloc) -#endif - -#define MOZALLOC_THROW_BAD_ALLOC MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS - -MOZALLOC_EXPORT_NEW -#if defined(__GNUC__) && !defined(__clang__) && defined(__SANITIZE_ADDRESS__) -/* gcc's asan somehow doesn't like always_inline on this function. */ -__attribute__((gnu_inline)) inline -#else -MOZALLOC_INLINE -#endif -void* operator new(size_t size) MOZALLOC_THROW_BAD_ALLOC -{ - return moz_xmalloc(size); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void* operator new(size_t size, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return malloc_impl(size); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void* operator new[](size_t size) MOZALLOC_THROW_BAD_ALLOC -{ - return moz_xmalloc(size); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void* operator new[](size_t size, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return malloc_impl(size); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void operator delete(void* ptr) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return free_impl(ptr); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void operator delete(void* ptr, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return free_impl(ptr); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void operator delete[](void* ptr) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return free_impl(ptr); -} - -MOZALLOC_EXPORT_NEW MOZALLOC_INLINE -void operator delete[](void* ptr, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return free_impl(ptr); -} - - -/* - * We also add a new allocator variant: "fallible operator new." - * Unlike libmozalloc's implementations of the standard nofail - * allocators, this allocator is allowed to return NULL. It can be used - * as follows - * - * Foo* f = new (mozilla::fallible) Foo(...); - * - * operator delete(fallible) is defined for completeness only. - * - * Each operator new below returns a pointer to memory that can be - * delete'd by any of - * - * (1) the matching "fallible" operator delete below - * (2) the matching infallible operator delete above - * (3) the matching system |operator delete(void*, std::nothrow)| - * (4) the matching system |operator delete(void*) throw(std::bad_alloc)| - */ - -MOZALLOC_INLINE -void* operator new(size_t size, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return malloc_impl(size); -} - -MOZALLOC_INLINE -void* operator new[](size_t size, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - return malloc_impl(size); -} - -MOZALLOC_INLINE -void operator delete(void* ptr, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - free_impl(ptr); -} - -MOZALLOC_INLINE -void operator delete[](void* ptr, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS -{ - free_impl(ptr); -} - - -/* - * This policy is identical to MallocAllocPolicy, except it uses - * moz_xmalloc/moz_xcalloc/moz_xrealloc instead of - * malloc/calloc/realloc. - */ -class InfallibleAllocPolicy -{ -public: - template - T* maybe_pod_malloc(size_t aNumElems) - { - return pod_malloc(aNumElems); - } - - template - T* maybe_pod_calloc(size_t aNumElems) - { - return pod_calloc(aNumElems); - } - - template - T* maybe_pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) - { - return pod_realloc(aPtr, aOldSize, aNewSize); - } - - template - T* pod_malloc(size_t aNumElems) - { - if (aNumElems & mozilla::tl::MulOverflowMask::value) { - reportAllocOverflow(); - } - return static_cast(moz_xmalloc(aNumElems * sizeof(T))); - } - - template - T* pod_calloc(size_t aNumElems) - { - return static_cast(moz_xcalloc(aNumElems, sizeof(T))); - } - - template - T* pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) - { - if (aNewSize & mozilla::tl::MulOverflowMask::value) { - reportAllocOverflow(); - } - return static_cast(moz_xrealloc(aPtr, aNewSize * sizeof(T))); - } - - void free_(void* aPtr) - { - free_impl(aPtr); - } - - void reportAllocOverflow() const - { - mozalloc_abort("alloc overflow"); - } - - bool checkSimulatedOOM() const - { - return true; - } -}; - -#endif /* ifdef __cplusplus */ - -#ifdef malloc_impl_ -#undef malloc_impl_ -#undef malloc_impl -#endif -#ifdef free_impl_ -#undef free_impl_ -#undef free_impl -#endif - -#endif /* ifndef mozilla_mozalloc_h */ diff --git a/android/x86/include/spidermonkey/mozilla/mozalloc_abort.h b/android/x86/include/spidermonkey/mozilla/mozalloc_abort.h deleted file mode 100644 index 065cebcb..00000000 --- a/android/x86/include/spidermonkey/mozilla/mozalloc_abort.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: sw=4 ts=4 et : - */ -/* 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 mozilla_mozalloc_abort_h -#define mozilla_mozalloc_abort_h - -#include "mozilla/Attributes.h" -#include "mozilla/Types.h" - -/** - * Terminate this process in such a way that breakpad is triggered, if - * at all possible. - * - * Note: MOZ_NORETURN seems to break crash stacks on ARM, so we don't - * use that annotation there. - */ -MFBT_API -#if !defined(__arm__) - MOZ_NORETURN -#endif - void mozalloc_abort(const char* const msg); - - -#endif /* ifndef mozilla_mozalloc_abort_h */ diff --git a/android/x86/include/spidermonkey/mozilla/mozalloc_oom.h b/android/x86/include/spidermonkey/mozilla/mozalloc_oom.h deleted file mode 100644 index 35bb9acc..00000000 --- a/android/x86/include/spidermonkey/mozilla/mozalloc_oom.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: sw=4 ts=4 et : - */ -/* 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 mozilla_mozalloc_oom_h -#define mozilla_mozalloc_oom_h - -#include "mozalloc.h" - -/** - * Called when memory is critically low. Returns iff it was able to - * remedy the critical memory situation; if not, it will abort(). - */ -MFBT_API void mozalloc_handle_oom(size_t requestedSize); - -/** - * Called by embedders (specifically Mozilla breakpad) which wants to be - * notified of an intentional abort, to annotate any crash report with - * the size of the allocation on which we aborted. - */ -typedef void (*mozalloc_oom_abort_handler)(size_t size); -MFBT_API void mozalloc_set_oom_abort_handler(mozalloc_oom_abort_handler handler); - -/* TODO: functions to query system memory usage and register - * critical-memory handlers. */ - - -#endif /* ifndef mozilla_mozalloc_oom_h */ diff --git a/android/x86/include/spidermonkey/mozilla/utils.h b/android/x86/include/spidermonkey/mozilla/utils.h deleted file mode 100644 index 15dd4bfb..00000000 --- a/android/x86/include/spidermonkey/mozilla/utils.h +++ /dev/null @@ -1,298 +0,0 @@ -// Copyright 2010 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DOUBLE_CONVERSION_UTILS_H_ -#define DOUBLE_CONVERSION_UTILS_H_ - -#include -#include - -#include "mozilla/Assertions.h" -#ifndef ASSERT -#define ASSERT(condition) MOZ_ASSERT(condition) -#endif -#ifndef UNIMPLEMENTED -#define UNIMPLEMENTED() MOZ_CRASH() -#endif -#ifndef UNREACHABLE -#define UNREACHABLE() MOZ_CRASH() -#endif - -// Double operations detection based on target architecture. -// Linux uses a 80bit wide floating point stack on x86. This induces double -// rounding, which in turn leads to wrong results. -// An easy way to test if the floating-point operations are correct is to -// evaluate: 89255.0/1e22. If the floating-point stack is 64 bits wide then -// the result is equal to 89255e-22. -// The best way to test this, is to create a division-function and to compare -// the output of the division with the expected result. (Inlining must be -// disabled.) -// On Linux,x86 89255e-22 != Div_double(89255.0/1e22) -#if defined(_M_X64) || defined(__x86_64__) || \ - defined(__ARMEL__) || defined(__avr32__) || \ - defined(__hppa__) || defined(__ia64__) || \ - defined(__mips__) || \ - defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \ - defined(__sparc__) || defined(__sparc) || defined(__s390__) || \ - defined(__SH4__) || defined(__alpha__) || \ - defined(_MIPS_ARCH_MIPS32R2) || \ - defined(__AARCH64EL__) || defined(__aarch64__) -#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 -#elif defined(_M_IX86) || defined(__i386__) || defined(__i386) -#if defined(_WIN32) -// Windows uses a 64bit wide floating point stack. -#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 -#else -#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS -#endif // _WIN32 -#else -#error Target architecture was not detected as supported by Double-Conversion. -#endif - - -#include - -// The following macro works on both 32 and 64-bit platforms. -// Usage: instead of writing 0x1234567890123456 -// write UINT64_2PART_C(0x12345678,90123456); -#define UINT64_2PART_C(a, b) (((static_cast(a) << 32) + 0x##b##u)) - - -// The expression ARRAY_SIZE(a) is a compile-time constant of type -// size_t which represents the number of elements of the given -// array. You should only use ARRAY_SIZE on statically allocated -// arrays. -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) \ - ((sizeof(a) / sizeof(*(a))) / \ - static_cast(!(sizeof(a) % sizeof(*(a))))) -#endif - -// A macro to disallow the evil copy constructor and operator= functions -// This should be used in the private: declarations for a class -#ifndef DISALLOW_COPY_AND_ASSIGN -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) -#endif - -// A macro to disallow all the implicit constructors, namely the -// default constructor, copy constructor and operator= functions. -// -// This should be used in the private: declarations for a class -// that wants to prevent anyone from instantiating it. This is -// especially useful for classes containing only static methods. -#ifndef DISALLOW_IMPLICIT_CONSTRUCTORS -#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ - TypeName(); \ - DISALLOW_COPY_AND_ASSIGN(TypeName) -#endif - -namespace double_conversion { - -static const int kCharSize = sizeof(char); - -// Returns the maximum of the two parameters. -template -static T Max(T a, T b) { - return a < b ? b : a; -} - - -// Returns the minimum of the two parameters. -template -static T Min(T a, T b) { - return a < b ? a : b; -} - - -inline int StrLength(const char* string) { - size_t length = strlen(string); - ASSERT(length == static_cast(static_cast(length))); - return static_cast(length); -} - -// This is a simplified version of V8's Vector class. -template -class Vector { - public: - Vector() : start_(NULL), length_(0) {} - Vector(T* data, int len) : start_(data), length_(len) { - ASSERT(len == 0 || (len > 0 && data != NULL)); - } - - // Returns a vector using the same backing storage as this one, - // spanning from and including 'from', to but not including 'to'. - Vector SubVector(int from, int to) { - ASSERT(to <= length_); - ASSERT(from < to); - ASSERT(0 <= from); - return Vector(start() + from, to - from); - } - - // Returns the length of the vector. - int length() const { return length_; } - - // Returns whether or not the vector is empty. - bool is_empty() const { return length_ == 0; } - - // Returns the pointer to the start of the data in the vector. - T* start() const { return start_; } - - // Access individual vector elements - checks bounds in debug mode. - T& operator[](int index) const { - ASSERT(0 <= index && index < length_); - return start_[index]; - } - - T& first() { return start_[0]; } - - T& last() { return start_[length_ - 1]; } - - private: - T* start_; - int length_; -}; - - -// Helper class for building result strings in a character buffer. The -// purpose of the class is to use safe operations that checks the -// buffer bounds on all operations in debug mode. -class StringBuilder { - public: - StringBuilder(char* buffer, int buffer_size) - : buffer_(buffer, buffer_size), position_(0) { } - - ~StringBuilder() { if (!is_finalized()) Finalize(); } - - int size() const { return buffer_.length(); } - - // Get the current position in the builder. - int position() const { - ASSERT(!is_finalized()); - return position_; - } - - // Reset the position. - void Reset() { position_ = 0; } - - // Add a single character to the builder. It is not allowed to add - // 0-characters; use the Finalize() method to terminate the string - // instead. - void AddCharacter(char c) { - ASSERT(c != '\0'); - ASSERT(!is_finalized() && position_ < buffer_.length()); - buffer_[position_++] = c; - } - - // Add an entire string to the builder. Uses strlen() internally to - // compute the length of the input string. - void AddString(const char* s) { - AddSubstring(s, StrLength(s)); - } - - // Add the first 'n' characters of the given string 's' to the - // builder. The input string must have enough characters. - void AddSubstring(const char* s, int n) { - ASSERT(!is_finalized() && position_ + n < buffer_.length()); - ASSERT(static_cast(n) <= strlen(s)); - memmove(&buffer_[position_], s, n * kCharSize); - position_ += n; - } - - - // Add character padding to the builder. If count is non-positive, - // nothing is added to the builder. - void AddPadding(char c, int count) { - for (int i = 0; i < count; i++) { - AddCharacter(c); - } - } - - // Finalize the string by 0-terminating it and returning the buffer. - char* Finalize() { - ASSERT(!is_finalized() && position_ < buffer_.length()); - buffer_[position_] = '\0'; - // Make sure nobody managed to add a 0-character to the - // buffer while building the string. - ASSERT(strlen(buffer_.start()) == static_cast(position_)); - position_ = -1; - ASSERT(is_finalized()); - return buffer_.start(); - } - - private: - Vector buffer_; - int position_; - - bool is_finalized() const { return position_ < 0; } - - DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder); -}; - -// The type-based aliasing rule allows the compiler to assume that pointers of -// different types (for some definition of different) never alias each other. -// Thus the following code does not work: -// -// float f = foo(); -// int fbits = *(int*)(&f); -// -// The compiler 'knows' that the int pointer can't refer to f since the types -// don't match, so the compiler may cache f in a register, leaving random data -// in fbits. Using C++ style casts makes no difference, however a pointer to -// char data is assumed to alias any other pointer. This is the 'memcpy -// exception'. -// -// Bit_cast uses the memcpy exception to move the bits from a variable of one -// type of a variable of another type. Of course the end result is likely to -// be implementation dependent. Most compilers (gcc-4.2 and MSVC 2005) -// will completely optimize BitCast away. -// -// There is an additional use for BitCast. -// Recent gccs will warn when they see casts that may result in breakage due to -// the type-based aliasing rule. If you have checked that there is no breakage -// you can use BitCast to cast one pointer type to another. This confuses gcc -// enough that it can no longer see that you have cast one pointer type to -// another thus avoiding the warning. -template -inline Dest BitCast(const Source& source) { - static_assert(sizeof(Dest) == sizeof(Source), - "BitCast's source and destination types must be the same size"); - - Dest dest; - memmove(&dest, &source, sizeof(dest)); - return dest; -} - -template -inline Dest BitCast(Source* source) { - return BitCast(reinterpret_cast(source)); -} - -} // namespace double_conversion - -#endif // DOUBLE_CONVERSION_UTILS_H_ diff --git a/android/x86/include/spidermonkey/mozmemory.h b/android/x86/include/spidermonkey/mozmemory.h deleted file mode 100644 index 84007fff..00000000 --- a/android/x86/include/spidermonkey/mozmemory.h +++ /dev/null @@ -1,91 +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/. */ - -#ifndef mozmemory_h -#define mozmemory_h - -/* - * This header is meant to be used when the following functions are - * necessary: - * - malloc_good_size (used to be called je_malloc_usable_in_advance) - * - jemalloc_stats - * - jemalloc_purge_freed_pages - * - jemalloc_free_dirty_pages - */ - -#ifndef MOZ_MEMORY -# error Should not include mozmemory.h when MOZ_MEMORY is not set -#endif - -#include "mozmemory_wrap.h" -#include "mozilla/Attributes.h" -#include "mozilla/Types.h" -#include "jemalloc_types.h" - -MOZ_BEGIN_EXTERN_C - -/* - * On OSX, malloc/malloc.h contains the declaration for malloc_good_size, - * which will call back in jemalloc, through the zone allocator so just use it. - */ -#ifdef XP_DARWIN -# include -#else -MOZ_MEMORY_API size_t malloc_good_size_impl(size_t size); - -/* Note: the MOZ_GLUE_IN_PROGRAM ifdef below is there to avoid -Werror turning - * the protective if into errors. MOZ_GLUE_IN_PROGRAM is what triggers MFBT_API - * to use weak imports. */ - -static inline size_t _malloc_good_size(size_t size) { -# if defined(MOZ_GLUE_IN_PROGRAM) && !defined(IMPL_MFBT) - if (!malloc_good_size) - return size; -# endif - return malloc_good_size_impl(size); -} - -# define malloc_good_size _malloc_good_size -#endif - -MOZ_JEMALLOC_API void jemalloc_stats(jemalloc_stats_t *stats); - -/* - * On some operating systems (Mac), we use madvise(MADV_FREE) to hand pages - * back to the operating system. On Mac, the operating system doesn't take - * this memory back immediately; instead, the OS takes it back only when the - * machine is running out of physical memory. - * - * This is great from the standpoint of efficiency, but it makes measuring our - * actual RSS difficult, because pages which we've MADV_FREE'd shouldn't count - * against our RSS. - * - * This function explicitly purges any MADV_FREE'd pages from physical memory, - * causing our reported RSS match the amount of memory we're actually using. - * - * Note that this call is expensive in two ways. First, it may be slow to - * execute, because it may make a number of slow syscalls to free memory. This - * function holds the big jemalloc locks, so basically all threads are blocked - * while this function runs. - * - * This function is also expensive in that the next time we go to access a page - * which we've just explicitly decommitted, the operating system has to attach - * to it a physical page! If we hadn't run this function, the OS would have - * less work to do. - * - * If MALLOC_DOUBLE_PURGE is not defined, this function does nothing. - */ -MOZ_JEMALLOC_API void jemalloc_purge_freed_pages(); - -/* - * Free all unused dirty pages in all arenas. Calling this function will slow - * down subsequent allocations so it is recommended to use it only when - * memory needs to be reclaimed at all costs (see bug 805855). This function - * provides functionality similar to mallctl("arenas.purge") in jemalloc 3. - */ -MOZ_JEMALLOC_API void jemalloc_free_dirty_pages(); - -MOZ_END_EXTERN_C - -#endif /* mozmemory_h */ diff --git a/android/x86/include/spidermonkey/mozmemory_wrap.h b/android/x86/include/spidermonkey/mozmemory_wrap.h deleted file mode 100644 index 066d5778..00000000 --- a/android/x86/include/spidermonkey/mozmemory_wrap.h +++ /dev/null @@ -1,219 +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/. */ - -#ifndef mozmemory_wrap_h -#define mozmemory_wrap_h - -/* - * This header contains #defines which tweak the names of various memory - * allocation functions. - * - * There are several types of functions related to memory allocation - * that are meant to be used publicly by the Gecko codebase: - * - * - malloc implementation functions: - * - malloc - * - posix_memalign - * - aligned_alloc - * - calloc - * - realloc - * - free - * - memalign - * - valloc - * - malloc_usable_size - * - malloc_good_size - * Some of these functions are specific to some systems, but for - * convenience, they are treated as being cross-platform, and available - * as such. - * - * - duplication functions: - * - strndup - * - strdup - * - wcsdup (Windows only) - * - * - jemalloc specific functions: - * - jemalloc_stats - * - jemalloc_purge_freed_pages - * - jemalloc_free_dirty_pages - * (these functions are native to mozjemalloc, and have compatibility - * implementations for jemalloc3) - * - * These functions are all exported as part of libmozglue (see - * $(topsrcdir)/mozglue/build/Makefile.in), with a few implementation - * peculiarities: - * - * - On Windows, the malloc implementation functions are all prefixed with - * "je_", the duplication functions are prefixed with "wrap_", and jemalloc - * specific functions are left unprefixed. All these functions are however - * aliased when exporting them, such that the resulting mozglue.dll exports - * them unprefixed (see $(topsrcdir)/mozglue/build/mozglue.def.in). The - * prefixed malloc implementation and duplication functions are not - * exported. - * - * - On MacOSX, the system libc has a zone allocator, which allows us to - * hook custom malloc implementation functions without exporting them. - * The malloc implementation functions are all prefixed with "je_" and used - * this way from the custom zone allocator. They are not exported. - * Duplication functions are not included, since they will call the custom - * zone allocator anyways. Jemalloc-specific functions are also left - * unprefixed. - * - * - On Android and Gonk, all functions are left unprefixed. Additionally, - * C++ allocation functions (operator new/delete) are also exported and - * unprefixed. - * - * - On other systems (mostly Linux), all functions are left unprefixed. - * - * Only Android and Gonk add C++ allocation functions. - * - * Proper exporting of the various functions is done with the MOZ_MEMORY_API - * and MOZ_JEMALLOC_API macros. MOZ_MEMORY_API is meant to be used for malloc - * implementation and duplication functions, while MOZ_JEMALLOC_API is - * dedicated to jemalloc specific functions. - * - * - * All these functions are meant to be called with no prefix from Gecko code. - * In most cases, this is because that's how they are available at runtime. - * However, on Android, this relies on faulty.lib (the custom dynamic linker) - * resolving mozglue symbols before libc symbols, which is guaranteed by the - * way faulty.lib works (it respects the DT_NEEDED order, and libc always - * appears after mozglue ; which we double check when building anyways) - * - * - * Within libmozglue (when MOZ_MEMORY_IMPL is defined), all the functions - * should be suffixed with "_impl" both for declarations and use. - * That is, the implementation declaration for e.g. strdup would look like: - * char* strdup_impl(const char *) - * That implementation would call malloc by using "malloc_impl". - * - * While mozjemalloc uses these "_impl" suffixed helpers, jemalloc3, being - * third-party code, doesn't, but instead has an elaborate way to mangle - * individual functions. See under "Run jemalloc configure script" in - * $(topsrcdir)/configure.in. - * - * - * When building with replace-malloc support, the above still holds, but - * the malloc implementation and jemalloc specific functions are the - * replace-malloc functions from replace_malloc.c. - * - * The actual jemalloc/mozjemalloc implementation is prefixed with "je_". - * - * Thus, when MOZ_REPLACE_MALLOC is defined, the "_impl" suffixed macros - * expand to "je_" prefixed function when building mozjemalloc or - * jemalloc3/mozjemalloc_compat, where MOZ_JEMALLOC_IMPL is defined. - * - * In other cases, the "_impl" suffixed macros follow the original scheme, - * except on Windows and MacOSX, where they would expand to "je_" prefixed - * functions. Instead, they are left unmodified (malloc_impl expands to - * malloc_impl). - */ - -#ifndef MOZ_MEMORY -# error Should only include mozmemory_wrap.h when MOZ_MEMORY is set. -#endif - -#if defined(MOZ_JEMALLOC_IMPL) && !defined(MOZ_MEMORY_IMPL) -# define MOZ_MEMORY_IMPL -#endif -#if defined(MOZ_MEMORY_IMPL) && !defined(IMPL_MFBT) -# ifdef MFBT_API /* mozilla/Types.h was already included */ -# error mozmemory_wrap.h has to be included before mozilla/Types.h when MOZ_MEMORY_IMPL is set and IMPL_MFBT is not. -# endif -# define IMPL_MFBT -#endif - -#include "mozilla/Types.h" - -#if !defined(MOZ_SYSTEM_JEMALLOC) -# ifdef MOZ_MEMORY_IMPL -# if defined(MOZ_JEMALLOC_IMPL) && defined(MOZ_REPLACE_MALLOC) && !defined(MOZ_REPLACE_JEMALLOC) -# define mozmem_malloc_impl(a) je_ ## a -# define mozmem_jemalloc_impl(a) je_ ## a -# else -# define MOZ_JEMALLOC_API MFBT_API -# ifdef MOZ_REPLACE_JEMALLOC -# define MOZ_MEMORY_API MFBT_API -# define mozmem_malloc_impl(a) replace_ ## a -# define mozmem_jemalloc_impl(a) replace_ ## a -# elif (defined(XP_WIN) || defined(XP_DARWIN)) -# if defined(MOZ_REPLACE_MALLOC) -# define mozmem_malloc_impl(a) a ## _impl -# else -# define mozmem_malloc_impl(a) je_ ## a -# endif -# else -# define MOZ_MEMORY_API MFBT_API -# if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK) -# define MOZ_WRAP_NEW_DELETE -# endif -# endif -# endif -# ifdef XP_WIN -# define mozmem_dup_impl(a) wrap_ ## a -# endif -# endif - -/* All other jemalloc3 functions are prefixed with "je_", except when - * building against an unprefixed system jemalloc library */ -# define je_(a) je_ ## a -#else /* defined(MOZ_SYSTEM_JEMALLOC) */ -# define je_(a) a -#endif - -#if !defined(MOZ_MEMORY_IMPL) || defined(MOZ_SYSTEM_JEMALLOC) -# define MOZ_MEMORY_API MFBT_API -# define MOZ_JEMALLOC_API MFBT_API -#endif - -#ifndef MOZ_MEMORY_API -# define MOZ_MEMORY_API -#endif -#ifndef MOZ_JEMALLOC_API -# define MOZ_JEMALLOC_API -#endif - -#ifndef mozmem_malloc_impl -# define mozmem_malloc_impl(a) a -#endif -#ifndef mozmem_dup_impl -# define mozmem_dup_impl(a) a -#endif -#ifndef mozmem_jemalloc_impl -# define mozmem_jemalloc_impl(a) a -#endif - -/* Malloc implementation functions */ -#define malloc_impl mozmem_malloc_impl(malloc) -#define posix_memalign_impl mozmem_malloc_impl(posix_memalign) -#define aligned_alloc_impl mozmem_malloc_impl(aligned_alloc) -#define calloc_impl mozmem_malloc_impl(calloc) -#define realloc_impl mozmem_malloc_impl(realloc) -#define free_impl mozmem_malloc_impl(free) -#define memalign_impl mozmem_malloc_impl(memalign) -#define valloc_impl mozmem_malloc_impl(valloc) -#define malloc_usable_size_impl mozmem_malloc_impl(malloc_usable_size) -#define malloc_good_size_impl mozmem_malloc_impl(malloc_good_size) - -/* Duplication functions */ -#define strndup_impl mozmem_dup_impl(strndup) -#define strdup_impl mozmem_dup_impl(strdup) -#ifdef XP_WIN -# define wcsdup_impl mozmem_dup_impl(wcsdup) -#endif - -/* String functions */ -#ifdef ANDROID -/* Bug 801571 and Bug 879668, libstagefright uses vasprintf, causing malloc()/ - * free() to be mismatched between bionic and mozglue implementation. - */ -#define vasprintf_impl mozmem_dup_impl(vasprintf) -#define asprintf_impl mozmem_dup_impl(asprintf) -#endif - -/* Jemalloc specific function */ -#define jemalloc_stats_impl mozmem_jemalloc_impl(jemalloc_stats) -#define jemalloc_purge_freed_pages_impl mozmem_jemalloc_impl(jemalloc_purge_freed_pages) -#define jemalloc_free_dirty_pages_impl mozmem_jemalloc_impl(jemalloc_free_dirty_pages) - -#endif /* mozmemory_wrap_h */ diff --git a/android/x86/libjs_static.a b/android/x86/libjs_static.a deleted file mode 100644 index e00bb3bc..00000000 Binary files a/android/x86/libjs_static.a and /dev/null differ diff --git a/android/x86/libmozglue.a b/android/x86/libmozglue.a deleted file mode 100644 index 2a1b3213..00000000 Binary files a/android/x86/libmozglue.a and /dev/null differ