diff --git a/external/spidermonkey/include/android/js-config.h b/external/spidermonkey/include/android/js-config.h index 4b893482f4..b1563e37e9 100644 --- a/external/spidermonkey/include/android/js-config.h +++ b/external/spidermonkey/include/android/js-config.h @@ -5,8 +5,8 @@ * License, v. 2.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___ +#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, @@ -34,12 +34,8 @@ useable. See jscpucfg.h. */ /* #undef JS_HAVE_SYS_ISA_DEFS_H */ -/* The configure script defines these if it doesn't #define - JS_HAVE_STDINT_H. */ -#define JS_BYTES_PER_WORD 4 - /* MOZILLA JSAPI version number components */ -#define MOZJS_MAJOR_VERSION 25 +#define MOZJS_MAJOR_VERSION 27 #define MOZJS_MINOR_VERSION 0 -#endif /* js_config_h___ */ +#endif /* js_config_h */ diff --git a/external/spidermonkey/include/android/js.msg b/external/spidermonkey/include/android/js.msg index 3f665d8d54..da7361d5df 100644 --- a/external/spidermonkey/include/android/js.msg +++ b/external/spidermonkey/include/android/js.msg @@ -221,8 +221,8 @@ MSG_DEF(JSMSG_CANT_DECODE_PRINCIPALS, 167, 0, JSEXN_INTERNALERR, "can't decode J MSG_DEF(JSMSG_CANT_SEAL_OBJECT, 168, 1, JSEXN_ERR, "can't seal {0} objects") MSG_DEF(JSMSG_TOO_MANY_CATCH_VARS, 169, 0, JSEXN_SYNTAXERR, "too many catch variables") MSG_DEF(JSMSG_NEGATIVE_REPETITION_COUNT, 170, 0, JSEXN_RANGEERR, "repeat count must be non-negative") -MSG_DEF(JSMSG_UNUSED171, 171, 0, JSEXN_NONE, "") -MSG_DEF(JSMSG_UNUSED172, 172, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_INVALID_FOR_OF_INIT, 171, 0, JSEXN_SYNTAXERR, "for-of loop variable declaration may not have an initializer") +MSG_DEF(JSMSG_INVALID_MAP_ITERABLE, 172, 0, JSEXN_TYPEERR, "iterable for map should have array-like objects") MSG_DEF(JSMSG_UNUSED173, 173, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED174, 174, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_NESTING_GENERATOR, 175, 0, JSEXN_TYPEERR, "already executing generator") @@ -233,8 +233,8 @@ MSG_DEF(JSMSG_UNUSED179, 179, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED180, 180, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED181, 181, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_BAD_GENERATOR_SEND, 182, 1, JSEXN_TYPEERR, "attempt to send {0} to newborn generator") -MSG_DEF(JSMSG_UNUSED183, 183, 0, JSEXN_NONE, "") -MSG_DEF(JSMSG_UNUSED184, 184, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_SC_NOT_TRANSFERABLE, 183, 0, JSEXN_TYPEERR, "invalid transferable array for structured clone") +MSG_DEF(JSMSG_SC_DUP_TRANSFERABLE, 184, 0, JSEXN_TYPEERR, "duplicate transferable for structured clone") MSG_DEF(JSMSG_CANT_REPORT_AS_NON_EXTENSIBLE, 185, 0, JSEXN_TYPEERR, "proxy can't report an extensible object as non-extensible") MSG_DEF(JSMSG_UNUSED186, 186, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED187, 187, 0, JSEXN_NONE, "") @@ -260,7 +260,7 @@ MSG_DEF(JSMSG_USER_DEFINED_ERROR, 206, 0, JSEXN_ERR, "JS_ReportError was cal MSG_DEF(JSMSG_WRONG_CONSTRUCTOR, 207, 1, JSEXN_TYPEERR, "wrong constructor called for {0}") MSG_DEF(JSMSG_BAD_GENERATOR_RETURN, 208, 1, JSEXN_TYPEERR, "generator function {0} returns a value") MSG_DEF(JSMSG_BAD_ANON_GENERATOR_RETURN, 209, 0, JSEXN_TYPEERR, "anonymous generator function returns a value") -MSG_DEF(JSMSG_NAME_AFTER_FOR_PAREN, 210, 0, JSEXN_SYNTAXERR, "missing name after for (") +MSG_DEF(JSMSG_UNUSED210, 210, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_IN_AFTER_FOR_NAME, 211, 0, JSEXN_SYNTAXERR, "missing 'in' or 'of' after for") MSG_DEF(JSMSG_BAD_TRAP_RETURN_VALUE, 212, 2, JSEXN_TYPEERR,"trap {1} for {0} returned a primitive value") MSG_DEF(JSMSG_UNUSED213, 213, 0, JSEXN_NONE, "") @@ -269,7 +269,7 @@ MSG_DEF(JSMSG_BAD_GENERATOR_SYNTAX, 215, 1, JSEXN_SYNTAXERR, "{0} expression m MSG_DEF(JSMSG_ARRAY_COMP_LEFTSIDE, 216, 0, JSEXN_SYNTAXERR, "invalid array comprehension left-hand side") MSG_DEF(JSMSG_UNUSED217, 217, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_EMPTY_ARRAY_REDUCE, 218, 0, JSEXN_TYPEERR, "reduce of empty array with no initial value") -MSG_DEF(JSMSG_UNUSED219, 219, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_BAD_SYMBOL, 219, 1, JSEXN_TYPEERR, "{0} is not a well-known @@-symbol") MSG_DEF(JSMSG_BAD_DELETE_OPERAND, 220, 0, JSEXN_REFERENCEERR, "invalid delete operand") MSG_DEF(JSMSG_BAD_INCOP_OPERAND, 221, 0, JSEXN_REFERENCEERR, "invalid increment/decrement operand") MSG_DEF(JSMSG_UNEXPECTED_TYPE, 222, 2, JSEXN_TYPEERR, "{0} is {1}") @@ -353,7 +353,7 @@ MSG_DEF(JSMSG_REST_WITH_DEFAULT, 299, 0, JSEXN_SYNTAXERR, "rest parameter m MSG_DEF(JSMSG_NONDEFAULT_FORMAL_AFTER_DEFAULT, 300, 0, JSEXN_SYNTAXERR, "parameter(s) with default followed by parameter without default") MSG_DEF(JSMSG_YIELD_IN_DEFAULT, 301, 0, JSEXN_SYNTAXERR, "yield in default expression") MSG_DEF(JSMSG_INTRINSIC_NOT_DEFINED, 302, 1, JSEXN_REFERENCEERR, "no intrinsic function {0}") -MSG_DEF(JSMSG_ALREADY_HAS_SOURCEMAP, 303, 1, JSEXN_ERR, "{0} is being assigned a source map, yet already has one") +MSG_DEF(JSMSG_ALREADY_HAS_PRAGMA, 303, 2, JSEXN_ERR, "{0} is being assigned a {1}, but already has one") MSG_DEF(JSMSG_PAR_ARRAY_BAD_ARG, 304, 1, JSEXN_RANGEERR, "invalid ParallelArray{0} argument") MSG_DEF(JSMSG_PAR_ARRAY_BAD_PARTITION, 305, 0, JSEXN_ERR, "argument must be divisible by outermost dimension") MSG_DEF(JSMSG_PAR_ARRAY_REDUCE_EMPTY, 306, 0, JSEXN_ERR, "cannot reduce ParallelArray object whose outermost dimension is empty") @@ -375,7 +375,7 @@ MSG_DEF(JSMSG_MUST_REPORT_UNDEFINED, 321, 0, JSEXN_TYPEERR, "proxy must report MSG_DEF(JSMSG_CANT_SET_NW_NC, 322, 0, JSEXN_TYPEERR, "proxy can't successfully set a non-writable, non-configurable property") MSG_DEF(JSMSG_CANT_SET_WO_SETTER, 323, 0, JSEXN_TYPEERR, "proxy can't succesfully set an accessor property without a setter") MSG_DEF(JSMSG_DEBUG_BAD_REFERENT, 324, 2, JSEXN_TYPEERR, "{0} does not refer to {1}") -MSG_DEF(JSMSG_DEBUG_WRAPPER_IN_WAY, 325, 2, JSEXN_TYPEERR, "{0} is a wrapper around {1}, but a direct reference is required") +MSG_DEF(JSMSG_DEBUG_WRAPPER_IN_WAY, 325, 3, JSEXN_TYPEERR, "{0} is {1}{2}a global object, but a direct reference is required") MSG_DEF(JSMSG_UNWRAP_DENIED, 326, 0, JSEXN_ERR, "permission denied to unwrap object") MSG_DEF(JSMSG_INTL_OBJECT_NOT_INITED, 327, 3, JSEXN_TYPEERR, "Intl.{0}.prototype.{1} called on value that's not an object initialized as a {2}") MSG_DEF(JSMSG_INVALID_LOCALES_ELEMENT,328, 0, JSEXN_TYPEERR, "invalid element in locales argument") @@ -400,12 +400,23 @@ MSG_DEF(JSMSG_YIELD_IN_ARROW, 346, 0, JSEXN_SYNTAXERR, "arrow function m MSG_DEF(JSMSG_WRONG_VALUE, 347, 2, JSEXN_ERR, "expected {0} but found {1}") MSG_DEF(JSMSG_PAR_ARRAY_SCATTER_BAD_TARGET, 348, 1, JSEXN_ERR, "target for index {0} is not an integer") MSG_DEF(JSMSG_SELFHOSTED_UNBOUND_NAME,349, 0, JSEXN_TYPEERR, "self-hosted code may not contain unbound name lookups") -MSG_DEF(JSMSG_DEPRECATED_SOURCE_MAP, 350, 0, JSEXN_SYNTAXERR, "Using //@ to indicate source map URL pragmas is deprecated. Use //# instead") +MSG_DEF(JSMSG_DEPRECATED_PRAGMA, 350, 1, JSEXN_SYNTAXERR, "Using //@ to indicate {0} pragmas is deprecated. Use //# instead") MSG_DEF(JSMSG_BAD_DESTRUCT_ASSIGN, 351, 1, JSEXN_SYNTAXERR, "can't assign to {0} using destructuring assignment") -MSG_DEF(JSMSG_BINARYDATA_ARRAYTYPE_BAD_ARGS, 352, 0, JSEXN_ERR, "Invalid arguments") -MSG_DEF(JSMSG_BINARYDATA_BINARYARRAY_BAD_INDEX, 353, 0, JSEXN_RANGEERR, "invalid or out-of-range index") -MSG_DEF(JSMSG_BINARYDATA_STRUCTTYPE_BAD_ARGS, 354, 0, JSEXN_RANGEERR, "invalid field descriptor") -MSG_DEF(JSMSG_BINARYDATA_NOT_BINARYSTRUCT, 355, 1, JSEXN_TYPEERR, "{0} is not a BinaryStruct") -MSG_DEF(JSMSG_BINARYDATA_SUBARRAY_INTEGER_ARG, 356, 1, JSEXN_ERR, "argument {0} must be an integer") -MSG_DEF(JSMSG_BINARYDATA_STRUCTTYPE_EMPTY_DESCRIPTOR, 357, 0, JSEXN_ERR, "field descriptor cannot be empty") -MSG_DEF(JSMSG_BINARYDATA_STRUCTTYPE_BAD_FIELD, 358, 1, JSEXN_ERR, "field {0} is not a valid BinaryData Type descriptor") +MSG_DEF(JSMSG_TYPEDOBJECT_ARRAYTYPE_BAD_ARGS, 352, 0, JSEXN_ERR, "Invalid arguments") +MSG_DEF(JSMSG_TYPEDOBJECT_BINARYARRAY_BAD_INDEX, 353, 0, JSEXN_RANGEERR, "invalid or out-of-range index") +MSG_DEF(JSMSG_TYPEDOBJECT_STRUCTTYPE_BAD_ARGS, 354, 0, JSEXN_RANGEERR, "invalid field descriptor") +MSG_DEF(JSMSG_TYPEDOBJECT_NOT_BINARYSTRUCT, 355, 1, JSEXN_TYPEERR, "{0} is not a BinaryStruct") +MSG_DEF(JSMSG_TYPEDOBJECT_SUBARRAY_INTEGER_ARG, 356, 1, JSEXN_ERR, "argument {0} must be an integer") +MSG_DEF(JSMSG_TYPEDOBJECT_STRUCTTYPE_EMPTY_DESCRIPTOR, 357, 0, JSEXN_ERR, "field descriptor cannot be empty") +MSG_DEF(JSMSG_TYPEDOBJECT_STRUCTTYPE_BAD_FIELD, 358, 1, JSEXN_ERR, "field {0} is not a valid BinaryData Type descriptor") +MSG_DEF(JSMSG_GENERATOR_FINISHED, 359, 0, JSEXN_TYPEERR, "generator has already finished") +MSG_DEF(JSMSG_TYPEDOBJECT_TOO_BIG, 360, 0, JSEXN_ERR, "Type is too large to allocate") +MSG_DEF(JSMSG_TYPEDOBJECT_NOT_TYPE_OBJECT, 361, 0, JSEXN_ERR, "Expected a type object") +MSG_DEF(JSMSG_TOO_MANY_CON_SPREADARGS, 362, 0, JSEXN_RANGEERR, "too many constructor arguments") +MSG_DEF(JSMSG_TOO_MANY_FUN_SPREADARGS, 363, 0, JSEXN_RANGEERR, "too many function arguments") +MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGEE, 364, 2, JSEXN_ERR, "{0} is not a debuggee {1}") +MSG_DEF(JSMSG_TYPEDOBJECT_NOT_TYPED_OBJECT, 365, 0, JSEXN_ERR, "Expected a typed object") +MSG_DEF(JSMSG_TYPEDOBJECT_NO_SUCH_PROP, 366, 1, JSEXN_TYPEERR, "No such property: {0}") +MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_BAD_ARGS, 367, 2, JSEXN_TYPEERR, "argument {0} invalid: expected {1}") +MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED, 368, 0, JSEXN_TYPEERR, "handle unattached") +MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_BAD_TYPE, 369, 0, JSEXN_TYPEERR, "handle moved to destination of incorrect type") diff --git a/external/spidermonkey/include/android/js/Anchor.h b/external/spidermonkey/include/android/js/Anchor.h index 0d458e6fb6..c2324fb2e9 100644 --- a/external/spidermonkey/include/android/js/Anchor.h +++ b/external/spidermonkey/include/android/js/Anchor.h @@ -11,12 +11,7 @@ #include "mozilla/Attributes.h" -class JSFunction; -class JSObject; -class JSScript; -class JSString; - -namespace JS { class Value; } +#include "js/TypeDecls.h" namespace JS { diff --git a/external/spidermonkey/include/android/js/CallArgs.h b/external/spidermonkey/include/android/js/CallArgs.h index 8027ffc71a..5c7a201101 100644 --- a/external/spidermonkey/include/android/js/CallArgs.h +++ b/external/spidermonkey/include/android/js/CallArgs.h @@ -38,22 +38,19 @@ #include "js/RootingAPI.h" #include "js/Value.h" -struct JSContext; -class JSObject; - /* Typedef for native functions called by the JS VM. */ -typedef JSBool +typedef bool (* JSNative)(JSContext *cx, unsigned argc, JS::Value *vp); /* Typedef for native functions that may be called in parallel. */ -typedef js::ParallelResult +typedef bool (* JSParallelNative)(js::ForkJoinSlice *slice, unsigned argc, JS::Value *vp); /* * Typedef for native functions that may be called either in parallel or * sequential execution. */ -typedef JSBool +typedef bool (* JSThreadSafeNative)(js::ThreadSafeContext *cx, unsigned argc, JS::Value *vp); /* @@ -61,11 +58,11 @@ typedef JSBool * a JSNative or a JSParallelNative. */ template -inline JSBool +inline bool JSNativeThreadSafeWrapper(JSContext *cx, unsigned argc, JS::Value *vp); template -inline js::ParallelResult +inline bool JSParallelNativeThreadSafeWrapper(js::ForkJoinSlice *slice, unsigned argc, JS::Value *vp); /* @@ -89,7 +86,7 @@ extern JS_PUBLIC_DATA(const HandleValue) UndefinedHandleValue; * return value for a function call. The principal way to create a * CallReceiver is using JS::CallReceiverFromVp: * - * static JSBool + * static bool * FunctionReturningThis(JSContext *cx, unsigned argc, JS::Value *vp) * { * JS::CallReceiver rec = JS::CallReceiverFromVp(vp); @@ -282,7 +279,7 @@ CallReceiverFromVp(Value *vp) * the function call's arguments. The principal way to create a CallArgs is * like so, using JS::CallArgsFromVp: * - * static JSBool + * static bool * FunctionReturningArgcTimesArg0(JSContext *cx, unsigned argc, JS::Value *vp) * { * JS::CallArgs args = JS::CallArgsFromVp(argc, vp); diff --git a/external/spidermonkey/include/android/js/CallNonGenericMethod.h b/external/spidermonkey/include/android/js/CallNonGenericMethod.h new file mode 100644 index 0000000000..05097f0294 --- /dev/null +++ b/external/spidermonkey/include/android/js/CallNonGenericMethod.h @@ -0,0 +1,117 @@ +/* -*- 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)(Handle 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, 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, 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 +JS_ALWAYS_INLINE bool +CallNonGenericMethod(JSContext *cx, CallArgs args) +{ + HandleValue thisv = args.thisv(); + if (Test(thisv)) + return Impl(cx, args); + + return detail::CallMethodIfWrapped(cx, Test, Impl, args); +} + +JS_ALWAYS_INLINE bool +CallNonGenericMethod(JSContext *cx, IsAcceptableThis Test, NativeImpl Impl, 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/external/spidermonkey/include/android/js/CharacterEncoding.h b/external/spidermonkey/include/android/js/CharacterEncoding.h index e88e08e1be..7918b83484 100644 --- a/external/spidermonkey/include/android/js/CharacterEncoding.h +++ b/external/spidermonkey/include/android/js/CharacterEncoding.h @@ -7,11 +7,15 @@ #ifndef js_CharacterEncoding_h #define js_CharacterEncoding_h +#include "mozilla/NullPtr.h" #include "mozilla/Range.h" +#include "js/TypeDecls.h" #include "js/Utility.h" -#include "jspubtd.h" +namespace js { +struct ThreadSafeContext; +} namespace JS { @@ -41,7 +45,7 @@ class Latin1CharsZ : public mozilla::RangedPtr typedef mozilla::RangedPtr Base; public: - Latin1CharsZ() : Base(NULL, 0) {} + Latin1CharsZ() : Base(nullptr, 0) {} Latin1CharsZ(char *aBytes, size_t aLength) : Base(reinterpret_cast(aBytes), aLength) @@ -80,7 +84,7 @@ class UTF8CharsZ : public mozilla::RangedPtr typedef mozilla::RangedPtr Base; public: - UTF8CharsZ() : Base(NULL, 0) {} + UTF8CharsZ() : Base(nullptr, 0) {} UTF8CharsZ(char *aBytes, size_t aLength) : Base(reinterpret_cast(aBytes), aLength) @@ -138,7 +142,7 @@ class TwoByteCharsZ : public mozilla::RangedPtr typedef mozilla::RangedPtr Base; public: - TwoByteCharsZ() : Base(NULL, 0) {} + TwoByteCharsZ() : Base(nullptr, 0) {} TwoByteCharsZ(jschar *chars, size_t length) : Base(chars, length) @@ -154,7 +158,7 @@ class TwoByteCharsZ : public mozilla::RangedPtr * 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 NULL chars (which can be tested for with the ! operator). + * will return a nullptr chars (which can be tested for with the ! operator). * This method cannot trigger GC. */ extern Latin1CharsZ diff --git a/external/spidermonkey/include/android/js/Class.h b/external/spidermonkey/include/android/js/Class.h new file mode 100644 index 0000000000..4058688e99 --- /dev/null +++ b/external/spidermonkey/include/android/js/Class.h @@ -0,0 +1,699 @@ +/* -*- 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 "mozilla/NullPtr.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. + */ + +class JSFreeOp; + +namespace js { + +class Class; +class FreeOp; +class PropertyId; +class PropertyName; +class Shape; +class SpecialId; + +// 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; + +static JS_ALWAYS_INLINE jsid +SPECIALID_TO_JSID(const SpecialId &sid); + +/* + * We partition the ways to refer to a property into three: by an index + * (uint32_t); by a string whose characters do not represent an index + * (PropertyName, see vm/String.h); and by various special values. + * + * Special values are encoded using SpecialId, which is layout-compatible but + * non-interconvertible with jsid. A SpecialId is used for JSID_VOID, which + * does not occur in JS scripts but may be used to indicate the absence of a + * valid identifier. In the future, a SpecialId may also be an object used by + * Harmony-proposed private names. + */ +class SpecialId +{ + uintptr_t bits_; + + /* Needs access to raw bits. */ + friend JS_ALWAYS_INLINE jsid SPECIALID_TO_JSID(const SpecialId &sid); + friend class PropertyId; + + static const uintptr_t TYPE_VOID = JSID_TYPE_VOID; + static const uintptr_t TYPE_OBJECT = JSID_TYPE_OBJECT; + static const uintptr_t TYPE_MASK = JSID_TYPE_MASK; + + SpecialId(uintptr_t bits) : bits_(bits) { } + + public: + SpecialId() : bits_(TYPE_VOID) { } + + /* Object-valued */ + + SpecialId(JSObject &obj) + : bits_(uintptr_t(&obj) | TYPE_OBJECT) + { + JS_ASSERT(&obj != nullptr); + JS_ASSERT((uintptr_t(&obj) & TYPE_MASK) == 0); + } + + bool isObject() const { + return (bits_ & TYPE_MASK) == TYPE_OBJECT && bits_ != TYPE_OBJECT; + } + + JSObject *toObject() const { + JS_ASSERT(isObject()); + return reinterpret_cast(bits_ & ~TYPE_MASK); + } + + /* Empty */ + + static SpecialId empty() { + SpecialId sid(TYPE_OBJECT); + JS_ASSERT(sid.isEmpty()); + return sid; + } + + bool isEmpty() const { + return bits_ == TYPE_OBJECT; + } + + /* Void */ + + static SpecialId voidId() { + SpecialId sid(TYPE_VOID); + JS_ASSERT(sid.isVoid()); + return sid; + } + + bool isVoid() const { + return bits_ == TYPE_VOID; + } +}; + +static JS_ALWAYS_INLINE jsid +SPECIALID_TO_JSID(const SpecialId &sid) +{ + jsid id; + JSID_BITS(id) = sid.bits_; + JS_ASSERT_IF(sid.isObject(), JSID_IS_OBJECT(id) && JSID_TO_OBJECT(id) == sid.toObject()); + JS_ASSERT_IF(sid.isVoid(), JSID_IS_VOID(id)); + JS_ASSERT_IF(sid.isEmpty(), JSID_IS_EMPTY(id)); + return id; +} + +static JS_ALWAYS_INLINE bool +JSID_IS_SPECIAL(jsid id) +{ + return JSID_IS_OBJECT(id) || JSID_IS_EMPTY(id) || JSID_IS_VOID(id); +} + +static JS_ALWAYS_INLINE SpecialId +JSID_TO_SPECIALID(jsid id) +{ + JS_ASSERT(JSID_IS_SPECIAL(id)); + if (JSID_IS_OBJECT(id)) + return SpecialId(*JSID_TO_OBJECT(id)); + if (JSID_IS_EMPTY(id)) + return SpecialId::empty(); + JS_ASSERT(JSID_IS_VOID(id)); + return SpecialId::voidId(); +} + +typedef JS::Handle HandleSpecialId; + +} // namespace js + +// JSClass operation signatures. + +// Add or 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 +(* JSPropertyOp)(JSContext *cx, JS::Handle obj, JS::Handle id, + JS::MutableHandle vp); + +// 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 +(* JSStrictPropertyOp)(JSContext *cx, JS::Handle obj, JS::Handle id, + bool strict, JS::MutableHandle vp); + +// 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), set *succeeded to false 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), +// set *succeeded to true and return true. +typedef bool +(* JSDeletePropertyOp)(JSContext *cx, JS::Handle obj, JS::Handle id, + bool *succeeded); + +// This function type is used for callbacks that enumerate the properties of +// a JSObject. The behavior depends on the value of enum_op: +// +// JSENUMERATE_INIT +// A new, opaque iterator state should be allocated and stored in *statep. +// (You can use PRIVATE_TO_JSVAL() to tag the pointer to be stored). +// +// The number of properties that will be enumerated should be returned as +// an integer jsval in *idp, if idp is non-null, and provided the number of +// enumerable properties is known. If idp is non-null and the number of +// enumerable properties can't be computed in advance, *idp should be set +// to JSVAL_ZERO. +// +// JSENUMERATE_INIT_ALL +// Used identically to JSENUMERATE_INIT, but exposes all properties of the +// object regardless of enumerability. +// +// JSENUMERATE_NEXT +// A previously allocated opaque iterator state is passed in via statep. +// Return the next jsid in the iteration using *idp. The opaque iterator +// state pointed at by statep is destroyed and *statep is set to JSVAL_NULL +// if there are no properties left to enumerate. +// +// JSENUMERATE_DESTROY +// Destroy the opaque iterator state previously allocated in *statep by a +// call to this function when enum_op was JSENUMERATE_INIT or +// JSENUMERATE_INIT_ALL. +// +// The return value is used to indicate success, with a value of false +// indicating failure. +typedef bool +(* JSNewEnumerateOp)(JSContext *cx, JS::Handle obj, JSIterateOp enum_op, + JS::MutableHandle statep, JS::MutableHandle idp); + +// The old-style JSClass.enumerate op should define all lazy properties not +// yet reflected in obj. +typedef bool +(* JSEnumerateOp)(JSContext *cx, JS::Handle obj); + +// 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. If resolve succeeds, the engine looks again in case resolve +// defined obj[id]. If no such property exists directly in obj, the process +// is repeated with obj's prototype, etc. +// +// NB: JSNewResolveOp provides a cheaper way to resolve lazy properties. +typedef bool +(* JSResolveOp)(JSContext *cx, JS::Handle obj, JS::Handle id); + +// Like JSResolveOp, but flags provide contextual information as follows: +// +// JSRESOLVE_ASSIGNING obj[id] is on the left-hand side of an assignment +// +// The *objp out parameter, on success, should be null to indicate that id +// was not resolved; and non-null, referring to obj or one of its prototypes, +// if id was resolved. The hook may assume *objp is null on entry. +// +// This hook instead of JSResolveOp is called via the JSClass.resolve member +// if JSCLASS_NEW_RESOLVE is set in JSClass.flags. +typedef bool +(* JSNewResolveOp)(JSContext *cx, JS::Handle obj, JS::Handle id, unsigned flags, + JS::MutableHandle objp); + +// Convert obj to the given type, returning true with the resulting value in +// *vp on success, and returning false on error or exception. +typedef bool +(* JSConvertOp)(JSContext *cx, JS::Handle obj, JSType type, + JS::MutableHandle vp); + +// 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)(const JSStringFinalizer *fin, jschar *chars); +}; + +// JSClass.checkAccess type: check whether obj[id] may be accessed per mode, +// returning false on error/exception, true on success with obj[id]'s last-got +// value in *vp, and its attributes in *attrsp. As for JSPropertyOp above, id +// is either a string or an int jsval. +typedef bool +(* JSCheckAccessOp)(JSContext *cx, JS::Handle obj, JS::Handle id, + JSAccessMode mode, JS::MutableHandle vp); + +// 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); + +// 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::Handle obj, JS::MutableHandle 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 one of the JS_Call*Tracer variants +// on the thing. +// +// 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); + +// A generic type for functions mapping an object to another object, or null +// if an error or exception was thrown on cx. +typedef JSObject * +(* JSObjectOp)(JSContext *cx, JS::Handle obj); + +// Hook that creates an iterator object for a given object. Returns the +// iterator object or null if an error or exception was thrown on cx. +typedef JSObject * +(* JSIteratorOp)(JSContext *cx, JS::HandleObject obj, bool keysonly); + +typedef JSObject * +(* JSWeakmapKeyDelegateOp)(JSObject *obj); + +/* js::Class operation signatures. */ + +namespace js { + +typedef bool +(* LookupGenericOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, + JS::MutableHandleObject objp, JS::MutableHandle propp); +typedef bool +(* LookupPropOp)(JSContext *cx, JS::HandleObject obj, JS::Handle name, + JS::MutableHandleObject objp, JS::MutableHandle propp); +typedef bool +(* LookupElementOp)(JSContext *cx, JS::HandleObject obj, uint32_t index, + JS::MutableHandleObject objp, JS::MutableHandle propp); +typedef bool +(* LookupSpecialOp)(JSContext *cx, JS::HandleObject obj, HandleSpecialId sid, + JS::MutableHandleObject objp, JS::MutableHandle propp); +typedef bool +(* DefineGenericOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value, + JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs); +typedef bool +(* DefinePropOp)(JSContext *cx, JS::HandleObject obj, JS::Handle name, + JS::HandleValue value, JSPropertyOp getter, JSStrictPropertyOp setter, + unsigned attrs); +typedef bool +(* DefineElementOp)(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value, + JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs); +typedef bool +(* DefineSpecialOp)(JSContext *cx, JS::HandleObject obj, HandleSpecialId sid, + JS::HandleValue value, JSPropertyOp getter, JSStrictPropertyOp setter, + unsigned attrs); +typedef bool +(* GenericIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id, + JS::MutableHandleValue vp); +typedef bool +(* PropertyIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, + JS::Handle name, JS::MutableHandleValue vp); +typedef bool +(* ElementIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, uint32_t index, + JS::MutableHandleValue vp); +typedef bool +(* ElementIfPresentOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, + uint32_t index, JS::MutableHandleValue vp, bool* present); +typedef bool +(* SpecialIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, + HandleSpecialId sid, JS::MutableHandleValue vp); +typedef bool +(* StrictGenericIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, + JS::MutableHandleValue vp, bool strict); +typedef bool +(* StrictPropertyIdOp)(JSContext *cx, JS::HandleObject obj, JS::Handle name, + JS::MutableHandleValue vp, bool strict); +typedef bool +(* StrictElementIdOp)(JSContext *cx, JS::HandleObject obj, uint32_t index, + JS::MutableHandleValue vp, bool strict); +typedef bool +(* StrictSpecialIdOp)(JSContext *cx, JS::HandleObject obj, HandleSpecialId sid, + JS::MutableHandleValue vp, bool strict); +typedef bool +(* GenericAttributesOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, unsigned *attrsp); +typedef bool +(* PropertyAttributesOp)(JSContext *cx, JS::HandleObject obj, JS::Handle name, + unsigned *attrsp); +typedef bool +(* DeletePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::Handle name, + bool *succeeded); +typedef bool +(* DeleteElementOp)(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *succeeded); +typedef bool +(* DeleteSpecialOp)(JSContext *cx, JS::HandleObject obj, HandleSpecialId sid, bool *succeeded); + +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); + +typedef JSObject * +(* ObjectOp)(JSContext *cx, JS::HandleObject obj); +typedef void +(* FinalizeOp)(FreeOp *fop, JSObject *obj); + +#define JS_CLASS_MEMBERS \ + const char *name; \ + uint32_t flags; \ + \ + /* Mandatory function pointer members. */ \ + JSPropertyOp addProperty; \ + JSDeletePropertyOp delProperty; \ + JSPropertyOp getProperty; \ + JSStrictPropertyOp setProperty; \ + JSEnumerateOp enumerate; \ + JSResolveOp resolve; \ + JSConvertOp convert; \ + \ + /* Optional members (may be null). */ \ + FinalizeOp finalize; \ + JSCheckAccessOp checkAccess; \ + JSNative call; \ + JSHasInstanceOp hasInstance; \ + JSNative construct; \ + JSTraceOp trace + +/* + * The helper struct to measure the size of JS_CLASS_MEMBERS to know how much + * we have to pad js::Class to match the size of JSClass. + */ +struct ClassSizeMeasurement +{ + JS_CLASS_MEMBERS; +}; + +struct ClassExtension +{ + JSObjectOp outerObject; + JSObjectOp innerObject; + JSIteratorOp iteratorObject; + + /* + * isWrappedNative is true only if the class is an XPCWrappedNative. + * WeakMaps use this to override the wrapper disposal optimization. + */ + bool isWrappedNative; + + /* + * 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; +}; + +#define JS_NULL_CLASS_EXT {nullptr,nullptr,nullptr,false,nullptr} + +struct ObjectOps +{ + LookupGenericOp lookupGeneric; + LookupPropOp lookupProperty; + LookupElementOp lookupElement; + LookupSpecialOp lookupSpecial; + DefineGenericOp defineGeneric; + DefinePropOp defineProperty; + DefineElementOp defineElement; + DefineSpecialOp defineSpecial; + GenericIdOp getGeneric; + PropertyIdOp getProperty; + ElementIdOp getElement; + ElementIfPresentOp getElementIfPresent; /* can be null */ + SpecialIdOp getSpecial; + StrictGenericIdOp setGeneric; + StrictPropertyIdOp setProperty; + StrictElementIdOp setElement; + StrictSpecialIdOp setSpecial; + GenericAttributesOp getGenericAttributes; + GenericAttributesOp setGenericAttributes; + DeletePropertyOp deleteProperty; + DeleteElementOp deleteElement; + DeleteSpecialOp deleteSpecial; + WatchOp watch; + UnwatchOp unwatch; + + JSNewEnumerateOp enumerate; + ObjectOp thisObject; +}; + +#define JS_NULL_OBJECT_OPS \ + {nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr, \ + nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr, \ + nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr} + +} // namespace js + +// Classes, objects, and properties. + +typedef void (*JSClassInternal)(); + +struct JSClass { + const char *name; + uint32_t flags; + + // Mandatory function pointer members. + JSPropertyOp addProperty; + JSDeletePropertyOp delProperty; + JSPropertyOp getProperty; + JSStrictPropertyOp setProperty; + JSEnumerateOp enumerate; + JSResolveOp resolve; + JSConvertOp convert; + + // Optional members (may be null). + JSFinalizeOp finalize; + JSCheckAccessOp checkAccess; + JSNative call; + JSHasInstanceOp hasInstance; + JSNative construct; + JSTraceOp trace; + + void *reserved[42]; +}; + +#define JSCLASS_HAS_PRIVATE (1<<0) // objects have private slot +#define JSCLASS_NEW_ENUMERATE (1<<1) // has JSNewEnumerateOp hook +#define JSCLASS_NEW_RESOLVE (1<<2) // has JSNewResolveOp hook +#define JSCLASS_PRIVATE_IS_NSISUPPORTS (1<<3) // private is (nsISupports *) +#define JSCLASS_IS_DOMJSCLASS (1<<4) // objects are DOM +#define JSCLASS_IMPLEMENTS_BARRIERS (1<<5) // Correctly implements GC read + // and write barriers +#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)) + +// Indicate whether the proto or ctor should be frozen. +#define JSCLASS_FREEZE_PROTO (1<<(JSCLASS_HIGH_FLAGS_SHIFT+4)) +#define JSCLASS_FREEZE_CTOR (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)) + +// 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. +// +#define JSCLASS_GLOBAL_SLOT_COUNT (3 + JSProto_LIMIT * 3 + 28) +#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_WIDTH 6 +#define JSCLASS_CACHED_PROTO_MASK JS_BITMASK(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; + ClassExtension ext; + ObjectOps ops; + uint8_t pad[sizeof(JSClass) - sizeof(ClassSizeMeasurement) - + sizeof(ClassExtension) - sizeof(ObjectOps)]; + + /* Class is not native and its map is not a scope. */ + 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 isCallable() const { + return this == js::FunctionClassPtr || call; + } + + static size_t offsetOfFlags() { return offsetof(Class, flags); } +}; + +JS_STATIC_ASSERT(offsetof(JSClass, name) == offsetof(Class, name)); +JS_STATIC_ASSERT(offsetof(JSClass, flags) == offsetof(Class, flags)); +JS_STATIC_ASSERT(offsetof(JSClass, addProperty) == offsetof(Class, addProperty)); +JS_STATIC_ASSERT(offsetof(JSClass, delProperty) == offsetof(Class, delProperty)); +JS_STATIC_ASSERT(offsetof(JSClass, getProperty) == offsetof(Class, getProperty)); +JS_STATIC_ASSERT(offsetof(JSClass, setProperty) == offsetof(Class, setProperty)); +JS_STATIC_ASSERT(offsetof(JSClass, enumerate) == offsetof(Class, enumerate)); +JS_STATIC_ASSERT(offsetof(JSClass, resolve) == offsetof(Class, resolve)); +JS_STATIC_ASSERT(offsetof(JSClass, convert) == offsetof(Class, convert)); +JS_STATIC_ASSERT(offsetof(JSClass, finalize) == offsetof(Class, finalize)); +JS_STATIC_ASSERT(offsetof(JSClass, checkAccess) == offsetof(Class, checkAccess)); +JS_STATIC_ASSERT(offsetof(JSClass, call) == offsetof(Class, call)); +JS_STATIC_ASSERT(offsetof(JSClass, construct) == offsetof(Class, construct)); +JS_STATIC_ASSERT(offsetof(JSClass, hasInstance) == offsetof(Class, hasInstance)); +JS_STATIC_ASSERT(offsetof(JSClass, trace) == offsetof(Class, trace)); +JS_STATIC_ASSERT(sizeof(JSClass) == sizeof(Class)); + +static JS_ALWAYS_INLINE const JSClass * +Jsvalify(const Class *c) +{ + return (const JSClass *)c; +} + +static JS_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 ESClassValue { + ESClass_Array, ESClass_Number, ESClass_String, ESClass_Boolean, + ESClass_RegExp, ESClass_ArrayBuffer, ESClass_Date +}; + +/* + * Return whether the given object has the given [[Class]] internal property + * value. Beware, this query says nothing about the js::Class of the JSObject + * so the caller must not assume anything about obj's representation (e.g., obj + * may be a proxy). + */ +inline bool +ObjectClassIs(JSObject &obj, ESClassValue classValue, JSContext *cx); + +/* Just a helper that checks v.isObject before calling ObjectClassIs. */ +inline bool +IsObjectWithClass(const JS::Value &v, ESClassValue classValue, JSContext *cx); + +inline bool +IsPoisonedSpecialId(js::SpecialId iden) +{ + if (iden.isObject()) + return JS::IsPoisonedPtr(iden.toObject()); + return false; +} + +template <> struct GCMethods +{ + static SpecialId initial() { return SpecialId(); } + static ThingRootKind kind() { return THING_ROOT_ID; } + static bool poisoned(SpecialId id) { return IsPoisonedSpecialId(id); } +}; + +} /* namespace js */ + +#endif /* js_Class_h */ diff --git a/external/spidermonkey/include/android/js/GCAPI.h b/external/spidermonkey/include/android/js/GCAPI.h index a9bef77c09..9cdf56bcce 100644 --- a/external/spidermonkey/include/android/js/GCAPI.h +++ b/external/spidermonkey/include/android/js/GCAPI.h @@ -7,7 +7,11 @@ #ifndef js_GCAPI_h #define js_GCAPI_h +#include "mozilla/NullPtr.h" + #include "js/HeapAPI.h" +#include "js/RootingAPI.h" +#include "js/Value.h" namespace JS { @@ -15,13 +19,12 @@ namespace JS { /* Reasons internal to the JS engine */ \ D(API) \ D(MAYBEGC) \ - D(LAST_CONTEXT) \ + D(DESTROY_RUNTIME) \ D(DESTROY_CONTEXT) \ D(LAST_DITCH) \ D(TOO_MUCH_MALLOC) \ D(ALLOC_TRIGGER) \ D(DEBUG_GC) \ - D(DEBUG_MODE_GC) \ D(TRANSPLANT) \ D(RESET) \ D(OUT_OF_NURSERY) \ @@ -206,12 +209,25 @@ PokeGC(JSRuntime *rt); extern JS_FRIEND_API(bool) WasIncrementalGC(JSRuntime *rt); -class ObjectPtr +extern JS_FRIEND_API(size_t) +GetGCNumber(); + +class AutoAssertNoGC { +#ifdef DEBUG + size_t gcNumber; + + public: + AutoAssertNoGC(); + ~AutoAssertNoGC(); +#endif +}; + +class JS_PUBLIC_API(ObjectPtr) { Heap value; public: - ObjectPtr() : value(NULL) {} + ObjectPtr() : value(nullptr) {} ObjectPtr(JSObject *obj) : value(obj) {} @@ -221,7 +237,7 @@ class ObjectPtr void finalize(JSRuntime *rt) { if (IsIncrementalBarrierNeeded(rt)) IncrementalObjectBarrier(value); - value = NULL; + value = nullptr; } void init(JSObject *obj) { value = obj; } @@ -232,9 +248,7 @@ class ObjectPtr IncrementalObjectBarrier(value); } - bool isAboutToBeFinalized() { - return JS_IsAboutToBeFinalized(&value); - } + bool isAboutToBeFinalized(); ObjectPtr &operator=(JSObject *obj) { IncrementalObjectBarrier(value); @@ -242,9 +256,7 @@ class ObjectPtr return *this; } - void trace(JSTracer *trc, const char *name) { - JS_CallHeapObjectTracer(trc, &value, name); - } + void trace(JSTracer *trc, const char *name); JSObject &operator*() const { return *value; } JSObject *operator->() const { return value; } @@ -255,7 +267,7 @@ class ObjectPtr * Unsets the gray bit for anything reachable from |thing|. |kind| should not be * JSTRACE_SHAPE. |thing| should be non-null. */ -extern JS_FRIEND_API(void) +extern JS_FRIEND_API(bool) UnmarkGrayGCThingRecursively(void *thing, JSGCTraceKind kind); /* @@ -276,7 +288,7 @@ ExposeGCThingToActiveJS(void *thing, JSGCTraceKind kind) * 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 (uintptr_t(thing) >= rt->gcNurseryStart_ && uintptr_t(thing) < rt->gcNurseryEnd_) + if (js::gc::IsInsideNursery(rt, thing)) return; #endif if (IsIncrementalBarrierNeededOnGCThing(rt, thing, kind)) @@ -292,6 +304,37 @@ ExposeValueToActiveJS(const Value &v) ExposeGCThingToActiveJS(v.toGCThing(), v.gcKind()); } +static JS_ALWAYS_INLINE void +ExposeObjectToActiveJS(JSObject *obj) +{ + ExposeGCThingToActiveJS(obj, JSTRACE_OBJECT); +} + +/* + * If a GC is currently marking, mark the object black. + */ +static JS_ALWAYS_INLINE void +MarkGCThingAsLive(JSRuntime *rt_, void *thing, JSGCTraceKind kind) +{ + shadow::Runtime *rt = shadow::Runtime::asShadowRuntime(rt_); +#ifdef JSGC_GENERATIONAL + /* + * Any object in the nursery will not be freed during any GC running at that time. + */ + if (js::gc::IsInsideNursery(rt, thing)) + return; +#endif + if (IsIncrementalBarrierNeededOnGCThing(rt, thing, kind)) + IncrementalReferenceBarrier(thing, kind); +} + +static JS_ALWAYS_INLINE void +MarkStringAsLive(Zone *zone, JSString *string) +{ + JSRuntime *rt = JS::shadow::Zone::asShadowZone(zone)->runtimeFromMainThread(); + MarkGCThingAsLive(rt, string, JSTRACE_STRING); +} + } /* namespace JS */ #endif /* js_GCAPI_h */ diff --git a/external/spidermonkey/include/android/js/HashTable.h b/external/spidermonkey/include/android/js/HashTable.h index aa05b71472..a6b4361dea 100644 --- a/external/spidermonkey/include/android/js/HashTable.h +++ b/external/spidermonkey/include/android/js/HashTable.h @@ -7,17 +7,18 @@ #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/DebugOnly.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Move.h" +#include "mozilla/NullPtr.h" #include "mozilla/PodOperations.h" #include "mozilla/ReentrancyGuard.h" #include "mozilla/TemplateLib.h" #include "mozilla/TypeTraits.h" -#include "mozilla/Util.h" #include "js/Utility.h" @@ -60,7 +61,7 @@ class HashMap { typedef Key KeyType; static const Key &getKey(TableEntry &e) { return e.key; } - static void setKey(TableEntry &e, Key &k) { const_cast(e.key) = k; } + static void setKey(TableEntry &e, Key &k) { HashPolicy::rekey(const_cast(e.key), k); } }; typedef detail::HashTable Impl; @@ -138,18 +139,18 @@ class HashMap template bool add(AddPtr &p, const KeyInput &k, const ValueInput &v) { Entry e(k, v); - return impl.add(p, mozilla::Move(e)); + return impl.add(p, mozilla::OldMove(e)); } bool add(AddPtr &p, const Key &k) { Entry e(k, Value()); - return impl.add(p, mozilla::Move(e)); + return impl.add(p, mozilla::OldMove(e)); } template bool relookupOrAdd(AddPtr &p, const KeyInput &k, const ValueInput &v) { Entry e(k, v); - return impl.relookupOrAdd(p, k, mozilla::Move(e)); + return impl.relookupOrAdd(p, k, mozilla::OldMove(e)); } // |all()| returns a Range containing |count()| elements. E.g.: @@ -213,7 +214,7 @@ class HashMap /************************************************** Shorthand operations */ bool has(const Lookup &l) const { - return impl.lookup(l) != NULL; + return impl.lookup(l) != nullptr; } // Overwrite existing value with v. Return false on oom. @@ -231,7 +232,7 @@ class HashMap template bool putNew(const KeyInput &k, const ValueInput &v) { Entry e(k, v); - return impl.putNew(k, mozilla::Move(e)); + return impl.putNew(k, mozilla::OldMove(e)); } // Add (k,defaultValue) if |k| is not found. Return a false-y Ptr on oom. @@ -249,17 +250,22 @@ class HashMap 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. - void rekey(const Lookup &old_key, const Key &new_key) { - if (old_key != new_key) { - if (Ptr p = lookup(old_key)) - impl.rekey(p, new_key, new_key); - } + void 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); } // HashMap is movable - HashMap(mozilla::MoveRef rhs) : impl(mozilla::Move(rhs->impl)) {} - void operator=(mozilla::MoveRef rhs) { impl = mozilla::Move(rhs->impl); } + HashMap(mozilla::MoveRef rhs) : impl(mozilla::OldMove(rhs->impl)) {} + void operator=(mozilla::MoveRef rhs) { impl = mozilla::OldMove(rhs->impl); } private: // HashMap is not copyable or assignable @@ -295,7 +301,7 @@ class HashSet { typedef T KeyType; static const KeyType &getKey(const T &t) { return t; } - static void setKey(T &t, KeyType &k) { t = k; } + static void setKey(T &t, KeyType &k) { HashPolicy::rekey(t, k); } }; typedef detail::HashTable Impl; @@ -323,6 +329,10 @@ class HashSet 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); } @@ -425,7 +435,7 @@ class HashSet /************************************************** Shorthand operations */ bool has(const Lookup &l) const { - return impl.lookup(l) != NULL; + return impl.lookup(l) != nullptr; } // Overwrite existing value with v. Return false on oom. @@ -449,16 +459,21 @@ class HashSet } // Infallibly rekey one entry, if present. - void rekey(const Lookup &old_key, const T &new_key) { - if (old_key != new_key) { - if (Ptr p = lookup(old_key)) - impl.rekey(p, new_key, new_key); - } + // 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. + void 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); } // HashSet is movable - HashSet(mozilla::MoveRef rhs) : impl(mozilla::Move(rhs->impl)) {} - void operator=(mozilla::MoveRef rhs) { impl = mozilla::Move(rhs->impl); } + HashSet(mozilla::MoveRef rhs) : impl(mozilla::OldMove(rhs->impl)) {} + void operator=(mozilla::MoveRef rhs) { impl = mozilla::OldMove(rhs->impl); } private: // HashSet is not copyable or assignable @@ -505,7 +520,7 @@ struct PointerHasher JS_ASSERT(!JS::IsPoisonedPtr(l)); size_t word = reinterpret_cast(l) >> zeroBits; JS_STATIC_ASSERT(sizeof(HashNumber) == 4); -#if JS_BYTES_PER_WORD == 4 +#if JS_BITS_PER_WORD == 32 return HashNumber(word); #else JS_STATIC_ASSERT(sizeof word == 8); @@ -517,6 +532,9 @@ struct PointerHasher JS_ASSERT(!JS::IsPoisonedPtr(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 @@ -535,6 +553,9 @@ struct DefaultHasher // 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 @@ -558,6 +579,19 @@ struct DefaultHasher } }; +template <> +struct DefaultHasher +{ + typedef float Lookup; + static HashNumber hash(float f) { + JS_STATIC_ASSERT(sizeof(HashNumber) == 4); + return HashNumber(mozilla::BitwiseCast(f)); + } + static bool match(float lhs, float rhs) { + return mozilla::BitwiseCast(lhs) == mozilla::BitwiseCast(rhs); + } +}; + /*****************************************************************************/ // Both HashMap and HashSet are implemented by a single HashTable that is even @@ -579,7 +613,7 @@ class HashMapEntry HashMapEntry(const KeyInput &k, const ValueInput &v) : key(k), value(v) {} HashMapEntry(mozilla::MoveRef rhs) - : key(mozilla::Move(rhs->key)), value(mozilla::Move(rhs->value)) { } + : key(mozilla::OldMove(rhs->key)), value(mozilla::OldMove(rhs->value)) { } typedef Key KeyType; typedef Value ValueType; @@ -750,7 +784,7 @@ class HashTable : private AllocPolicy mozilla::DebugOnly validEntry; public: - Range() : cur(NULL), end(NULL), validEntry(false) {} + Range() : cur(nullptr), end(nullptr), validEntry(false) {} bool empty() const { return cur == end; @@ -808,7 +842,7 @@ class HashTable : private AllocPolicy // 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) { - table.rekey(*this->cur, l, k); + table.rekeyWithoutRehash(*this->cur, l, k); rekeyed = true; this->validEntry = false; } @@ -834,13 +868,13 @@ class HashTable : private AllocPolicy : AllocPolicy(*rhs) { mozilla::PodAssign(this, &*rhs); - rhs->table = NULL; + rhs->table = nullptr; } void operator=(mozilla::MoveRef rhs) { if (table) destroyTable(*this, table, capacity()); mozilla::PodAssign(this, &*rhs); - rhs->table = NULL; + rhs->table = nullptr; } private: @@ -941,7 +975,7 @@ class HashTable : private AllocPolicy entryCount(0), gen(0), removedCount(0), - table(NULL), + table(nullptr), entered(false), mutationCount(0) {} @@ -1067,7 +1101,7 @@ class HashTable : private AllocPolicy DoubleHash dh = hash2(keyHash); // Save the first removed entry pointer so we can recycle later. - Entry *firstRemoved = NULL; + Entry *firstRemoved = nullptr; while(true) { if (JS_UNLIKELY(entry->isRemoved())) { @@ -1163,7 +1197,7 @@ class HashTable : private AllocPolicy for (Entry *src = oldTable, *end = src + oldCap; src < end; ++src) { if (src->isLive()) { HashNumber hn = src->getKeyHash(); - findFreeEntry(hn).setLive(hn, mozilla::Move(src->get())); + findFreeEntry(hn).setLive(hn, mozilla::OldMove(src->get())); src->destroy(); } } @@ -1307,7 +1341,7 @@ class HashTable : private AllocPolicy return; destroyTable(*this, table, capacity()); - table = NULL; + table = nullptr; gen++; entryCount = 0; removedCount = 0; @@ -1456,15 +1490,21 @@ class HashTable : private AllocPolicy checkUnderloaded(); } - void rekey(Ptr p, const Lookup &l, const Key &k) + void rekeyWithoutRehash(Ptr p, const Lookup &l, const Key &k) { JS_ASSERT(table); mozilla::ReentrancyGuard g(*this); JS_ASSERT(p.found()); - typename HashTableEntry::NonConstT t(mozilla::Move(*p)); + typename HashTableEntry::NonConstT t(mozilla::OldMove(*p)); HashPolicy::setKey(t, const_cast(k)); remove(*p.entry_); - putNewInfallible(l, mozilla::Move(t)); + putNewInfallible(l, mozilla::OldMove(t)); + } + + void rekeyAndMaybeRehash(Ptr p, const Lookup &l, const Key &k) + { + rekeyWithoutRehash(p, l, k); + checkOverRemoved(); } #undef METER diff --git a/external/spidermonkey/include/android/js/HeapAPI.h b/external/spidermonkey/include/android/js/HeapAPI.h index 4d739304bc..438c23c05f 100644 --- a/external/spidermonkey/include/android/js/HeapAPI.h +++ b/external/spidermonkey/include/android/js/HeapAPI.h @@ -7,12 +7,23 @@ #ifndef js_HeapAPI_h #define js_HeapAPI_h +#include + #include "jspubtd.h" #include "js/Utility.h" /* These values are private to the JS engine. */ namespace js { + +// Whether the current thread is permitted access to any part of the specified +// runtime or zone. +JS_FRIEND_API(bool) +CurrentThreadCanAccessRuntime(JSRuntime *rt); + +JS_FRIEND_API(bool) +CurrentThreadCanAccessZone(JS::Zone *zone); + namespace gc { const size_t ArenaShift = 12; @@ -57,9 +68,43 @@ struct ArenaHeader struct Zone { + protected: + JSRuntime *const runtime_; + JSTracer *const barrierTracer_; // A pointer to the JSRuntime's |gcMarker|. + + public: bool needsBarrier_; - Zone() : needsBarrier_(false) {} + Zone(JSRuntime *runtime, JSTracer *barrierTracerArg) + : runtime_(runtime), + barrierTracer_(barrierTracerArg), + needsBarrier_(false) + {} + + bool needsBarrier() const { + return needsBarrier_; + } + + JSTracer *barrierTracer() { + JS_ASSERT(needsBarrier_); + JS_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_)); + return barrierTracer_; + } + + JSRuntime *runtimeFromMainThread() const { + JS_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 JS::shadow::Zone *asShadowZone(JS::Zone *zone) { + return reinterpret_cast(zone); + } }; } /* namespace shadow */ @@ -94,8 +139,9 @@ GetGCThingMarkWordAndMask(const void *thing, uint32_t color, size_t bit = (addr & js::gc::ChunkMask) / js::gc::CellSize + color; JS_ASSERT(bit < js::gc::ChunkMarkBitmapBits); uintptr_t *bitmap = GetGCThingMarkBitmap(thing); - *maskp = uintptr_t(1) << (bit % JS_BITS_PER_WORD); - *wordp = &bitmap[bit / JS_BITS_PER_WORD]; + const uintptr_t nbits = sizeof(*bitmap) * CHAR_BIT; + *maskp = uintptr_t(1) << (bit % nbits); + *wordp = &bitmap[bit / nbits]; } static JS_ALWAYS_INLINE JS::shadow::ArenaHeader * @@ -106,6 +152,16 @@ GetGCThingArena(void *thing) return reinterpret_cast(addr); } +JS_ALWAYS_INLINE bool +IsInsideNursery(const JS::shadow::Runtime *runtime, const void *p) +{ +#ifdef JSGC_GENERATIONAL + return uintptr_t(p) >= runtime->gcNurseryStart_ && uintptr_t(p) < runtime->gcNurseryEnd_; +#else + return false; +#endif +} + } /* namespace gc */ } /* namespace js */ @@ -128,6 +184,16 @@ GetObjectZone(JSObject *obj) static JS_ALWAYS_INLINE bool GCThingIsMarkedGray(void *thing) { +#ifdef JSGC_GENERATIONAL + /* + * 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. + */ + JS::shadow::Runtime *rt = js::gc::GetGCThingRuntime(thing); + if (js::gc::IsInsideNursery(rt, thing)) + return false; +#endif uintptr_t *word, mask; js::gc::GetGCThingMarkWordAndMask(thing, js::gc::GRAY, &word, &mask); return *word & mask; diff --git a/external/spidermonkey/include/android/js/Id.h b/external/spidermonkey/include/android/js/Id.h new file mode 100644 index 0000000000..447deb62e6 --- /dev/null +++ b/external/spidermonkey/include/android/js/Id.h @@ -0,0 +1,192 @@ +/* -*- 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 signed integer, interned string or object. +// +// 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 jsval; JS_ValueToId or +// JS_IdToValue must be used instead. + +#include "mozilla/NullPtr.h" + +#include "jstypes.h" + +#include "js/RootingAPI.h" +#include "js/TypeDecls.h" +#include "js/Utility.h" + +#ifdef JS_USE_JSID_STRUCT_TYPES +struct jsid +{ + size_t asBits; + bool operator==(jsid rhs) const { return asBits == rhs.asBits; } + bool operator!=(jsid rhs) const { return asBits != rhs.asBits; } +}; +# define JSID_BITS(id) (id.asBits) +#else +# define JSID_BITS(id) (id) +#endif + +#define JSID_TYPE_STRING 0x0 +#define JSID_TYPE_INT 0x1 +#define JSID_TYPE_VOID 0x2 +#define JSID_TYPE_OBJECT 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 JS_ALWAYS_INLINE bool +JSID_IS_STRING(jsid id) +{ + return (JSID_BITS(id) & JSID_TYPE_MASK) == 0; +} + +static JS_ALWAYS_INLINE JSString * +JSID_TO_STRING(jsid id) +{ + JS_ASSERT(JSID_IS_STRING(id)); + return (JSString *)JSID_BITS(id); +} + +static JS_ALWAYS_INLINE bool +JSID_IS_ZERO(jsid id) +{ + return JSID_BITS(id) == 0; +} + +static JS_ALWAYS_INLINE bool +JSID_IS_INT(jsid id) +{ + return !!(JSID_BITS(id) & JSID_TYPE_INT); +} + +static JS_ALWAYS_INLINE int32_t +JSID_TO_INT(jsid id) +{ + JS_ASSERT(JSID_IS_INT(id)); + return ((uint32_t)JSID_BITS(id)) >> 1; +} + +#define JSID_INT_MIN 0 +#define JSID_INT_MAX INT32_MAX + +static JS_ALWAYS_INLINE bool +INT_FITS_IN_JSID(int32_t i) +{ + return i >= 0; +} + +static JS_ALWAYS_INLINE jsid +INT_TO_JSID(int32_t i) +{ + jsid id; + JS_ASSERT(INT_FITS_IN_JSID(i)); + JSID_BITS(id) = ((i << 1) | JSID_TYPE_INT); + return id; +} + +static JS_ALWAYS_INLINE bool +JSID_IS_OBJECT(jsid id) +{ + return (JSID_BITS(id) & JSID_TYPE_MASK) == JSID_TYPE_OBJECT && + (size_t)JSID_BITS(id) != JSID_TYPE_OBJECT; +} + +static JS_ALWAYS_INLINE JSObject * +JSID_TO_OBJECT(jsid id) +{ + JS_ASSERT(JSID_IS_OBJECT(id)); + return (JSObject *)(JSID_BITS(id) & ~(size_t)JSID_TYPE_MASK); +} + +static JS_ALWAYS_INLINE jsid +OBJECT_TO_JSID(JSObject *obj) +{ + jsid id; + JS_ASSERT(obj != nullptr); + JS_ASSERT(((size_t)obj & JSID_TYPE_MASK) == 0); + JSID_BITS(id) = ((size_t)obj | JSID_TYPE_OBJECT); + return id; +} + +static JS_ALWAYS_INLINE bool +JSID_IS_GCTHING(jsid id) +{ + return JSID_IS_STRING(id) || JSID_IS_OBJECT(id); +} + +static JS_ALWAYS_INLINE void * +JSID_TO_GCTHING(jsid id) +{ + return (void *)(JSID_BITS(id) & ~(size_t)JSID_TYPE_MASK); +} + +static JS_ALWAYS_INLINE bool +JSID_IS_VOID(const jsid id) +{ + JS_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 JS_ALWAYS_INLINE bool +JSID_IS_EMPTY(const jsid id) +{ + return ((size_t)JSID_BITS(id) == JSID_TYPE_OBJECT); +} + +#undef id + +#ifdef JS_USE_JSID_STRUCT_TYPES +extern JS_PUBLIC_DATA(const jsid) JSID_VOID; +extern JS_PUBLIC_DATA(const jsid) JSID_EMPTY; +#else +# define JSID_VOID ((jsid)JSID_TYPE_VOID) +# define JSID_EMPTY ((jsid)JSID_TYPE_OBJECT) +#endif + +extern JS_PUBLIC_DATA(const JS::Handle) JSID_VOIDHANDLE; +extern JS_PUBLIC_DATA(const JS::Handle) JSID_EMPTYHANDLE; + +namespace js { + +inline bool +IsPoisonedId(jsid iden) +{ + if (JSID_IS_STRING(iden)) + return JS::IsPoisonedPtr(JSID_TO_STRING(iden)); + if (JSID_IS_OBJECT(iden)) + return JS::IsPoisonedPtr(JSID_TO_OBJECT(iden)); + return false; +} + +template <> struct GCMethods +{ + static jsid initial() { return JSID_VOID; } + static ThingRootKind kind() { return THING_ROOT_ID; } + static bool poisoned(jsid id) { return IsPoisonedId(id); } + static bool needsPostBarrier(jsid id) { return false; } +#ifdef JSGC_GENERATIONAL + static void postBarrier(jsid *idp) {} + static void relocate(jsid *idp) {} +#endif +}; + +} + +#endif /* js_Id_h */ diff --git a/external/spidermonkey/include/android/js/MemoryMetrics.h b/external/spidermonkey/include/android/js/MemoryMetrics.h index ed61e1c427..2336e35624 100644 --- a/external/spidermonkey/include/android/js/MemoryMetrics.h +++ b/external/spidermonkey/include/android/js/MemoryMetrics.h @@ -7,20 +7,54 @@ #ifndef js_MemoryMetrics_h #define js_MemoryMetrics_h -// These declarations are not within jsapi.h because they are highly likely to -// change in the future. Depend on them at your own risk. +// These declarations are highly likely to change in the future. Depend on them +// at your own risk. #include "mozilla/MemoryReporting.h" +#include "mozilla/NullPtr.h" +#include "mozilla/PodOperations.h" #include #include "jsalloc.h" #include "jspubtd.h" +#include "js/HashTable.h" #include "js/Utility.h" #include "js/Vector.h" -class nsISupports; // This is needed for ObjectPrivateVisitor. +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; +}; + +} // namespace JS namespace js { @@ -30,9 +64,86 @@ namespace js { // MemoryReportingSundriesThreshold() bytes. // // We need to define this value here, rather than in the code which actually -// generates the memory reports, because HugeStringInfo uses this value. +// 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); +}; + +// 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. +// +// In some classes, one or more of the macro arguments aren't used. We use '_' +// for those. +// +#define DECL_SIZE(kind, gc, mSize) size_t mSize; +#define ZERO_SIZE(kind, gc, mSize) mSize(0), +#define COPY_OTHER_SIZE(kind, gc, mSize) mSize(other.mSize), +#define ADD_OTHER_SIZE(kind, gc, mSize) mSize += other.mSize; +#define ADD_SIZE_TO_N_IF_LIVE_GC_THING(kind, gc, mSize) n += (js::gc == js::IsLiveGCThing) ? mSize : 0; +#define ADD_TO_TAB_SIZES(kind, gc, mSize) sizes->add(JS::TabSizes::kind, mSize); + +// Used to annotate which size_t fields measure live GC things and which don't. +enum { + NotLiveGCThing = false, + IsLiveGCThing = true +}; + +struct ZoneStatsPod +{ +#define FOR_EACH_SIZE(macro) \ + macro(Other, NotLiveGCThing, gcHeapArenaAdmin) \ + macro(Other, NotLiveGCThing, unusedGCThings) \ + macro(Other, IsLiveGCThing, lazyScriptsGCHeap) \ + macro(Other, NotLiveGCThing, lazyScriptsMallocHeap) \ + macro(Other, IsLiveGCThing, ionCodesGCHeap) \ + macro(Other, IsLiveGCThing, typeObjectsGCHeap) \ + macro(Other, NotLiveGCThing, typeObjectsMallocHeap) \ + macro(Other, NotLiveGCThing, typePool) \ + macro(Strings, IsLiveGCThing, stringsShortGCHeap) \ + macro(Strings, IsLiveGCThing, stringsNormalGCHeap) \ + macro(Strings, NotLiveGCThing, stringsNormalMallocHeap) + + ZoneStatsPod() + : FOR_EACH_SIZE(ZERO_SIZE) + extra() + {} + + void add(const ZoneStatsPod &other) { + FOR_EACH_SIZE(ADD_OTHER_SIZE) + // Do nothing with |extra|. + } + + size_t sizeOfLiveGCThings() const { + size_t n = 0; + FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) + // Do nothing with |extra|. + return n; + } + + void addToTabSizes(JS::TabSizes *sizes) const { + FOR_EACH_SIZE(ADD_TO_TAB_SIZES) + // Do nothing with |extra|. + } + + FOR_EACH_SIZE(DECL_SIZE) + void *extra; // This field can be used by embedders. + +#undef FOR_EACH_SIZE +}; + } // namespace js namespace JS { @@ -40,352 +151,320 @@ namespace JS { // Data for tracking memory usage of things hanging off objects. struct ObjectsExtraSizes { - size_t slots; - size_t elementsNonAsmJS; - size_t elementsAsmJSHeap; - size_t elementsAsmJSNonHeap; - size_t argumentsData; - size_t regExpStatics; - size_t propertyIteratorData; - size_t ctypesData; - size_t private_; // The '_' suffix is required because |private| is a keyword. - // Note that this field is measured separately from the others. +#define FOR_EACH_SIZE(macro) \ + macro(Objects, NotLiveGCThing, mallocHeapSlots) \ + macro(Objects, NotLiveGCThing, mallocHeapElementsNonAsmJS) \ + macro(Objects, NotLiveGCThing, mallocHeapElementsAsmJS) \ + macro(Objects, NotLiveGCThing, nonHeapElementsAsmJS) \ + macro(Objects, NotLiveGCThing, nonHeapCodeAsmJS) \ + macro(Objects, NotLiveGCThing, mallocHeapAsmJSModuleData) \ + macro(Objects, NotLiveGCThing, mallocHeapArgumentsData) \ + macro(Objects, NotLiveGCThing, mallocHeapRegExpStatics) \ + macro(Objects, NotLiveGCThing, mallocHeapPropertyIteratorData) \ + macro(Objects, NotLiveGCThing, mallocHeapCtypesData) - ObjectsExtraSizes() { memset(this, 0, sizeof(ObjectsExtraSizes)); } + ObjectsExtraSizes() + : FOR_EACH_SIZE(ZERO_SIZE) + dummy() + {} - void add(ObjectsExtraSizes &sizes) { - this->slots += sizes.slots; - this->elementsNonAsmJS += sizes.elementsNonAsmJS; - this->elementsAsmJSHeap += sizes.elementsAsmJSHeap; - this->elementsAsmJSNonHeap += sizes.elementsAsmJSNonHeap; - this->argumentsData += sizes.argumentsData; - this->regExpStatics += sizes.regExpStatics; - this->propertyIteratorData += sizes.propertyIteratorData; - this->ctypesData += sizes.ctypesData; - this->private_ += sizes.private_; + void add(const ObjectsExtraSizes &other) { + FOR_EACH_SIZE(ADD_OTHER_SIZE) } -}; -// Data for tracking analysis/inference memory usage. -struct TypeInferenceSizes -{ - size_t typeScripts; - size_t typeResults; - size_t analysisPool; - size_t pendingArrays; - size_t allocationSiteTables; - size_t arrayTypeTables; - size_t objectTypeTables; - - TypeInferenceSizes() { memset(this, 0, sizeof(TypeInferenceSizes)); } - - void add(TypeInferenceSizes &sizes) { - this->typeScripts += sizes.typeScripts; - this->typeResults += sizes.typeResults; - this->analysisPool += sizes.analysisPool; - this->pendingArrays += sizes.pendingArrays; - this->allocationSiteTables += sizes.allocationSiteTables; - this->arrayTypeTables += sizes.arrayTypeTables; - this->objectTypeTables += sizes.objectTypeTables; + 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) + } + + 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 JIT-code memory usage. struct CodeSizes { - size_t ion; - size_t asmJS; - size_t baseline; - size_t regexp; - size_t other; - size_t unused; +#define FOR_EACH_SIZE(macro) \ + macro(_, _, ion) \ + macro(_, _, baseline) \ + macro(_, _, regexp) \ + macro(_, _, other) \ + macro(_, _, unused) - CodeSizes() { memset(this, 0, sizeof(CodeSizes)); } + CodeSizes() + : FOR_EACH_SIZE(ZERO_SIZE) + dummy() + {} + + 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 huge string (one which uses more HugeStringInfo::MinSize -// bytes of memory), so we can report it individually. -struct HugeStringInfo +// 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. +struct StringInfo { - HugeStringInfo() : length(0), size(0) { memset(&buffer, 0, sizeof(buffer)); } + StringInfo() + : length(0), numCopies(0), shortGCHeap(0), normalGCHeap(0), normalMallocHeap(0) + {} + + StringInfo(size_t len, size_t shorts, size_t normals, size_t chars) + : length(len), + numCopies(1), + shortGCHeap(shorts), + normalGCHeap(normals), + normalMallocHeap(chars) + {} + + void add(size_t shorts, size_t normals, size_t chars) { + shortGCHeap += shorts; + normalGCHeap += normals; + normalMallocHeap += chars; + numCopies++; + } + + void add(const StringInfo& info) { + MOZ_ASSERT(length == info.length); + + shortGCHeap += info.shortGCHeap; + normalGCHeap += info.normalGCHeap; + normalMallocHeap += info.normalMallocHeap; + numCopies += info.numCopies; + } + + size_t totalSizeOf() const { + return shortGCHeap + normalGCHeap + normalMallocHeap; + } + + size_t totalGCHeapSizeOf() const { + return shortGCHeap + normalGCHeap; + } + + // The string's length, excluding the null-terminator. + size_t length; + + // How many copies of the string have we seen? + size_t numCopies; + + // These are all totals across all copies of the string we've seen. + size_t shortGCHeap; + size_t normalGCHeap; + size_t normalMallocHeap; +}; + +// Holds data about a notable string (one which uses more than +// NotableStringInfo::notableSize() bytes of memory), so we can report it +// individually. +// +// Essentially the only difference between this class and StringInfo is that +// NotableStringInfo holds a copy of the string's chars. +struct NotableStringInfo : public StringInfo +{ + NotableStringInfo(); + NotableStringInfo(JSString *str, const StringInfo &info); + NotableStringInfo(mozilla::MoveRef info); + NotableStringInfo &operator=(mozilla::MoveRef info); + + ~NotableStringInfo() { + js_free(buffer); + } // A string needs to take up this many bytes of storage before we consider - // it to be "huge". - static size_t MinSize() { + // it to be "notable". + static size_t notableSize() { return js::MemoryReportingSundriesThreshold(); } - // A string's size in memory is not necessarily equal to twice its length - // because the allocator and the JS engine both may round up. - size_t length; - size_t size; + char *buffer; - // We record the first 32 chars of the escaped string here. (We escape the - // string so we can use a char[] instead of a jschar[] here. - char buffer[32]; + private: + NotableStringInfo(const NotableStringInfo& info) MOZ_DELETE; }; -// These measurements relate directly to the JSRuntime, and not to +// These measurements relate directly to the JSRuntime, and not to zones and // compartments within it. struct RuntimeSizes { - RuntimeSizes() { memset(this, 0, sizeof(RuntimeSizes)); } +#define FOR_EACH_SIZE(macro) \ + macro(_, _, object) \ + macro(_, _, atomsTable) \ + macro(_, _, contexts) \ + macro(_, _, dtoa) \ + macro(_, _, temporary) \ + macro(_, _, regexpData) \ + macro(_, _, interpreterStack) \ + macro(_, _, gcMarker) \ + macro(_, _, mathCache) \ + macro(_, _, scriptData) \ + macro(_, _, scriptSources) - size_t object; - size_t atomsTable; - size_t contexts; - size_t dtoa; - size_t temporary; - size_t regexpData; - size_t interpreterStack; - size_t gcMarker; - size_t mathCache; - size_t scriptData; - size_t scriptSources; - - CodeSizes code; -}; - -struct ZoneStats -{ - ZoneStats() - : extra(NULL), - gcHeapArenaAdmin(0), - gcHeapUnusedGcThings(0), - gcHeapStringsNormal(0), - gcHeapStringsShort(0), - gcHeapLazyScripts(0), - gcHeapTypeObjects(0), - gcHeapIonCodes(0), - stringCharsNonHuge(0), - lazyScripts(0), - typeObjects(0), - typePool(0), - hugeStrings() + RuntimeSizes() + : FOR_EACH_SIZE(ZERO_SIZE) + code() {} - ZoneStats(const ZoneStats &other) - : extra(other.extra), - gcHeapArenaAdmin(other.gcHeapArenaAdmin), - gcHeapUnusedGcThings(other.gcHeapUnusedGcThings), - gcHeapStringsNormal(other.gcHeapStringsNormal), - gcHeapStringsShort(other.gcHeapStringsShort), - gcHeapLazyScripts(other.gcHeapLazyScripts), - gcHeapTypeObjects(other.gcHeapTypeObjects), - gcHeapIonCodes(other.gcHeapIonCodes), - stringCharsNonHuge(other.stringCharsNonHuge), - lazyScripts(other.lazyScripts), - typeObjects(other.typeObjects), - typePool(other.typePool), - hugeStrings() - { - hugeStrings.appendAll(other.hugeStrings); + FOR_EACH_SIZE(DECL_SIZE) + CodeSizes code; + +#undef FOR_EACH_SIZE +}; + +struct ZoneStats : js::ZoneStatsPod +{ + ZoneStats() { + strings.init(); } - // Add other's numbers to this object's numbers. - void add(ZoneStats &other) { - #define ADD(x) this->x += other.x + ZoneStats(mozilla::MoveRef other) + : ZoneStatsPod(other), + strings(mozilla::OldMove(other->strings)), + notableStrings(mozilla::OldMove(other->notableStrings)) + {} - ADD(gcHeapArenaAdmin); - ADD(gcHeapUnusedGcThings); + // Add other's numbers to this object's numbers. Both objects' + // notableStrings vectors must be empty at this point, because we can't + // merge them. (A NotableStringInfo contains only a prefix of the string, + // so we can't tell whether two NotableStringInfo objects correspond to the + // same string.) + void add(const ZoneStats &other) { + ZoneStatsPod::add(other); - ADD(gcHeapStringsNormal); - ADD(gcHeapStringsShort); - ADD(gcHeapLazyScripts); - ADD(gcHeapTypeObjects); - ADD(gcHeapIonCodes); + MOZ_ASSERT(notableStrings.empty()); + MOZ_ASSERT(other.notableStrings.empty()); - ADD(stringCharsNonHuge); - ADD(lazyScripts); - ADD(typeObjects); - ADD(typePool); - - #undef ADD - - hugeStrings.appendAll(other.hugeStrings); + for (StringsHashMap::Range r = other.strings.all(); !r.empty(); r.popFront()) { + StringsHashMap::AddPtr p = strings.lookupForAdd(r.front().key); + if (p) { + // We've seen this string before; add its size to our tally. + p->value.add(r.front().value); + } else { + // We haven't seen this string before; add it to the hashtable. + strings.add(p, r.front().key, r.front().value); + } + } } - // This field can be used by embedders. - void *extra; + size_t sizeOfLiveGCThings() const { + size_t n = ZoneStatsPod::sizeOfLiveGCThings(); + for (size_t i = 0; i < notableStrings.length(); i++) { + const JS::NotableStringInfo& info = notableStrings[i]; + n += info.totalGCHeapSizeOf(); + } + return n; + } - size_t gcHeapArenaAdmin; - size_t gcHeapUnusedGcThings; + typedef js::HashMap StringsHashMap; - size_t gcHeapStringsNormal; - size_t gcHeapStringsShort; - - size_t gcHeapLazyScripts; - size_t gcHeapTypeObjects; - size_t gcHeapIonCodes; - - size_t stringCharsNonHuge; - size_t lazyScripts; - size_t typeObjects; - size_t typePool; - - js::Vector hugeStrings; - - // The size of all the live things in the GC heap that don't belong to any - // compartment. - size_t GCHeapThingsSize(); + StringsHashMap strings; + js::Vector notableStrings; }; struct CompartmentStats { +#define FOR_EACH_SIZE(macro) \ + macro(Objects, IsLiveGCThing, objectsGCHeapOrdinary) \ + macro(Objects, IsLiveGCThing, objectsGCHeapFunction) \ + macro(Objects, IsLiveGCThing, objectsGCHeapDenseArray) \ + macro(Objects, IsLiveGCThing, objectsGCHeapSlowArray) \ + macro(Objects, IsLiveGCThing, objectsGCHeapCrossCompartmentWrapper) \ + macro(Private, NotLiveGCThing, objectsPrivate) \ + macro(Other, IsLiveGCThing, shapesGCHeapTreeGlobalParented) \ + macro(Other, IsLiveGCThing, shapesGCHeapTreeNonGlobalParented) \ + macro(Other, IsLiveGCThing, shapesGCHeapDict) \ + macro(Other, IsLiveGCThing, shapesGCHeapBase) \ + macro(Other, NotLiveGCThing, shapesMallocHeapTreeTables) \ + macro(Other, NotLiveGCThing, shapesMallocHeapDictTables) \ + macro(Other, NotLiveGCThing, shapesMallocHeapTreeShapeKids) \ + macro(Other, NotLiveGCThing, shapesMallocHeapCompartmentTables) \ + macro(Other, IsLiveGCThing, scriptsGCHeap) \ + macro(Other, NotLiveGCThing, scriptsMallocHeapData) \ + macro(Other, NotLiveGCThing, baselineData) \ + macro(Other, NotLiveGCThing, baselineStubsFallback) \ + macro(Other, NotLiveGCThing, baselineStubsOptimized) \ + macro(Other, NotLiveGCThing, ionData) \ + macro(Other, NotLiveGCThing, typeInferenceTypeScripts) \ + macro(Other, NotLiveGCThing, typeInferencePendingArrays) \ + macro(Other, NotLiveGCThing, typeInferenceAllocationSiteTables) \ + macro(Other, NotLiveGCThing, typeInferenceArrayTypeTables) \ + macro(Other, NotLiveGCThing, typeInferenceObjectTypeTables) \ + macro(Other, NotLiveGCThing, compartmentObject) \ + macro(Other, NotLiveGCThing, crossCompartmentWrappersTable) \ + macro(Other, NotLiveGCThing, regexpCompartment) \ + macro(Other, NotLiveGCThing, debuggeesSet) + CompartmentStats() - : extra(NULL), - gcHeapObjectsOrdinary(0), - gcHeapObjectsFunction(0), - gcHeapObjectsDenseArray(0), - gcHeapObjectsSlowArray(0), - gcHeapObjectsCrossCompartmentWrapper(0), - gcHeapShapesTreeGlobalParented(0), - gcHeapShapesTreeNonGlobalParented(0), - gcHeapShapesDict(0), - gcHeapShapesBase(0), - gcHeapScripts(0), + : FOR_EACH_SIZE(ZERO_SIZE) objectsExtra(), - shapesExtraTreeTables(0), - shapesExtraDictTables(0), - shapesExtraTreeShapeKids(0), - shapesCompartmentTables(0), - scriptData(0), - baselineData(0), - baselineStubsFallback(0), - baselineStubsOptimized(0), - ionData(0), - compartmentObject(0), - crossCompartmentWrappersTable(0), - regexpCompartment(0), - debuggeesSet(0), - typeInference() + extra() {} CompartmentStats(const CompartmentStats &other) - : extra(other.extra), - gcHeapObjectsOrdinary(other.gcHeapObjectsOrdinary), - gcHeapObjectsFunction(other.gcHeapObjectsFunction), - gcHeapObjectsDenseArray(other.gcHeapObjectsDenseArray), - gcHeapObjectsSlowArray(other.gcHeapObjectsSlowArray), - gcHeapObjectsCrossCompartmentWrapper(other.gcHeapObjectsCrossCompartmentWrapper), - gcHeapShapesTreeGlobalParented(other.gcHeapShapesTreeGlobalParented), - gcHeapShapesTreeNonGlobalParented(other.gcHeapShapesTreeNonGlobalParented), - gcHeapShapesDict(other.gcHeapShapesDict), - gcHeapShapesBase(other.gcHeapShapesBase), - gcHeapScripts(other.gcHeapScripts), + : FOR_EACH_SIZE(COPY_OTHER_SIZE) objectsExtra(other.objectsExtra), - shapesExtraTreeTables(other.shapesExtraTreeTables), - shapesExtraDictTables(other.shapesExtraDictTables), - shapesExtraTreeShapeKids(other.shapesExtraTreeShapeKids), - shapesCompartmentTables(other.shapesCompartmentTables), - scriptData(other.scriptData), - baselineData(other.baselineData), - baselineStubsFallback(other.baselineStubsFallback), - baselineStubsOptimized(other.baselineStubsOptimized), - ionData(other.ionData), - compartmentObject(other.compartmentObject), - crossCompartmentWrappersTable(other.crossCompartmentWrappersTable), - regexpCompartment(other.regexpCompartment), - debuggeesSet(other.debuggeesSet), - typeInference(other.typeInference) - { + extra(other.extra) + {} + + void add(const CompartmentStats &other) { + FOR_EACH_SIZE(ADD_OTHER_SIZE) + objectsExtra.add(other.objectsExtra); + // Do nothing with |extra|. } - // This field can be used by embedders. - void *extra; - - // If you add a new number, remember to update the constructors, add(), and - // maybe gcHeapThingsSize()! - size_t gcHeapObjectsOrdinary; - size_t gcHeapObjectsFunction; - size_t gcHeapObjectsDenseArray; - size_t gcHeapObjectsSlowArray; - size_t gcHeapObjectsCrossCompartmentWrapper; - size_t gcHeapShapesTreeGlobalParented; - size_t gcHeapShapesTreeNonGlobalParented; - size_t gcHeapShapesDict; - size_t gcHeapShapesBase; - size_t gcHeapScripts; - ObjectsExtraSizes objectsExtra; - - size_t shapesExtraTreeTables; - size_t shapesExtraDictTables; - size_t shapesExtraTreeShapeKids; - size_t shapesCompartmentTables; - size_t scriptData; - size_t baselineData; - size_t baselineStubsFallback; - size_t baselineStubsOptimized; - size_t ionData; - size_t compartmentObject; - size_t crossCompartmentWrappersTable; - size_t regexpCompartment; - size_t debuggeesSet; - - TypeInferenceSizes typeInference; - - // Add cStats's numbers to this object's numbers. - void add(CompartmentStats &cStats) { - #define ADD(x) this->x += cStats.x - - ADD(gcHeapObjectsOrdinary); - ADD(gcHeapObjectsFunction); - ADD(gcHeapObjectsDenseArray); - ADD(gcHeapObjectsSlowArray); - ADD(gcHeapObjectsCrossCompartmentWrapper); - ADD(gcHeapShapesTreeGlobalParented); - ADD(gcHeapShapesTreeNonGlobalParented); - ADD(gcHeapShapesDict); - ADD(gcHeapShapesBase); - ADD(gcHeapScripts); - objectsExtra.add(cStats.objectsExtra); - - ADD(shapesExtraTreeTables); - ADD(shapesExtraDictTables); - ADD(shapesExtraTreeShapeKids); - ADD(shapesCompartmentTables); - ADD(scriptData); - ADD(baselineData); - ADD(baselineStubsFallback); - ADD(baselineStubsOptimized); - ADD(ionData); - ADD(compartmentObject); - ADD(crossCompartmentWrappersTable); - ADD(regexpCompartment); - ADD(debuggeesSet); - - #undef ADD - - typeInference.add(cStats.typeInference); + size_t sizeOfLiveGCThings() const { + size_t n = 0; + FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) + n += objectsExtra.sizeOfLiveGCThings(); + // Do nothing with |extra|. + return n; } - // The size of all the live things in the GC heap. - size_t GCHeapThingsSize(); + void addToTabSizes(TabSizes *sizes) const { + FOR_EACH_SIZE(ADD_TO_TAB_SIZES); + objectsExtra.addToTabSizes(sizes); + // Do nothing with |extra|. + } + + FOR_EACH_SIZE(DECL_SIZE) + ObjectsExtraSizes objectsExtra; + void *extra; // This field can be used by embedders. + +#undef FOR_EACH_SIZE }; struct RuntimeStats { +#define FOR_EACH_SIZE(macro) \ + macro(_, _, gcHeapChunkTotal) \ + macro(_, _, gcHeapDecommittedArenas) \ + macro(_, _, gcHeapUnusedChunks) \ + macro(_, _, gcHeapUnusedArenas) \ + macro(_, _, gcHeapChunkAdmin) \ + macro(_, _, gcHeapGCThings) \ + RuntimeStats(mozilla::MallocSizeOf mallocSizeOf) - : runtime(), - gcHeapChunkTotal(0), - gcHeapDecommittedArenas(0), - gcHeapUnusedChunks(0), - gcHeapUnusedArenas(0), - gcHeapUnusedGcThings(0), - gcHeapChunkAdmin(0), - gcHeapGcThings(0), + : FOR_EACH_SIZE(ZERO_SIZE) + runtime(), cTotals(), zTotals(), compartmentStatsVector(), zoneStatsVector(), - currZoneStats(NULL), + currZoneStats(nullptr), mallocSizeOf_(mallocSizeOf) {} - RuntimeSizes runtime; - - // If you add a new number, remember to update the constructor! - // Here's a useful breakdown of the GC heap. // // - rtStats.gcHeapChunkTotal @@ -394,28 +473,24 @@ struct RuntimeStats // - unused bytes // - rtStats.gcHeapUnusedChunks (empty chunks) // - rtStats.gcHeapUnusedArenas (empty arenas within non-empty chunks) - // - rtStats.total.gcHeapUnusedGcThings (empty GC thing slots within non-empty arenas) + // - rtStats.zTotals.unusedGCThings (empty GC thing slots within non-empty arenas) // - used bytes // - rtStats.gcHeapChunkAdmin - // - rtStats.total.gcHeapArenaAdmin - // - rtStats.gcHeapGcThings (in-use GC things) + // - 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. - size_t gcHeapChunkTotal; - size_t gcHeapDecommittedArenas; - size_t gcHeapUnusedChunks; - size_t gcHeapUnusedArenas; - size_t gcHeapUnusedGcThings; - size_t gcHeapChunkAdmin; - size_t gcHeapGcThings; + FOR_EACH_SIZE(DECL_SIZE) - // The sum of all compartment's measurements. - CompartmentStats cTotals; - ZoneStats zTotals; + RuntimeSizes runtime; + + CompartmentStats cTotals; // The sum of this runtime's compartments' measurements. + ZoneStats zTotals; // The sum of this runtime's zones' measurements. js::Vector compartmentStatsVector; js::Vector zoneStatsVector; @@ -426,6 +501,8 @@ struct RuntimeStats virtual void initExtraCompartmentStats(JSCompartment *c, CompartmentStats *cstats) = 0; virtual void initExtraZoneStats(JS::Zone *zone, ZoneStats *zstats) = 0; + +#undef FOR_EACH_SIZE }; class ObjectPrivateVisitor @@ -437,7 +514,7 @@ class ObjectPrivateVisitor // A callback that gets a JSObject's nsISupports pointer, if it has one. // Note: this function does *not* addref |iface|. - typedef JSBool(*GetISupportsFun)(JSObject *obj, nsISupports **iface); + typedef bool(*GetISupportsFun)(JSObject *obj, nsISupports **iface); GetISupportsFun getISupports_; ObjectPrivateVisitor(GetISupportsFun getISupports) @@ -457,6 +534,17 @@ UserCompartmentCount(JSRuntime *rt); extern JS_PUBLIC_API(size_t) PeakSizeOfTemporary(const JSRuntime *rt); +extern JS_PUBLIC_API(bool) +AddSizeOfTab(JSRuntime *rt, JSObject *obj, mozilla::MallocSizeOf mallocSizeOf, + ObjectPrivateVisitor *opv, TabSizes *sizes); + } // namespace JS +#undef DECL_SIZE +#undef ZERO_SIZE +#undef COPY_OTHER_SIZE +#undef ADD_OTHER_SIZE +#undef ADD_SIZE_TO_N_IF_LIVE_GC_THING +#undef ADD_TO_TAB_SIZES + #endif /* js_MemoryMetrics_h */ diff --git a/external/spidermonkey/include/android/jsdbgapi.h b/external/spidermonkey/include/android/js/OldDebugAPI.h similarity index 77% rename from external/spidermonkey/include/android/jsdbgapi.h rename to external/spidermonkey/include/android/js/OldDebugAPI.h index 0ce7101337..5e5bdf38d7 100644 --- a/external/spidermonkey/include/android/jsdbgapi.h +++ b/external/spidermonkey/include/android/js/OldDebugAPI.h @@ -4,13 +4,24 @@ * License, v. 2.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 jsdbgapi_h -#define jsdbgapi_h +#ifndef js_OldDebugAPI_h +#define js_OldDebugAPI_h + /* * JS debugger API. */ -#include "jsprvtd.h" +#include "mozilla/NullPtr.h" + +#include "jsbytecode.h" + +#include "js/CallArgs.h" +#include "js/TypeDecls.h" + +class JSAtom; +class JSFreeOp; + +namespace js { class StackFrame; } namespace JS { @@ -34,21 +45,68 @@ extern JS_PUBLIC_API(void) FreeStackDescription(JSContext *cx, StackDescription *desc); extern JS_PUBLIC_API(char *) -FormatStackDump(JSContext *cx, char *buf, - JSBool showArgs, JSBool showLocals, - JSBool showThisProps); +FormatStackDump(JSContext *cx, char *buf, bool showArgs, bool showLocals, bool showThisProps); } # ifdef DEBUG -JS_FRIEND_API(void) js_DumpValue(const js::Value &val); +JS_FRIEND_API(void) js_DumpValue(const JS::Value &val); JS_FRIEND_API(void) js_DumpId(jsid id); -JS_FRIEND_API(void) js_DumpStackFrame(JSContext *cx, js::StackFrame *start = NULL); +JS_FRIEND_API(void) js_DumpStackFrame(JSContext *cx, js::StackFrame *start = nullptr); # endif JS_FRIEND_API(void) js_DumpBacktrace(JSContext *cx); +typedef enum JSTrapStatus { + JSTRAP_ERROR, + JSTRAP_CONTINUE, + JSTRAP_RETURN, + JSTRAP_THROW, + JSTRAP_LIMIT +} JSTrapStatus; + +typedef JSTrapStatus +(* JSTrapHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, JS::Value *rval, + JS::Value closure); + +typedef JSTrapStatus +(* JSInterruptHook)(JSContext *cx, JSScript *script, jsbytecode *pc, JS::Value *rval, + void *closure); + +typedef JSTrapStatus +(* JSDebuggerHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, JS::Value *rval, + void *closure); + +typedef JSTrapStatus +(* JSThrowHook)(JSContext *cx, JSScript *script, jsbytecode *pc, JS::Value *rval, + void *closure); + +typedef bool +(* JSWatchPointHandler)(JSContext *cx, JSObject *obj, jsid id, JS::Value old, + JS::Value *newp, void *closure); + +/* called just after script creation */ +typedef void +(* JSNewScriptHook)(JSContext *cx, + const char *filename, /* URL of script */ + unsigned lineno, /* first line */ + JSScript *script, + JSFunction *fun, + void *callerdata); + +/* called just before script destruction */ +typedef void +(* JSDestroyScriptHook)(JSFreeOp *fop, + JSScript *script, + void *callerdata); + +typedef void +(* JSSourceHandler)(const char *filename, unsigned lineno, const jschar *str, + size_t length, void **listenerTSData, void *closure); + + + extern JS_PUBLIC_API(JSCompartment *) JS_EnterCompartmentOfScript(JSContext *cx, JSScript *target); @@ -60,7 +118,7 @@ JS_DecompileScript(JSContext *cx, JSScript *script, const char *name, unsigned i * be able to support compartment-wide debugging. */ extern JS_PUBLIC_API(void) -JS_SetRuntimeDebugMode(JSRuntime *rt, JSBool debug); +JS_SetRuntimeDebugMode(JSRuntime *rt, bool debug); /* * Debug mode is a compartment-wide mode that enables a debugger to attach @@ -73,42 +131,42 @@ JS_SetRuntimeDebugMode(JSRuntime *rt, JSBool debug); */ /* Get current state of debugging mode. */ -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_GetDebugMode(JSContext *cx); /* * Turn on/off debugging mode for all compartments. This returns false if any code * from any of the runtime's compartments is running or on the stack. */ -JS_FRIEND_API(JSBool) -JS_SetDebugModeForAllCompartments(JSContext *cx, JSBool debug); +JS_FRIEND_API(bool) +JS_SetDebugModeForAllCompartments(JSContext *cx, bool debug); /* * Turn on/off debugging mode for a single compartment. This should only be * used when no code from this compartment is running or on the stack in any * thread. */ -JS_FRIEND_API(JSBool) -JS_SetDebugModeForCompartment(JSContext *cx, JSCompartment *comp, JSBool debug); +JS_FRIEND_API(bool) +JS_SetDebugModeForCompartment(JSContext *cx, JSCompartment *comp, bool debug); /* * Turn on/off debugging mode for a context's compartment. */ -JS_FRIEND_API(JSBool) -JS_SetDebugMode(JSContext *cx, JSBool debug); +JS_FRIEND_API(bool) +JS_SetDebugMode(JSContext *cx, bool debug); /* Turn on single step mode. */ -extern JS_PUBLIC_API(JSBool) -JS_SetSingleStepMode(JSContext *cx, JSScript *script, JSBool singleStep); +extern JS_PUBLIC_API(bool) +JS_SetSingleStepMode(JSContext *cx, JSScript *script, bool singleStep); /* The closure argument will be marked. */ -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc, - JSTrapHandler handler, jsval closure); + JSTrapHandler handler, JS::Value closure); extern JS_PUBLIC_API(void) JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc, - JSTrapHandler *handlerp, jsval *closurep); + JSTrapHandler *handlerp, JS::Value *closurep); extern JS_PUBLIC_API(void) JS_ClearScriptTraps(JSRuntime *rt, JSScript *script); @@ -116,28 +174,25 @@ JS_ClearScriptTraps(JSRuntime *rt, JSScript *script); extern JS_PUBLIC_API(void) JS_ClearAllTrapsForCompartment(JSContext *cx); -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_SetInterrupt(JSRuntime *rt, JSInterruptHook handler, void *closure); -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_ClearInterrupt(JSRuntime *rt, JSInterruptHook *handlerp, void **closurep); /************************************************************************/ -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsid id, JSWatchPointHandler handler, JSObject *closure); -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsid id, JSWatchPointHandler *handlerp, JSObject **closurep); -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_ClearWatchPointsForObject(JSContext *cx, JSObject *obj); -extern JS_PUBLIC_API(JSBool) -JS_ClearAllWatchPoints(JSContext *cx); - /************************************************************************/ // Raw JSScript* because this needs to be callable from a signal handler. @@ -150,7 +205,7 @@ JS_LineNumberToPC(JSContext *cx, JSScript *script, unsigned lineno); extern JS_PUBLIC_API(jsbytecode *) JS_EndPC(JSContext *cx, JSScript *script); -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_GetLinePCs(JSContext *cx, JSScript *script, unsigned startLine, unsigned maxLines, unsigned* count, unsigned** lines, jsbytecode*** pcs); @@ -158,7 +213,7 @@ JS_GetLinePCs(JSContext *cx, JSScript *script, extern JS_PUBLIC_API(unsigned) JS_GetFunctionArgumentCount(JSContext *cx, JSFunction *fun); -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_FunctionHasLocalNames(JSContext *cx, JSFunction *fun); /* @@ -230,9 +285,8 @@ JS_GetScriptIsSelfHosted(JSScript *script); /************************************************************************/ /* - * Hook setters for script creation and destruction, see jsprvtd.h for the - * typedefs. These macros provide binary compatibility and newer, shorter - * synonyms. + * Hook setters for script creation and destruction. These macros provide + * binary compatibility and newer, shorter synonyms. */ #define JS_SetNewScriptHook JS_SetNewScriptHookProc #define JS_SetDestroyScriptHook JS_SetDestroyScriptHookProc @@ -247,11 +301,11 @@ JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook, /************************************************************************/ typedef struct JSPropertyDesc { - jsval id; /* primary id, atomized string, or int */ - jsval value; /* property value */ + JS::Value id; /* primary id, atomized string, or int */ + JS::Value value; /* property value */ uint8_t flags; /* flags, see below */ uint8_t spare; /* unused */ - jsval alias; /* alias id if JSPD_ALIAS flag */ + JS::Value alias; /* alias id if JSPD_ALIAS flag */ } JSPropertyDesc; #define JSPD_ENUMERATE 0x01 /* visible to for/in loop */ @@ -260,7 +314,7 @@ typedef struct JSPropertyDesc { #define JSPD_ALIAS 0x08 /* property has an alias id */ #define JSPD_EXCEPTION 0x40 /* exception occurred fetching the property, */ /* value is exception */ -#define JSPD_ERROR 0x80 /* native getter returned JS_FALSE without */ +#define JSPD_ERROR 0x80 /* native getter returned false without */ /* throwing an exception */ typedef struct JSPropertyDescArray { @@ -270,7 +324,7 @@ typedef struct JSPropertyDescArray { typedef struct JSScopeProperty JSScopeProperty; -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda); extern JS_PUBLIC_API(void) @@ -358,8 +412,8 @@ class JS_PUBLIC_API(JSBrokenFrameIterator) * or function call: just before execution begins and just after it finishes. * In both cases the 'current' frame is that of the executing code. * - * The 'before' param is JS_TRUE for the hook invocation before the execution - * and JS_FALSE for the invocation after the code has run. + * The 'before' param is true for the hook invocation before the execution + * and false for the invocation after the code has run. * * The 'ok' param is significant only on the post execution invocation to * signify whether or not the code completed 'normally'. @@ -373,14 +427,14 @@ class JS_PUBLIC_API(JSBrokenFrameIterator) * in 'closure' to cause the 'after' invocation to be called with the same * 'closure' value as the 'before'. * - * Returning NULL in the 'before' hook will cause the 'after' hook *not* to + * Returning nullptr in the 'before' hook will cause the 'after' hook *not* to * be called. */ typedef void * (* JSInterpreterHook)(JSContext *cx, JSAbstractFramePtr frame, bool isConstructing, - JSBool before, JSBool *ok, void *closure); + bool before, bool *ok, void *closure); -typedef JSBool +typedef bool (* JSDebugErrorHook)(JSContext *cx, const char *message, JSErrorReport *report, void *closure); @@ -407,22 +461,22 @@ typedef struct JSDebugHooks { /************************************************************************/ -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_SetDebuggerHandler(JSRuntime *rt, JSDebuggerHandler hook, void *closure); -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure); -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure); -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure); -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_SetThrowHook(JSRuntime *rt, JSThrowHook hook, void *closure); -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure); /************************************************************************/ @@ -433,11 +487,11 @@ JS_GetGlobalDebugHooks(JSRuntime *rt); /** * Add various profiling-related functions as properties of the given object. */ -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_DefineProfilingFunctions(JSContext *cx, JSObject *obj); /* Defined in vm/Debugger.cpp. */ -extern JS_PUBLIC_API(JSBool) +extern JS_PUBLIC_API(bool) JS_DefineDebuggerObject(JSContext *cx, JSObject *obj); extern JS_PUBLIC_API(void) @@ -452,8 +506,13 @@ JS_DumpPCCounts(JSContext *cx, JSScript *script); extern JS_PUBLIC_API(void) JS_DumpCompartmentPCCounts(JSContext *cx); +namespace js { +extern JS_FRIEND_API(bool) +CanCallContextDebugHandler(JSContext *cx); +} + /* Call the context debug handler on the topmost scripted frame. */ -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) js_CallContextDebugHandler(JSContext *cx); -#endif /* jsdbgapi_h */ +#endif /* js_OldDebugAPI_h */ diff --git a/external/spidermonkey/include/android/js/ProfilingStack.h b/external/spidermonkey/include/android/js/ProfilingStack.h new file mode 100644 index 0000000000..c67f98952c --- /dev/null +++ b/external/spidermonkey/include/android/js/ProfilingStack.h @@ -0,0 +1,95 @@ +/* -*- 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 "mozilla/NullPtr.h" + +#include "jsbytecode.h" +#include "jstypes.h" + +#include "js/Utility.h" + +struct JSRuntime; + +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. Both use + // the string as a description, but JS uses the sp as nullptr to indicate + // that it is a JS entry. The script_ is then only ever examined for a JS + // entry, and the idx is used by both, but with different meanings. + // + const char * volatile string; // Descriptive string of this entry + void * volatile sp; // Relevant stack pointer for the entry + JSScript * volatile script_; // if js(), non-null script which is running + int32_t volatile idx; // if js(), idx of pc, otherwise line number + + public: + // 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 js() volatile { + JS_ASSERT_IF(sp == nullptr, script_ != nullptr); + return sp == nullptr; + } + + uint32_t line() volatile { JS_ASSERT(!js()); return idx; } + JSScript *script() volatile { JS_ASSERT(js()); return script_; } + void *stackAddress() volatile { return sp; } + const char *label() volatile { return string; } + + void setLine(uint32_t aLine) volatile { JS_ASSERT(!js()); idx = aLine; } + void setLabel(const char *aString) volatile { string = aString; } + void setStackAddress(void *aSp) volatile { sp = aSp; } + void setScript(JSScript *aScript) volatile { script_ = aScript; } + + // We can't know the layout of JSScript, so look in vm/SPSProfiler.cpp. + JS_FRIEND_API(jsbytecode *) pc() volatile; + JS_FRIEND_API(void) setPC(jsbytecode *pc) volatile; + + static size_t offsetOfString() { return offsetof(ProfileEntry, string); } + static size_t offsetOfStackAddress() { return offsetof(ProfileEntry, sp); } + static size_t offsetOfPCIdx() { return offsetof(ProfileEntry, idx); } + static size_t offsetOfScript() { return offsetof(ProfileEntry, script_); } + + // The index used in the entry can either be a line number or the offset of + // a pc into a script's code. 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 NullPCIndex = -1; +}; + +JS_FRIEND_API(void) +SetRuntimeProfilingStack(JSRuntime *rt, ProfileEntry *stack, uint32_t *size, + uint32_t max); + +JS_FRIEND_API(void) +EnableRuntimeProfilingStack(JSRuntime *rt, bool enabled); + +JS_FRIEND_API(jsbytecode*) +ProfilingGetPC(JSRuntime *rt, JSScript *script, void *ip); + +} // namespace js + +#endif /* js_ProfilingStack_h */ diff --git a/external/spidermonkey/include/android/js/PropertyKey.h b/external/spidermonkey/include/android/js/PropertyKey.h index c949db13a5..1f90653b40 100644 --- a/external/spidermonkey/include/android/js/PropertyKey.h +++ b/external/spidermonkey/include/android/js/PropertyKey.h @@ -9,12 +9,9 @@ #ifndef js_PropertyKey_h #define js_PropertyKey_h -#include "mozilla/Attributes.h" - +#include "js/TypeDecls.h" #include "js/Value.h" -struct JSContext; - namespace JS { class PropertyKey; diff --git a/external/spidermonkey/include/android/js/RequiredDefines.h b/external/spidermonkey/include/android/js/RequiredDefines.h index 6af9ca871b..3c8f429132 100644 --- a/external/spidermonkey/include/android/js/RequiredDefines.h +++ b/external/spidermonkey/include/android/js/RequiredDefines.h @@ -15,9 +15,17 @@ /* * 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. + * + * 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 #endif /* js_RequiredDefines_h */ diff --git a/external/spidermonkey/include/android/js/RootingAPI.h b/external/spidermonkey/include/android/js/RootingAPI.h index c4a5925ae7..82863f020a 100644 --- a/external/spidermonkey/include/android/js/RootingAPI.h +++ b/external/spidermonkey/include/android/js/RootingAPI.h @@ -8,12 +8,14 @@ #define js_RootingAPI_h #include "mozilla/GuardObjects.h" +#include "mozilla/NullPtr.h" #include "mozilla/TypeTraits.h" -#include "js/Utility.h" - #include "jspubtd.h" +#include "js/TypeDecls.h" +#include "js/Utility.h" + /* * Moving GC Stack Rooting * @@ -97,7 +99,6 @@ namespace js { -class Module; class ScriptSourceObject; template @@ -116,13 +117,13 @@ template class HeapBase {}; /* - * js::NullPtr acts like a NULL pointer in contexts that require a Handle. + * js::NullPtr acts like a nullptr pointer in contexts that require a Handle. * * Handle provides an implicit constructor for js::NullPtr so that, given: * foo(Handle h); * callers can simply write: * foo(js::NullPtr()); - * which avoids creating a Rooted just to pass NULL. + * which avoids creating a Rooted just to pass nullptr. * * This is the SpiderMonkey internal variant. js::NullPtr should be used in * preference to JS::NullPtr to avoid the GOT access required for JS_PUBLIC_API @@ -143,9 +144,6 @@ namespace JS { template class Rooted; -template class Handle; -template class MutableHandle; - /* This is exposing internal state of the GC for inlining purposes. */ JS_FRIEND_API(bool) isGCEnabled(); @@ -155,13 +153,13 @@ CheckStackRoots(JSContext *cx); #endif /* - * JS::NullPtr acts like a NULL pointer in contexts that require a Handle. + * JS::NullPtr acts like a nullptr pointer in contexts that require a Handle. * * Handle provides an implicit constructor for JS::NullPtr so that, given: * foo(Handle h); * callers can simply write: * foo(JS::NullPtr()); - * which avoids creating a Rooted just to pass NULL. + * which avoids creating a Rooted just to pass nullptr. */ struct JS_PUBLIC_API(NullPtr) { @@ -377,7 +375,7 @@ class TenuredHeap : public js::HeapBase template class MOZ_NONHEAP_CLASS Handle : public js::HandleBase { - friend class MutableHandle; + friend class JS::MutableHandle; public: /* Creates a handle from a handle of a type convertible to T. */ @@ -390,14 +388,14 @@ class MOZ_NONHEAP_CLASS Handle : public js::HandleBase ptr = reinterpret_cast(handle.address()); } - /* Create a handle for a NULL pointer. */ + /* Create a handle for a nullptr pointer. */ Handle(js::NullPtr) { static_assert(mozilla::IsPointer::value, "js::NullPtr overload not valid for non-pointer types"); ptr = reinterpret_cast(&js::NullPtr::constNullValue); } - /* Create a handle for a NULL pointer. */ + /* Create a handle for a nullptr pointer. */ Handle(JS::NullPtr) { static_assert(mozilla::IsPointer::value, "JS::NullPtr overload not valid for non-pointer types"); @@ -457,24 +455,18 @@ class MOZ_NONHEAP_CLASS Handle : public js::HandleBase bool operator!=(const T &other) const { return *ptr != other; } bool operator==(const T &other) const { return *ptr == other; } + /* Change this handle to point to the same rooted location RHS does. */ + void repoint(const Handle &rhs) { ptr = rhs.address(); } + private: Handle() {} const T *ptr; - template - void operator=(S v) MOZ_DELETE; + template void operator=(S) MOZ_DELETE; + void operator=(Handle) MOZ_DELETE; }; -typedef Handle HandleObject; -typedef Handle HandleModule; -typedef Handle HandleScriptSource; -typedef Handle HandleFunction; -typedef Handle HandleScript; -typedef Handle HandleString; -typedef Handle HandleId; -typedef Handle HandleValue; - /* * Similar to a handle, but the underlying storage can be changed. This is * useful for outparams. @@ -488,6 +480,10 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase { public: inline MutableHandle(Rooted *root); + MutableHandle(int) MOZ_DELETE; +#ifdef MOZ_HAVE_CXX11_NULLPTR + MutableHandle(decltype(nullptr)) MOZ_DELETE; +#endif void set(T v) { JS_ASSERT(!js::GCMethods::poisoned(v)); @@ -526,13 +522,6 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase void operator=(MutableHandle other) MOZ_DELETE; }; -typedef MutableHandle MutableHandleObject; -typedef MutableHandle MutableHandleFunction; -typedef MutableHandle MutableHandleScript; -typedef MutableHandle MutableHandleString; -typedef MutableHandle MutableHandleId; -typedef MutableHandle MutableHandleValue; - #ifdef JSGC_GENERATIONAL JS_PUBLIC_API(void) HeapCellPostBarrier(js::gc::Cell **cellp); JS_PUBLIC_API(void) HeapCellRelocate(js::gc::Cell **cellp); @@ -614,7 +603,7 @@ struct RootKind template struct GCMethods { - static T *initial() { return NULL; } + static T *initial() { return nullptr; } static ThingRootKind kind() { return RootKind::rootKind(); } static bool poisoned(T *v) { return JS::IsPoisonedPtr(v); } static bool needsPostBarrier(T *v) { return v; } @@ -628,12 +617,11 @@ struct GCMethods #endif }; -// XXX: Needed for cocos2d JS Bindings -//#if defined(DEBUG) +#if defined(DEBUG) /* This helper allows us to assert that Rooted is scoped within a request. */ extern JS_PUBLIC_API(bool) IsInRequest(JSContext *cx); -//#endif +#endif } /* namespace js */ @@ -730,12 +718,15 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase init(js::PerThreadDataFriendFields::getMainThread(rt)); } - ~Rooted() { + // Note that we need to let the compiler generate the default destructor in + // non-exact-rooting builds because of a bug in the instrumented PGO builds + // using MSVC, see bug 915735 for more details. #ifdef JSGC_TRACK_EXACT_ROOTS + ~Rooted() { JS_ASSERT(*stack == reinterpret_cast*>(this)); *stack = prev; -#endif } +#endif #ifdef JSGC_TRACK_EXACT_ROOTS Rooted *previous() { return prev; } @@ -803,8 +794,6 @@ class Rooted; #endif typedef Rooted RootedObject; -typedef Rooted RootedModule; -typedef Rooted RootedScriptSource; typedef Rooted RootedFunction; typedef Rooted RootedScript; typedef Rooted RootedString; @@ -857,6 +846,10 @@ class SkipRoot void init(js::ContextFriendFields *cx, const T *ptr, size_t count) {} public: + ~SkipRoot() { + // An empty destructor is needed to avoid warnings from clang about + // unused local variables of this type. + } #endif /* DEBUG && JSGC_ROOT_ANALYSIS */ @@ -1063,7 +1056,7 @@ inline void MaybeCheckStackRoots(JSContext *cx) class CompilerRootNode { protected: - CompilerRootNode(js::gc::Cell *ptr) : next(NULL), ptr_(ptr) {} + CompilerRootNode(js::gc::Cell *ptr) : next(nullptr), ptr_(ptr) {} public: void **address() { return (void **)&ptr_; } diff --git a/external/spidermonkey/include/android/js/StructuredClone.h b/external/spidermonkey/include/android/js/StructuredClone.h new file mode 100644 index 0000000000..d32bdd8dd6 --- /dev/null +++ b/external/spidermonkey/include/android/js/StructuredClone.h @@ -0,0 +1,163 @@ +/* -*- 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/NullPtr.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. + +// 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, and ArrayBuffers. 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::Handle 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); + +// The maximum supported structured-clone serialization format version. 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 2 + +struct JSStructuredCloneCallbacks { + ReadStructuredCloneOp read; + WriteStructuredCloneOp write; + StructuredCloneErrorOp reportError; +}; + +// Note: if the *data contains transferable objects, it can be read only once. +JS_PUBLIC_API(bool) +JS_ReadStructuredClone(JSContext *cx, uint64_t *data, size_t nbytes, uint32_t version, + JS::MutableHandleValue vp, + const JSStructuredCloneCallbacks *optionalCallbacks, void *closure); + +// Note: On success, the caller is responsible for calling +// JS_ClearStructuredClone(*datap, nbytesp). +JS_PUBLIC_API(bool) +JS_WriteStructuredClone(JSContext *cx, JS::HandleValue v, uint64_t **datap, size_t *nbytesp, + const JSStructuredCloneCallbacks *optionalCallbacks, + void *closure, JS::HandleValue transferable); + +JS_PUBLIC_API(bool) +JS_ClearStructuredClone(const uint64_t *data, size_t nbytes); + +JS_PUBLIC_API(bool) +JS_StructuredCloneHasTransferables(const uint64_t *data, size_t nbytes, 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) { + uint64_t *data_; + size_t nbytes_; + uint32_t version_; + + public: + JSAutoStructuredCloneBuffer() + : data_(nullptr), nbytes_(0), version_(JS_STRUCTURED_CLONE_VERSION) {} + + ~JSAutoStructuredCloneBuffer() { clear(); } + + uint64_t *data() const { return data_; } + size_t nbytes() const { return nbytes_; } + + void clear(); + + // Copy some memory. It will be automatically freed by the destructor. + bool copy(const uint64_t *data, size_t nbytes, uint32_t version=JS_STRUCTURED_CLONE_VERSION); + + // 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(uint64_t *data, size_t nbytes, uint32_t version=JS_STRUCTURED_CLONE_VERSION); + + // Remove the buffer so that it will not be automatically freed. + // After this, the caller is responsible for feeding the memory back to + // JSAutoStructuredCloneBuffer::adopt. + void steal(uint64_t **datap, size_t *nbytesp, uint32_t *versionp=nullptr); + + 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, + const JSStructuredCloneCallbacks *optionalCallbacks=nullptr, void *closure=nullptr); + + // Swap ownership with another JSAutoStructuredCloneBuffer. + void swap(JSAutoStructuredCloneBuffer &other); + + private: + // Copy and assignment are not supported. + JSAutoStructuredCloneBuffer(const JSAutoStructuredCloneBuffer &other); + JSAutoStructuredCloneBuffer &operator=(const JSAutoStructuredCloneBuffer &other); +}; + +// 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 + +JS_PUBLIC_API(void) +JS_SetStructuredCloneCallbacks(JSRuntime *rt, const JSStructuredCloneCallbacks *callbacks); + +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::Value *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_WriteTypedArray(JSStructuredCloneWriter *w, JS::Value v); + +#endif /* js_StructuredClone_h */ diff --git a/external/spidermonkey/include/android/js/Tracer.h b/external/spidermonkey/include/android/js/Tracer.h new file mode 100644 index 0000000000..89994612f6 --- /dev/null +++ b/external/spidermonkey/include/android/js/Tracer.h @@ -0,0 +1,193 @@ +/* -*- 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_Tracer_h +#define js_Tracer_h + +#include "mozilla/NullPtr.h" + +#include "jspubtd.h" + +struct JSTracer; + +namespace JS { +template class Heap; +template class TenuredHeap; +} + +// Tracer callback, called for each traceable thing directly referenced by a +// particular object or runtime structure. It is the callback responsibility +// to ensure the traversal of the full object graph via calling eventually +// JS_TraceChildren on the passed thing. In this case the callback must be +// prepared to deal with cycles in the traversal graph. +// +// kind argument is one of JSTRACE_OBJECT, JSTRACE_STRING or a tag denoting +// internal implementation-specific traversal kind. In the latter case the only +// operations on thing that the callback can do is to call JS_TraceChildren or +// JS_GetTraceThingInfo. +// +// If eagerlyTraceWeakMaps is true, when we trace a WeakMap visit all +// of its mappings. This should be used in cases where the tracer +// wants to use the existing liveness of entries. +typedef void +(* JSTraceCallback)(JSTracer *trc, void **thingp, JSGCTraceKind kind); + +// Callback that JSTraceOp implementation can provide to return a string +// describing the reference traced with JS_CallTracer. +typedef void +(* JSTraceNamePrinter)(JSTracer *trc, char *buf, size_t bufsize); + +enum WeakMapTraceKind { + DoNotTraceWeakMaps = 0, + TraceWeakMapValues = 1, + TraceWeakMapKeysValues = 2 +}; + +struct JSTracer { + JSRuntime *runtime; + JSTraceCallback callback; + JSTraceNamePrinter debugPrinter; + const void *debugPrintArg; + size_t debugPrintIndex; + WeakMapTraceKind eagerlyTraceWeakMaps; +#ifdef JS_GC_ZEAL + void *realLocation; +#endif +}; + +// Set debugging information about a reference to a traceable thing to prepare +// for the following call to JS_CallTracer. +// +// When printer is null, arg must be const char * or char * C string naming +// the reference and index must be either (size_t)-1 indicating that the name +// alone describes the reference or it must be an index into some array vector +// that stores the reference. +// +// When printer callback is not null, the arg and index arguments are +// available to the callback as debugPrintArg and debugPrintIndex fields +// of JSTracer. +// +// The storage for name or callback's arguments needs to live only until +// the following call to JS_CallTracer returns. +// +# define JS_SET_TRACING_DETAILS(trc, printer, arg, index) \ + JS_BEGIN_MACRO \ + (trc)->debugPrinter = (printer); \ + (trc)->debugPrintArg = (arg); \ + (trc)->debugPrintIndex = (index); \ + JS_END_MACRO + +// Sets the real location for a marked reference, when passing the address +// directly is not feasable. +// +// FIXME: This is currently overcomplicated by our need to nest calls for Values +// stored as keys in hash tables, but will get simplified once we can rekey +// in-place. +// +#ifdef JS_GC_ZEAL +# define JS_SET_TRACING_LOCATION(trc, location) \ + JS_BEGIN_MACRO \ + if (!(trc)->realLocation || !(location)) \ + (trc)->realLocation = (location); \ + JS_END_MACRO +# define JS_UNSET_TRACING_LOCATION(trc) \ + JS_BEGIN_MACRO \ + (trc)->realLocation = nullptr; \ + JS_END_MACRO +#else +# define JS_SET_TRACING_LOCATION(trc, location) \ + JS_BEGIN_MACRO \ + JS_END_MACRO +# define JS_UNSET_TRACING_LOCATION(trc) \ + JS_BEGIN_MACRO \ + JS_END_MACRO +#endif + +// Convenience macro to describe the argument of JS_CallTracer using C string +// and index. +# define JS_SET_TRACING_INDEX(trc, name, index) \ + JS_SET_TRACING_DETAILS(trc, nullptr, name, index) + +// Convenience macro to describe the argument of JS_CallTracer using C string. +# define JS_SET_TRACING_NAME(trc, name) \ + JS_SET_TRACING_DETAILS(trc, nullptr, name, (size_t)-1) + +// The JS_Call*Tracer 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_Call*Tracer 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_Call*Tracer will be updated to the object'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. +// +extern JS_PUBLIC_API(void) +JS_CallValueTracer(JSTracer *trc, JS::Value *valuep, const char *name); + +extern JS_PUBLIC_API(void) +JS_CallIdTracer(JSTracer *trc, jsid *idp, const char *name); + +extern JS_PUBLIC_API(void) +JS_CallObjectTracer(JSTracer *trc, JSObject **objp, const char *name); + +extern JS_PUBLIC_API(void) +JS_CallStringTracer(JSTracer *trc, JSString **strp, const char *name); + +extern JS_PUBLIC_API(void) +JS_CallScriptTracer(JSTracer *trc, JSScript **scriptp, const char *name); + +extern JS_PUBLIC_API(void) +JS_CallHeapValueTracer(JSTracer *trc, JS::Heap *valuep, const char *name); + +extern JS_PUBLIC_API(void) +JS_CallHeapIdTracer(JSTracer *trc, JS::Heap *idp, const char *name); + +extern JS_PUBLIC_API(void) +JS_CallHeapObjectTracer(JSTracer *trc, JS::Heap *objp, const char *name); + +extern JS_PUBLIC_API(void) +JS_CallHeapStringTracer(JSTracer *trc, JS::Heap *strp, const char *name); + +extern JS_PUBLIC_API(void) +JS_CallHeapScriptTracer(JSTracer *trc, JS::Heap *scriptp, const char *name); + +template +inline void +JS_CallHashSetObjectTracer(JSTracer *trc, HashSetEnum &e, JSObject *const &key, const char *name) +{ + JSObject *updated = key; + JS_SET_TRACING_LOCATION(trc, reinterpret_cast(&const_cast(key))); + JS_CallObjectTracer(trc, &updated, name); + if (updated != key) + e.rekeyFront(key, updated); +} + +// Trace an object that is known to always be tenured. No post barriers are +// required in this case. +extern JS_PUBLIC_API(void) +JS_CallTenuredObjectTracer(JSTracer *trc, JS::TenuredHeap *objp, const char *name); + +// API for JSTraceCallback implementations. +extern JS_PUBLIC_API(void) +JS_TracerInit(JSTracer *trc, JSRuntime *rt, JSTraceCallback callback); + +extern JS_PUBLIC_API(void) +JS_TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind); + +extern JS_PUBLIC_API(void) +JS_TraceRuntime(JSTracer *trc); + +extern JS_PUBLIC_API(void) +JS_GetTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc, + void *thing, JSGCTraceKind kind, bool includeDetails); + +extern JS_PUBLIC_API(const char *) +JS_GetTraceEdgeName(JSTracer *trc, char *buffer, int bufferSize); + +#endif /* js_Tracer_h */ diff --git a/external/spidermonkey/include/android/js/TypeDecls.h b/external/spidermonkey/include/android/js/TypeDecls.h new file mode 100644 index 0000000000..ec944d374c --- /dev/null +++ b/external/spidermonkey/include/android/js/TypeDecls.h @@ -0,0 +1,81 @@ +/* -*- 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 + +struct JSContext; +class JSFunction; +class JSObject; +class JSScript; +class JSString; + +// In release builds, jsid is defined to be an integral type. This +// prevents many bugs from being caught at compile time. E.g.: +// +// jsid id = ... +// if (id) // error +// ... +// +// size_t n = id; // error +// +// To catch more errors, jsid is given a struct type in C++ debug builds. +// Struct assignment and (in C++) operator== allow correct code to be mostly +// oblivious to the change. This feature can be explicitly disabled in debug +// builds by defining JS_NO_JSVAL_JSID_STRUCT_TYPES. +// + +// Needed for cocos2d-js +#define JS_NO_JSVAL_JSID_STRUCT_TYPES + +#if defined(DEBUG) && !defined(JS_NO_JSVAL_JSID_STRUCT_TYPES) +# define JS_USE_JSID_STRUCT_TYPES +#endif + +#ifdef JS_USE_JSID_STRUCT_TYPES +struct jsid; +#else +typedef ptrdiff_t jsid; +#endif + +typedef char16_t jschar; + +namespace JS { + +class Value; +template class Handle; +template class MutableHandle; + +typedef Handle HandleFunction; +typedef Handle HandleId; +typedef Handle HandleObject; +typedef Handle HandleScript; +typedef Handle HandleString; +typedef Handle HandleValue; + +typedef MutableHandle MutableHandleFunction; +typedef MutableHandle MutableHandleId; +typedef MutableHandle MutableHandleObject; +typedef MutableHandle MutableHandleScript; +typedef MutableHandle MutableHandleString; +typedef MutableHandle MutableHandleValue; + +} // namespace JS + +#endif /* js_TypeDecls_h */ diff --git a/external/spidermonkey/include/android/js/Utility.h b/external/spidermonkey/include/android/js/Utility.h index 9d391e5c8a..cdaf19ba5f 100644 --- a/external/spidermonkey/include/android/js/Utility.h +++ b/external/spidermonkey/include/android/js/Utility.h @@ -11,6 +11,7 @@ #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" #include "mozilla/Move.h" +#include "mozilla/NullPtr.h" #include "mozilla/Scoped.h" #include "mozilla/TemplateLib.h" @@ -18,8 +19,8 @@ #include #ifdef JS_OOM_DO_BACKTRACES -#include #include +#include #endif #include "jstypes.h" @@ -44,16 +45,6 @@ namespace js {} #define JS_ALWAYS_TRUE(expr) MOZ_ALWAYS_TRUE(expr) #define JS_ALWAYS_FALSE(expr) MOZ_ALWAYS_FALSE(expr) -#ifdef DEBUG -# ifdef JS_THREADSAFE -# define JS_THREADSAFE_ASSERT(expr) JS_ASSERT(expr) -# else -# define JS_THREADSAFE_ASSERT(expr) ((void) 0) -# endif -#else -# define JS_THREADSAFE_ASSERT(expr) ((void) 0) -#endif - #if defined(DEBUG) # define JS_DIAGNOSTICS_ASSERT(expr) MOZ_ASSERT(expr) #elif defined(JS_CRASH_DIAGNOSTICS) @@ -96,7 +87,7 @@ static JS_ALWAYS_INLINE void PrintBacktrace() { void* OOM_trace[JS_OOM_BACKTRACE_SIZE]; - char** OOM_traceSymbols = NULL; + char** OOM_traceSymbols = nullptr; int32_t OOM_traceSize = 0; int32_t OOM_traceIdx = 0; OOM_traceSize = backtrace(OOM_trace, JS_OOM_BACKTRACE_SIZE); @@ -126,7 +117,7 @@ PrintBacktrace() { \ if (++OOM_counter > OOM_maxAllocations) { \ JS_OOM_EMIT_BACKTRACE();\ - return NULL; \ + return nullptr; \ } \ } while (0) @@ -136,7 +127,7 @@ PrintBacktrace() if (++OOM_counter > OOM_maxAllocations) { \ JS_OOM_EMIT_BACKTRACE();\ js_ReportOutOfMemory(cx);\ - return NULL; \ + return nullptr; \ } \ } while (0) @@ -145,31 +136,31 @@ PrintBacktrace() # define JS_OOM_POSSIBLY_FAIL_REPORT(cx) do {} while(0) # endif /* DEBUG */ -static JS_INLINE void* js_malloc(size_t bytes) +static inline void* js_malloc(size_t bytes) { JS_OOM_POSSIBLY_FAIL(); return malloc(bytes); } -static JS_INLINE void* js_calloc(size_t bytes) +static inline void* js_calloc(size_t bytes) { JS_OOM_POSSIBLY_FAIL(); return calloc(bytes, 1); } -static JS_INLINE void* js_calloc(size_t nmemb, size_t size) +static inline void* js_calloc(size_t nmemb, size_t size) { JS_OOM_POSSIBLY_FAIL(); return calloc(nmemb, size); } -static JS_INLINE void* js_realloc(void* p, size_t bytes) +static inline void* js_realloc(void* p, size_t bytes) { JS_OOM_POSSIBLY_FAIL(); return realloc(p, bytes); } -static JS_INLINE void js_free(void* p) +static inline void js_free(void* p) { free(p); } @@ -241,7 +232,7 @@ static JS_INLINE void js_free(void* p) #define JS_NEW_BODY(allocator, t, parms) \ void *memory = allocator(sizeof(t)); \ - return memory ? new(memory) t parms : NULL; + return memory ? new(memory) t parms : nullptr; /* * Given a class which should provide 'new' methods, add @@ -360,7 +351,7 @@ static JS_ALWAYS_INLINE T * js_pod_malloc(size_t numElems) { if (numElems & mozilla::tl::MulOverflowMask::value) - return NULL; + return nullptr; return (T *)js_malloc(numElems * sizeof(T)); } @@ -369,7 +360,7 @@ static JS_ALWAYS_INLINE T * js_pod_calloc(size_t numElems) { if (numElems & mozilla::tl::MulOverflowMask::value) - return NULL; + return nullptr; return (T *)js_calloc(numElems * sizeof(T)); } @@ -379,7 +370,7 @@ template struct ScopedFreePtrTraits { typedef T* type; - static T* empty() { return NULL; } + static T* empty() { return nullptr; } static void release(T* ptr) { js_free(ptr); } }; SCOPED_TEMPLATE(ScopedJSFreePtr, ScopedFreePtrTraits) diff --git a/external/spidermonkey/include/android/js/Value.h b/external/spidermonkey/include/android/js/Value.h index 9b2c5dd6f9..7a772bcfba 100644 --- a/external/spidermonkey/include/android/js/Value.h +++ b/external/spidermonkey/include/android/js/Value.h @@ -15,6 +15,8 @@ #include /* for std::numeric_limits */ +#include "jstypes.h" + #include "js/Anchor.h" #include "js/RootingAPI.h" #include "js/Utility.h" @@ -248,7 +250,7 @@ typedef union jsval_layout union { int32_t i32; uint32_t u32; - JSBool boo; + uint32_t boo; // Don't use |bool| -- it must be four bytes. JSString *str; JSObject *obj; void *ptr; @@ -295,7 +297,7 @@ typedef union jsval_layout union { int32_t i32; uint32_t u32; - JSBool boo; + uint32_t boo; // Don't use |bool| -- it must be four bytes. JSString *str; JSObject *obj; void *ptr; @@ -333,6 +335,49 @@ typedef union jsval_layout JS_STATIC_ASSERT(sizeof(jsval_layout) == 8); +/* + * For codesize purposes on some platforms, it's important that the + * compiler know that JS::Values constructed from constant values can be + * folded to constant bit patterns at compile time, rather than + * constructed at runtime. Doing this requires a fair amount of C++11 + * features, which are not supported on all of our compilers. Set up + * some defines and helper macros in an attempt to confine the ugliness + * here, rather than scattering it all about the file. The important + * features are: + * + * - constexpr; + * - defaulted functions; + * - C99-style designated initializers. + */ +#if defined(__clang__) +# if __has_feature(cxx_constexpr) && __has_feature(cxx_defaulted_functions) +# define JS_VALUE_IS_CONSTEXPR +# endif +#elif defined(__GNUC__) +/* + * We need 4.5 for defaulted functions, 4.6 for constexpr, 4.7 because 4.6 + * doesn't understand |(X) { .field = ... }| syntax, and 4.7.3 because + * versions prior to that have bugs in the C++ front-end that cause crashes. + */ +# if MOZ_GCC_VERSION_AT_LEAST(4, 7, 3) +# define JS_VALUE_IS_CONSTEXPR +# endif +#endif + +#if defined(JS_VALUE_IS_CONSTEXPR) +# define JS_RETURN_LAYOUT_FROM_BITS(BITS) \ + return (jsval_layout) { .asBits = (BITS) } +# define JS_VALUE_CONSTEXPR MOZ_CONSTEXPR +# define JS_VALUE_CONSTEXPR_VAR MOZ_CONSTEXPR_VAR +#else +# define JS_RETURN_LAYOUT_FROM_BITS(BITS) \ + jsval_layout l; \ + l.asBits = (BITS); \ + return l; +# define JS_VALUE_CONSTEXPR +# define JS_VALUE_CONSTEXPR_VAR const +#endif + #if JS_BITS_PER_WORD == 32 /* @@ -341,15 +386,13 @@ JS_STATIC_ASSERT(sizeof(jsval_layout) == 8); * Thus, all comparisons should explicitly cast operands to uint32_t. */ -static inline jsval_layout +static inline JS_VALUE_CONSTEXPR jsval_layout BUILD_JSVAL(JSValueTag tag, uint32_t payload) { - jsval_layout l; - l.asBits = (((uint64_t)(uint32_t)tag) << 32) | payload; - return l; + JS_RETURN_LAYOUT_FROM_BITS((((uint64_t)(uint32_t)tag) << 32) | payload); } -static inline JSBool +static inline bool JSVAL_IS_DOUBLE_IMPL(jsval_layout l) { return (uint32_t)l.s.tag <= (uint32_t)JSVAL_TAG_CLEAR; @@ -364,7 +407,7 @@ DOUBLE_TO_JSVAL_IMPL(double d) return l; } -static inline JSBool +static inline bool JSVAL_IS_INT32_IMPL(jsval_layout l) { return l.s.tag == JSVAL_TAG_INT32; @@ -376,16 +419,20 @@ JSVAL_TO_INT32_IMPL(jsval_layout l) return l.s.payload.i32; } -static inline jsval_layout +static inline JS_VALUE_CONSTEXPR jsval_layout INT32_TO_JSVAL_IMPL(int32_t i) { +#if defined(JS_VALUE_IS_CONSTEXPR) + return BUILD_JSVAL(JSVAL_TAG_INT32, i); +#else jsval_layout l; l.s.tag = JSVAL_TAG_INT32; l.s.payload.i32 = i; return l; +#endif } -static inline JSBool +static inline bool JSVAL_IS_NUMBER_IMPL(jsval_layout l) { JSValueTag tag = l.s.tag; @@ -393,13 +440,13 @@ JSVAL_IS_NUMBER_IMPL(jsval_layout l) return (uint32_t)tag <= (uint32_t)JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET; } -static inline JSBool +static inline bool JSVAL_IS_UNDEFINED_IMPL(jsval_layout l) { return l.s.tag == JSVAL_TAG_UNDEFINED; } -static inline JSBool +static inline bool JSVAL_IS_STRING_IMPL(jsval_layout l) { return l.s.tag == JSVAL_TAG_STRING; @@ -421,47 +468,46 @@ JSVAL_TO_STRING_IMPL(jsval_layout l) return l.s.payload.str; } -static inline JSBool +static inline bool JSVAL_IS_BOOLEAN_IMPL(jsval_layout l) { return l.s.tag == JSVAL_TAG_BOOLEAN; } -static inline JSBool +static inline bool JSVAL_TO_BOOLEAN_IMPL(jsval_layout l) { return l.s.payload.boo; } static inline jsval_layout -BOOLEAN_TO_JSVAL_IMPL(JSBool b) +BOOLEAN_TO_JSVAL_IMPL(bool b) { jsval_layout l; - MOZ_ASSERT(b == JS_TRUE || b == JS_FALSE); l.s.tag = JSVAL_TAG_BOOLEAN; l.s.payload.boo = b; return l; } -static inline JSBool +static inline bool JSVAL_IS_MAGIC_IMPL(jsval_layout l) { return l.s.tag == JSVAL_TAG_MAGIC; } -static inline JSBool +static inline bool JSVAL_IS_OBJECT_IMPL(jsval_layout l) { return l.s.tag == JSVAL_TAG_OBJECT; } -static inline JSBool +static inline bool JSVAL_IS_PRIMITIVE_IMPL(jsval_layout l) { return (uint32_t)l.s.tag < (uint32_t)JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET; } -static inline JSBool +static inline bool JSVAL_IS_OBJECT_OR_NULL_IMPL(jsval_layout l) { MOZ_ASSERT((uint32_t)l.s.tag <= (uint32_t)JSVAL_TAG_OBJECT); @@ -484,7 +530,7 @@ OBJECT_TO_JSVAL_IMPL(JSObject *obj) return l; } -static inline JSBool +static inline bool JSVAL_IS_NULL_IMPL(jsval_layout l) { return l.s.tag == JSVAL_TAG_NULL; @@ -507,7 +553,7 @@ JSVAL_TO_PRIVATE_PTR_IMPL(jsval_layout l) return l.s.payload.ptr; } -static inline JSBool +static inline bool JSVAL_IS_GCTHING_IMPL(jsval_layout l) { /* gcc sometimes generates signed < without explicit casts. */ @@ -520,7 +566,7 @@ JSVAL_TO_GCTHING_IMPL(jsval_layout l) return l.s.payload.ptr; } -static inline JSBool +static inline bool JSVAL_IS_TRACEABLE_IMPL(jsval_layout l) { return l.s.tag == JSVAL_TAG_STRING || l.s.tag == JSVAL_TAG_OBJECT; @@ -529,19 +575,19 @@ JSVAL_IS_TRACEABLE_IMPL(jsval_layout l) static inline uint32_t JSVAL_TRACE_KIND_IMPL(jsval_layout l) { - return (uint32_t)(JSBool)JSVAL_IS_STRING_IMPL(l); + return (uint32_t)(bool)JSVAL_IS_STRING_IMPL(l); } -static inline JSBool +static inline bool JSVAL_IS_SPECIFIC_INT32_IMPL(jsval_layout l, int32_t i32) { return l.s.tag == JSVAL_TAG_INT32 && l.s.payload.i32 == i32; } -static inline JSBool -JSVAL_IS_SPECIFIC_BOOLEAN(jsval_layout l, JSBool b) +static inline bool +JSVAL_IS_SPECIFIC_BOOLEAN(jsval_layout l, bool b) { - return (l.s.tag == JSVAL_TAG_BOOLEAN) && (l.s.payload.boo == b); + return (l.s.tag == JSVAL_TAG_BOOLEAN) && (l.s.payload.boo == uint32_t(b)); } static inline jsval_layout @@ -553,7 +599,7 @@ MAGIC_TO_JSVAL_IMPL(JSWhyMagic why) return l; } -static inline JSBool +static inline bool JSVAL_SAME_TYPE_IMPL(jsval_layout lhs, jsval_layout rhs) { JSValueTag ltag = lhs.s.tag, rtag = rhs.s.tag; @@ -570,15 +616,13 @@ JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l) #elif JS_BITS_PER_WORD == 64 -static inline jsval_layout +static inline JS_VALUE_CONSTEXPR jsval_layout BUILD_JSVAL(JSValueTag tag, uint64_t payload) { - jsval_layout l; - l.asBits = (((uint64_t)(uint32_t)tag) << JSVAL_TAG_SHIFT) | payload; - return l; + JS_RETURN_LAYOUT_FROM_BITS((((uint64_t)(uint32_t)tag) << JSVAL_TAG_SHIFT) | payload); } -static inline JSBool +static inline bool JSVAL_IS_DOUBLE_IMPL(jsval_layout l) { return l.asBits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE; @@ -593,7 +637,7 @@ DOUBLE_TO_JSVAL_IMPL(double d) return l; } -static inline JSBool +static inline bool JSVAL_IS_INT32_IMPL(jsval_layout l) { return (uint32_t)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_INT32; @@ -605,27 +649,25 @@ JSVAL_TO_INT32_IMPL(jsval_layout l) return (int32_t)l.asBits; } -static inline jsval_layout +static inline JS_VALUE_CONSTEXPR jsval_layout INT32_TO_JSVAL_IMPL(int32_t i32) { - jsval_layout l; - l.asBits = ((uint64_t)(uint32_t)i32) | JSVAL_SHIFTED_TAG_INT32; - return l; + JS_RETURN_LAYOUT_FROM_BITS(((uint64_t)(uint32_t)i32) | JSVAL_SHIFTED_TAG_INT32); } -static inline JSBool +static inline bool JSVAL_IS_NUMBER_IMPL(jsval_layout l) { return l.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET; } -static inline JSBool +static inline bool JSVAL_IS_UNDEFINED_IMPL(jsval_layout l) { return l.asBits == JSVAL_SHIFTED_TAG_UNDEFINED; } -static inline JSBool +static inline bool JSVAL_IS_STRING_IMPL(jsval_layout l) { return (uint32_t)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_STRING; @@ -648,47 +690,46 @@ JSVAL_TO_STRING_IMPL(jsval_layout l) return (JSString *)(l.asBits & JSVAL_PAYLOAD_MASK); } -static inline JSBool +static inline bool JSVAL_IS_BOOLEAN_IMPL(jsval_layout l) { return (uint32_t)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_BOOLEAN; } -static inline JSBool +static inline bool JSVAL_TO_BOOLEAN_IMPL(jsval_layout l) { - return (JSBool)l.asBits; + return (bool)(l.asBits & JSVAL_PAYLOAD_MASK); } static inline jsval_layout -BOOLEAN_TO_JSVAL_IMPL(JSBool b) +BOOLEAN_TO_JSVAL_IMPL(bool b) { jsval_layout l; - MOZ_ASSERT(b == JS_TRUE || b == JS_FALSE); l.asBits = ((uint64_t)(uint32_t)b) | JSVAL_SHIFTED_TAG_BOOLEAN; return l; } -static inline JSBool +static inline bool JSVAL_IS_MAGIC_IMPL(jsval_layout l) { return (l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_MAGIC; } -static inline JSBool +static inline bool JSVAL_IS_PRIMITIVE_IMPL(jsval_layout l) { return l.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET; } -static inline JSBool +static inline bool JSVAL_IS_OBJECT_IMPL(jsval_layout l) { MOZ_ASSERT((l.asBits >> JSVAL_TAG_SHIFT) <= JSVAL_SHIFTED_TAG_OBJECT); return l.asBits >= JSVAL_SHIFTED_TAG_OBJECT; } -static inline JSBool +static inline bool JSVAL_IS_OBJECT_OR_NULL_IMPL(jsval_layout l) { MOZ_ASSERT((l.asBits >> JSVAL_TAG_SHIFT) <= JSVAL_TAG_OBJECT); @@ -714,13 +755,13 @@ OBJECT_TO_JSVAL_IMPL(JSObject *obj) return l; } -static inline JSBool +static inline bool JSVAL_IS_NULL_IMPL(jsval_layout l) { return l.asBits == JSVAL_SHIFTED_TAG_NULL; } -static inline JSBool +static inline bool JSVAL_IS_GCTHING_IMPL(jsval_layout l) { return l.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET; @@ -734,7 +775,7 @@ JSVAL_TO_GCTHING_IMPL(jsval_layout l) return (void *)ptrBits; } -static inline JSBool +static inline bool JSVAL_IS_TRACEABLE_IMPL(jsval_layout l) { return JSVAL_IS_GCTHING_IMPL(l) && !JSVAL_IS_NULL_IMPL(l); @@ -743,7 +784,7 @@ JSVAL_IS_TRACEABLE_IMPL(jsval_layout l) static inline uint32_t JSVAL_TRACE_KIND_IMPL(jsval_layout l) { - return (uint32_t)(JSBool)!(JSVAL_IS_OBJECT_IMPL(l)); + return (uint32_t)(bool)!(JSVAL_IS_OBJECT_IMPL(l)); } static inline jsval_layout @@ -764,14 +805,14 @@ JSVAL_TO_PRIVATE_PTR_IMPL(jsval_layout l) return (void *)(l.asBits << 1); } -static inline JSBool +static inline bool JSVAL_IS_SPECIFIC_INT32_IMPL(jsval_layout l, int32_t i32) { return l.asBits == (((uint64_t)(uint32_t)i32) | JSVAL_SHIFTED_TAG_INT32); } -static inline JSBool -JSVAL_IS_SPECIFIC_BOOLEAN(jsval_layout l, JSBool b) +static inline bool +JSVAL_IS_SPECIFIC_BOOLEAN(jsval_layout l, bool b) { return l.asBits == (((uint64_t)(uint32_t)b) | JSVAL_SHIFTED_TAG_BOOLEAN); } @@ -784,7 +825,7 @@ MAGIC_TO_JSVAL_IMPL(JSWhyMagic why) return l; } -static inline JSBool +static inline bool JSVAL_SAME_TYPE_IMPL(jsval_layout lhs, jsval_layout rhs) { uint64_t lbits = lhs.asBits, rbits = rhs.asBits; @@ -803,10 +844,12 @@ JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l) #endif /* JS_BITS_PER_WORD */ static inline jsval_layout JSVAL_TO_IMPL(JS::Value v); -static inline JS::Value IMPL_TO_JSVAL(jsval_layout l); +static inline JS_VALUE_CONSTEXPR JS::Value IMPL_TO_JSVAL(jsval_layout l); namespace JS { +static inline JS_VALUE_CONSTEXPR JS::Value UndefinedValue(); + /** * Returns a generic quiet NaN value, with all payload bits set to zero. * @@ -816,7 +859,7 @@ namespace JS { static MOZ_ALWAYS_INLINE double GenericNaN() { - return mozilla::SpecificNaN(0, 0x8000000000000ULL); + return mozilla::SpecificNaN(0, 0x8000000000000ULL); } static inline double @@ -869,6 +912,10 @@ class Value * N.B. the default constructor leaves Value unitialized. Adding a default * constructor prevents Value from being stored in a union. */ +#if defined(JS_VALUE_IS_CONSTEXPR) + Value() = default; + Value(const Value& v) = default; +#endif /*** Mutators ***/ @@ -893,6 +940,10 @@ class Value data = DOUBLE_TO_JSVAL_IMPL(d); } + void setNaN() { + setDouble(GenericNaN()); + } + double &getDoubleRef() { MOZ_ASSERT(isDouble()); return data.asDouble; @@ -1173,16 +1224,20 @@ class Value jsval_layout data; private: +#if defined(JS_VALUE_IS_CONSTEXPR) + JS_VALUE_CONSTEXPR Value(jsval_layout layout) : data(layout) {} +#endif + void staticAssertions() { JS_STATIC_ASSERT(sizeof(JSValueType) == 1); JS_STATIC_ASSERT(sizeof(JSValueTag) == 4); - JS_STATIC_ASSERT(sizeof(JSBool) == 4); JS_STATIC_ASSERT(sizeof(JSWhyMagic) <= 4); JS_STATIC_ASSERT(sizeof(Value) == 8); } friend jsval_layout (::JSVAL_TO_IMPL)(Value); - friend Value (::IMPL_TO_JSVAL)(jsval_layout l); + friend Value JS_VALUE_CONSTEXPR (::IMPL_TO_JSVAL)(jsval_layout l); + friend Value JS_VALUE_CONSTEXPR (JS::UndefinedValue)(); }; inline bool @@ -1205,12 +1260,16 @@ NullValue() return v; } -static inline Value +static inline JS_VALUE_CONSTEXPR Value UndefinedValue() { - Value v; +#if defined(JS_VALUE_IS_CONSTEXPR) + return Value(BUILD_JSVAL(JSVAL_TAG_UNDEFINED, 0)); +#else + JS::Value v; v.setUndefined(); return v; +#endif } static inline Value @@ -1229,6 +1288,22 @@ DoubleValue(double dbl) return v; } +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) { @@ -1499,6 +1574,7 @@ class UnbarrieredMutableValueOperations : public ValueOperations 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); } @@ -1620,12 +1696,16 @@ JSVAL_TO_IMPL(JS::Value v) return v.data; } -inline JS::Value +inline JS_VALUE_CONSTEXPR JS::Value IMPL_TO_JSVAL(jsval_layout l) { +#if defined(JS_VALUE_IS_CONSTEXPR) + return JS::Value(l); +#else JS::Value v; v.data = l; return v; +#endif } namespace JS { @@ -1678,19 +1758,19 @@ static_assert(sizeof(jsval_layout) == sizeof(JS::Value), /************************************************************************/ -static inline JSBool +static inline bool JSVAL_IS_NULL(jsval v) { return JSVAL_IS_NULL_IMPL(JSVAL_TO_IMPL(v)); } -static inline JSBool +static inline bool JSVAL_IS_VOID(jsval v) { return JSVAL_IS_UNDEFINED_IMPL(JSVAL_TO_IMPL(v)); } -static inline JSBool +static inline bool JSVAL_IS_INT(jsval v) { return JSVAL_IS_INT32_IMPL(JSVAL_TO_IMPL(v)); @@ -1703,13 +1783,13 @@ JSVAL_TO_INT(jsval v) return JSVAL_TO_INT32_IMPL(JSVAL_TO_IMPL(v)); } -static inline jsval +static inline JS_VALUE_CONSTEXPR jsval INT_TO_JSVAL(int32_t i) { return IMPL_TO_JSVAL(INT32_TO_JSVAL_IMPL(i)); } -static inline JSBool +static inline bool JSVAL_IS_DOUBLE(jsval v) { return JSVAL_IS_DOUBLE_IMPL(JSVAL_TO_IMPL(v)); @@ -1724,7 +1804,7 @@ JSVAL_TO_DOUBLE(jsval v) return l.asDouble; } -static inline jsval +static inline JS_VALUE_CONSTEXPR jsval DOUBLE_TO_JSVAL(double d) { /* @@ -1733,29 +1813,35 @@ DOUBLE_TO_JSVAL(double d) * return IMPL_TO_JSVAL(DOUBLE_TO_JSVAL_IMPL(d)); * because GCC from XCode 3.1.4 miscompiles the above code. */ +#if defined(JS_VALUE_IS_CONSTEXPR) + return IMPL_TO_JSVAL(MOZ_UNLIKELY(d != d) + ? (jsval_layout) { .asBits = 0x7FF8000000000000LL } + : (jsval_layout) { .asDouble = d }); +#else jsval_layout l; if (MOZ_UNLIKELY(d != d)) l.asBits = 0x7FF8000000000000LL; else l.asDouble = d; return IMPL_TO_JSVAL(l); +#endif } -static inline jsval +static inline JS_VALUE_CONSTEXPR jsval UINT_TO_JSVAL(uint32_t i) { - if (i <= JSVAL_INT_MAX) - return INT_TO_JSVAL((int32_t)i); - return DOUBLE_TO_JSVAL((double)i); + return (i <= JSVAL_INT_MAX + ? INT_TO_JSVAL((int32_t)i) + : DOUBLE_TO_JSVAL((double)i)); } -static inline JSBool +static inline bool JSVAL_IS_NUMBER(jsval v) { return JSVAL_IS_NUMBER_IMPL(JSVAL_TO_IMPL(v)); } -static inline JSBool +static inline bool JSVAL_IS_STRING(jsval v) { return JSVAL_IS_STRING_IMPL(JSVAL_TO_IMPL(v)); @@ -1789,13 +1875,13 @@ OBJECT_TO_JSVAL(JSObject *obj) return IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_NULL, 0)); } -static inline JSBool +static inline bool JSVAL_IS_BOOLEAN(jsval v) { return JSVAL_IS_BOOLEAN_IMPL(JSVAL_TO_IMPL(v)); } -static inline JSBool +static inline bool JSVAL_TO_BOOLEAN(jsval v) { MOZ_ASSERT(JSVAL_IS_BOOLEAN(v)); @@ -1803,18 +1889,18 @@ JSVAL_TO_BOOLEAN(jsval v) } static inline jsval -BOOLEAN_TO_JSVAL(JSBool b) +BOOLEAN_TO_JSVAL(bool b) { return IMPL_TO_JSVAL(BOOLEAN_TO_JSVAL_IMPL(b)); } -static inline JSBool +static inline bool JSVAL_IS_PRIMITIVE(jsval v) { return JSVAL_IS_PRIMITIVE_IMPL(JSVAL_TO_IMPL(v)); } -static inline JSBool +static inline bool JSVAL_IS_GCTHING(jsval v) { return JSVAL_IS_GCTHING_IMPL(JSVAL_TO_IMPL(v)); @@ -1842,4 +1928,25 @@ JSVAL_TO_PRIVATE(jsval v) return JSVAL_TO_PRIVATE_PTR_IMPL(JSVAL_TO_IMPL(v)); } +// JS constants. For efficiency, prefer predicates (e.g. v.isNull()) and +// constructing values from scratch (e.g. Int32Value(0)). These constants are +// stored in memory and initialized at startup, so testing against them and +// using them requires memory loads and will be correspondingly slow. +extern JS_PUBLIC_DATA(const jsval) JSVAL_NULL; +extern JS_PUBLIC_DATA(const jsval) JSVAL_ZERO; +extern JS_PUBLIC_DATA(const jsval) JSVAL_ONE; +extern JS_PUBLIC_DATA(const jsval) JSVAL_FALSE; +extern JS_PUBLIC_DATA(const jsval) JSVAL_TRUE; +extern JS_PUBLIC_DATA(const jsval) JSVAL_VOID; + +namespace JS { + +extern JS_PUBLIC_DATA(const Handle) NullHandleValue; +extern JS_PUBLIC_DATA(const Handle) UndefinedHandleValue; + +} + +#undef JS_VALUE_IS_CONSTEXPR +#undef JS_RETURN_LAYOUT_FROM_BITS + #endif /* js_Value_h */ diff --git a/external/spidermonkey/include/android/jsalloc.h b/external/spidermonkey/include/android/jsalloc.h index 3abc4966d1..03b6b569e1 100644 --- a/external/spidermonkey/include/android/jsalloc.h +++ b/external/spidermonkey/include/android/jsalloc.h @@ -9,12 +9,9 @@ #ifndef jsalloc_h #define jsalloc_h -#include "mozilla/AllocPolicy.h" - +#include "js/TypeDecls.h" #include "js/Utility.h" -struct JSContext; - namespace js { class ContextFriendFields; @@ -56,14 +53,14 @@ class TempAllocPolicy void *malloc_(size_t bytes) { void *p = js_malloc(bytes); if (JS_UNLIKELY(!p)) - p = onOutOfMemory(NULL, bytes); + p = onOutOfMemory(nullptr, bytes); return p; } void *calloc_(size_t bytes) { void *p = js_calloc(bytes); if (JS_UNLIKELY(!p)) - p = onOutOfMemory(NULL, bytes); + p = onOutOfMemory(nullptr, bytes); return p; } diff --git a/external/spidermonkey/include/android/jsapi.h.REMOVED.git-id b/external/spidermonkey/include/android/jsapi.h.REMOVED.git-id index 27b6bbed78..f73a8c745e 100644 --- a/external/spidermonkey/include/android/jsapi.h.REMOVED.git-id +++ b/external/spidermonkey/include/android/jsapi.h.REMOVED.git-id @@ -1 +1 @@ -e14ea931f699b1808c06886e55e977c9819f3774 \ No newline at end of file +38fc2004d49d7c513aff0f7f43d79524ec667c2c \ No newline at end of file diff --git a/external/spidermonkey/include/android/jsbytecode.h b/external/spidermonkey/include/android/jsbytecode.h new file mode 100644 index 0000000000..8e4f4cf90b --- /dev/null +++ b/external/spidermonkey/include/android/jsbytecode.h @@ -0,0 +1,14 @@ +/* -*- 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/external/spidermonkey/include/android/jsclass.h b/external/spidermonkey/include/android/jsclass.h deleted file mode 100644 index def641715d..0000000000 --- a/external/spidermonkey/include/android/jsclass.h +++ /dev/null @@ -1,405 +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 jsclass_h -#define jsclass_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. - */ - -#include "jsapi.h" -#include "jsprvtd.h" - -namespace js { - -class PropertyName; -class SpecialId; -class PropertyId; - -// This is equal to JSFunction::class_. Use it in places where you don't want -// to #include jsfun.h. -extern JS_FRIEND_DATA(js::Class* const) FunctionClassPtr; - -static JS_ALWAYS_INLINE jsid -SPECIALID_TO_JSID(const SpecialId &sid); - -/* - * We partition the ways to refer to a property into three: by an index - * (uint32_t); by a string whose characters do not represent an index - * (PropertyName, see vm/String.h); and by various special values. - * - * Special values are encoded using SpecialId, which is layout-compatible but - * non-interconvertible with jsid. A SpecialId is used for JSID_VOID, which - * does not occur in JS scripts but may be used to indicate the absence of a - * valid identifier. In the future, a SpecialId may also be an object used by - * Harmony-proposed private names. - */ -class SpecialId -{ - uintptr_t bits_; - - /* Needs access to raw bits. */ - friend JS_ALWAYS_INLINE jsid SPECIALID_TO_JSID(const SpecialId &sid); - friend class PropertyId; - - static const uintptr_t TYPE_VOID = JSID_TYPE_VOID; - static const uintptr_t TYPE_OBJECT = JSID_TYPE_OBJECT; - static const uintptr_t TYPE_MASK = JSID_TYPE_MASK; - - SpecialId(uintptr_t bits) : bits_(bits) { } - - public: - SpecialId() : bits_(TYPE_VOID) { } - - /* Object-valued */ - - SpecialId(JSObject &obj) - : bits_(uintptr_t(&obj) | TYPE_OBJECT) - { - JS_ASSERT(&obj != NULL); - JS_ASSERT((uintptr_t(&obj) & TYPE_MASK) == 0); - } - - bool isObject() const { - return (bits_ & TYPE_MASK) == TYPE_OBJECT && bits_ != TYPE_OBJECT; - } - - JSObject *toObject() const { - JS_ASSERT(isObject()); - return reinterpret_cast(bits_ & ~TYPE_MASK); - } - - /* Empty */ - - static SpecialId empty() { - SpecialId sid(TYPE_OBJECT); - JS_ASSERT(sid.isEmpty()); - return sid; - } - - bool isEmpty() const { - return bits_ == TYPE_OBJECT; - } - - /* Void */ - - static SpecialId voidId() { - SpecialId sid(TYPE_VOID); - JS_ASSERT(sid.isVoid()); - return sid; - } - - bool isVoid() const { - return bits_ == TYPE_VOID; - } -}; - -static JS_ALWAYS_INLINE jsid -SPECIALID_TO_JSID(const SpecialId &sid) -{ - jsid id; - JSID_BITS(id) = sid.bits_; - JS_ASSERT_IF(sid.isObject(), JSID_IS_OBJECT(id) && JSID_TO_OBJECT(id) == sid.toObject()); - JS_ASSERT_IF(sid.isVoid(), JSID_IS_VOID(id)); - JS_ASSERT_IF(sid.isEmpty(), JSID_IS_EMPTY(id)); - return id; -} - -static JS_ALWAYS_INLINE bool -JSID_IS_SPECIAL(jsid id) -{ - return JSID_IS_OBJECT(id) || JSID_IS_EMPTY(id) || JSID_IS_VOID(id); -} - -static JS_ALWAYS_INLINE SpecialId -JSID_TO_SPECIALID(jsid id) -{ - JS_ASSERT(JSID_IS_SPECIAL(id)); - if (JSID_IS_OBJECT(id)) - return SpecialId(*JSID_TO_OBJECT(id)); - if (JSID_IS_EMPTY(id)) - return SpecialId::empty(); - JS_ASSERT(JSID_IS_VOID(id)); - return SpecialId::voidId(); -} - -typedef JS::Handle HandleSpecialId; - -/* js::Class operation signatures. */ - -typedef JSBool -(* LookupGenericOp)(JSContext *cx, HandleObject obj, HandleId id, - MutableHandleObject objp, MutableHandleShape propp); -typedef JSBool -(* LookupPropOp)(JSContext *cx, HandleObject obj, HandlePropertyName name, - MutableHandleObject objp, MutableHandleShape propp); -typedef JSBool -(* LookupElementOp)(JSContext *cx, HandleObject obj, uint32_t index, - MutableHandleObject objp, MutableHandleShape propp); -typedef JSBool -(* LookupSpecialOp)(JSContext *cx, HandleObject obj, HandleSpecialId sid, - MutableHandleObject objp, MutableHandleShape propp); -typedef JSBool -(* DefineGenericOp)(JSContext *cx, HandleObject obj, HandleId id, HandleValue value, - PropertyOp getter, StrictPropertyOp setter, unsigned attrs); -typedef JSBool -(* DefinePropOp)(JSContext *cx, HandleObject obj, HandlePropertyName name, HandleValue value, - PropertyOp getter, StrictPropertyOp setter, unsigned attrs); -typedef JSBool -(* DefineElementOp)(JSContext *cx, HandleObject obj, uint32_t index, HandleValue value, - PropertyOp getter, StrictPropertyOp setter, unsigned attrs); -typedef JSBool -(* DefineSpecialOp)(JSContext *cx, HandleObject obj, HandleSpecialId sid, HandleValue value, - PropertyOp getter, StrictPropertyOp setter, unsigned attrs); -typedef JSBool -(* GenericIdOp)(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id, MutableHandleValue vp); -typedef JSBool -(* PropertyIdOp)(JSContext *cx, HandleObject obj, HandleObject receiver, HandlePropertyName name, MutableHandleValue vp); -typedef JSBool -(* ElementIdOp)(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index, MutableHandleValue vp); -typedef JSBool -(* ElementIfPresentOp)(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index, MutableHandleValue vp, bool* present); -typedef JSBool -(* SpecialIdOp)(JSContext *cx, HandleObject obj, HandleObject receiver, HandleSpecialId sid, MutableHandleValue vp); -typedef JSBool -(* StrictGenericIdOp)(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue vp, JSBool strict); -typedef JSBool -(* StrictPropertyIdOp)(JSContext *cx, HandleObject obj, HandlePropertyName name, MutableHandleValue vp, JSBool strict); -typedef JSBool -(* StrictElementIdOp)(JSContext *cx, HandleObject obj, uint32_t index, MutableHandleValue vp, JSBool strict); -typedef JSBool -(* StrictSpecialIdOp)(JSContext *cx, HandleObject obj, HandleSpecialId sid, MutableHandleValue vp, JSBool strict); -typedef JSBool -(* GenericAttributesOp)(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp); -typedef JSBool -(* PropertyAttributesOp)(JSContext *cx, HandleObject obj, HandlePropertyName name, unsigned *attrsp); -typedef JSBool -(* ElementAttributesOp)(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp); -typedef JSBool -(* SpecialAttributesOp)(JSContext *cx, HandleObject obj, HandleSpecialId sid, unsigned *attrsp); -typedef JSBool -(* DeletePropertyOp)(JSContext *cx, HandleObject obj, HandlePropertyName name, JSBool *succeeded); -typedef JSBool -(* DeleteElementOp)(JSContext *cx, HandleObject obj, uint32_t index, JSBool *succeeded); -typedef JSBool -(* DeleteSpecialOp)(JSContext *cx, HandleObject obj, HandleSpecialId sid, JSBool *succeeded); - - -typedef JSObject * -(* ObjectOp)(JSContext *cx, HandleObject obj); -typedef void -(* FinalizeOp)(FreeOp *fop, JSObject *obj); - -#define JS_CLASS_MEMBERS \ - const char *name; \ - uint32_t flags; \ - \ - /* Mandatory function pointer members. */ \ - JSPropertyOp addProperty; \ - JSDeletePropertyOp delProperty; \ - JSPropertyOp getProperty; \ - JSStrictPropertyOp setProperty; \ - JSEnumerateOp enumerate; \ - JSResolveOp resolve; \ - JSConvertOp convert; \ - \ - /* Optional members (may be null). */ \ - FinalizeOp finalize; \ - JSCheckAccessOp checkAccess; \ - JSNative call; \ - JSHasInstanceOp hasInstance; \ - JSNative construct; \ - JSTraceOp trace - -/* - * The helper struct to measure the size of JS_CLASS_MEMBERS to know how much - * we have to pad js::Class to match the size of JSClass. - */ -struct ClassSizeMeasurement -{ - JS_CLASS_MEMBERS; -}; - -struct ClassExtension -{ - JSObjectOp outerObject; - JSObjectOp innerObject; - JSIteratorOp iteratorObject; - - /* - * isWrappedNative is true only if the class is an XPCWrappedNative. - * WeakMaps use this to override the wrapper disposal optimization. - */ - bool isWrappedNative; - - /* - * 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; -}; - -#define JS_NULL_CLASS_EXT {NULL,NULL,NULL,false,NULL} - -struct ObjectOps -{ - LookupGenericOp lookupGeneric; - LookupPropOp lookupProperty; - LookupElementOp lookupElement; - LookupSpecialOp lookupSpecial; - DefineGenericOp defineGeneric; - DefinePropOp defineProperty; - DefineElementOp defineElement; - DefineSpecialOp defineSpecial; - GenericIdOp getGeneric; - PropertyIdOp getProperty; - ElementIdOp getElement; - ElementIfPresentOp getElementIfPresent; /* can be null */ - SpecialIdOp getSpecial; - StrictGenericIdOp setGeneric; - StrictPropertyIdOp setProperty; - StrictElementIdOp setElement; - StrictSpecialIdOp setSpecial; - GenericAttributesOp getGenericAttributes; - PropertyAttributesOp getPropertyAttributes; - ElementAttributesOp getElementAttributes; - SpecialAttributesOp getSpecialAttributes; - GenericAttributesOp setGenericAttributes; - PropertyAttributesOp setPropertyAttributes; - ElementAttributesOp setElementAttributes; - SpecialAttributesOp setSpecialAttributes; - DeletePropertyOp deleteProperty; - DeleteElementOp deleteElement; - DeleteSpecialOp deleteSpecial; - - JSNewEnumerateOp enumerate; - ObjectOp thisObject; -}; - -#define JS_NULL_OBJECT_OPS \ - {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, \ - NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, \ - NULL,NULL,NULL} - -struct Class -{ - JS_CLASS_MEMBERS; - ClassExtension ext; - ObjectOps ops; - uint8_t pad[sizeof(JSClass) - sizeof(ClassSizeMeasurement) - - sizeof(ClassExtension) - sizeof(ObjectOps)]; - - /* Class is not native and its map is not a scope. */ - 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 isCallable() const { - return this == js::FunctionClassPtr || call; - } - - static size_t offsetOfFlags() { return offsetof(Class, flags); } -}; - -JS_STATIC_ASSERT(offsetof(JSClass, name) == offsetof(Class, name)); -JS_STATIC_ASSERT(offsetof(JSClass, flags) == offsetof(Class, flags)); -JS_STATIC_ASSERT(offsetof(JSClass, addProperty) == offsetof(Class, addProperty)); -JS_STATIC_ASSERT(offsetof(JSClass, delProperty) == offsetof(Class, delProperty)); -JS_STATIC_ASSERT(offsetof(JSClass, getProperty) == offsetof(Class, getProperty)); -JS_STATIC_ASSERT(offsetof(JSClass, setProperty) == offsetof(Class, setProperty)); -JS_STATIC_ASSERT(offsetof(JSClass, enumerate) == offsetof(Class, enumerate)); -JS_STATIC_ASSERT(offsetof(JSClass, resolve) == offsetof(Class, resolve)); -JS_STATIC_ASSERT(offsetof(JSClass, convert) == offsetof(Class, convert)); -JS_STATIC_ASSERT(offsetof(JSClass, finalize) == offsetof(Class, finalize)); -JS_STATIC_ASSERT(offsetof(JSClass, checkAccess) == offsetof(Class, checkAccess)); -JS_STATIC_ASSERT(offsetof(JSClass, call) == offsetof(Class, call)); -JS_STATIC_ASSERT(offsetof(JSClass, construct) == offsetof(Class, construct)); -JS_STATIC_ASSERT(offsetof(JSClass, hasInstance) == offsetof(Class, hasInstance)); -JS_STATIC_ASSERT(offsetof(JSClass, trace) == offsetof(Class, trace)); -JS_STATIC_ASSERT(sizeof(JSClass) == sizeof(Class)); - -static JS_ALWAYS_INLINE JSClass * -Jsvalify(Class *c) -{ - return (JSClass *)c; -} -static JS_ALWAYS_INLINE const JSClass * -Jsvalify(const Class *c) -{ - return (const JSClass *)c; -} - -static JS_ALWAYS_INLINE Class * -Valueify(JSClass *c) -{ - return (Class *)c; -} -static JS_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 ESClassValue { - ESClass_Array, ESClass_Number, ESClass_String, ESClass_Boolean, - ESClass_RegExp, ESClass_ArrayBuffer, ESClass_Date -}; - -/* - * Return whether the given object has the given [[Class]] internal property - * value. Beware, this query says nothing about the js::Class of the JSObject - * so the caller must not assume anything about obj's representation (e.g., obj - * may be a proxy). - */ -inline bool -ObjectClassIs(JSObject &obj, ESClassValue classValue, JSContext *cx); - -/* Just a helper that checks v.isObject before calling ObjectClassIs. */ -inline bool -IsObjectWithClass(const Value &v, ESClassValue classValue, JSContext *cx); - -inline bool -IsPoisonedSpecialId(js::SpecialId iden) -{ - if (iden.isObject()) - return IsPoisonedPtr(iden.toObject()); - return false; -} - -template <> struct GCMethods -{ - static SpecialId initial() { return SpecialId(); } - static ThingRootKind kind() { return THING_ROOT_ID; } - static bool poisoned(SpecialId id) { return IsPoisonedSpecialId(id); } -}; - -} /* namespace js */ - -#endif /* jsclass_h */ diff --git a/external/spidermonkey/include/android/jscpucfg.h b/external/spidermonkey/include/android/jscpucfg.h index c79bd7ad14..ccacab3482 100644 --- a/external/spidermonkey/include/android/jscpucfg.h +++ b/external/spidermonkey/include/android/jscpucfg.h @@ -14,8 +14,6 @@ # if defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_) # define IS_LITTLE_ENDIAN 1 # undef IS_BIG_ENDIAN -# define JS_BYTES_PER_WORD 8 -# define JS_BITS_PER_WORD_LOG2 6 # else /* !(defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_)) */ # error "CPU type is unknown" # endif /* !(defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_)) */ @@ -28,8 +26,6 @@ # define IS_LITTLE_ENDIAN 1 # undef IS_BIG_ENDIAN -# define JS_BYTES_PER_WORD 4 -# define JS_BITS_PER_WORD_LOG2 5 #elif defined(__APPLE__) # if __LITTLE_ENDIAN__ @@ -57,8 +53,8 @@ /* BSDs */ #elif defined(JS_HAVE_MACHINE_ENDIAN_H) -# include # include +# include # if defined(_BYTE_ORDER) # if _BYTE_ORDER == _LITTLE_ENDIAN diff --git a/external/spidermonkey/include/android/jsfriendapi.h b/external/spidermonkey/include/android/jsfriendapi.h index a1c3024fed..811275d332 100644 --- a/external/spidermonkey/include/android/jsfriendapi.h +++ b/external/spidermonkey/include/android/jsfriendapi.h @@ -9,11 +9,12 @@ #include "mozilla/MemoryReporting.h" -#include "jsclass.h" -#include "jsprvtd.h" +#include "jsbytecode.h" #include "jspubtd.h" #include "js/CallArgs.h" +#include "js/CallNonGenericMethod.h" +#include "js/Class.h" /* * This macro checks if the stack pointer has exceeded a given limit. If @@ -30,6 +31,12 @@ #define JS_CHECK_STACK_SIZE(limit, lval) JS_CHECK_STACK_SIZE_WITH_TOLERANCE(limit, lval, 0) +class JSAtom; +struct JSErrorFormatString; +class JSLinearString; +struct JSJitInfo; +class JSErrorReport; + namespace JS { template class Heap; @@ -47,11 +54,11 @@ JS_FindCompilationScope(JSContext *cx, JSObject *obj); extern JS_FRIEND_API(JSFunction *) JS_GetObjectFunction(JSObject *obj); -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) JS_SplicePrototype(JSContext *cx, JSObject *obj, JSObject *proto); extern JS_FRIEND_API(JSObject *) -JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent); +JS_NewObjectWithUniqueType(JSContext *cx, const JSClass *clasp, JSObject *proto, JSObject *parent); extern JS_FRIEND_API(uint32_t) JS_ObjectCountDynamicSlots(JS::HandleObject obj); @@ -62,7 +69,7 @@ JS_SetProtoCalled(JSContext *cx); extern JS_FRIEND_API(size_t) JS_GetCustomIteratorCount(JSContext *cx); -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) JS_NondeterministicGetWeakMapKeys(JSContext *cx, JSObject *obj, JSObject **ret); /* @@ -71,7 +78,7 @@ JS_NondeterministicGetWeakMapKeys(JSContext *cx, JSObject *obj, JSObject **ret); * 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(JSBool) +extern JS_FRIEND_API(bool) JS_IsDeadWrapper(JSObject *obj); /* @@ -112,11 +119,11 @@ JS_GetCompartmentPrincipals(JSCompartment *compartment); extern JS_FRIEND_API(void) JS_SetCompartmentPrincipals(JSCompartment *compartment, JSPrincipals *principals); -/* Safe to call with input obj == NULL. Returns non-NULL iff obj != NULL. */ +/* Safe to call with input obj == nullptr. Returns non-nullptr iff obj != nullptr. */ extern JS_FRIEND_API(JSObject *) JS_ObjectToInnerObject(JSContext *cx, JSObject *obj); -/* Requires obj != NULL. */ +/* Requires obj != nullptr. */ extern JS_FRIEND_API(JSObject *) JS_ObjectToOuterObject(JSContext *cx, JSObject *obj); @@ -126,8 +133,8 @@ JS_CloneObject(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent); extern JS_FRIEND_API(JSString *) JS_BasicObjectToString(JSContext *cx, JS::HandleObject obj); -extern JS_FRIEND_API(JSBool) -js_GetterOnlyPropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JSBool strict, +extern JS_FRIEND_API(bool) +js_GetterOnlyPropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool strict, JS::MutableHandleValue vp); JS_FRIEND_API(void) @@ -166,18 +173,32 @@ extern JS_FRIEND_API(void) js_DumpChars(const jschar *s, size_t n); #endif +/* + * 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). + * + * On entry, |cx| must be in the compartment of |target|. + */ extern JS_FRIEND_API(bool) JS_CopyPropertiesFrom(JSContext *cx, JSObject *target, JSObject *obj); -extern JS_FRIEND_API(JSBool) -JS_WrapPropertyDescriptor(JSContext *cx, js::PropertyDescriptor *desc); +/* + * Single-property version of the above. This function asserts that an |own| + * property of the given name exists on |obj|. + */ +extern JS_FRIEND_API(bool) +JS_CopyPropertyFrom(JSContext *cx, JS::HandleId id, JS::HandleObject target, + JS::HandleObject obj); -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) +JS_WrapPropertyDescriptor(JSContext *cx, JS::MutableHandle desc); + +extern JS_FRIEND_API(bool) JS_WrapAutoIdVector(JSContext *cx, JS::AutoIdVector &props); -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) JS_EnumerateState(JSContext *cx, JS::HandleObject obj, JSIterateOp enum_op, - js::MutableHandleValue statep, js::MutableHandleId idp); + JS::MutableHandleValue statep, JS::MutableHandleId idp); struct JSFunctionSpecWithHelp { const char *name; @@ -191,19 +212,49 @@ struct JSFunctionSpecWithHelp { #define JS_FN_HELP(name,call,nargs,flags,usage,help) \ {name, call, nargs, (flags) | JSPROP_ENUMERATE | JSFUN_STUB_GSOPS, usage, help} #define JS_FS_HELP_END \ - {NULL, NULL, 0, 0, NULL, NULL} + {nullptr, nullptr, 0, 0, nullptr, nullptr} extern JS_FRIEND_API(bool) JS_DefineFunctionsWithHelp(JSContext *cx, JSObject *obj, const JSFunctionSpecWithHelp *fs); -typedef bool (* JS_SourceHook)(JSContext *cx, JS::Handle script, - jschar **src, uint32_t *length); - -extern JS_FRIEND_API(void) -JS_SetSourceHook(JSRuntime *rt, JS_SourceHook hook); - namespace js { +/* + * A class of objects that return source code on demand. + * + * When code is compiled with CompileOptions::LAZY_SOURCE, 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, jschar **src, size_t *length) = 0; +}; + +/* + * Have |rt| use |hook| to retrieve LAZY_SOURCE source code. See the + * comments for SourceHook. The runtime takes ownership of the hook, and + * will delete it when the runtime itself is deleted, or when a new hook is + * set. + */ +extern JS_FRIEND_API(void) +SetSourceHook(JSRuntime *rt, SourceHook *hook); + +/* Remove |rt|'s source hook, and return it. The caller now owns the hook. */ +extern JS_FRIEND_API(SourceHook *) +ForgetSourceHook(JSRuntime *rt); + inline JSRuntime * GetRuntime(const JSContext *cx) { @@ -228,16 +279,21 @@ 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) -DumpHeapComplete(JSRuntime *rt, FILE *fp); +DumpHeapComplete(JSRuntime *rt, FILE *fp, DumpHeapNurseryBehaviour nurseryBehaviour); -#ifdef OLD_GETTER_SETTER_METHODS -JS_FRIEND_API(JSBool) obj_defineGetter(JSContext *cx, unsigned argc, js::Value *vp); -JS_FRIEND_API(JSBool) obj_defineSetter(JSContext *cx, unsigned argc, js::Value *vp); +#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) @@ -257,7 +313,7 @@ IsAtomsCompartment(JSCompartment *comp); * particularly, always reports when it returns false). */ extern JS_FRIEND_API(bool) -ReportIfUndeclaredVarAssignment(JSContext *cx, HandleString propname); +ReportIfUndeclaredVarAssignment(JSContext *cx, JS::HandleString propname); /* * Returns whether we're in a non-strict property set (in that we're in a @@ -274,7 +330,7 @@ struct WeakMapTracer; * 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 NULL if the weak map is not contained in a JS Object. + * m will be nullptr if the weak map is not contained in a JS Object. */ typedef void (* WeakMapTraceCallback)(WeakMapTracer *trc, JSObject *m, @@ -330,12 +386,12 @@ GetAnyCompartmentInZone(JS::Zone *zone); namespace shadow { struct TypeObject { - Class *clasp; + const Class *clasp; JSObject *proto; }; struct BaseShape { - js::Class *clasp; + const js::Class *clasp; JSObject *parent; JSObject *_1; JSCompartment *compartment; @@ -353,15 +409,15 @@ public: struct Object { shadow::Shape *shape; shadow::TypeObject *type; - js::Value *slots; - js::Value *_1; + JS::Value *slots; + JS::Value *_1; size_t numFixedSlots() const { return shape->slotInfo >> Shape::FIXED_SLOTS_SHIFT; } - Value *fixedSlots() const { - return (Value *)(uintptr_t(this) + sizeof(shadow::Object)); + JS::Value *fixedSlots() const { + return (JS::Value *)(uintptr_t(this) + sizeof(shadow::Object)); } - js::Value &slotRef(size_t slot) const { + JS::Value &slotRef(size_t slot) const { size_t nfixed = numFixedSlots(); if (slot < nfixed) return fixedSlots()[slot]; @@ -374,7 +430,7 @@ struct Function { uint16_t nargs; uint16_t flags; /* Used only for natives */ - Native native; + JSNative native; const JSJitInfo *jitinfo; void *_1; }; @@ -387,23 +443,17 @@ struct Atom { } /* namespace shadow */ -// These are equal to |&{Function,Object,OuterWindow}ProxyObject::class_|. Use -// them in places where you don't want to #include vm/ProxyObject.h. -extern JS_FRIEND_DATA(js::Class* const) FunctionProxyClassPtr; -extern JS_FRIEND_DATA(js::Class* const) ObjectProxyClassPtr; -extern JS_FRIEND_DATA(js::Class* const) OuterWindowProxyClassPtr; - // This is equal to |&JSObject::class_|. Use it in places where you don't want // to #include jsobj.h. -extern JS_FRIEND_DATA(js::Class* const) ObjectClassPtr; +extern JS_FRIEND_DATA(const js::Class* const) ObjectClassPtr; -inline js::Class * +inline const js::Class * GetObjectClass(JSObject *obj) { return reinterpret_cast(obj)->type->clasp; } -inline JSClass * +inline const JSClass * GetObjectJSClass(JSObject *obj) { return js::Jsvalify(GetObjectClass(obj)); @@ -447,6 +497,16 @@ GetObjectParentMaybeScope(JSObject *obj); JS_FRIEND_API(JSObject *) GetGlobalForObjectCrossCompartment(JSObject *obj); +JS_FRIEND_API(void) +AssertSameCompartment(JSContext *cx, JSObject *obj); + +#ifdef DEBUG +JS_FRIEND_API(void) +AssertSameCompartment(JSObject *objA, JSObject *objB); +#else +inline void AssertSameCompartment(JSObject *objA, JSObject *objB) {} +#endif + // For legacy consumers only. This whole concept is going away soon. JS_FRIEND_API(JSObject *) DefaultObjectForContextOrNull(JSContext *cx); @@ -462,7 +522,7 @@ IsOriginalScriptFunction(JSFunction *fun); /* * Return the outermost enclosing function (script) of the scripted caller. - * This function returns NULL in several cases: + * 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 @@ -486,30 +546,18 @@ NewFunctionByIdWithReserved(JSContext *cx, JSNative native, unsigned nargs, unsi JS_FRIEND_API(JSObject *) InitClassWithReserved(JSContext *cx, JSObject *obj, JSObject *parent_proto, - JSClass *clasp, JSNative constructor, unsigned nargs, + const JSClass *clasp, JSNative constructor, unsigned nargs, const JSPropertySpec *ps, const JSFunctionSpec *fs, const JSPropertySpec *static_ps, const JSFunctionSpec *static_fs); -JS_FRIEND_API(const Value &) +JS_FRIEND_API(const JS::Value &) GetFunctionNativeReserved(JSObject *fun, size_t which); JS_FRIEND_API(void) -SetFunctionNativeReserved(JSObject *fun, size_t which, const Value &val); +SetFunctionNativeReserved(JSObject *fun, size_t which, const JS::Value &val); -inline bool -GetObjectProto(JSContext *cx, JS::Handle obj, JS::MutableHandle proto) -{ - js::Class *clasp = GetObjectClass(obj); - if (clasp == js::ObjectProxyClassPtr || - clasp == js::OuterWindowProxyClassPtr || - clasp == js::FunctionProxyClassPtr) - { - return JS_GetPrototype(cx, obj, proto); - } - - proto.set(reinterpret_cast(obj.get())->type->proto); - return true; -} +JS_FRIEND_API(bool) +GetObjectProto(JSContext *cx, JS::Handle obj, JS::MutableHandle proto); inline void * GetObjectPrivate(JSObject *obj) @@ -523,7 +571,7 @@ GetObjectPrivate(JSObject *obj) * Get a slot that is both reserved for object's clasp *and* is fixed (fits * within the maximum capacity for the object's fixed slots). */ -inline const Value & +inline const JS::Value & GetReservedSlot(JSObject *obj, size_t slot) { JS_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj))); @@ -531,10 +579,10 @@ GetReservedSlot(JSObject *obj, size_t slot) } JS_FRIEND_API(void) -SetReservedSlotWithBarrier(JSObject *obj, size_t slot, const Value &value); +SetReservedSlotWithBarrier(JSObject *obj, size_t slot, const JS::Value &value); inline void -SetReservedSlot(JSObject *obj, size_t slot, const Value &value) +SetReservedSlot(JSObject *obj, size_t slot, const JS::Value &value) { JS_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj))); shadow::Object *sobj = reinterpret_cast(obj); @@ -553,7 +601,7 @@ SetReservedSlot(JSObject *obj, size_t slot, const Value &value) JS_FRIEND_API(uint32_t) GetObjectSlotSpan(JSObject *obj); -inline const Value & +inline const JS::Value & GetObjectSlot(JSObject *obj, size_t slot) { JS_ASSERT(slot < GetObjectSlotSpan(obj)); @@ -579,26 +627,14 @@ AtomToLinearString(JSAtom *atom) return reinterpret_cast(atom); } -static inline js::PropertyOp -CastAsJSPropertyOp(JSObject *object) -{ - return JS_DATA_TO_FUNC_PTR(js::PropertyOp, object); -} - -static inline js::StrictPropertyOp -CastAsJSStrictPropertyOp(JSObject *object) -{ - return JS_DATA_TO_FUNC_PTR(js::StrictPropertyOp, object); -} +JS_FRIEND_API(bool) +GetPropertyNames(JSContext *cx, JSObject *obj, unsigned flags, JS::AutoIdVector *props); JS_FRIEND_API(bool) -GetPropertyNames(JSContext *cx, JSObject *obj, unsigned flags, js::AutoIdVector *props); +AppendUnique(JSContext *cx, JS::AutoIdVector &base, JS::AutoIdVector &others); JS_FRIEND_API(bool) -AppendUnique(JSContext *cx, AutoIdVector &base, AutoIdVector &others); - -JS_FRIEND_API(bool) -GetGeneric(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp); +GetGeneric(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, JS::Value *vp); JS_FRIEND_API(bool) StringIsArrayIndex(JSLinearString *str, uint32_t *indexp); @@ -609,6 +645,14 @@ SetPreserveWrapperCallback(JSRuntime *rt, PreserveWrapperCallback callback); JS_FRIEND_API(bool) IsObjectInContextCompartment(JSObject *obj, const JSContext *cx); +/* + * ErrorFromException takes a raw Value so that it's possible to call it during + * GC/CC/whatever, when it may not be possible to get a JSContext to create a + * Rooted. It promises to never ever GC. + */ +JS_FRIEND_API(JSErrorReport*) +ErrorFromException(JS::Value val); + /* * NB: these flag bits are encoded into the bytecode stream in the immediate * operand of JSOP_ITER, so don't change them without advancing vm/Xdr.h's @@ -619,18 +663,18 @@ IsObjectInContextCompartment(JSObject *obj, const JSContext *cx); #define JSITER_KEYVALUE 0x4 /* 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_FOR_OF 0x20 /* harmony for-of loop */ -inline uintptr_t -GetNativeStackLimit(const JSRuntime *rt) -{ - return PerThreadDataFriendFields::getMainThread(rt)->nativeStackLimit; -} +JS_FRIEND_API(bool) +RunningWithTrustedPrincipals(JSContext *cx); inline uintptr_t GetNativeStackLimit(JSContext *cx) { - return GetNativeStackLimit(GetRuntime(cx)); + StackKind kind = RunningWithTrustedPrincipals(cx) ? StackForTrustedScript + : StackForUntrustedScript; + PerThreadDataFriendFields *mainThread = + PerThreadDataFriendFields::getMainThread(GetRuntime(cx)); + return mainThread->nativeStackLimit[kind]; } /* @@ -655,6 +699,14 @@ GetNativeStackLimit(JSContext *cx) } \ 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_CHROME_RECURSION(cx, onerror) \ JS_BEGIN_MACRO \ int stackDummy_; \ @@ -685,94 +737,13 @@ GetPCCountScriptSummary(JSContext *cx, size_t script); JS_FRIEND_API(JSString *) GetPCCountScriptContents(JSContext *cx, size_t script); -/* - * 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. Both use - * the string as a description, but JS uses the sp as NULL to indicate that - * it is a JS entry. The script_ is then only ever examined for a JS entry, - * and the idx is used by both, but with different meanings. - */ - const char * volatile string; // Descriptive string of this entry - void * volatile sp; // Relevant stack pointer for the entry - JSScript * volatile script_; // if js(), non-null script which is running - int32_t volatile idx; // if js(), idx of pc, otherwise line number - - public: - /* - * 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 js() volatile { - JS_ASSERT_IF(sp == NULL, script_ != NULL); - return sp == NULL; - } - - uint32_t line() volatile { JS_ASSERT(!js()); return idx; } - JSScript *script() volatile { JS_ASSERT(js()); return script_; } - void *stackAddress() volatile { return sp; } - const char *label() volatile { return string; } - - void setLine(uint32_t aLine) volatile { JS_ASSERT(!js()); idx = aLine; } - void setLabel(const char *aString) volatile { string = aString; } - void setStackAddress(void *aSp) volatile { sp = aSp; } - void setScript(JSScript *aScript) volatile { script_ = aScript; } - - /* we can't know the layout of JSScript, so look in vm/SPSProfiler.cpp */ - JS_FRIEND_API(jsbytecode *) pc() volatile; - JS_FRIEND_API(void) setPC(jsbytecode *pc) volatile; - - static size_t offsetOfString() { return offsetof(ProfileEntry, string); } - static size_t offsetOfStackAddress() { return offsetof(ProfileEntry, sp); } - static size_t offsetOfPCIdx() { return offsetof(ProfileEntry, idx); } - static size_t offsetOfScript() { return offsetof(ProfileEntry, script_); } - - /* - * The index used in the entry can either be a line number or the offset of - * a pc into a script's code. To signify a NULL pc, use a -1 index. This is - * checked against in pc() and setPC() to set/get the right pc. - */ - static const int32_t NullPCIndex = -1; -}; - -JS_FRIEND_API(void) -SetRuntimeProfilingStack(JSRuntime *rt, ProfileEntry *stack, uint32_t *size, - uint32_t max); - -JS_FRIEND_API(void) -EnableRuntimeProfilingStack(JSRuntime *rt, bool enabled); - -JS_FRIEND_API(jsbytecode*) -ProfilingGetPC(JSRuntime *rt, JSScript *script, void *ip); - #ifdef JS_THREADSAFE JS_FRIEND_API(bool) ContextHasOutstandingRequests(const JSContext *cx); #endif -JS_FRIEND_API(bool) -HasUnrootedGlobal(const JSContext *cx); - typedef void -(* ActivityCallback)(void *arg, JSBool active); +(* ActivityCallback)(void *arg, bool active); /* * Sets a callback that is run whenever the runtime goes idle - the @@ -785,22 +756,10 @@ SetActivityCallback(JSRuntime *rt, ActivityCallback cb, void *arg); extern JS_FRIEND_API(const JSStructuredCloneCallbacks *) GetContextStructuredCloneCallbacks(JSContext *cx); -extern JS_FRIEND_API(bool) -CanCallContextDebugHandler(JSContext *cx); - -extern JS_FRIEND_API(JSTrapStatus) -CallContextDebugHandler(JSContext *cx, JSScript *script, jsbytecode *bc, Value *rval); - extern JS_FRIEND_API(bool) IsContextRunningJS(JSContext *cx); -typedef void -(* AnalysisPurgeCallback)(JSRuntime *rt, JS::Handle desc); - -extern JS_FRIEND_API(AnalysisPurgeCallback) -SetAnalysisPurgeCallback(JSRuntime *rt, AnalysisPurgeCallback callback); - -typedef JSBool +typedef bool (* DOMInstanceClassMatchesProto)(JS::HandleObject protoObject, uint32_t protoID, uint32_t depth); struct JSDOMCallbacks { @@ -832,10 +791,10 @@ CastToJSFreeOp(FreeOp *fop) /* * Get an error type name from a JSExnType constant. - * Returns NULL for invalid arguments and JSEXN_INTERNALERR + * Returns nullptr for invalid arguments and JSEXN_INTERNALERR */ extern JS_FRIEND_API(const jschar*) -GetErrorTypeName(JSContext* cx, int16_t exnType); +GetErrorTypeName(JSRuntime* rt, int16_t exnType); #ifdef DEBUG extern JS_FRIEND_API(unsigned) @@ -886,7 +845,7 @@ struct CompartmentsWithPrincipals : public CompartmentFilter { } }; -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) NukeCrossCompartmentWrappers(JSContext* cx, const CompartmentFilter& sourceFilter, const CompartmentFilter& targetFilter, @@ -910,7 +869,7 @@ NukeCrossCompartmentWrappers(JSContext* cx, struct ExpandoAndGeneration { ExpandoAndGeneration() - : expando(UndefinedValue()), + : expando(JS::UndefinedValue()), generation(0) {} @@ -933,10 +892,10 @@ typedef enum DOMProxyShadowsResult { typedef DOMProxyShadowsResult (* DOMProxyShadowsCheck)(JSContext* cx, JS::HandleObject object, JS::HandleId id); JS_FRIEND_API(void) -SetDOMProxyInformation(void *domProxyHandlerFamily, uint32_t domProxyExpandoSlot, +SetDOMProxyInformation(const void *domProxyHandlerFamily, uint32_t domProxyExpandoSlot, DOMProxyShadowsCheck domProxyShadowsCheck); -void *GetDOMProxyHandlerFamily(); +const void *GetDOMProxyHandlerFamily(); uint32_t GetDOMProxyExpandoSlot(); DOMProxyShadowsCheck GetDOMProxyShadowsCheck(); @@ -948,7 +907,7 @@ DOMProxyShadowsCheck GetDOMProxyShadowsCheck(); * Detect whether the internal date value is NaN. (Because failure is * out-of-band for js_DateGet*) */ -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) js_DateIsValid(JSObject* obj); extern JS_FRIEND_API(double) @@ -1008,136 +967,6 @@ enum ViewType { } /* namespace ArrayBufferView */ -/* - * A helper for building up an ArrayBuffer object's data - * before creating the ArrayBuffer itself. Will do doubling - * based reallocation, up to an optional maximum growth given. - * - * When all the data has been appended, call getArrayBuffer, - * passing in the JSContext* for which the ArrayBuffer object - * is to be created. This also implicitly resets the builder, - * or it can be reset explicitly at any point by calling reset(). - */ -class ArrayBufferBuilder -{ - void *rawcontents_; - uint8_t *dataptr_; - uint32_t capacity_; - uint32_t length_; - public: - ArrayBufferBuilder() - : rawcontents_(NULL), - dataptr_(NULL), - capacity_(0), - length_(0) - { - } - - ~ArrayBufferBuilder() { - reset(); - } - - void reset() { - if (rawcontents_) - JS_free(NULL, rawcontents_); - rawcontents_ = dataptr_ = NULL; - capacity_ = length_ = 0; - } - - // will truncate if newcap is < length() - bool setCapacity(uint32_t newcap) { - if (!JS_ReallocateArrayBufferContents(NULL, newcap, &rawcontents_, &dataptr_)) - return false; - - capacity_ = newcap; - if (length_ > newcap) - length_ = newcap; - - return true; - } - - // Append datalen bytes from data to the current buffer. If we - // need to grow the buffer, grow by doubling the size up to a - // maximum of maxgrowth (if given). If datalen is greater than - // what the new capacity would end up as, then grow by datalen. - // - // The data parameter must not overlap with anything beyond the - // builder's current valid contents [0..length) - bool append(const uint8_t *newdata, uint32_t datalen, uint32_t maxgrowth = 0) { - if (length_ + datalen > capacity_) { - uint32_t newcap; - // double while under maxgrowth or if not specified - if (!maxgrowth || capacity_ < maxgrowth) - newcap = capacity_ * 2; - else - newcap = capacity_ + maxgrowth; - - // but make sure there's always enough to satisfy our request - if (newcap < length_ + datalen) - newcap = length_ + datalen; - - // did we overflow? - if (newcap < capacity_) - return false; - - if (!setCapacity(newcap)) - return false; - } - - // assert that the region isn't overlapping so we can memcpy; - JS_ASSERT(!areOverlappingRegions(newdata, datalen, dataptr_ + length_, datalen)); - - memcpy(dataptr_ + length_, newdata, datalen); - length_ += datalen; - - return true; - } - - uint8_t *data() { - return dataptr_; - } - - uint32_t length() { - return length_; - } - - uint32_t capacity() { - return capacity_; - } - - JSObject* getArrayBuffer(JSContext *cx) { - // we need to check for length_ == 0, because nothing may have been - // added - if (capacity_ > length_ || length_ == 0) { - if (!setCapacity(length_)) - return NULL; - } - - JSObject* obj = JS_NewArrayBufferWithContents(cx, rawcontents_); - if (!obj) - return NULL; - - rawcontents_ = dataptr_ = NULL; - length_ = capacity_ = 0; - - return obj; - } - -protected: - - static bool areOverlappingRegions(const uint8_t *start1, uint32_t length1, - const uint8_t *start2, uint32_t length2) - { - const uint8_t *end1 = start1 + length1; - const uint8_t *end2 = start2 + length2; - - const uint8_t *max_start = start1 > start2 ? start1 : start2; - const uint8_t *min_end = end1 < end2 ? end1 : end2; - - return max_start < min_end; - } -}; - } /* namespace js */ typedef js::ArrayBufferView::ViewType JSArrayBufferViewType; @@ -1241,7 +1070,7 @@ JS_NewArrayBuffer(JSContext *cx, uint32_t nbytes); * 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(JSBool) +extern JS_FRIEND_API(bool) JS_IsTypedArrayObject(JSObject *obj); /* @@ -1251,36 +1080,36 @@ JS_IsTypedArrayObject(JSObject *obj); * is safe to call the various ArrayBufferView accessor JSAPI calls defined * below. */ -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) JS_IsArrayBufferViewObject(JSObject *obj); /* * Test for specific typed array types (ArrayBufferView subtypes) */ -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) JS_IsInt8Array(JSObject *obj); -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) JS_IsUint8Array(JSObject *obj); -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) JS_IsUint8ClampedArray(JSObject *obj); -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) JS_IsInt16Array(JSObject *obj); -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) JS_IsUint16Array(JSObject *obj); -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) JS_IsInt32Array(JSObject *obj); -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) JS_IsUint32Array(JSObject *obj); -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) JS_IsFloat32Array(JSObject *obj); -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) JS_IsFloat64Array(JSObject *obj); /* - * Unwrap Typed arrays all at once. Return NULL without throwing if the object - * cannot be viewed as the correct typed array, or the typed array object on - * success, filling both outparameters. + * 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, int8_t **data); @@ -1321,7 +1150,7 @@ JS_GetArrayBufferViewType(JSObject *obj); * unwrapping. If this test succeeds, then it is safe to call the various * accessor JSAPI calls defined below. */ -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) JS_IsArrayBufferObject(JSObject *obj); /* @@ -1382,7 +1211,7 @@ JS_GetTypedArrayByteLength(JSObject *obj); * return false if a security wrapper is encountered that denies the * unwrapping. */ -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) JS_IsArrayBufferViewObject(JSObject *obj); /* @@ -1435,10 +1264,16 @@ JS_GetArrayBufferViewData(JSObject *obj); extern JS_FRIEND_API(JSObject *) JS_GetArrayBufferViewBuffer(JSObject *obj); +/* + * Set an ArrayBuffer's length to 0 and neuter all of its views. + */ +extern JS_FRIEND_API(void) +JS_NeuterArrayBuffer(JSObject *obj, JSContext *cx); + /* * Check whether obj supports JS_GetDataView* APIs. */ -JS_FRIEND_API(JSBool) +JS_FRIEND_API(bool) JS_IsDataViewObject(JSObject *obj); /* @@ -1457,7 +1292,7 @@ JS_GetDataViewByteOffset(JSObject *obj); * * |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 NULL, then DEBUG builds may be + * 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) @@ -1468,12 +1303,39 @@ JS_GetDataViewByteLength(JSObject *obj); * * |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 NULL, then DEBUG builds may be + * 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); +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 js + /* * A class, expected to be passed by value, which represents the CallArgs for a * JSJitGetterOp. @@ -1599,7 +1461,7 @@ struct JSJitInfo { }; #define JS_JITINFO_NATIVE_PARALLEL(op) \ - {{NULL},0,0,JSJitInfo::OpType_None,false,false,false,JSVAL_TYPE_MISSING,op} + {{nullptr},0,0,JSJitInfo::OpType_None,false,false,false,JSVAL_TYPE_MISSING,op} static JS_ALWAYS_INLINE const JSJitInfo * FUNCTION_VALUE_TO_JITINFO(const JS::Value& v) @@ -1632,6 +1494,12 @@ JSID_FROM_BITS(size_t bits) return id; } +namespace js { +namespace detail { +bool IdMatchesAtom(jsid id, JSAtom *atom); +} +} + /* * Must not be used on atoms that are representable as integer jsids. * Prefer NameToId or AtomToId over this function: @@ -1658,18 +1526,18 @@ NON_INTEGER_ATOM_TO_JSID(JSAtom *atom) { JS_ASSERT(((size_t)atom & 0x7) == 0); jsid id = JSID_FROM_BITS((size_t)atom); - JS_ASSERT(id == INTERNED_STRING_TO_JSID(NULL, (JSString*)atom)); + JS_ASSERT(js::detail::IdMatchesAtom(id, atom)); return id; } /* All strings stored in jsids are atomized, but are not necessarily property names. */ -static JS_ALWAYS_INLINE JSBool +static JS_ALWAYS_INLINE bool JSID_IS_ATOM(jsid id) { return JSID_IS_STRING(id); } -static JS_ALWAYS_INLINE JSBool +static JS_ALWAYS_INLINE bool JSID_IS_ATOM(jsid id, JSAtom *atom) { return id == JSID_FROM_BITS((size_t)atom); @@ -1681,21 +1549,21 @@ JSID_TO_ATOM(jsid id) return (JSAtom *)JSID_TO_STRING(id); } -JS_STATIC_ASSERT(sizeof(jsid) == JS_BYTES_PER_WORD); +JS_STATIC_ASSERT(sizeof(jsid) == sizeof(void*)); namespace js { -static JS_ALWAYS_INLINE Value +static JS_ALWAYS_INLINE JS::Value IdToValue(jsid id) { if (JSID_IS_STRING(id)) - return StringValue(JSID_TO_STRING(id)); + return JS::StringValue(JSID_TO_STRING(id)); if (JS_LIKELY(JSID_IS_INT(id))) - return Int32Value(JSID_TO_INT(id)); + return JS::Int32Value(JSID_TO_INT(id)); if (JS_LIKELY(JSID_IS_OBJECT(id))) - return ObjectValue(*JSID_TO_OBJECT(id)); + return JS::ObjectValue(*JSID_TO_OBJECT(id)); JS_ASSERT(JSID_IS_VOID(id)); - return UndefinedValue(); + return JS::UndefinedValue(); } static JS_ALWAYS_INLINE jsval @@ -1710,6 +1578,20 @@ IsReadOnlyDateMethod(JS::IsAcceptableThis test, JS::NativeImpl method); extern JS_FRIEND_API(bool) IsTypedArrayThisCheck(JS::IsAcceptableThis test); +/* + * If the embedder has registered a default JSContext callback, returns the + * result of the callback. Otherwise, asserts that |rt| has exactly one + * JSContext associated with it, and returns that context. + */ +extern JS_FRIEND_API(JSContext *) +DefaultJSContext(JSRuntime *rt); + +typedef JSContext* +(* DefaultJSContextCallback)(JSRuntime *rt); + +JS_FRIEND_API(void) +SetDefaultJSContextCallback(JSRuntime *rt, DefaultJSContextCallback cb); + enum CTypesActivityType { CTYPES_CALL_BEGIN, CTYPES_CALL_END, @@ -1744,7 +1626,7 @@ class JS_FRIEND_API(AutoCTypesActivityCallback) { void DoEndCallback() { if (callback) { callback(cx, endType); - callback = NULL; + callback = nullptr; } } }; @@ -1777,8 +1659,8 @@ JS_FRIEND_API(JSObject *) GetObjectMetadata(JSObject *obj); /* ES5 8.12.8. */ -extern JS_FRIEND_API(JSBool) -DefaultValue(JSContext *cx, JS::HandleObject obj, JSType hint, MutableHandleValue vp); +extern JS_FRIEND_API(bool) +DefaultValue(JSContext *cx, JS::HandleObject obj, JSType hint, JS::MutableHandleValue vp); /* * Helper function. To approximate a call to the [[DefineOwnProperty]] internal @@ -1794,16 +1676,16 @@ DefaultValue(JSContext *cx, JS::HandleObject obj, JSType hint, MutableHandleValu * js::ProxyHandler, or the JSAPI with precisely the right semantics for it. */ extern JS_FRIEND_API(bool) -CheckDefineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value, - PropertyOp getter, StrictPropertyOp setter, unsigned attrs); +CheckDefineProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value, + JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs); } /* namespace js */ -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) js_DefineOwnProperty(JSContext *cx, JSObject *objArg, jsid idArg, - const js::PropertyDescriptor& descriptor, JSBool *bp); + JS::Handle descriptor, bool *bp); -extern JS_FRIEND_API(JSBool) +extern JS_FRIEND_API(bool) js_ReportIsNotFunction(JSContext *cx, const JS::Value& v); #ifdef JSGC_GENERATIONAL diff --git a/external/spidermonkey/include/android/jslock.h b/external/spidermonkey/include/android/jslock.h deleted file mode 100644 index 522034ad68..0000000000 --- a/external/spidermonkey/include/android/jslock.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/. */ - -#ifndef jslock_h -#define jslock_h - -#ifdef JS_THREADSAFE - -# include "jsapi.h" -# include "pratom.h" -# include "prcvar.h" -# include "prinit.h" -# include "prlock.h" -# include "prthread.h" - -# define JS_ATOMIC_INCREMENT(p) PR_ATOMIC_INCREMENT((int32_t *)(p)) -# define JS_ATOMIC_DECREMENT(p) PR_ATOMIC_DECREMENT((int32_t *)(p)) -# define JS_ATOMIC_ADD(p,v) PR_ATOMIC_ADD((int32_t *)(p), (int32_t)(v)) -# define JS_ATOMIC_SET(p,v) PR_ATOMIC_SET((int32_t *)(p), (int32_t)(v)) - -namespace js { - // Defined in jsgc.cpp. - unsigned GetCPUCount(); -} - -#else /* JS_THREADSAFE */ - -typedef struct PRThread PRThread; -typedef struct PRCondVar PRCondVar; -typedef struct PRLock PRLock; - -# define JS_ATOMIC_INCREMENT(p) (++*(p)) -# define JS_ATOMIC_DECREMENT(p) (--*(p)) -# define JS_ATOMIC_ADD(p,v) (*(p) += (v)) -# define JS_ATOMIC_SET(p,v) (*(p) = (v)) - -#endif /* JS_THREADSAFE */ - -#endif /* jslock_h */ diff --git a/external/spidermonkey/include/android/jsperf.h b/external/spidermonkey/include/android/jsperf.h index 468ce8609c..e3cbc23143 100644 --- a/external/spidermonkey/include/android/jsperf.h +++ b/external/spidermonkey/include/android/jsperf.h @@ -6,7 +6,10 @@ #ifndef perf_jsperf_h #define perf_jsperf_h -#include "jsapi.h" +#include "jstypes.h" + +#include "js/TypeDecls.h" +#include "js/Utility.h" namespace JS { @@ -118,12 +121,12 @@ extern JS_FRIEND_API(JSObject*) RegisterPerfMeasurement(JSContext *cx, JSObject *global); /* - * Given a jsval which contains an instance of the aforementioned - * wrapper class, extract the C++ object. Returns NULL if the - * jsval is not an instance of the wrapper. + * 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(jsval wrapper); + ExtractPerfMeasurement(Value wrapper); } // namespace JS diff --git a/external/spidermonkey/include/android/jsprf.h b/external/spidermonkey/include/android/jsprf.h index ce159d8115..b235f0b4fb 100644 --- a/external/spidermonkey/include/android/jsprf.h +++ b/external/spidermonkey/include/android/jsprf.h @@ -26,7 +26,6 @@ */ #include -#include #include "jstypes.h" @@ -39,7 +38,7 @@ extern JS_PUBLIC_API(uint32_t) JS_snprintf(char *out, uint32_t outlen, const cha /* ** sprintf into a malloc'd buffer. Return a pointer to the malloc'd -** buffer on success, NULL on failure. Call "JS_smprintf_free" to release +** 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, ...); @@ -52,9 +51,9 @@ 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 NULL, JS_sprintf_append +** 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 NULL if there is a malloc failure. +** 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, ...); diff --git a/external/spidermonkey/include/android/jsprototypes.h b/external/spidermonkey/include/android/jsprototypes.h index f9bacac409..b0fee8c468 100644 --- a/external/spidermonkey/include/android/jsprototypes.h +++ b/external/spidermonkey/include/android/jsprototypes.h @@ -9,8 +9,6 @@ #ifndef jsprototypes_h #define jsprototypes_h -#include "jsversion.h" - /* * Enumerator codes in the second column must not change -- they are part of * the JS XDR API. Also note the symbols in the third column are extern "C"; @@ -56,20 +54,7 @@ macro(DataView, 35, js_InitTypedArrayClasses) \ macro(ParallelArray, 36, js_InitParallelArrayClass) \ macro(Intl, 37, js_InitIntlClass) \ - macro(Type, 38, js_InitBinaryDataClasses) \ - macro(Data, 39, js_InitBinaryDataClasses) \ - macro(uint8, 40, js_InitBinaryDataClasses) \ - macro(uint16, 41, js_InitBinaryDataClasses) \ - macro(uint32, 42, js_InitBinaryDataClasses) \ - macro(uint64, 43, js_InitBinaryDataClasses) \ - macro(int8, 44, js_InitBinaryDataClasses) \ - macro(int16, 45, js_InitBinaryDataClasses) \ - macro(int32, 46, js_InitBinaryDataClasses) \ - macro(int64, 47, js_InitBinaryDataClasses) \ - macro(float32, 48, js_InitBinaryDataClasses) \ - macro(float64, 49, js_InitBinaryDataClasses) \ - macro(ArrayType, 50, js_InitBinaryDataClasses) \ - macro(StructType, 51, js_InitBinaryDataClasses) \ - macro(ArrayTypeObject, 52, js_InitBinaryDataClasses) \ + macro(TypedObject, 38, js_InitTypedObjectDummy) \ + macro(GeneratorFunction, 39, js_InitIteratorClasses) \ #endif /* jsprototypes_h */ diff --git a/external/spidermonkey/include/android/jsproxy.h b/external/spidermonkey/include/android/jsproxy.h index 56868a05c3..c54e300d73 100644 --- a/external/spidermonkey/include/android/jsproxy.h +++ b/external/spidermonkey/include/android/jsproxy.h @@ -7,11 +7,29 @@ #ifndef jsproxy_h #define jsproxy_h -#include "jsapi.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::HandleId; +using JS::HandleObject; +using JS::HandleValue; +using JS::IsAcceptableThis; +using JS::MutableHandle; +using JS::MutableHandleObject; +using JS::MutableHandleValue; +using JS::NativeImpl; +using JS::PrivateValue; +using JS::Value; + +class RegExpGuard; class JS_FRIEND_API(Wrapper); /* @@ -49,7 +67,7 @@ class JS_FRIEND_API(Wrapper); */ class JS_FRIEND_API(BaseProxyHandler) { - void *mFamily; + const void *mFamily; bool mHasPrototype; bool mHasPolicy; protected: @@ -58,7 +76,7 @@ class JS_FRIEND_API(BaseProxyHandler) void setHasPolicy(bool aHasPolicy) { mHasPolicy = aHasPolicy; } public: - explicit BaseProxyHandler(void *family); + explicit BaseProxyHandler(const void *family); virtual ~BaseProxyHandler(); bool hasPrototype() { @@ -69,9 +87,12 @@ class JS_FRIEND_API(BaseProxyHandler) return mHasPolicy; } - inline void *family() { + inline const void *family() { return mFamily; } + static size_t offsetOfFamily() { + return offsetof(BaseProxyHandler, mFamily); + } virtual bool isOuterWindow() { return false; @@ -106,12 +127,13 @@ class JS_FRIEND_API(BaseProxyHandler) /* ES5 Harmony fundamental proxy traps. */ virtual bool preventExtensions(JSContext *cx, HandleObject proxy) = 0; virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, - PropertyDescriptor *desc, unsigned flags) = 0; + MutableHandle desc, + unsigned flags) = 0; virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, - HandleId id, PropertyDescriptor *desc, + HandleId id, MutableHandle desc, unsigned flags) = 0; virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id, - PropertyDescriptor *desc) = 0; + MutableHandle desc) = 0; virtual bool getOwnPropertyNames(JSContext *cx, HandleObject proxy, AutoIdVector &props) = 0; virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) = 0; @@ -144,7 +166,13 @@ class JS_FRIEND_API(BaseProxyHandler) uint32_t index, MutableHandleValue vp, bool *present); virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop); - /* See comment for weakmapKeyDelegateOp in jsclass.h. */ + // 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); + virtual bool unwatch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id); + + /* See comment for weakmapKeyDelegateOp in js/Class.h. */ virtual JSObject *weakmapKeyDelegate(JSObject *proxy); }; @@ -157,17 +185,17 @@ class JS_FRIEND_API(BaseProxyHandler) class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler { public: - explicit DirectProxyHandler(void *family); + explicit DirectProxyHandler(const void *family); /* ES5 Harmony fundamental proxy traps. */ virtual bool preventExtensions(JSContext *cx, HandleObject proxy) MOZ_OVERRIDE; virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, - PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE; + MutableHandle desc, unsigned flags) MOZ_OVERRIDE; virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, - HandleId id, PropertyDescriptor *desc, + HandleId id, MutableHandle desc, unsigned flags) MOZ_OVERRIDE; virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id, - PropertyDescriptor *desc) MOZ_OVERRIDE; + MutableHandle desc) MOZ_OVERRIDE; virtual bool getOwnPropertyNames(JSContext *cx, HandleObject proxy, AutoIdVector &props) MOZ_OVERRIDE; virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, @@ -204,8 +232,6 @@ class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler unsigned indent) MOZ_OVERRIDE; virtual bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g) MOZ_OVERRIDE; - virtual bool defaultValue(JSContext *cx, HandleObject obj, JSType hint, - MutableHandleValue vp) MOZ_OVERRIDE; virtual JSObject *weakmapKeyDelegate(JSObject *proxy); }; @@ -216,14 +242,15 @@ class Proxy /* ES5 Harmony fundamental proxy traps. */ static bool preventExtensions(JSContext *cx, HandleObject proxy); static bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, - PropertyDescriptor *desc, unsigned flags); + MutableHandle desc, unsigned flags); static bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, unsigned flags, HandleId id, MutableHandleValue vp); static bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, - PropertyDescriptor *desc, unsigned flags); + MutableHandle desc, unsigned flags); static bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, unsigned flags, HandleId id, MutableHandleValue vp); - static bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id, PropertyDescriptor *desc); + static bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id, + MutableHandle desc); static bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v); static bool getOwnPropertyNames(JSContext *cx, HandleObject proxy, AutoIdVector &props); static bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp); @@ -254,32 +281,27 @@ class Proxy static bool defaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp); static bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop); + static bool watch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, + JS::HandleObject callable); + static bool unwatch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id); + + /* IC entry path for handling __noSuchMethod__ on access. */ + static bool callProp(JSContext *cx, HandleObject proxy, HandleObject reveiver, HandleId id, + MutableHandleValue vp); + static JSObject * const LazyProto; }; -inline bool IsObjectProxyClass(const Class *clasp) -{ - return clasp == js::ObjectProxyClassPtr || clasp == js::OuterWindowProxyClassPtr; -} - -inline bool IsFunctionProxyClass(const Class *clasp) -{ - return clasp == js::FunctionProxyClassPtr; -} +// Use these in places where you don't want to #include vm/ProxyObject.h. +extern JS_FRIEND_DATA(const js::Class* const) CallableProxyClassPtr; +extern JS_FRIEND_DATA(const js::Class* const) UncallableProxyClassPtr; +extern JS_FRIEND_DATA(const js::Class* const) OuterWindowProxyClassPtr; inline bool IsProxyClass(const Class *clasp) { - return IsObjectProxyClass(clasp) || IsFunctionProxyClass(clasp); -} - -inline bool IsObjectProxy(JSObject *obj) -{ - return IsObjectProxyClass(GetObjectClass(obj)); -} - -inline bool IsFunctionProxy(JSObject *obj) -{ - return IsFunctionProxyClass(GetObjectClass(obj)); + return clasp == CallableProxyClassPtr || + clasp == UncallableProxyClassPtr || + clasp == OuterWindowProxyClassPtr; } inline bool IsProxy(JSObject *obj) @@ -342,14 +364,42 @@ SetProxyExtra(JSObject *obj, size_t n, const Value &extra) SetReservedSlot(obj, PROXY_EXTRA_SLOT + n, extra); } -enum ProxyCallable { - ProxyNotCallable = false, - ProxyIsCallable = true +class MOZ_STACK_CLASS ProxyOptions { + public: + ProxyOptions() : callable_(false), + singleton_(false), + forceForegroundFinalization_(false) + {} + + bool callable() const { return callable_; } + ProxyOptions &setCallable(bool flag) { + callable_ = flag; + return *this; + } + + bool singleton() const { return singleton_; } + ProxyOptions &setSingleton(bool flag) { + singleton_ = flag; + return *this; + } + + bool forceForegroundFinalization() const { + return forceForegroundFinalization_; + } + ProxyOptions &setForceForegroundFinalization(bool flag) { + forceForegroundFinalization_ = true; + return *this; + } + + private: + bool callable_; + bool singleton_; + bool forceForegroundFinalization_; }; JS_FRIEND_API(JSObject *) NewProxyObject(JSContext *cx, BaseProxyHandler *handler, HandleValue priv, - JSObject *proto, JSObject *parent, ProxyCallable callable = ProxyNotCallable); + JSObject *proto, JSObject *parent, const ProxyOptions &options = ProxyOptions()); JSObject * RenewProxyObject(JSContext *cx, JSObject *obj, BaseProxyHandler *handler, Value priv); @@ -361,7 +411,7 @@ class JS_FRIEND_API(AutoEnterPolicy) AutoEnterPolicy(JSContext *cx, BaseProxyHandler *handler, HandleObject wrapper, HandleId id, Action act, bool mayThrow) #ifdef DEBUG - : context(NULL) + : context(nullptr) #endif { allow = handler->hasPolicy() ? handler->enter(cx, wrapper, id, act, &rv) @@ -372,8 +422,8 @@ class JS_FRIEND_API(AutoEnterPolicy) // * 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 && !JS_IsExceptionPending(cx)) - reportError(cx, id); + if (!allow && !rv && mayThrow) + reportErrorIfExceptionIsNotPending(cx, id); } virtual ~AutoEnterPolicy() { recordLeave(); } @@ -384,10 +434,10 @@ class JS_FRIEND_API(AutoEnterPolicy) // no-op constructor for subclass AutoEnterPolicy() #ifdef DEBUG - : context(NULL) + : context(nullptr) #endif {}; - void reportError(JSContext *cx, jsid id); + void reportErrorIfExceptionIsNotPending(JSContext *cx, jsid id); bool allow; bool rv; diff --git a/external/spidermonkey/include/android/jsprvtd.h b/external/spidermonkey/include/android/jsprvtd.h deleted file mode 100644 index 1fbc086a7c..0000000000 --- a/external/spidermonkey/include/android/jsprvtd.h +++ /dev/null @@ -1,297 +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 jsprvtd_h -#define jsprvtd_h -/* - * JS private typename definitions. - * - * This header is included only in other .h files, for convenience and for - * simplicity of type naming. The alternative for structures is to use tags, - * which are named the same as their typedef names (legal in C/C++, and less - * noisy than suffixing the typedef name with "Struct" or "Str"). Instead, - * all .h files that include this file may use the same typedef name, whether - * declaring a pointer to struct type, or defining a member of struct type. - * - * A few fundamental scalar types are defined here too. Neither the scalar - * nor the struct typedefs should change much, therefore the nearly-global - * make dependency induced by this file should not prove painful. - */ - -#include "jsapi.h" -#include "jsutil.h" - -#include "js/HashTable.h" -#include "js/Vector.h" - -/* - * Convenience constants. - */ -#define JS_BITS_PER_UINT32_LOG2 5 -#define JS_BITS_PER_UINT32 32 - -/* The alignment required of objects stored in GC arenas. */ -static const unsigned JS_GCTHING_ALIGN = 8; -static const unsigned JS_GCTHING_ZEROBITS = 3; - -/* Scalar typedefs. */ -typedef uint8_t jsbytecode; -typedef uint8_t jssrcnote; -typedef uintptr_t jsatomid; - -/* Struct typedefs. */ -typedef struct JSGCThing JSGCThing; -typedef struct JSGenerator JSGenerator; -typedef struct JSNativeEnumerator JSNativeEnumerator; -typedef struct JSTryNote JSTryNote; - -/* Friend "Advanced API" typedefs. */ -typedef struct JSAtomState JSAtomState; -typedef struct JSCodeSpec JSCodeSpec; -typedef struct JSPrinter JSPrinter; -typedef struct JSStackHeader JSStackHeader; -typedef struct JSSubString JSSubString; -typedef struct JSSpecializedNative JSSpecializedNative; - -/* String typedefs. */ -class JSDependentString; -class JSExtensibleString; -class JSExternalString; -class JSLinearString; -class JSRope; -class JSAtom; -class JSWrapper; - -namespace js { - -struct ArgumentsData; -struct Class; - -class AutoNameVector; -class RegExpGuard; -class RegExpObject; -class RegExpObjectBuilder; -class RegExpShared; -class RegExpStatics; -class MatchPairs; -class PropertyName; -class LazyScript; - -enum RegExpFlag -{ - IgnoreCaseFlag = 0x01, - GlobalFlag = 0x02, - MultilineFlag = 0x04, - StickyFlag = 0x08, - - NoFlags = 0x00, - AllFlags = 0x0f -}; - -class StringBuffer; - -class FrameRegs; -class StackFrame; -class ScriptFrameIter; - -class Proxy; -class JS_FRIEND_API(AutoEnterPolicy); -class JS_FRIEND_API(BaseProxyHandler); -class JS_FRIEND_API(Wrapper); -class JS_FRIEND_API(CrossCompartmentWrapper); - -class TempAllocPolicy; -class RuntimeAllocPolicy; - -class GlobalObject; - -template -class InlineMap; - -class LifoAlloc; - -class Shape; - -class Breakpoint; -class BreakpointSite; -class Debugger; -class WatchpointMap; - -/* - * Env is the type of what ES5 calls "lexical environments" (runtime - * activations of lexical scopes). This is currently just JSObject, and is - * implemented by Call, Block, With, and DeclEnv objects, among others--but - * environments and objects are really two different concepts. - */ -typedef JSObject Env; - -typedef JSNative Native; -typedef JSParallelNative ParallelNative; -typedef JSThreadSafeNative ThreadSafeNative; -typedef JSPropertyOp PropertyOp; -typedef JSStrictPropertyOp StrictPropertyOp; -typedef JSPropertyDescriptor PropertyDescriptor; - -struct SourceCompressionToken; - -namespace frontend { - -struct BytecodeEmitter; -struct Definition; -class FullParseHandler; -class FunctionBox; -class ObjectBox; -struct Token; -struct TokenPos; -class TokenStream; -class ParseMapPool; -class ParseNode; - -template -class Parser; - -} /* namespace frontend */ - -namespace analyze { - -struct LifetimeVariable; -class LoopAnalysis; -class ScriptAnalysis; -class SlotValue; -class SSAValue; -class SSAUseChain; - -} /* namespace analyze */ - -namespace types { - -class TypeSet; -struct TypeCallsite; -struct TypeObject; -struct TypeCompartment; - -} /* namespace types */ - -typedef JS::Handle HandleShape; -typedef JS::Handle HandleTypeObject; -typedef JS::Handle HandleAtom; -typedef JS::Handle HandlePropertyName; - -typedef JS::MutableHandle MutableHandleShape; -typedef JS::MutableHandle MutableHandleAtom; - -typedef JS::Rooted RootedShape; -typedef JS::Rooted RootedTypeObject; -typedef JS::Rooted RootedAtom; -typedef JS::Rooted RootedPropertyName; - -enum XDRMode { - XDR_ENCODE, - XDR_DECODE -}; - -template -class XDRState; - -class FreeOp; - -struct IdValuePair -{ - jsid id; - Value value; - - IdValuePair() {} - IdValuePair(jsid idArg) - : id(idArg), value(UndefinedValue()) - {} -}; - -} /* namespace js */ - -namespace JSC { - -class ExecutableAllocator; - -} /* namespace JSC */ - -namespace WTF { - -class BumpPointerAllocator; - -} /* namespace WTF */ - -/* "Friend" types used by jscntxt.h and jsdbgapi.h. */ -typedef enum JSTrapStatus { - JSTRAP_ERROR, - JSTRAP_CONTINUE, - JSTRAP_RETURN, - JSTRAP_THROW, - JSTRAP_LIMIT -} JSTrapStatus; - -typedef JSTrapStatus -(* JSTrapHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, - jsval closure); - -typedef JSTrapStatus -(* JSInterruptHook)(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, - void *closure); - -typedef JSTrapStatus -(* JSDebuggerHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, - void *closure); - -typedef JSTrapStatus -(* JSThrowHook)(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, - void *closure); - -typedef JSBool -(* JSWatchPointHandler)(JSContext *cx, JSObject *obj, jsid id, jsval old, - jsval *newp, void *closure); - -/* called just after script creation */ -typedef void -(* JSNewScriptHook)(JSContext *cx, - const char *filename, /* URL of script */ - unsigned lineno, /* first line */ - JSScript *script, - JSFunction *fun, - void *callerdata); - -/* called just before script destruction */ -typedef void -(* JSDestroyScriptHook)(JSFreeOp *fop, - JSScript *script, - void *callerdata); - -typedef void -(* JSSourceHandler)(const char *filename, unsigned lineno, const jschar *str, - size_t length, void **listenerTSData, void *closure); - -/* js::ObjectOps function pointer typedefs. */ - -/* - * A generic type for functions mapping an object to another object, or null - * if an error or exception was thrown on cx. - */ -typedef JSObject * -(* JSObjectOp)(JSContext *cx, JS::Handle obj); - -/* Signature for class initialization ops. */ -typedef JSObject * -(* JSClassInitializerOp)(JSContext *cx, JS::HandleObject obj); - -/* - * Hook that creates an iterator object for a given object. Returns the - * iterator object or null if an error or exception was thrown on cx. - */ -typedef JSObject * -(* JSIteratorOp)(JSContext *cx, JS::HandleObject obj, JSBool keysonly); - - -#endif /* jsprvtd_h */ diff --git a/external/spidermonkey/include/android/jspubtd.h b/external/spidermonkey/include/android/jspubtd.h index 96f5dd8297..4aa922eb84 100644 --- a/external/spidermonkey/include/android/jspubtd.h +++ b/external/spidermonkey/include/android/jspubtd.h @@ -11,72 +11,35 @@ * JS public API typedefs. */ +#include "mozilla/NullPtr.h" #include "mozilla/PodOperations.h" #include "jsprototypes.h" #include "jstypes.h" +#include "js/TypeDecls.h" + #if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) || defined(DEBUG) # define JSGC_TRACK_EXACT_ROOTS #endif namespace JS { -/* - * Allow headers to reference JS::Value without #including the whole jsapi.h. - * Unfortunately, typedefs (hence jsval) cannot be declared. - */ -class Value; +class AutoIdVector; +class CallArgs; template class Rooted; class JS_PUBLIC_API(AutoGCRooter); +class JS_PUBLIC_API(CompileOptions); +class JS_PUBLIC_API(CompartmentOptions); + struct Zone; } /* namespace JS */ -/* - * In release builds, jsid is defined to be an integral type. This - * prevents many bugs from being caught at compile time. E.g.: - * - * jsid id = ... - * if (id == JS_TRUE) // error - * ... - * - * size_t n = id; // error - * - * To catch more errors, jsid is given a struct type in C++ debug builds. - * Struct assignment and (in C++) operator== allow correct code to be mostly - * oblivious to the change. This feature can be explicitly disabled in debug - * builds by defining JS_NO_JSVAL_JSID_STRUCT_TYPES. - */ -// Needed for cocos2d-js -#define JS_NO_JSVAL_JSID_STRUCT_TYPES -# if defined(DEBUG) && !defined(JS_NO_JSVAL_JSID_STRUCT_TYPES) -# define JS_USE_JSID_STRUCT_TYPES -# endif - -# ifdef JS_USE_JSID_STRUCT_TYPES -struct jsid -{ - size_t asBits; - bool operator==(jsid rhs) const { return asBits == rhs.asBits; } - bool operator!=(jsid rhs) const { return asBits != rhs.asBits; } -}; -# define JSID_BITS(id) (id.asBits) -# else /* defined(JS_USE_JSID_STRUCT_TYPES) */ -typedef ptrdiff_t jsid; -# define JSID_BITS(id) (id) -# endif /* defined(JS_USE_JSID_STRUCT_TYPES) */ - -#ifdef WIN32 -typedef wchar_t jschar; -#else -typedef uint16_t jschar; -#endif - /* * Run-time version enumeration. For compile-time version checking, please use * the JS_HAS_* macros in jsversion.h, or use MOZJS_MAJOR_VERSION, @@ -109,7 +72,7 @@ typedef enum JSType { typedef enum JSProtoKey { #define PROTOKEY_AND_INITIALIZER(name,code,init) JSProto_##name = code, JS_FOR_EACH_PROTOTYPE(PROTOKEY_AND_INITIALIZER) -#undef JS_PROTO +#undef PROTOKEY_AND_INITIALIZER JSProto_LIMIT } JSProtoKey; @@ -175,7 +138,6 @@ typedef enum { typedef struct JSClass JSClass; typedef struct JSCompartment JSCompartment; typedef struct JSConstDoubleSpec JSConstDoubleSpec; -typedef struct JSContext JSContext; typedef struct JSCrossCompartmentCall JSCrossCompartmentCall; typedef struct JSErrorReport JSErrorReport; typedef struct JSExceptionState JSExceptionState; @@ -195,20 +157,32 @@ typedef struct JSStructuredCloneWriter JSStructuredCloneWriter; typedef struct JSTracer JSTracer; class JSFlatString; -class JSFunction; -class JSObject; -class JSScript; class JSStableString; // long story -class JSString; #ifdef JS_THREADSAFE -typedef struct PRCallOnceType JSCallOnceType; +typedef struct PRCallOnceType JSCallOnceType; #else -typedef JSBool JSCallOnceType; +typedef bool JSCallOnceType; #endif -typedef JSBool (*JSInitCallback)(void); +typedef bool (*JSInitCallback)(void); + +/* + * Generic trace operation that calls JS_CallTracer on each traceable thing + * stored in data. + */ +typedef void +(* JSTraceDataOp)(JSTracer *trc, void *data); + +namespace js { +namespace gc { +class StoreBuffer; +} +} namespace JS { + +typedef void (*OffThreadCompileCallback)(void *token, void *callbackData); + namespace shadow { struct Runtime @@ -220,15 +194,36 @@ struct Runtime /* Allow inlining of Nursery::isInside. */ uintptr_t gcNurseryStart_; uintptr_t gcNurseryEnd_; + + private: + js::gc::StoreBuffer *gcStoreBufferPtr_; #endif - Runtime() + public: + Runtime( +#ifdef JSGC_GENERATIONAL + js::gc::StoreBuffer *storeBuffer +#endif + ) : needsBarrier_(false) #ifdef JSGC_GENERATIONAL , gcNurseryStart_(0) , gcNurseryEnd_(0) + , gcStoreBufferPtr_(storeBuffer) #endif {} + + bool needsBarrier() const { + return needsBarrier_; + } + +#ifdef JSGC_GENERATIONAL + js::gc::StoreBuffer *gcStoreBufferPtr() { return gcStoreBufferPtr_; } +#endif + + static JS::shadow::Runtime *asShadowRuntime(JSRuntime *rt) { + return reinterpret_cast(rt); + } }; } /* namespace shadow */ @@ -270,6 +265,19 @@ enum ThingRootKind THING_ROOT_LIMIT }; +/* + * 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 +}; + template struct RootKind; @@ -305,13 +313,13 @@ struct ContextFriendFields public: explicit ContextFriendFields(JSRuntime *rt) - : runtime_(rt), compartment_(NULL), zone_(NULL), autoGCRooters(NULL) + : runtime_(rt), compartment_(nullptr), zone_(nullptr), autoGCRooters(nullptr) { #ifdef JSGC_TRACK_EXACT_ROOTS mozilla::PodArrayZero(thingGCRooters); #endif #if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) - skipGCRooters = NULL; + skipGCRooters = nullptr; #endif } @@ -395,7 +403,7 @@ struct PerThreadDataFriendFields #endif /* Limit pointer for checking native stack consumption. */ - uintptr_t nativeStackLimit; + uintptr_t nativeStackLimit[StackKindCount]; static const size_t RuntimeMainThreadOffset = offsetof(RuntimeDummy, mainThread); diff --git a/external/spidermonkey/include/android/jstypes.h b/external/spidermonkey/include/android/jstypes.h index 17f67f70e1..d5b15ccb1d 100644 --- a/external/spidermonkey/include/android/jstypes.h +++ b/external/spidermonkey/include/android/jstypes.h @@ -22,9 +22,16 @@ #define jstypes_h #include "mozilla/Attributes.h" -#include "mozilla/Util.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 @@ -82,10 +89,6 @@ #define JS_NO_FASTCALL #endif -#ifndef JS_INLINE -#define JS_INLINE MOZ_INLINE -#endif - #ifndef JS_ALWAYS_INLINE #define JS_ALWAYS_INLINE MOZ_ALWAYS_INLINE #endif @@ -180,19 +183,6 @@ # error "Implement me" #endif - -/************************************************************************ -** TYPES: JSBool -** DESCRIPTION: -** Use JSBool for variables and parameter types. Use JS_FALSE and JS_TRUE -** for clarity of target type in assignments and actual arguments. Use -** 'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans -** just as you would C int-valued conditions. -************************************************************************/ -typedef int JSBool; -#define JS_TRUE (int)1 -#define JS_FALSE (int)0 - /*********************************************************************** ** MACROS: JS_LIKELY ** JS_UNLIKELY @@ -244,7 +234,11 @@ typedef int JSBool; #define JS_BITS_PER_BYTE 8 #define JS_BITS_PER_BYTE_LOG2 3 -#define JS_BITS_PER_WORD (JS_BITS_PER_BYTE * JS_BYTES_PER_WORD) +#if defined(JS_64BIT) +# define JS_BITS_PER_WORD 64 +#else +# define JS_BITS_PER_WORD 32 +#endif /*********************************************************************** ** MACROS: JS_FUNC_TO_DATA_PTR diff --git a/external/spidermonkey/include/android/jsutil.h b/external/spidermonkey/include/android/jsutil.h deleted file mode 100644 index 4020822be1..0000000000 --- a/external/spidermonkey/include/android/jsutil.h +++ /dev/null @@ -1,385 +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/. */ - -/* - * PR assertion checker. - */ - -#ifndef jsutil_h -#define jsutil_h - -#include "mozilla/Attributes.h" -#include "mozilla/Compiler.h" -#include "mozilla/GuardObjects.h" - -#ifdef USE_ZLIB -#include -#endif - -#include "js/Utility.h" - -/* Forward declarations. */ -struct JSContext; - -static JS_ALWAYS_INLINE void * -js_memcpy(void *dst_, const void *src_, size_t len) -{ - char *dst = (char *) dst_; - const char *src = (const char *) src_; - JS_ASSERT_IF(dst >= src, (size_t) (dst - src) >= len); - JS_ASSERT_IF(src >= dst, (size_t) (src - dst) >= len); - - return memcpy(dst, src, len); -} - -namespace js { - -template -struct AlignmentTestStruct -{ - char c; - T t; -}; - -/* This macro determines the alignment requirements of a type. */ -#define JS_ALIGNMENT_OF(t_) \ - (sizeof(js::AlignmentTestStruct) - sizeof(t_)) - -template -class AlignedPtrAndFlag -{ - uintptr_t bits; - - public: - AlignedPtrAndFlag(T *t, bool aFlag) { - JS_ASSERT((uintptr_t(t) & 1) == 0); - bits = uintptr_t(t) | uintptr_t(aFlag); - } - - T *ptr() const { - return (T *)(bits & ~uintptr_t(1)); - } - - bool flag() const { - return (bits & 1) != 0; - } - - void setPtr(T *t) { - JS_ASSERT((uintptr_t(t) & 1) == 0); - bits = uintptr_t(t) | uintptr_t(flag()); - } - - void setFlag() { - bits |= 1; - } - - void unsetFlag() { - bits &= ~uintptr_t(1); - } - - void set(T *t, bool aFlag) { - JS_ASSERT((uintptr_t(t) & 1) == 0); - bits = uintptr_t(t) | aFlag; - } -}; - -template -static inline void -Reverse(T *beg, T *end) -{ - while (beg != end) { - if (--end == beg) - return; - T tmp = *beg; - *beg = *end; - *end = tmp; - ++beg; - } -} - -template -static inline T * -Find(T *beg, T *end, const T &v) -{ - for (T *p = beg; p != end; ++p) { - if (*p == v) - return p; - } - return end; -} - -template -static inline typename Container::ElementType * -Find(Container &c, const typename Container::ElementType &v) -{ - return Find(c.begin(), c.end(), v); -} - -template -void -ForEach(InputIterT begin, InputIterT end, CallableT f) -{ - for (; begin != end; ++begin) - f(*begin); -} - -template -static inline T -Min(T t1, T t2) -{ - return t1 < t2 ? t1 : t2; -} - -template -static inline T -Max(T t1, T t2) -{ - return t1 > t2 ? t1 : t2; -} - -/* Allows a const variable to be initialized after its declaration. */ -template -static T& -InitConst(const T &t) -{ - return const_cast(t); -} - -template -JS_ALWAYS_INLINE T & -ImplicitCast(U &u) -{ - T &t = u; - return t; -} - -template -class AutoScopedAssign -{ - public: - AutoScopedAssign(T *addr, const T &value - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : addr_(addr), old(*addr_) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - *addr_ = value; - } - - ~AutoScopedAssign() { *addr_ = old; } - - private: - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - T *addr_; - T old; -}; - -template -static inline bool -IsPowerOfTwo(T t) -{ - return t && !(t & (t - 1)); -} - -template -static inline U -ComputeByteAlignment(T bytes, U alignment) -{ - JS_ASSERT(IsPowerOfTwo(alignment)); - return (alignment - (bytes % alignment)) % alignment; -} - -template -static inline T -AlignBytes(T bytes, U alignment) -{ - return bytes + ComputeByteAlignment(bytes, alignment); -} - -JS_ALWAYS_INLINE static size_t -UnsignedPtrDiff(const void *bigger, const void *smaller) -{ - return size_t(bigger) - size_t(smaller); -} - -/*****************************************************************************/ - -/* A bit array is an array of bits represented by an array of words (size_t). */ - -static inline unsigned -NumWordsForBitArrayOfLength(size_t length) -{ - return (length + (JS_BITS_PER_WORD - 1)) / JS_BITS_PER_WORD; -} - -static inline unsigned -BitArrayIndexToWordIndex(size_t length, size_t bitIndex) -{ - unsigned wordIndex = bitIndex / JS_BITS_PER_WORD; - JS_ASSERT(wordIndex < length); - return wordIndex; -} - -static inline size_t -BitArrayIndexToWordMask(size_t i) -{ - return size_t(1) << (i % JS_BITS_PER_WORD); -} - -static inline bool -IsBitArrayElementSet(size_t *array, size_t length, size_t i) -{ - return array[BitArrayIndexToWordIndex(length, i)] & BitArrayIndexToWordMask(i); -} - -static inline bool -IsAnyBitArrayElementSet(size_t *array, size_t length) -{ - unsigned numWords = NumWordsForBitArrayOfLength(length); - for (unsigned i = 0; i < numWords; ++i) { - if (array[i]) - return true; - } - return false; -} - -static inline void -SetBitArrayElement(size_t *array, size_t length, size_t i) -{ - array[BitArrayIndexToWordIndex(length, i)] |= BitArrayIndexToWordMask(i); -} - -static inline void -ClearBitArrayElement(size_t *array, size_t length, size_t i) -{ - array[BitArrayIndexToWordIndex(length, i)] &= ~BitArrayIndexToWordMask(i); -} - -static inline void -ClearAllBitArrayElements(size_t *array, size_t length) -{ - for (unsigned i = 0; i < length; ++i) - array[i] = 0; -} - -#ifdef USE_ZLIB -class Compressor -{ - /* Number of bytes we should hand to zlib each compressMore() call. */ - static const size_t CHUNKSIZE = 2048; - z_stream zs; - const unsigned char *inp; - size_t inplen; - size_t outbytes; - - public: - enum Status { - MOREOUTPUT, - DONE, - CONTINUE, - OOM - }; - - Compressor(const unsigned char *inp, size_t inplen); - ~Compressor(); - bool init(); - void setOutput(unsigned char *out, size_t outlen); - size_t outWritten() const { return outbytes; } - /* Compress some of the input. Return true if it should be called again. */ - Status compressMore(); -}; - -/* - * Decompress a string. The caller must know the length of the output and - * allocate |out| to a string of that length. - */ -bool DecompressString(const unsigned char *inp, size_t inplen, - unsigned char *out, size_t outlen); -#endif - -} /* namespace js */ - -/* Crash diagnostics */ -#ifdef DEBUG -# define JS_CRASH_DIAGNOSTICS 1 -#endif -#ifdef JS_CRASH_DIAGNOSTICS -# define JS_POISON(p, val, size) memset((p), (val), (size)) -#else -# define JS_POISON(p, val, size) ((void) 0) -#endif - -/* Basic stats */ -#ifdef DEBUG -# define JS_BASIC_STATS 1 -#endif -#ifdef JS_BASIC_STATS -# include -typedef struct JSBasicStats { - uint32_t num; - uint32_t max; - double sum; - double sqsum; - uint32_t logscale; /* logarithmic scale: 0 (linear), 2, 10 */ - uint32_t hist[11]; -} JSBasicStats; -# define JS_INIT_STATIC_BASIC_STATS {0,0,0,0,0,{0,0,0,0,0,0,0,0,0,0,0}} -# define JS_BASIC_STATS_INIT(bs) memset((bs), 0, sizeof(JSBasicStats)) -# define JS_BASIC_STATS_ACCUM(bs,val) \ - JS_BasicStatsAccum(bs, val) -# define JS_MeanAndStdDevBS(bs,sigma) \ - JS_MeanAndStdDev((bs)->num, (bs)->sum, (bs)->sqsum, sigma) -extern void -JS_BasicStatsAccum(JSBasicStats *bs, uint32_t val); -extern double -JS_MeanAndStdDev(uint32_t num, double sum, double sqsum, double *sigma); -extern void -JS_DumpBasicStats(JSBasicStats *bs, const char *title, FILE *fp); -extern void -JS_DumpHistogram(JSBasicStats *bs, FILE *fp); -#else -# define JS_BASIC_STATS_ACCUM(bs,val) -#endif - -/* A jsbitmap_t is a long integer that can be used for bitmaps. */ -typedef size_t jsbitmap; -#define JS_TEST_BIT(_map,_bit) ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] & \ - ((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1)))) -#define JS_SET_BIT(_map,_bit) ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] |= \ - ((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1)))) -#define JS_CLEAR_BIT(_map,_bit) ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] &= \ - ~((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1)))) - -/* Wrapper for various macros to stop warnings coming from their expansions. */ -#if defined(__clang__) -# define JS_SILENCE_UNUSED_VALUE_IN_EXPR(expr) \ - JS_BEGIN_MACRO \ - _Pragma("clang diagnostic push") \ - /* If these _Pragmas cause warnings for you, try disabling ccache. */ \ - _Pragma("clang diagnostic ignored \"-Wunused-value\"") \ - { expr; } \ - _Pragma("clang diagnostic pop") \ - JS_END_MACRO -#elif MOZ_IS_GCC - -#if MOZ_GCC_VERSION_AT_LEAST(4, 6, 0) -# define JS_SILENCE_UNUSED_VALUE_IN_EXPR(expr) \ - JS_BEGIN_MACRO \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wunused-but-set-variable\"") \ - expr; \ - _Pragma("GCC diagnostic pop") \ - JS_END_MACRO -#endif -#endif - -#if !defined(JS_SILENCE_UNUSED_VALUE_IN_EXPR) -# define JS_SILENCE_UNUSED_VALUE_IN_EXPR(expr) \ - JS_BEGIN_MACRO \ - expr; \ - JS_END_MACRO -#endif - -#endif /* jsutil_h */ diff --git a/external/spidermonkey/include/android/jsversion.h b/external/spidermonkey/include/android/jsversion.h index 1780616a32..827a56981d 100644 --- a/external/spidermonkey/include/android/jsversion.h +++ b/external/spidermonkey/include/android/jsversion.h @@ -7,19 +7,6 @@ #ifndef jsversion_h #define jsversion_h -/* - * Deprecated JS_VERSION handler. - */ -#ifdef JS_VERSION -# if JS_VERSION == 185 -# warning "JS_VERSION defined but unsupported (legacy)" -# elif JS_VERSION < 185 -# error "Unsupported JS_VERSION" -# else -# error "Unknown JS_VERSION" -# endif -#endif - /* * JS Capability Macros. */ @@ -52,15 +39,15 @@ * Feature for Object.prototype.__{define,lookup}{G,S}etter__ legacy support; * support likely to be made opt-in at some future time. */ -#define OLD_GETTER_SETTER_METHODS 1 +#define JS_OLD_GETTER_SETTER_METHODS 1 /* A kill-switch for bug 586842. Embedders shouldn't touch this! */ -#define USE_NEW_OBJECT_REPRESENTATION 0 +#define JS_USE_NEW_OBJECT_REPRESENTATION 0 -#if USE_NEW_OBJECT_REPRESENTATION -# define NEW_OBJECT_REPRESENTATION_ONLY() ((void)0) +#if JS_USE_NEW_OBJECT_REPRESENTATION +# define JS_NEW_OBJECT_REPRESENTATION_ONLY() ((void)0) #else -# define NEW_OBJECT_REPRESENTATION_ONLY() \ +# define JS_NEW_OBJECT_REPRESENTATION_ONLY() \ MOZ_ASSUME_UNREACHABLE("don't call this! to be used in the new object representation") #endif diff --git a/external/spidermonkey/include/android/jswrapper.h b/external/spidermonkey/include/android/jswrapper.h index f78df7db60..938db73ec8 100644 --- a/external/spidermonkey/include/android/jswrapper.h +++ b/external/spidermonkey/include/android/jswrapper.h @@ -9,7 +9,6 @@ #include "mozilla/Attributes.h" -#include "jsapi.h" #include "jsproxy.h" namespace js { @@ -38,6 +37,9 @@ class JS_FRIEND_API(Wrapper) : public DirectProxyHandler LAST_USED_FLAG = CROSS_COMPARTMENT }; + virtual bool defaultValue(JSContext *cx, HandleObject obj, JSType hint, + MutableHandleValue vp) MOZ_OVERRIDE; + /* * Wrappers can explicitly specify that they are unsafe to unwrap from a * security perspective (as is the case for SecurityWrappers). If a wrapper @@ -64,6 +66,8 @@ class JS_FRIEND_API(Wrapper) : public DirectProxyHandler virtual ~Wrapper(); + virtual bool finalizeInBackground(Value priv) MOZ_OVERRIDE; + static Wrapper singleton; static Wrapper singletonWithPrototype; }; @@ -76,16 +80,16 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper virtual ~CrossCompartmentWrapper(); - virtual bool finalizeInBackground(Value priv) MOZ_OVERRIDE; - /* ES5 Harmony fundamental wrapper traps. */ virtual bool preventExtensions(JSContext *cx, HandleObject wrapper) MOZ_OVERRIDE; virtual bool getPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id, - PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE; + MutableHandle desc, + unsigned flags) MOZ_OVERRIDE; virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id, - PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE; + MutableHandle desc, + unsigned flags) MOZ_OVERRIDE; virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id, - PropertyDescriptor *desc) MOZ_OVERRIDE; + MutableHandle desc) MOZ_OVERRIDE; virtual bool getOwnPropertyNames(JSContext *cx, HandleObject wrapper, AutoIdVector &props) MOZ_OVERRIDE; virtual bool delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) MOZ_OVERRIDE; @@ -149,7 +153,7 @@ class JS_FRIEND_API(SecurityWrapper) : public Base JSContext *cx) MOZ_OVERRIDE; virtual bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g) MOZ_OVERRIDE; virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id, - PropertyDescriptor *desc) MOZ_OVERRIDE; + MutableHandle desc) MOZ_OVERRIDE; /* * Allow our subclasses to select the superclass behavior they want without @@ -165,18 +169,21 @@ typedef SecurityWrapper CrossCompartmentSecurityWrapper class JS_FRIEND_API(DeadObjectProxy) : public BaseProxyHandler { public: - static int sDeadObjectFamily; + // This variable exists solely to provide a unique address for use as an identifier. + static const char sDeadObjectFamily; explicit DeadObjectProxy(); /* ES5 Harmony fundamental wrapper traps. */ virtual bool preventExtensions(JSContext *cx, HandleObject proxy) MOZ_OVERRIDE; virtual bool getPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id, - PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE; + MutableHandle desc, + unsigned flags) MOZ_OVERRIDE; virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id, - PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE; + MutableHandle desc, + unsigned flags) MOZ_OVERRIDE; virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id, - PropertyDescriptor *desc) MOZ_OVERRIDE; + MutableHandle desc) MOZ_OVERRIDE; virtual bool getOwnPropertyNames(JSContext *cx, HandleObject wrapper, AutoIdVector &props) MOZ_OVERRIDE; virtual bool delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) MOZ_OVERRIDE; @@ -213,7 +220,8 @@ TransparentObjectWrapper(JSContext *cx, HandleObject existing, HandleObject obj, // Proxy family for wrappers. Public so that IsWrapper() can be fully inlined by // jsfriendapi users. -extern JS_FRIEND_DATA(int) sWrapperFamily; +// This variable exists solely to provide a unique address for use as an identifier. +extern JS_FRIEND_DATA(const char) sWrapperFamily; inline bool IsWrapper(JSObject *obj) @@ -226,7 +234,7 @@ IsWrapper(JSObject *obj) // previously wrapped. Otherwise, this returns the first object for // which JSObject::isWrapper returns false. JS_FRIEND_API(JSObject *) -UncheckedUnwrap(JSObject *obj, bool stopAtOuter = true, unsigned *flagsp = NULL); +UncheckedUnwrap(JSObject *obj, bool stopAtOuter = 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. Since checked @@ -247,7 +255,8 @@ bool IsDeadProxyObject(JSObject *obj); JSObject * -NewDeadProxyObject(JSContext *cx, JSObject *parent); +NewDeadProxyObject(JSContext *cx, JSObject *parent, + const ProxyOptions &options = ProxyOptions()); void NukeCrossCompartmentWrapper(JSContext *cx, JSObject *wrapper); diff --git a/external/spidermonkey/include/android/mozilla/Alignment.h b/external/spidermonkey/include/android/mozilla/Alignment.h new file mode 100644 index 0000000000..29599d0ef1 --- /dev/null +++ b/external/spidermonkey/include/android/mozilla/Alignment.h @@ -0,0 +1,137 @@ +/* -*- 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 +#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 c; + T t; + }; + + 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 bytes[Nbytes]; + uint64_t _; + } u; + + const void* addr() const { return u.bytes; } + void* addr() { return u.bytes; } +}; + +template +struct AlignedStorage2 +{ + union U { + char bytes[sizeof(T)]; + uint64_t _; + } u; + + const T* addr() const { return reinterpret_cast(u.bytes); } + T* addr() { return static_cast(static_cast(u.bytes)); } +}; + +} /* namespace mozilla */ + +#endif /* mozilla_Alignment_h */ diff --git a/external/spidermonkey/include/android/mozilla/Assertions.h b/external/spidermonkey/include/android/mozilla/Assertions.h index 00b7037802..f902199051 100644 --- a/external/spidermonkey/include/android/mozilla/Assertions.h +++ b/external/spidermonkey/include/android/mozilla/Assertions.h @@ -180,7 +180,7 @@ __declspec(noreturn) __inline void MOZ_NoReturn() {} # ifdef __cplusplus # define MOZ_REALLY_CRASH() \ do { \ - __debugbreak(); \ + ::__debugbreak(); \ *((volatile int*) NULL) = 123; \ ::TerminateProcess(::GetCurrentProcess(), 3); \ ::MOZ_NoReturn(); \ diff --git a/external/spidermonkey/include/android/mozilla/Atomics.h b/external/spidermonkey/include/android/mozilla/Atomics.h index f876683c3e..31e6a7daec 100644 --- a/external/spidermonkey/include/android/mozilla/Atomics.h +++ b/external/spidermonkey/include/android/mozilla/Atomics.h @@ -17,6 +17,8 @@ #define mozilla_Atomics_h #include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" +#include "mozilla/Compiler.h" #include "mozilla/TypeTraits.h" #include @@ -26,34 +28,16 @@ * does not have . So be sure to check for support * along with C++0x support. */ -#if defined(__clang__) +#if defined(__clang__) || defined(__GNUC__) /* - * clang doesn't like libstdc++'s version of before GCC 4.7, - * due to the loose typing of the __sync_* family of functions done by - * GCC. We do not have a particularly good way to detect this sort of - * case at this point, so just assume that if we're on a Linux system, - * we can't use the system's . - * - * OpenBSD uses an old libstdc++ 4.2.1 and thus doesnt have . + * 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++. */ -# if !defined(__linux__) && !defined(__OpenBSD__) && \ - (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && \ - __has_include() +# if MOZ_USING_LIBSTDCXX && MOZ_LIBSTDCXX_VERSION_AT_LEAST(4, 7, 0) # define MOZ_HAVE_CXX11_ATOMICS -# endif -/* - * Android uses a different C++ standard library that does not provide - * support for . - * - * GCC 4.5.x and 4.6.x's unspecialized std::atomic template doesn't include - * inline definitions for the functions declared therein. This oversight - * leads to linking errors when using atomic enums. We therefore require - * GCC 4.7 or higher. - */ -#elif defined(__GNUC__) && !defined(__ANDROID__) -# include "mozilla/Compiler.h" -# if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) && \ - MOZ_GCC_VERSION_AT_LEAST(4, 7, 0) +# elif MOZ_USING_LIBCXX # define MOZ_HAVE_CXX11_ATOMICS # endif #elif defined(_MSC_VER) && _MSC_VER >= 1700 @@ -845,8 +829,8 @@ class AtomicBase typename Intrinsics::ValueType mValue; public: - AtomicBase() : mValue() {} - AtomicBase(T aInit) { Intrinsics::store(mValue, aInit); } + MOZ_CONSTEXPR AtomicBase() : mValue() {} + MOZ_CONSTEXPR AtomicBase(T aInit) : mValue(aInit) {} operator T() const { return Intrinsics::load(mValue); } @@ -889,8 +873,8 @@ class AtomicBaseIncDec : public AtomicBase typedef typename detail::AtomicBase Base; public: - AtomicBaseIncDec() : Base() {} - AtomicBaseIncDec(T aInit) : Base(aInit) {} + MOZ_CONSTEXPR AtomicBaseIncDec() : Base() {} + MOZ_CONSTEXPR AtomicBaseIncDec(T aInit) : Base(aInit) {} using Base::operator=; @@ -943,8 +927,8 @@ class Atomic::value>::Type> typedef typename detail::AtomicBaseIncDec Base; public: - Atomic() : Base() {} - Atomic(T aInit) : Base(aInit) {} + MOZ_CONSTEXPR Atomic() : Base() {} + MOZ_CONSTEXPR Atomic(T aInit) : Base(aInit) {} using Base::operator=; @@ -972,8 +956,8 @@ class Atomic : public detail::AtomicBaseIncDec typedef typename detail::AtomicBaseIncDec Base; public: - Atomic() : Base() {} - Atomic(T* aInit) : Base(aInit) {} + MOZ_CONSTEXPR Atomic() : Base() {} + MOZ_CONSTEXPR Atomic(T* aInit) : Base(aInit) {} using Base::operator=; @@ -1000,8 +984,8 @@ class Atomic::value>::Type> typedef typename detail::AtomicBase Base; public: - Atomic() : Base() {} - Atomic(T aInit) : Base(aInit) {} + MOZ_CONSTEXPR Atomic() : Base() {} + MOZ_CONSTEXPR Atomic(T aInit) : Base(aInit) {} using Base::operator=; diff --git a/external/spidermonkey/include/android/mozilla/Attributes.h b/external/spidermonkey/include/android/mozilla/Attributes.h index 6ea9776fbf..0786cb2fe5 100644 --- a/external/spidermonkey/include/android/mozilla/Attributes.h +++ b/external/spidermonkey/include/android/mozilla/Attributes.h @@ -11,26 +11,10 @@ #include "mozilla/Compiler.h" -/* - * MOZ_INLINE is a macro which expands to tell the compiler that the method - * decorated with it should be inlined. This macro is usable from C and C++ - * code, even though C89 does not support the |inline| keyword. The compiler - * may ignore this directive if it chooses. - */ -#if defined(__cplusplus) -# define MOZ_INLINE inline -#elif defined(_MSC_VER) -# define MOZ_INLINE __inline -#elif defined(__GNUC__) -# define MOZ_INLINE __inline__ -#else -# define MOZ_INLINE inline -#endif - /* * 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 MOZ_INLINE hint: + * 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). * @@ -40,15 +24,17 @@ #if defined(_MSC_VER) # define MOZ_ALWAYS_INLINE_EVEN_DEBUG __forceinline #elif defined(__GNUC__) -# define MOZ_ALWAYS_INLINE_EVEN_DEBUG __attribute__((always_inline)) MOZ_INLINE +# define MOZ_ALWAYS_INLINE_EVEN_DEBUG __attribute__((always_inline)) inline #else -# define MOZ_ALWAYS_INLINE_EVEN_DEBUG MOZ_INLINE +# define MOZ_ALWAYS_INLINE_EVEN_DEBUG inline #endif -#if defined(DEBUG) -# define MOZ_ALWAYS_INLINE MOZ_INLINE -#else +#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 /* @@ -170,12 +156,31 @@ * Furthermore, it will prevent the compiler from inlining the function because * inlining currently breaks the blacklisting mechanism of AddressSanitizer. */ -#if defined(MOZ_ASAN) -# define MOZ_ASAN_BLACKLIST MOZ_NEVER_INLINE __attribute__((no_address_safety_analysis)) -# else -# define MOZ_ASAN_BLACKLIST +#if defined(__has_feature) +# if __has_feature(address_sanitizer) +# define MOZ_ASAN_BLACKLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_address)) +# else +# define MOZ_ASAN_BLACKLIST /* nothing */ +# endif +#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 #ifdef __cplusplus diff --git a/external/spidermonkey/include/android/mozilla/Char16.h b/external/spidermonkey/include/android/mozilla/Char16.h index e4b184f950..fb182dfde2 100644 --- a/external/spidermonkey/include/android/mozilla/Char16.h +++ b/external/spidermonkey/include/android/mozilla/Char16.h @@ -9,16 +9,11 @@ #ifndef mozilla_Char16_h #define mozilla_Char16_h -#include "mozilla/Assertions.h" - /* * C11 and C++11 introduce a char16_t type and support for UTF-16 string and * character literals. C++11's char16_t is a distinct builtin type. C11's * char16_t is a typedef for uint_least16_t. Technically, char16_t is a 16-bit * code unit of a Unicode code point, not a "character". - * - * For now, Char16.h only supports C++ because we don't want mix different C - * and C++ definitions of char16_t in the same code base. */ #ifdef _MSC_VER @@ -26,20 +21,52 @@ * C++11 says char16_t is a distinct builtin type, but Windows's yvals.h * typedefs char16_t as an unsigned short. We would like to alias char16_t * to Windows's 16-bit wchar_t so we can declare UTF-16 literals as constant - * expressions (and pass char16_t pointers to Windows APIs). We #define our - * char16_t as a macro to override yval.h's typedef of the same name. + * expressions (and pass char16_t pointers to Windows APIs). We #define + * _CHAR16T here in order to prevent yvals.h from overriding our char16_t + * typedefs, which we set to wchar_t for C++ code and to unsigned short for + * C code. + * + * In addition, #defining _CHAR16T will prevent yvals.h from defining a + * char32_t type, so we have to undo that damage here and provide our own, + * which is identical to the yvals.h type. */ # define MOZ_UTF16_HELPER(s) L##s -# include -# define char16_t wchar_t +# define _CHAR16T +# ifdef __cplusplus + typedef wchar_t char16_t; +# else + typedef unsigned short char16_t; +# endif + typedef unsigned int char32_t; #elif defined(__cplusplus) && \ (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)) /* C++11 has a builtin char16_t type. */ # define MOZ_UTF16_HELPER(s) u##s + /** + * This macro is used to distinguish when char16_t would be a distinct + * typedef from wchar_t. + */ +# define MOZ_CHAR16_IS_NOT_WCHAR +#elif !defined(__cplusplus) +# if defined(WIN32) +# include + typedef wchar_t char16_t; +# else + /** + * We can't use the stdint.h uint16_t type here because including + * stdint.h will break building some of our C libraries, such as + * sqlite. + */ + typedef unsigned short char16_t; +# endif #else # error "Char16.h requires C++11 (or something like it) for UTF-16 support." #endif +/* This is a temporary hack until bug 927728 is fixed. */ +#define __PRUNICHAR__ +typedef char16_t PRUnichar; + /* * Macro arguments used in concatenation or stringification won't be expanded. * Therefore, in order for |MOZ_UTF16(FOO)| to work as expected (which is to @@ -50,8 +77,12 @@ */ #define MOZ_UTF16(s) MOZ_UTF16_HELPER(s) +#if defined(__cplusplus) && \ + (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)) 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(MOZ_UTF16('A')) == 2, "Is char literal 16 bits?"); static_assert(sizeof(MOZ_UTF16("")[0]) == 2, "Is string char 16 bits?"); +#endif #endif /* mozilla_Char16_h */ diff --git a/external/spidermonkey/include/android/mozilla/Compiler.h b/external/spidermonkey/include/android/mozilla/Compiler.h index d1ef1e79aa..fd5c98c98d 100644 --- a/external/spidermonkey/include/android/mozilla/Compiler.h +++ b/external/spidermonkey/include/android/mozilla/Compiler.h @@ -29,4 +29,77 @@ #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/external/spidermonkey/include/android/mozilla/Compression.h b/external/spidermonkey/include/android/mozilla/Compression.h new file mode 100644 index 0000000000..da77fa895f --- /dev/null +++ b/external/spidermonkey/include/android/mozilla/Compression.h @@ -0,0 +1,116 @@ +/* -*- 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/. */ + +/* Various simple compression/decompression functions. */ + +#ifndef mozilla_Compression_h_ +#define mozilla_Compression_h_ + +#include "mozilla/Types.h" +#include "mozilla/Assertions.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 'inputSize' bytes from 'source' into 'dest'. + * 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 LZ4_compressBound() + * + * @param inputSize is the input size. Max supported value is ~1.9GB + * @param return the number of bytes written in buffer dest + */ + static MFBT_API size_t compress(const char* source, size_t inputSize, char* dest); + + /** + * Compress 'inputSize' bytes from 'source' into an output buffer + * 'dest' of maximum size 'maxOutputSize'. If it cannot achieve it, + * compression will stop, and result of the function will be zero, + * 'dest' 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 inputSize is the input size. Max supported value is ~1.9GB + * @param maxOutputSize is the size of the destination buffer (which must be already allocated) + * @return the number of bytes written in buffer 'dest' + or 0 if the compression fails + */ + static MFBT_API size_t compressLimitedOutput(const char* source, size_t inputSize, char* dest, + size_t maxOutputSize); + + /** + * If the source stream is malformed, the function will stop decoding + * and return a negative result, indicating the byte position of the + * faulty instruction + * + * This function never writes outside of provided buffers, and never + * modifies input buffer. + * + * note : destination buffer must be already allocated. + * its size must be a minimum of 'outputSize' bytes. + * @param outputSize is the output size, therefore the original size + * @return the number of bytes read in the source buffer + */ + static MFBT_API bool decompress(const char* source, char* dest, size_t outputSize); + + /** + * If the source stream is malformed, the function will stop decoding + * and return false. + * + * This function never writes beyond dest + maxOutputSize, 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 maxOutputSize + * + * @param inputSize is the length of the input compressed data + * @param maxOutputSize is the size of the destination buffer (which must be already allocated) + * @param outputSize the actual number of bytes decoded in the destination buffer (necessarily <= maxOutputSize) + + */ + static MFBT_API bool decompress(const char* source, size_t inputSize, char* dest, + size_t maxOutputSize, size_t *outputSize); + + /* + 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 inputSize is the input size. Max supported value is ~1.9GB + @return maximum output size in a "worst case" scenario + */ + static MFBT_API size_t maxCompressedSize(size_t inputSize) + { + size_t max = ((inputSize) + ((inputSize)/255) + 16); + MOZ_ASSERT(max > inputSize); + return max; + } + +}; + +} /* namespace Compression */ +} /* namespace mozilla */ + +#endif /* mozilla_Compression_h_ */ diff --git a/external/spidermonkey/include/android/mozilla/Endian.h b/external/spidermonkey/include/android/mozilla/Endian.h index dc6d11d3ba..cb6bd27c05 100644 --- a/external/spidermonkey/include/android/mozilla/Endian.h +++ b/external/spidermonkey/include/android/mozilla/Endian.h @@ -238,9 +238,9 @@ class EndianUtils { DebugOnly byteDestPtr = static_cast(dest); DebugOnly byteSrcPtr = static_cast(src); - MOZ_ASSERT((byteDestPtr < byteSrcPtr && + MOZ_ASSERT((byteDestPtr <= byteSrcPtr && byteDestPtr + count <= byteSrcPtr) || - (byteSrcPtr < byteDestPtr && + (byteSrcPtr <= byteDestPtr && byteSrcPtr + count <= byteDestPtr)); } diff --git a/external/spidermonkey/include/android/mozilla/FloatingPoint.h b/external/spidermonkey/include/android/mozilla/FloatingPoint.h index d80f6a7234..eff26b4bb8 100644 --- a/external/spidermonkey/include/android/mozilla/FloatingPoint.h +++ b/external/spidermonkey/include/android/mozilla/FloatingPoint.h @@ -12,6 +12,7 @@ #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/Casting.h" +#include "mozilla/Types.h" #include @@ -58,6 +59,30 @@ static_assert((DoubleSignBit | DoubleExponentBits | DoubleSignificandBits) == ~uint64_t(0), "all bits accounted for"); +/* + * Ditto for |float| that must be a 32-bit double format number type, compatible + * with the IEEE-754 standard. + */ +static_assert(sizeof(float) == sizeof(uint32_t), "float must be 32bits"); + +const unsigned FloatExponentBias = 127; +const unsigned FloatExponentShift = 23; + +const uint32_t FloatSignBit = 0x80000000UL; +const uint32_t FloatExponentBits = 0x7F800000UL; +const uint32_t FloatSignificandBits = 0x007FFFFFUL; + +static_assert((FloatSignBit & FloatExponentBits) == 0, + "sign bit doesn't overlap exponent bits"); +static_assert((FloatSignBit & FloatSignificandBits) == 0, + "sign bit doesn't overlap significand bits"); +static_assert((FloatExponentBits & FloatSignificandBits) == 0, + "exponent bits don't overlap significand bits"); + +static_assert((FloatSignBit | FloatExponentBits | FloatSignificandBits) == + ~uint32_t(0), + "all bits accounted for"); + /** Determines whether a double is NaN. */ static MOZ_ALWAYS_INLINE bool IsNaN(double d) @@ -115,7 +140,12 @@ IsNegativeZero(double d) return bits == DoubleSignBit; } -/** Returns the exponent portion of the double. */ +/** + * Returns the exponent portion of the double. + * + * Zero is not special-cased, so ExponentComponent(0.0) is + * -int_fast16_t(DoubleExponentBias). + */ static MOZ_ALWAYS_INLINE int_fast16_t ExponentComponent(double d) { @@ -190,7 +220,13 @@ DoubleIsInt32(double d, int32_t* i) static MOZ_ALWAYS_INLINE double UnspecifiedNaN() { - return SpecificNaN(0, 0xfffffffffffffULL); + /* + * 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). + */ + return SpecificNaN(1, 0xfffffffffffffULL); } /** @@ -206,6 +242,46 @@ DoublesAreIdentical(double d1, double d2) return BitwiseCast(d1) == BitwiseCast(d2); } +/** Determines whether a float is NaN. */ +static MOZ_ALWAYS_INLINE bool +IsFloatNaN(float f) +{ + /* + * A float is NaN if all exponent bits are 1 and the significand contains at + * least one non-zero bit. + */ + uint32_t bits = BitwiseCast(f); + return (bits & FloatExponentBits) == FloatExponentBits && + (bits & FloatSignificandBits) != 0; +} + +/** Constructs a NaN value with the specified sign bit and significand bits. */ +static MOZ_ALWAYS_INLINE float +SpecificFloatNaN(int signbit, uint32_t significand) +{ + MOZ_ASSERT(signbit == 0 || signbit == 1); + MOZ_ASSERT((significand & ~FloatSignificandBits) == 0); + MOZ_ASSERT(significand & FloatSignificandBits); + + float f = BitwiseCast((signbit ? FloatSignBit : 0) | + FloatExponentBits | + significand); + MOZ_ASSERT(IsFloatNaN(f)); + return f; +} + +/** + * 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_WARN_UNUSED_RESULT +extern MFBT_API bool +IsFloat32Representable(double x); + } /* namespace mozilla */ #endif /* mozilla_FloatingPoint_h */ diff --git a/external/spidermonkey/include/android/mozilla/HashFunctions.h b/external/spidermonkey/include/android/mozilla/HashFunctions.h index 6d0d24e7b1..b228955ce5 100644 --- a/external/spidermonkey/include/android/mozilla/HashFunctions.h +++ b/external/spidermonkey/include/android/mozilla/HashFunctions.h @@ -48,6 +48,7 @@ #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/Char16.h" #include "mozilla/Types.h" #include @@ -326,6 +327,22 @@ HashString(const uint16_t* str, size_t length) return detail::HashKnownLength(str, length); } +#ifdef MOZ_CHAR16_IS_NOT_WCHAR +MOZ_WARN_UNUSED_RESULT +inline uint32_t +HashString(const char16_t* str) +{ + return detail::HashUntilZero(str); +} + +MOZ_WARN_UNUSED_RESULT +inline uint32_t +HashString(const char16_t* str, size_t length) +{ + return detail::HashKnownLength(str, length); +} +#endif + /* * On Windows, wchar_t (PRUnichar) is not the same as uint16_t, even though it's * the same width! diff --git a/external/spidermonkey/include/android/mozilla/IntegerPrintfMacros.h b/external/spidermonkey/include/android/mozilla/IntegerPrintfMacros.h new file mode 100644 index 0000000000..1ae60d618e --- /dev/null +++ b/external/spidermonkey/include/android/mozilla/IntegerPrintfMacros.h @@ -0,0 +1,40 @@ +/* -*- 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/. */ + +/* Implements the C99 interface, minus the SCN* format macros. */ + +#ifndef mozilla_IntegerPrintfMacros_h_ +#define mozilla_IntegerPrintfMacros_h_ + +/* + * MSVC++ doesn't include , even in versions shipping , so + * we have to reimplement it there. Note: #includes . + * + * Note that this header DOES NOT implement 's scanf macros. MSVC's + * scanf doesn't have sufficient format specifier support to implement them + * (specifically, to implement scanning into an 8-bit location). + * + * http://stackoverflow.com/questions/3036396/scanfd-char-char-as-int-format-string + * + * Moreover, 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 + * + * This header will sometimes provide SCN* macros, by dint of being implemented + * using . But for these reasons, *never* use them! + */ + +#if defined(MOZ_CUSTOM_INTTYPES_H) +# include MOZ_CUSTOM_INTTYPES_H +#elif defined(_MSC_VER) +# include "mozilla/MSIntTypes.h" +#else +# include +#endif + +#endif /* mozilla_IntegerPrintfMacros_h_ */ diff --git a/external/spidermonkey/include/android/mozilla/LinkedList.h b/external/spidermonkey/include/android/mozilla/LinkedList.h index c29760b3e7..f35e7d56ab 100644 --- a/external/spidermonkey/include/android/mozilla/LinkedList.h +++ b/external/spidermonkey/include/android/mozilla/LinkedList.h @@ -58,6 +58,7 @@ #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/Move.h" #include "mozilla/NullPtr.h" #ifdef __cplusplus @@ -116,6 +117,36 @@ class LinkedListElement isSentinel(false) { } + LinkedListElement(LinkedListElement&& other) + : isSentinel(other.isSentinel) + { + if (!other.isInList()) { + next = this; + prev = this; + return; + } + + MOZ_ASSERT(other.next->prev == &other); + MOZ_ASSERT(other.prev->next == &other); + + /* + * Initialize |this| with |other|'s prev/next pointers, and adjust those + * element to point to this one. + */ + next = other.next; + prev = other.prev; + + next->prev = this; + prev->next = this; + + /* + * Adjust |other| so it doesn't think it's in a list. This makes it + * safely destructable. + */ + other.next = &other; + other.prev = &other; + } + ~LinkedListElement() { if (!isSentinel && isInList()) remove(); @@ -148,8 +179,8 @@ class LinkedListElement * linked list when you call setNext(); otherwise, this method will assert. */ void setNext(T* elem) { - MOZ_ASSERT(isInList()); - setNextUnsafe(elem); + MOZ_ASSERT(isInList()); + setNextUnsafe(elem); } /* @@ -252,8 +283,8 @@ class LinkedListElement } private: - LinkedListElement& operator=(const LinkedList& other) MOZ_DELETE; - LinkedListElement(const LinkedList& other) MOZ_DELETE; + LinkedListElement& operator=(const LinkedListElement& other) MOZ_DELETE; + LinkedListElement(const LinkedListElement& other) MOZ_DELETE; }; template @@ -265,6 +296,10 @@ class LinkedList public: LinkedList() : sentinel(LinkedListElement::NODE_KIND_SENTINEL) { } + LinkedList(LinkedList&& other) + : sentinel(mozilla::Move(other.sentinel)) + { } + ~LinkedList() { MOZ_ASSERT(isEmpty()); } @@ -361,7 +396,7 @@ class LinkedList for (slow = sentinel.next, fast1 = sentinel.next->next, fast2 = sentinel.next->next->next; - slow != sentinel && fast1 != sentinel && fast2 != sentinel; + slow != &sentinel && fast1 != &sentinel && fast2 != &sentinel; slow = slow->next, fast1 = fast2->next, fast2 = fast1->next) { MOZ_ASSERT(slow != fast1); @@ -372,7 +407,7 @@ class LinkedList for (slow = sentinel.prev, fast1 = sentinel.prev->prev, fast2 = sentinel.prev->prev->prev; - slow != sentinel && fast1 != sentinel && fast2 != sentinel; + slow != &sentinel && fast1 != &sentinel && fast2 != &sentinel; slow = slow->prev, fast1 = fast2->prev, fast2 = fast1->prev) { MOZ_ASSERT(slow != fast1); @@ -384,14 +419,14 @@ class LinkedList * isSentinel == true. */ for (const LinkedListElement* elem = sentinel.next; - elem != sentinel; + elem != &sentinel; elem = elem->next) { MOZ_ASSERT(!elem->isSentinel); } /* Check that the next/prev pointers match up. */ - const LinkedListElement* prev = sentinel; + const LinkedListElement* prev = &sentinel; const LinkedListElement* cur = sentinel.next; do { MOZ_ASSERT(cur->prev == prev); @@ -399,7 +434,7 @@ class LinkedList prev = cur; cur = cur->next; - } while (cur != sentinel); + } while (cur != &sentinel); #endif /* ifdef DEBUG */ } diff --git a/external/spidermonkey/include/android/mozilla/MSIntTypes.h b/external/spidermonkey/include/android/mozilla/MSIntTypes.h new file mode 100644 index 0000000000..3dfba55f58 --- /dev/null +++ b/external/spidermonkey/include/android/mozilla/MSIntTypes.h @@ -0,0 +1,198 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006 Alexander Chemeris +// +// 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, +// this list of conditions and the following disclaimer. +// +// 2. 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. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// DO NOT SUPPORT THE scanf MACROS! See the comment at the top of +// IntegerPrintfMacros.h. + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + + +#endif // _MSC_INTTYPES_H_ ] diff --git a/external/spidermonkey/include/android/mozilla/MathAlgorithms.h b/external/spidermonkey/include/android/mozilla/MathAlgorithms.h index 6d58691e06..941ac81271 100644 --- a/external/spidermonkey/include/android/mozilla/MathAlgorithms.h +++ b/external/spidermonkey/include/android/mozilla/MathAlgorithms.h @@ -186,6 +186,16 @@ namespace detail { return uint_fast8_t(index); } + inline uint_fast8_t + CountPopulation32(uint32_t u) + { + uint32_t sum2 = (u & 0x55555555) + ((u & 0xaaaaaaaa) >> 1); + uint32_t sum4 = (sum2 & 0x33333333) + ((sum2 & 0xcccccccc) >> 2); + uint32_t sum8 = (sum4 & 0x0f0f0f0f) + ((sum4 & 0xf0f0f0f0) >> 4); + uint32_t sum16 = (sum8 & 0x00ff00ff) + ((sum8 & 0xff00ff00) >> 8); + return sum16; + } + inline uint_fast8_t CountLeadingZeroes64(uint64_t u) { @@ -242,6 +252,12 @@ namespace detail { return __builtin_ctz(u); } + inline uint_fast8_t + CountPopulation32(uint32_t u) + { + return __builtin_popcount(u); + } + inline uint_fast8_t CountLeadingZeroes64(uint64_t u) { @@ -258,6 +274,7 @@ namespace detail { # error "Implement these!" inline uint_fast8_t CountLeadingZeroes32(uint32_t u) MOZ_DELETE; inline uint_fast8_t CountTrailingZeroes32(uint32_t u) MOZ_DELETE; + inline uint_fast8_t CountPopulation32(uint32_t u) MOZ_DELETE; inline uint_fast8_t CountLeadingZeroes64(uint64_t u) MOZ_DELETE; inline uint_fast8_t CountTrailingZeroes64(uint64_t u) MOZ_DELETE; #endif @@ -300,6 +317,15 @@ CountTrailingZeroes32(uint32_t u) return detail::CountTrailingZeroes32(u); } +/** + * Compute the number of one bits in the number |u|, + */ +inline uint_fast8_t +CountPopulation32(uint32_t u) +{ + return detail::CountPopulation32(u); +} + /** Analogous to CountLeadingZeroes32, but for 64-bit numbers. */ inline uint_fast8_t CountLeadingZeroes64(uint64_t u) diff --git a/external/spidermonkey/include/android/mozilla/Maybe.h b/external/spidermonkey/include/android/mozilla/Maybe.h new file mode 100644 index 0000000000..25683a28ab --- /dev/null +++ b/external/spidermonkey/include/android/mozilla/Maybe.h @@ -0,0 +1,163 @@ +/* -*- 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 lazily constructing an object without sticking it on the heap. */ + +#ifndef mozilla_Maybe_h +#define mozilla_Maybe_h + +#include "mozilla/Alignment.h" +#include "mozilla/Assertions.h" + +// For placement new +#include + +namespace mozilla { + +/* + * Small utility for lazily constructing objects without using dynamic storage. + * When a Maybe is constructed, it is |empty()|, i.e., no value of T has + * been constructed and no T destructor will be called when the Maybe is + * destroyed. Upon calling |construct|, a T object will be constructed with the + * given arguments and that object will be destroyed when the owning Maybe + * is destroyed. + * + * N.B. GCC seems to miss some optimizations with Maybe and may generate extra + * branches/loads/stores. Use with caution on hot paths. + */ +template +class Maybe +{ + AlignedStorage2 storage; + bool constructed; + + T& asT() { return *storage.addr(); } + + public: + Maybe() { constructed = false; } + ~Maybe() { if (constructed) asT().~T(); } + + bool empty() const { return !constructed; } + + void construct() { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(); + constructed = true; + } + + template + void construct(const T1& t1) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7, const T8& t8) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7, const T8& t8, const T9& t9) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8, t9); + constructed = true; + } + + template + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, + const T6& t6, const T7& t7, const T8& t8, const T9& t9, const T10& t10) { + MOZ_ASSERT(!constructed); + ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); + constructed = true; + } + + T* addr() { + MOZ_ASSERT(constructed); + return &asT(); + } + + T& ref() { + MOZ_ASSERT(constructed); + return asT(); + } + + const T& ref() const { + MOZ_ASSERT(constructed); + return const_cast(this)->asT(); + } + + void destroy() { + ref().~T(); + constructed = false; + } + + void destroyIfConstructed() { + if (!empty()) + destroy(); + } + + private: + Maybe(const Maybe& other) MOZ_DELETE; + const Maybe& operator=(const Maybe& other) MOZ_DELETE; +}; + +} // namespace mozilla + +#endif /* mozilla_Maybe_h */ diff --git a/external/spidermonkey/include/android/mozilla/Move.h b/external/spidermonkey/include/android/mozilla/Move.h index 97178daaa6..a18da32ad8 100644 --- a/external/spidermonkey/include/android/mozilla/Move.h +++ b/external/spidermonkey/include/android/mozilla/Move.h @@ -9,11 +9,21 @@ #ifndef mozilla_Move_h #define mozilla_Move_h +#include "mozilla/TypeTraits.h" + namespace mozilla { /* * "Move" References * + * [Once upon a time, C++11 rvalue references were not implemented by all the + * compilers we cared about, so we invented mozilla::Move() (now called + * OldMove()), which does something similar. We're in the process of + * transitioning away from this to pure stl (bug 896100). Until that bug is + * completed, this header will provide both mozilla::OldMove() and + * mozilla::Move().] + * + * * 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: @@ -48,18 +58,28 @@ namespace mozilla { * efficiently than it can be copied, and provide an implementation of that * move operation. * - * The Move(T&) function takes a reference to a T, and returns a MoveRef - * referring to the same value; that's 1). A MoveRef is simply a reference + * The OldMove(T&) function takes a reference to a T, and returns a MoveRef + * referring to the same value; that's (1). A MoveRef is simply a reference * to a T, annotated to say that a copy constructor applied to it may move that * T, instead of copying it. Finally, a constructor that accepts an MoveRef - * should perform a more efficient move, instead of a copy, providing 2). + * should perform a more efficient move, instead of a copy, providing (2). * - * So, where we might define a copy constructor for a class C like this: + * The Move(T&) function takes a reference to a T and returns a T&&. It acts + * just like std::move(), which is not available on all our platforms. + * + * In new code, you should use Move(T&) and T&& instead of OldMove(T&) and + * MoveRef, where possible. + * + * 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 ... } + * + * or, in the deprecated OldMove style: + * * C(MoveRef rhs) { ... move rhs to this ... } * * And where we might perform a copy like this: @@ -68,7 +88,11 @@ namespace mozilla { * * we would perform a move like this: * - * C c2(Move(c1)) + * C c2(Move(c1)); + * + * or, in the deprecated OldMove style: + * + * C c2(OldMove(c1)); * * Note that MoveRef implicitly converts to T&, so you can pass a MoveRef * to an ordinary copy constructor for a type that doesn't support a special @@ -82,7 +106,7 @@ namespace mozilla { * which runs this's destructor, and then applies the move constructor to * *this's memory. A typical definition: * - * C& operator=(MoveRef rhs) { + * C& operator=(C&& rhs) { // or |MoveRef rhs| * this->~C(); * new(this) C(rhs); * return *this; @@ -90,14 +114,14 @@ namespace mozilla { * * With that in place, one can write move assignments like this: * - * c2 = Move(c1); + * c2 = Move(c1); // or OldMove() * * This destroys c1, moves c1's value to c2, and leaves c1 in an undefined but * destructible state. * - * This header file defines MoveRef and Move 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. + * This header file defines MoveRef, Move, and OldMove in the mozilla namespace. + * It's up to individual containers to annotate moves as such, by calling Move + * or OldMove; and it's up to individual types to define move constructors. * * One hint: if you're writing a move constructor where the type has members * that should be moved themselves, it's much nicer to write this: @@ -125,14 +149,14 @@ class MoveRef template inline MoveRef -Move(T& t) +OldMove(T& t) { return MoveRef(t); } template inline MoveRef -Move(const T& t) +OldMove(const T& t) { // With some versions of gcc, for a class C, there's an (incorrect) ambiguity // between the C(const C&) constructor and the default C(C&&) C++11 move @@ -151,14 +175,45 @@ Move(const T& t) return MoveRef(const_cast(t)); } +/** + * Identical to std::Move(); this is necessary until our stlport supports + * std::move(). + */ +template +inline typename RemoveReference::Type&& +Move(T&& a) +{ + return static_cast::Type&&>(a); +} + +/** + * These two overloads are identidal to std::Forward(); they are necessary until + * our stlport supports std::forward(). + */ +template +inline T&& +Forward(typename RemoveReference::Type& a) +{ + return static_cast(a); +} + +template +inline T&& +Forward(typename RemoveReference::Type&& t) +{ + static_assert(!IsLvalueReference::value, + "misuse of Forward detected! try the other overload"); + return static_cast(t); +} + /** Swap |t| and |u| using move-construction if possible. */ template inline void Swap(T& t, T& u) { - T tmp(Move(t)); - t = Move(u); - u = Move(tmp); + T tmp(OldMove(t)); + t = OldMove(u); + u = OldMove(tmp); } } // namespace mozilla diff --git a/external/spidermonkey/include/android/mozilla/NullPtr.h b/external/spidermonkey/include/android/mozilla/NullPtr.h index 14c0f07df2..35faadc4c3 100644 --- a/external/spidermonkey/include/android/mozilla/NullPtr.h +++ b/external/spidermonkey/include/android/mozilla/NullPtr.h @@ -12,8 +12,6 @@ #ifndef mozilla_NullPtr_h #define mozilla_NullPtr_h -#include "mozilla/Compiler.h" - #if defined(__clang__) # ifndef __has_extension # define __has_extension __has_feature @@ -23,6 +21,7 @@ # endif #elif defined(__GNUC__) # if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L +# include "mozilla/Compiler.h" # if MOZ_GCC_VERSION_AT_LEAST(4, 6, 0) # define MOZ_HAVE_CXX11_NULLPTR # endif diff --git a/external/spidermonkey/include/android/mozilla/NumericLimits.h b/external/spidermonkey/include/android/mozilla/NumericLimits.h new file mode 100644 index 0000000000..d2ee29813e --- /dev/null +++ b/external/spidermonkey/include/android/mozilla/NumericLimits.h @@ -0,0 +1,40 @@ +/* -*- 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/. */ + +/* Compatibility with std::numeric_limits. */ + +#ifndef mozilla_NumericLimits_h +#define mozilla_NumericLimits_h + +#include "mozilla/Char16.h" + +#include +#include + +namespace mozilla { + +/** + * The NumericLimits class provides a compatibility layer with std::numeric_limits + * for char16_t, otherwise it is exactly the same as std::numeric_limits. + * Code which does not need std::numeric_limits should avoid using + * NumericLimits. + */ +template +class NumericLimits : public std::numeric_limits +{ +}; + +#ifdef MOZ_CHAR16_IS_NOT_WCHAR +template<> +class NumericLimits : public std::numeric_limits +{ + // char16_t and uint16_t numeric limits should be exactly the same. +}; +#endif + +} // namespace mozilla + +#endif /* mozilla_NumericLimits_h */ diff --git a/external/spidermonkey/include/android/mozilla/PodOperations.h b/external/spidermonkey/include/android/mozilla/PodOperations.h index bec89fa928..668197cdc1 100644 --- a/external/spidermonkey/include/android/mozilla/PodOperations.h +++ b/external/spidermonkey/include/android/mozilla/PodOperations.h @@ -24,7 +24,7 @@ namespace mozilla { /** Set the contents of |t| to 0. */ template -static void +static MOZ_ALWAYS_INLINE void PodZero(T* t) { memset(t, 0, sizeof(T)); @@ -32,7 +32,7 @@ PodZero(T* t) /** Set the contents of |nelem| elements starting at |t| to 0. */ template -static void +static MOZ_ALWAYS_INLINE void PodZero(T* t, size_t nelem) { /* @@ -58,7 +58,7 @@ static void PodZero(T (&t)[N], size_t nelem) MOZ_DELETE; /** Set the contents of the array |t| to zero. */ template -static void +static MOZ_ALWAYS_INLINE void PodArrayZero(T (&t)[N]) { memset(t, 0, N * sizeof(T)); @@ -69,7 +69,7 @@ PodArrayZero(T (&t)[N]) * overlap. */ template -static void +static MOZ_ALWAYS_INLINE void PodAssign(T* dst, const T* src) { MOZ_ASSERT(dst != src); @@ -83,7 +83,7 @@ PodAssign(T* dst, const T* src) * overlap! */ template -MOZ_ALWAYS_INLINE static void +static MOZ_ALWAYS_INLINE void PodCopy(T* dst, const T* src, size_t nelem) { MOZ_ASSERT(dst != src); @@ -103,7 +103,7 @@ PodCopy(T* dst, const T* src, size_t nelem) } template -MOZ_ALWAYS_INLINE static void +static MOZ_ALWAYS_INLINE void PodCopy(volatile T* dst, const volatile T* src, size_t nelem) { MOZ_ASSERT(dst != src); @@ -127,7 +127,7 @@ PodCopy(volatile T* dst, const volatile T* src, size_t nelem) * The arrays must not overlap! */ template -static void +static MOZ_ALWAYS_INLINE void PodArrayCopy(T (&dst)[N], const T (&src)[N]) { PodCopy(dst, src, N); @@ -138,7 +138,7 @@ PodArrayCopy(T (&dst)[N], const T (&src)[N]) * |len| elements at |two|. */ template -MOZ_ALWAYS_INLINE static bool +static MOZ_ALWAYS_INLINE bool PodEqual(const T* one, const T* two, size_t len) { if (len < 128) { diff --git a/external/spidermonkey/include/android/mozilla/RefPtr.h b/external/spidermonkey/include/android/mozilla/RefPtr.h index 3c275afdc7..72c7904554 100644 --- a/external/spidermonkey/include/android/mozilla/RefPtr.h +++ b/external/spidermonkey/include/android/mozilla/RefPtr.h @@ -68,18 +68,18 @@ class RefCounted public: // Compatibility with nsRefPtr. - void AddRef() { + void AddRef() const { MOZ_ASSERT(refCnt >= 0); ++refCnt; } - void Release() { + void Release() const { MOZ_ASSERT(refCnt > 0); if (0 == --refCnt) { #ifdef DEBUG refCnt = detail::DEAD; #endif - delete static_cast(this); + delete static_cast(this); } } @@ -93,7 +93,7 @@ class RefCounted } private: - typename Conditional, int>::Type refCnt; + mutable typename Conditional, int>::Type refCnt; }; } diff --git a/external/spidermonkey/include/android/mozilla/TypeTraits.h b/external/spidermonkey/include/android/mozilla/TypeTraits.h index 53c0b5c2f6..1ccd0c85d1 100644 --- a/external/spidermonkey/include/android/mozilla/TypeTraits.h +++ b/external/spidermonkey/include/android/mozilla/TypeTraits.h @@ -63,6 +63,9 @@ template<> struct IsIntegralHelper : TrueType {}; template<> struct IsIntegralHelper : TrueType {}; template<> struct IsIntegralHelper : TrueType {}; template<> struct IsIntegralHelper : TrueType {}; +#ifdef MOZ_CHAR16_IS_NOT_WCHAR +template<> struct IsIntegralHelper : TrueType {}; +#endif } /* namespace detail */ @@ -218,6 +221,9 @@ template<> struct IsPod : TrueType {}; template<> struct IsPod : TrueType {}; template<> struct IsPod : TrueType {}; template<> struct IsPod : TrueType {}; +#ifdef MOZ_CHAR16_IS_NOT_WCHAR +template<> struct IsPod : TrueType {}; +#endif template struct IsPod : TrueType {}; namespace detail { @@ -418,6 +424,16 @@ struct IsConvertible : IntegralConstant::value> {}; +/** + * Is IsLvalueReference is true if its template param is T& and is false if + * its type is T or T&&. + */ +template +struct IsLvalueReference : FalseType {}; + +template +struct IsLvalueReference : TrueType {}; + /* 20.9.7 Transformations between types [meta.trans] */ /* 20.9.7.1 Const-volatile modifications [meta.trans.cv] */ @@ -478,6 +494,32 @@ struct RemoveCV /* 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; +}; + /* 20.9.7.3 Sign modifications [meta.trans.sign] */ template diff --git a/external/spidermonkey/include/android/mozilla/TypedEnum.h b/external/spidermonkey/include/android/mozilla/TypedEnum.h index 6f595cb4c5..9c7590deff 100644 --- a/external/spidermonkey/include/android/mozilla/TypedEnum.h +++ b/external/spidermonkey/include/android/mozilla/TypedEnum.h @@ -28,7 +28,7 @@ # endif #elif defined(__GNUC__) # if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L -# if MOZ_GCC_VERSION_AT_LEAST(4, 5, 1) +# if MOZ_GCC_VERSION_AT_LEAST(4, 6, 3) # define MOZ_HAVE_CXX11_ENUM_TYPE # define MOZ_HAVE_CXX11_STRONG_ENUMS # endif @@ -72,7 +72,7 @@ * strongly-typed enumeration feature of C++11 ("enum class"). If supported * by the compiler, an enum defined using these macros will not be implicitly * converted to any other type, and its enumerators will be scoped using the - * enumeration name. Place MOZ_BEGIN_ENUM_CLASS(EnumName, type) in place of + * enumeration name. Place MOZ_BEGIN_ENUM_CLASS(EnumName [, type]) in place of * "enum EnumName {", and MOZ_END_ENUM_CLASS(EnumName) in place of the closing * "};". For example, * @@ -87,10 +87,9 @@ * fail. In other compilers, Enum itself will actually be defined as a class, * and some implicit conversions will fail while others will succeed. * - * The type argument specifies the underlying type for the enum where - * supported, as with MOZ_ENUM_TYPE(). For simplicity, it is currently - * mandatory. As with MOZ_ENUM_TYPE(), it will do nothing on compilers that do - * not support it. + * The optional type argument specifies the underlying type for the enum where + * supported, as with MOZ_ENUM_TYPE(). As with MOZ_ENUM_TYPE(), it will do + * nothing on compilers that do not support it. * * MOZ_{BEGIN,END}_ENUM_CLASS doesn't work for defining enum classes nested * inside classes. To define an enum class nested inside another class, use @@ -114,7 +113,12 @@ * All compilers that support strong enums also support an explicit * underlying type, so no extra check is needed. */ -# define MOZ_BEGIN_NESTED_ENUM_CLASS(Name, type) \ + + /* Single-argument form. */ +# define MOZ_BEGIN_NESTED_ENUM_CLASS_HELPER1(Name) \ + enum class Name { + /* Two-argument form. */ +# define MOZ_BEGIN_NESTED_ENUM_CLASS_HELPER2(Name, type) \ enum class Name : type { # define MOZ_END_NESTED_ENUM_CLASS(Name) \ }; @@ -154,8 +158,17 @@ * { * return Enum::A; * } - */\ -# define MOZ_BEGIN_NESTED_ENUM_CLASS(Name, type) \ + */ + + /* Single-argument form. */ +# define MOZ_BEGIN_NESTED_ENUM_CLASS_HELPER1(Name) \ + class Name \ + { \ + public: \ + enum Enum \ + { + /* Two-argument form. */ +# define MOZ_BEGIN_NESTED_ENUM_CLASS_HELPER2(Name, type) \ class Name \ { \ public: \ @@ -226,7 +239,36 @@ inline int& operator<<=(int&, const Name::Enum&) MOZ_DELETE; \ inline int& operator>>=(int&, const Name::Enum&) MOZ_DELETE; #endif -# define MOZ_BEGIN_ENUM_CLASS(Name, type) MOZ_BEGIN_NESTED_ENUM_CLASS(Name, type) + + /* + * Count the number of arguments passed to MOZ_COUNT_BEGIN_ENUM_CLASS_ARGS, + * very carefully tiptoeing around an MSVC bug where it improperly expands + * __VA_ARGS__ as a single token in argument lists. See these URLs for + * details: + * + * 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_COUNT_BEGIN_ENUM_CLASS_ARGS_IMPL2(_1, _2, count, ...) \ + count +# define MOZ_COUNT_BEGIN_ENUM_CLASS_ARGS_IMPL(args) \ + MOZ_COUNT_BEGIN_ENUM_CLASS_ARGS_IMPL2 args +# define MOZ_COUNT_BEGIN_ENUM_CLASS_ARGS(...) \ + MOZ_COUNT_BEGIN_ENUM_CLASS_ARGS_IMPL((__VA_ARGS__, 2, 1, 0)) + /* Pick the right helper macro to invoke. */ +# define MOZ_BEGIN_NESTED_ENUM_CLASS_CHOOSE_HELPER2(count) \ + MOZ_BEGIN_NESTED_ENUM_CLASS_HELPER##count +# define MOZ_BEGIN_NESTED_ENUM_CLASS_CHOOSE_HELPER1(count) \ + MOZ_BEGIN_NESTED_ENUM_CLASS_CHOOSE_HELPER2(count) +# define MOZ_BEGIN_NESTED_ENUM_CLASS_CHOOSE_HELPER(count) \ + MOZ_BEGIN_NESTED_ENUM_CLASS_CHOOSE_HELPER1(count) + /* The actual macro. */ +# define MOZ_BEGIN_NESTED_ENUM_CLASS_GLUE(x, y) x y +# define MOZ_BEGIN_NESTED_ENUM_CLASS(...) \ + MOZ_BEGIN_NESTED_ENUM_CLASS_GLUE(MOZ_BEGIN_NESTED_ENUM_CLASS_CHOOSE_HELPER(MOZ_COUNT_BEGIN_ENUM_CLASS_ARGS(__VA_ARGS__)), \ + (__VA_ARGS__)) + +# define MOZ_BEGIN_ENUM_CLASS(...) MOZ_BEGIN_NESTED_ENUM_CLASS(__VA_ARGS__) # define MOZ_END_ENUM_CLASS(Name) \ MOZ_END_NESTED_ENUM_CLASS(Name) \ MOZ_FINISH_NESTED_ENUM_CLASS(Name) diff --git a/external/spidermonkey/include/android/mozilla/Util.h b/external/spidermonkey/include/android/mozilla/Util.h index 4f1c634a59..b4cf2e425b 100644 --- a/external/spidermonkey/include/android/mozilla/Util.h +++ b/external/spidermonkey/include/android/mozilla/Util.h @@ -18,267 +18,10 @@ #ifdef __cplusplus +#include "mozilla/Alignment.h" + namespace mozilla { -/* - * This class, and the corresponding macro MOZ_ALIGNOF, figure out how many - * bytes of alignment a given type needs. - */ -template -class AlignmentFinder -{ - struct Aligner - { - char c; - T t; - }; - - 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 bytes[nbytes]; - uint64_t _; - } u; - - const void* addr() const { return u.bytes; } - void* addr() { return u.bytes; } -}; - -template -struct AlignedStorage2 -{ - union U { - char bytes[sizeof(T)]; - uint64_t _; - } u; - - const T* addr() const { return reinterpret_cast(u.bytes); } - T* addr() { return static_cast(static_cast(u.bytes)); } -}; - -/* - * Small utility for lazily constructing objects without using dynamic storage. - * When a Maybe is constructed, it is |empty()|, i.e., no value of T has - * been constructed and no T destructor will be called when the Maybe is - * destroyed. Upon calling |construct|, a T object will be constructed with the - * given arguments and that object will be destroyed when the owning Maybe - * is destroyed. - * - * N.B. GCC seems to miss some optimizations with Maybe and may generate extra - * branches/loads/stores. Use with caution on hot paths. - */ -template -class Maybe -{ - AlignedStorage2 storage; - bool constructed; - - T& asT() { return *storage.addr(); } - - public: - Maybe() { constructed = false; } - ~Maybe() { if (constructed) asT().~T(); } - - bool empty() const { return !constructed; } - - void construct() { - MOZ_ASSERT(!constructed); - ::new (storage.addr()) T(); - constructed = true; - } - - template - void construct(const T1& t1) { - MOZ_ASSERT(!constructed); - ::new (storage.addr()) T(t1); - constructed = true; - } - - template - void construct(const T1& t1, const T2& t2) { - MOZ_ASSERT(!constructed); - ::new (storage.addr()) T(t1, t2); - constructed = true; - } - - template - void construct(const T1& t1, const T2& t2, const T3& t3) { - MOZ_ASSERT(!constructed); - ::new (storage.addr()) T(t1, t2, t3); - constructed = true; - } - - template - void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4) { - MOZ_ASSERT(!constructed); - ::new (storage.addr()) T(t1, t2, t3, t4); - constructed = true; - } - - template - void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) { - MOZ_ASSERT(!constructed); - ::new (storage.addr()) T(t1, t2, t3, t4, t5); - constructed = true; - } - - template - void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, - const T6& t6) { - MOZ_ASSERT(!constructed); - ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6); - constructed = true; - } - - template - void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, - const T6& t6, const T7& t7) { - MOZ_ASSERT(!constructed); - ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7); - constructed = true; - } - - template - void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, - const T6& t6, const T7& t7, const T8& t8) { - MOZ_ASSERT(!constructed); - ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8); - constructed = true; - } - - template - void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, - const T6& t6, const T7& t7, const T8& t8, const T9& t9) { - MOZ_ASSERT(!constructed); - ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8, t9); - constructed = true; - } - - template - void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, - const T6& t6, const T7& t7, const T8& t8, const T9& t9, const T10& t10) { - MOZ_ASSERT(!constructed); - ::new (storage.addr()) T(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); - constructed = true; - } - - T* addr() { - MOZ_ASSERT(constructed); - return &asT(); - } - - T& ref() { - MOZ_ASSERT(constructed); - return asT(); - } - - const T& ref() const { - MOZ_ASSERT(constructed); - return const_cast(this)->asT(); - } - - void destroy() { - ref().~T(); - constructed = false; - } - - void destroyIfConstructed() { - if (!empty()) - destroy(); - } - - private: - Maybe(const Maybe& other) MOZ_DELETE; - const Maybe& operator=(const Maybe& other) MOZ_DELETE; -}; - /* * Safely subtract two pointers when it is known that end >= begin. This avoids * the common compiler bug that if (size_t(end) - size_t(begin)) has the MSB diff --git a/external/spidermonkey/include/android/mozilla/Vector.h b/external/spidermonkey/include/android/mozilla/Vector.h index 8759df8c06..54e266eeb7 100644 --- a/external/spidermonkey/include/android/mozilla/Vector.h +++ b/external/spidermonkey/include/android/mozilla/Vector.h @@ -9,6 +9,7 @@ #ifndef mozilla_Vector_h #define mozilla_Vector_h +#include "mozilla/Alignment.h" #include "mozilla/AllocPolicy.h" #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" @@ -19,7 +20,7 @@ #include "mozilla/ReentrancyGuard.h" #include "mozilla/TemplateLib.h" #include "mozilla/TypeTraits.h" -#include "mozilla/Util.h" +#include "mozilla/Util.h" // for PointerRangeSize #include // for placement new @@ -85,7 +86,7 @@ struct VectorImpl template static inline void moveConstruct(T* dst, const U* srcbeg, const U* srcend) { for (const U* p = srcbeg; p < srcend; ++p, ++dst) - new(dst) T(Move(*p)); + new(dst) T(OldMove(*p)); } /* @@ -114,7 +115,7 @@ struct VectorImpl T* dst = newbuf; T* src = v.beginNoCheck(); for (; src < v.endNoCheck(); ++dst, ++src) - new(dst) T(Move(*src)); + new(dst) T(OldMove(*src)); VectorImpl::destroy(v.beginNoCheck(), v.endNoCheck()); v.free_(v.mBegin); v.mBegin = newbuf; @@ -547,8 +548,8 @@ class VectorBase : private AllocPolicy void swap(ThisVector& other); private: - VectorBase(const ThisVector&) MOZ_DELETE; - void operator=(const ThisVector&) MOZ_DELETE; + VectorBase(const VectorBase&) MOZ_DELETE; + void operator=(const VectorBase&) MOZ_DELETE; }; /* This does the re-entrancy check plus several other sanity checks. */ @@ -565,14 +566,15 @@ template MOZ_ALWAYS_INLINE VectorBase::VectorBase(AP ap) : AP(ap), - mBegin(static_cast(storage.addr())), mLength(0), mCapacity(sInlineCapacity) #ifdef DEBUG , mReserved(sInlineCapacity), entered(false) #endif -{} +{ + mBegin = static_cast(storage.addr()); +} /* Move constructor. */ template diff --git a/external/spidermonkey/include/android/mozilla/WeakPtr.h b/external/spidermonkey/include/android/mozilla/WeakPtr.h index c714ebf565..0165e3a017 100644 --- a/external/spidermonkey/include/android/mozilla/WeakPtr.h +++ b/external/spidermonkey/include/android/mozilla/WeakPtr.h @@ -14,9 +14,6 @@ * the WeakPtrs to it and allows the WeakReference to live beyond the lifetime * of 'Foo'. * - * AtomicSupportsWeakPtr can be used for a variant with an atomically updated - * reference counter. - * * 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. @@ -63,7 +60,6 @@ #define mozilla_WeakPtr_h #include "mozilla/Assertions.h" -#include "mozilla/Atomics.h" #include "mozilla/NullPtr.h" #include "mozilla/RefPtr.h" #include "mozilla/TypeTraits.h" @@ -76,8 +72,8 @@ template class SupportsWeakPtrBase; namespace detail { // This can live beyond the lifetime of the class derived from SupportsWeakPtrBase. -template -class WeakReference : public RefCounted, Atomicity> +template +class WeakReference : public ::mozilla::RefCounted > { public: explicit WeakReference(T* p) : ptr(p) {} @@ -86,8 +82,8 @@ class WeakReference : public RefCounted, Atomicity> } private: - friend class WeakPtrBase; - friend class SupportsWeakPtrBase; + friend class WeakPtrBase >; + friend class SupportsWeakPtrBase >; void detach() { ptr = nullptr; } @@ -121,30 +117,10 @@ class SupportsWeakPtrBase }; template -class SupportsWeakPtr - : public SupportsWeakPtrBase > +class SupportsWeakPtr : public SupportsWeakPtrBase > { }; -template -class AtomicSupportsWeakPtr - : public SupportsWeakPtrBase > -{ -}; - -namespace detail { - -template -struct WeakReferenceCount -{ - static const RefCountAtomicity atomicity = - IsBaseOf, T>::value - ? AtomicRefCount - : NonAtomicRefCount; -}; - -} - template class WeakPtrBase { @@ -177,9 +153,9 @@ class WeakPtrBase }; template -class WeakPtr : public WeakPtrBase::atomicity> > +class WeakPtr : public WeakPtrBase > { - typedef WeakPtrBase::atomicity> > Base; + typedef WeakPtrBase > Base; public: WeakPtr(const WeakPtr& o) : Base(o) {} WeakPtr(const Base& o) : Base(o) {} diff --git a/external/spidermonkey/prebuilt/android/armeabi-v7a/libjs_static.a.REMOVED.git-id b/external/spidermonkey/prebuilt/android/armeabi-v7a/libjs_static.a.REMOVED.git-id index 66d2ff3161..6bbb419c6a 100644 --- a/external/spidermonkey/prebuilt/android/armeabi-v7a/libjs_static.a.REMOVED.git-id +++ b/external/spidermonkey/prebuilt/android/armeabi-v7a/libjs_static.a.REMOVED.git-id @@ -1 +1 @@ -0e1091b9f67b4d348d01b69e998be70c9e0b2dad \ No newline at end of file +4b3fc16c923b538ff3a3d9e92edb34f7f3667c7d \ No newline at end of file diff --git a/external/spidermonkey/prebuilt/android/armeabi/libjs_static.a.REMOVED.git-id b/external/spidermonkey/prebuilt/android/armeabi/libjs_static.a.REMOVED.git-id index 8a8f30faca..c1b52596e4 100644 --- a/external/spidermonkey/prebuilt/android/armeabi/libjs_static.a.REMOVED.git-id +++ b/external/spidermonkey/prebuilt/android/armeabi/libjs_static.a.REMOVED.git-id @@ -1 +1 @@ -23bfd06f14371832fa99b4efb76133ade10887ec \ No newline at end of file +dcc9ffddbaadb4ee17587e6aaf603411a3e01c20 \ No newline at end of file diff --git a/external/spidermonkey/prebuilt/android/x86/libjs_static.a.REMOVED.git-id b/external/spidermonkey/prebuilt/android/x86/libjs_static.a.REMOVED.git-id index fbdaca36eb..240dfdfb93 100644 --- a/external/spidermonkey/prebuilt/android/x86/libjs_static.a.REMOVED.git-id +++ b/external/spidermonkey/prebuilt/android/x86/libjs_static.a.REMOVED.git-id @@ -1 +1 @@ -1eb9de4a5ab182f329be479e736c06ac8ab83a00 \ No newline at end of file +6f92f63db1d08b638c61e8ca9fe26f90358a21f6 \ No newline at end of file